From: Petr Mladek <pmladek@suse.com>
To: Joe Lawrence <joe.lawrence@redhat.com>
Cc: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
Josh Poimboeuf <jpoimboe@redhat.com>,
Jessica Yu <jeyu@kernel.org>, Jiri Kosina <jikos@kernel.org>,
Miroslav Benes <mbenes@suse.cz>,
Chris J Arges <chris.j.arges@canonical.com>
Subject: Re: [RFC] livepatch: unpatch all klp_objects if klp_module_coming fails
Date: Wed, 27 Sep 2017 14:17:20 +0200 [thread overview]
Message-ID: <20170927121720.GN21048@pathway.suse.cz> (raw)
In-Reply-To: <1505338598-16041-1-git-send-email-joe.lawrence@redhat.com>
On Wed 2017-09-13 17:36:38, Joe Lawrence wrote:
> >From b80b90cb54b498d2b1165d409ce4b0ca47610b36 Mon Sep 17 00:00:00 2001
> From: Joe Lawrence <joe.lawrence@redhat.com>
> Date: Wed, 13 Sep 2017 16:51:13 -0400
> Subject: [RFC] livepatch: unpatch all klp_objects if klp_module_coming fails
>
> When an incoming module is considered for livepatching by
> klp_module_coming(), it iterates over multiple patches and multiple
> kernel objects in this order:
>
> list_for_each_entry(patch, &klp_patches, list) {
> klp_for_each_object(patch, obj) {
>
> which means that if one of the kernel objects fail to patch for whatever
> reason, klp_module_coming()'s error path should double back and unpatch
> any previous kernel object that was patched for a previous patch.
>
> Reported-by: Miroslav Benes <mbenes@suse.cz>
> Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
> ---
> kernel/livepatch/core.c | 30 +++++++++++++++++++++++++++++-
> 1 file changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
> index aca62c4b8616..7f5192618cc8 100644
> --- a/kernel/livepatch/core.c
> +++ b/kernel/livepatch/core.c
> @@ -889,6 +889,8 @@ int klp_module_coming(struct module *mod)
> goto err;
> }
>
> +pr_err("JL: klp_patch_object(%p) patch=%p obj->name: %s\n", obj, patch, obj->name);
> +
> ret = klp_patch_object(obj);
> if (ret) {
> pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
> @@ -919,7 +921,33 @@ int klp_module_coming(struct module *mod)
> pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n",
> patch->mod->name, obj->mod->name, obj->mod->name);
> mod->klp_alive = false;
> - klp_free_object_loaded(obj);
> +
> + /*
> + * Run back through the patch list and unpatch any klp_object that
> + * was patched before hitting an error above.
> + */
> +
> + list_for_each_entry(patch, &klp_patches, list) {
> +
> + if (!patch->enabled || patch == klp_transition_patch)
> + continue;
klp_init_object_loaded() is called even the patch is not enabled.
Therefore we need to call klp_free_object_loaded() for all
objects where this was called.
> + klp_for_each_object(patch, obj) {
> +
> + if (!obj->patched || !klp_is_module(obj) ||
> + strcmp(obj->name, mod->name))
> + continue;
> +
> + klp_pre_unpatch_callback(obj);
> +pr_err("JL: klp_unpatch_object(%p) patch=%p obj->name: %s\n", obj, patch, obj->name);
> + klp_unpatch_object(obj);
> + klp_post_unpatch_callback(obj);
> + klp_free_object_loaded(obj);
> +
> + break;
> + }
> + }
Well, we basically need to do the same as we do in
__klp_module_coming(). I would suggest to somehow
reuse the code.
The question is how to detect the patches that need
the revert. I would suggest to use the same trick that
we use in klp_free_funcs_limited() and do something like:
void __klp_module_going_limited(struct module *mod,
struct klp_patch *limit)
{
struct klp_patch *patch;
struct klp_object *obj;
/*
* Each module has to know that klp_module_going()
* has been called. We never know what module will
* get patched by a new patch.
*/
mod->klp_alive = false;
list_for_each_entry(patch, &klp_patches, list) {
if (patch == limit)
break;
klp_for_each_object(patch, obj) {
if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
continue;
/*
* Only unpatch the module if the patch is enabled or
* is in transition.
*/
if (patch->enabled || patch == klp_transition_patch) {
if (patch != klp_transition_patch)
klp_pre_unpatch_callback(obj);
pr_notice("reverting patch '%s' on unloading module '%s'\n",
patch->mod->name, obj->mod->name);
klp_unpatch_object(obj);
klp_post_unpatch_callback(obj);
}
klp_free_object_loaded(obj);
break;
}
}
}
Also please make this the first patch in the series. It fixes
an existing problem. We might want to get this in earlier
than the rest of the patchset.
Best Regards,
Petr
next prev parent reply other threads:[~2017-09-27 12:17 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-31 14:53 [PATCH v5 0/3] livepatch callbacks Joe Lawrence
2017-08-31 14:53 ` [PATCH v5 1/3] livepatch: add (un)patch callbacks Joe Lawrence
2017-09-12 8:53 ` Miroslav Benes
2017-09-12 15:48 ` Joe Lawrence
2017-09-12 22:05 ` Joe Lawrence
2017-09-12 22:22 ` Josh Poimboeuf
2017-09-13 7:29 ` Miroslav Benes
2017-09-13 13:53 ` Joe Lawrence
2017-09-13 21:36 ` [RFC] livepatch: unpatch all klp_objects if klp_module_coming fails Joe Lawrence
2017-09-20 11:19 ` Miroslav Benes
2017-09-20 15:17 ` Joe Lawrence
2017-09-27 12:17 ` Petr Mladek [this message]
2017-09-13 7:22 ` [PATCH v5 1/3] livepatch: add (un)patch callbacks Miroslav Benes
2017-09-26 14:49 ` Petr Mladek
2017-09-26 19:01 ` Joe Lawrence
2017-09-27 8:02 ` Petr Mladek
2017-08-31 14:53 ` [PATCH v5 2/3] livepatch: move transition "complete" notice into klp_complete_transition() Joe Lawrence
2017-09-12 9:09 ` Miroslav Benes
2017-09-27 11:35 ` Petr Mladek
2017-08-31 14:53 ` [PATCH v5 3/3] livepatch: add transition notices Joe Lawrence
2017-09-12 9:29 ` Miroslav Benes
2017-09-27 11:49 ` Petr Mladek
2017-09-27 15:45 ` Joe Lawrence
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=20170927121720.GN21048@pathway.suse.cz \
--to=pmladek@suse.com \
--cc=chris.j.arges@canonical.com \
--cc=jeyu@kernel.org \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
/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