diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 2 | ||||
-rw-r--r-- | kernel/livepatch/core.c | 30 | ||||
-rw-r--r-- | kernel/module.c | 2 |
3 files changed, 27 insertions, 7 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index f04daabfd1cf..453ef61311d4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -3591,7 +3591,7 @@ static void put_event(struct perf_event *event) | |||
3591 | ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING); | 3591 | ctx = perf_event_ctx_lock_nested(event, SINGLE_DEPTH_NESTING); |
3592 | WARN_ON_ONCE(ctx->parent_ctx); | 3592 | WARN_ON_ONCE(ctx->parent_ctx); |
3593 | perf_remove_from_context(event, true); | 3593 | perf_remove_from_context(event, true); |
3594 | mutex_unlock(&ctx->mutex); | 3594 | perf_event_ctx_unlock(event, ctx); |
3595 | 3595 | ||
3596 | _free_event(event); | 3596 | _free_event(event); |
3597 | } | 3597 | } |
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 01ca08804f51..3f9f1d6b4c2e 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
@@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj) | |||
89 | /* sets obj->mod if object is not vmlinux and module is found */ | 89 | /* sets obj->mod if object is not vmlinux and module is found */ |
90 | static void klp_find_object_module(struct klp_object *obj) | 90 | static void klp_find_object_module(struct klp_object *obj) |
91 | { | 91 | { |
92 | struct module *mod; | ||
93 | |||
92 | if (!klp_is_module(obj)) | 94 | if (!klp_is_module(obj)) |
93 | return; | 95 | return; |
94 | 96 | ||
95 | mutex_lock(&module_mutex); | 97 | mutex_lock(&module_mutex); |
96 | /* | 98 | /* |
97 | * We don't need to take a reference on the module here because we have | 99 | * We do not want to block removal of patched modules and therefore |
98 | * the klp_mutex, which is also taken by the module notifier. This | 100 | * we do not take a reference here. The patches are removed by |
99 | * prevents any module from unloading until we release the klp_mutex. | 101 | * a going module handler instead. |
102 | */ | ||
103 | mod = find_module(obj->name); | ||
104 | /* | ||
105 | * Do not mess work of the module coming and going notifiers. | ||
106 | * Note that the patch might still be needed before the going handler | ||
107 | * is called. Module functions can be called even in the GOING state | ||
108 | * until mod->exit() finishes. This is especially important for | ||
109 | * patches that modify semantic of the functions. | ||
100 | */ | 110 | */ |
101 | obj->mod = find_module(obj->name); | 111 | if (mod && mod->klp_alive) |
112 | obj->mod = mod; | ||
113 | |||
102 | mutex_unlock(&module_mutex); | 114 | mutex_unlock(&module_mutex); |
103 | } | 115 | } |
104 | 116 | ||
@@ -767,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | |||
767 | return -EINVAL; | 779 | return -EINVAL; |
768 | 780 | ||
769 | obj->state = KLP_DISABLED; | 781 | obj->state = KLP_DISABLED; |
782 | obj->mod = NULL; | ||
770 | 783 | ||
771 | klp_find_object_module(obj); | 784 | klp_find_object_module(obj); |
772 | 785 | ||
@@ -961,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action, | |||
961 | 974 | ||
962 | mutex_lock(&klp_mutex); | 975 | mutex_lock(&klp_mutex); |
963 | 976 | ||
977 | /* | ||
978 | * Each module has to know that the notifier has been called. | ||
979 | * We never know what module will get patched by a new patch. | ||
980 | */ | ||
981 | if (action == MODULE_STATE_COMING) | ||
982 | mod->klp_alive = true; | ||
983 | else /* MODULE_STATE_GOING */ | ||
984 | mod->klp_alive = false; | ||
985 | |||
964 | list_for_each_entry(patch, &klp_patches, list) { | 986 | list_for_each_entry(patch, &klp_patches, list) { |
965 | for (obj = patch->objs; obj->funcs; obj++) { | 987 | for (obj = patch->objs; obj->funcs; obj++) { |
966 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) | 988 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) |
diff --git a/kernel/module.c b/kernel/module.c index cc93cf68653c..b3d634ed06c9 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/async.h> | 56 | #include <linux/async.h> |
57 | #include <linux/percpu.h> | 57 | #include <linux/percpu.h> |
58 | #include <linux/kmemleak.h> | 58 | #include <linux/kmemleak.h> |
59 | #include <linux/kasan.h> | ||
60 | #include <linux/jump_label.h> | 59 | #include <linux/jump_label.h> |
61 | #include <linux/pfn.h> | 60 | #include <linux/pfn.h> |
62 | #include <linux/bsearch.h> | 61 | #include <linux/bsearch.h> |
@@ -1814,7 +1813,6 @@ static void unset_module_init_ro_nx(struct module *mod) { } | |||
1814 | void __weak module_memfree(void *module_region) | 1813 | void __weak module_memfree(void *module_region) |
1815 | { | 1814 | { |
1816 | vfree(module_region); | 1815 | vfree(module_region); |
1817 | kasan_module_free(module_region); | ||
1818 | } | 1816 | } |
1819 | 1817 | ||
1820 | void __weak module_arch_cleanup(struct module *mod) | 1818 | void __weak module_arch_cleanup(struct module *mod) |