From: Petr Mladek <pmladek@suse.cz>
To: Seth Jennings <sjenning@redhat.com>,
Josh Poimboeuf <jpoimboe@redhat.com>,
Jiri Kosina <jkosina@suse.cz>, Vojtech Pavlik <vojtech@suse.cz>,
Steven Rostedt <rostedt@goodmis.org>,
Miroslav Benes <mbenes@suse.cz>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Christoph Hellwig <hch@infradead.org>,
Greg KH <gregkh@linuxfoundation.org>,
Andy Lutomirski <luto@amacapital.net>,
live-patching@vger.kernel.org, x86@kernel.org, kpatch@redhat.com,
linux-kernel@vger.kernel.org, Petr Mladek <pmladek@suse.cz>
Subject: [PATCH 3/6] livepatch v5: find and verify the old address in klp_*_init()
Date: Tue, 9 Dec 2014 19:05:04 +0100 [thread overview]
Message-ID: <1418148307-21434-4-git-send-email-pmladek@suse.cz> (raw)
In-Reply-To: <1418148307-21434-1-git-send-email-pmladek@suse.cz>
The patched address is found and checked when the patch is enabled.
If there is a failure the patch must be reverted. It might happen,
for example, when there are duplicated symbols or when the patch
and the kernel are incompatible.
It would be better to detect these problems earlier when the structures
are initialized. It will also help to avoid the costly symbol lookup
when the patch is disabled and enabled again.
This patch does the necessary changes. It adds some complexity
to module_coming() and module_going() functions but I think that
the design is cleaner. For example, it removes the strange situation
when klp_find_verify_func_addr() sets func->old_addr but it complains
when even a valid value has already been set before.
Note that I plan to remove the duplicate code by introducing
__klp_init_func().
Signed-off-by: Petr Mladek <pmladek@suse.cz>
---
kernel/livepatch/core.c | 44 +++++++++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 034f79a926af..54bb39d3abb5 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -179,7 +179,8 @@ static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr)
return -EINVAL;
}
-static int klp_find_verify_func_addr(struct klp_func *func, const char *objname)
+static int klp_find_verify_func_addr(struct klp_object *obj,
+ struct klp_func *func)
{
int ret;
@@ -188,17 +189,18 @@ static int klp_find_verify_func_addr(struct klp_func *func, const char *objname)
func->old_addr = 0;
#endif
- if (func->old_addr && objname) {
- pr_err("old address specified for module symbol\n");
- return -EINVAL;
- }
-
- if (func->old_addr)
+ /*
+ * If the old address is predefined, it might be used to check
+ * the consistency between the patch and the patched kernel.
+ * This does not work for kernel modules where the address
+ * always must be detected.
+ */
+ if (!func->old_addr || klp_is_module(obj))
+ ret = klp_find_object_symbol(obj->name, func->old_name,
+ &func->old_addr);
+ else
ret = klp_verify_vmlinux_symbol(func->old_name,
func->old_addr);
- else
- ret = klp_find_object_symbol(objname, func->old_name,
- &func->old_addr);
return ret;
}
@@ -348,9 +350,6 @@ static int klp_disable_object(struct klp_object *obj)
ret = klp_disable_func(func);
if (ret)
return ret;
-
- if (klp_is_module(obj))
- func->old_addr = 0;
}
obj->state = KLP_DISABLED;
@@ -370,10 +369,6 @@ static int klp_enable_object(struct klp_object *obj)
return -EINVAL;
for (func = obj->funcs; func->old_name; func++) {
- ret = klp_find_verify_func_addr(func, obj->name);
- if (ret)
- goto unregister;
-
ret = klp_enable_func(func);
if (ret)
goto unregister;
@@ -512,6 +507,7 @@ EXPORT_SYMBOL_GPL(klp_enable_patch);
static void klp_module_notify_coming(struct module *pmod,
struct klp_object *obj)
{
+ struct klp_func *func;
struct module *mod = obj->mod;
int ret;
@@ -524,6 +520,12 @@ static void klp_module_notify_coming(struct module *pmod,
goto err;
}
+ for (func = obj->funcs; func->old_name; func++) {
+ ret = klp_find_verify_func_addr(obj, func);
+ if (ret)
+ goto err;
+ }
+
ret = klp_enable_object(obj);
if (!ret)
return;
@@ -536,6 +538,7 @@ err:
static void klp_module_notify_going(struct module *pmod,
struct klp_object *obj)
{
+ struct klp_func *func;
struct module *mod = obj->mod;
int ret;
@@ -547,6 +550,9 @@ static void klp_module_notify_going(struct module *pmod,
pr_warn("failed to revert patch '%s' on module '%s' (%d)\n",
pmod->name, mod->name, ret);
+ for (func = obj->funcs; func->old_name; func++)
+ func->old_addr = 0;
+
obj->mod = NULL;
}
@@ -719,6 +725,10 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func)
func->state = KLP_DISABLED;
+ ret = klp_find_verify_func_addr(obj, func);
+ if (ret)
+ return ret;
+
ops = kzalloc(sizeof(*ops), GFP_KERNEL);
if (!ops)
ret = -ENOMEM;
--
1.8.5.2
next prev parent reply other threads:[~2014-12-09 18:06 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-09 18:05 [PATCH 0/6] livepatch v5: more clean up for the v5 of the patchset Petr Mladek
2014-12-09 18:05 ` [PATCH 1/6] livepatch v5: avoid race when checking for state of the patch Petr Mladek
2014-12-09 18:32 ` Josh Poimboeuf
2014-12-10 10:11 ` Petr Mladek
2014-12-10 15:25 ` Josh Poimboeuf
2014-12-11 11:17 ` Petr Mladek
2014-12-11 14:23 ` Josh Poimboeuf
2014-12-09 18:05 ` [PATCH 2/6] livepatch v5: do not quietly ignore wrong usage Petr Mladek
2014-12-09 18:05 ` Petr Mladek [this message]
2014-12-09 18:05 ` [PATCH 4/6] livepatch v5: clean up ordering of functions Petr Mladek
2014-12-09 18:05 ` [PATCH 5/6] livepatch v5: split init and free code that is done only for loaded modules Petr Mladek
2014-12-09 18:51 ` Josh Poimboeuf
2014-12-10 10:30 ` Petr Mladek
2014-12-10 15:34 ` Josh Poimboeuf
2014-12-09 18:05 ` [PATCH 6/6] livepatch v5: clean up usage of the old and new addresses Petr Mladek
2014-12-09 19:20 ` Josh Poimboeuf
2014-12-10 13:50 ` Petr Mladek
2014-12-10 15:33 ` Josh Poimboeuf
2014-12-11 11:30 ` Petr Mladek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1418148307-21434-4-git-send-email-pmladek@suse.cz \
--to=pmladek@suse.cz \
--cc=gregkh@linuxfoundation.org \
--cc=hch@infradead.org \
--cc=jkosina@suse.cz \
--cc=jpoimboe@redhat.com \
--cc=kpatch@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mbenes@suse.cz \
--cc=rostedt@goodmis.org \
--cc=sjenning@redhat.com \
--cc=vojtech@suse.cz \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®