diff options
author | Petr Mladek <pmladek@suse.com> | 2019-01-09 07:43:22 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2019-01-11 14:51:24 -0500 |
commit | 68007289bf3cd937a5b8fc4987d2787167bd06ca (patch) | |
tree | 2c913929da4c5e65fcacdfc5afb47399d86cf446 /kernel/livepatch/core.c | |
parent | 0430f78bf38f9972f0cf0522709cc63d49fa164c (diff) |
livepatch: Don't block the removal of patches loaded after a forced transition
module_put() is currently never called in klp_complete_transition() when
klp_force is set. As a result, we might keep the reference count even when
klp_enable_patch() fails and klp_cancel_transition() is called.
This might give the impression that a module might get blocked in some
strange init state. Fortunately, it is not the case. The reference count
is ignored when mod->init fails and erroneous modules are always removed.
Anyway, this might be confusing. Instead, this patch moves
the global klp_forced flag into struct klp_patch. As a result,
we block only modules that might still be in use after a forced
transition. Newly loaded livepatches might be eventually completely
removed later.
It is not a big deal. But the code is at least consistent with
the reality.
Signed-off-by: Petr Mladek <pmladek@suse.com>
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r-- | kernel/livepatch/core.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 6f0d9095f662..e77c5017ae0c 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
@@ -45,7 +45,8 @@ | |||
45 | */ | 45 | */ |
46 | DEFINE_MUTEX(klp_mutex); | 46 | DEFINE_MUTEX(klp_mutex); |
47 | 47 | ||
48 | static LIST_HEAD(klp_patches); | 48 | /* Registered patches */ |
49 | LIST_HEAD(klp_patches); | ||
49 | 50 | ||
50 | static struct kobject *klp_root_kobj; | 51 | static struct kobject *klp_root_kobj; |
51 | 52 | ||
@@ -659,6 +660,7 @@ static int klp_init_patch_early(struct klp_patch *patch) | |||
659 | INIT_LIST_HEAD(&patch->list); | 660 | INIT_LIST_HEAD(&patch->list); |
660 | patch->kobj_added = false; | 661 | patch->kobj_added = false; |
661 | patch->enabled = false; | 662 | patch->enabled = false; |
663 | patch->forced = false; | ||
662 | init_completion(&patch->finish); | 664 | init_completion(&patch->finish); |
663 | 665 | ||
664 | klp_for_each_object(patch, obj) { | 666 | klp_for_each_object(patch, obj) { |