diff options
Diffstat (limited to 'kernel/livepatch/core.c')
| -rw-r--r-- | kernel/livepatch/core.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index ff7f47d026ac..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 | ||
| @@ -248,11 +260,12 @@ static int klp_find_external_symbol(struct module *pmod, const char *name, | |||
| 248 | /* first, check if it's an exported symbol */ | 260 | /* first, check if it's an exported symbol */ |
| 249 | preempt_disable(); | 261 | preempt_disable(); |
| 250 | sym = find_symbol(name, NULL, NULL, true, true); | 262 | sym = find_symbol(name, NULL, NULL, true, true); |
| 251 | preempt_enable(); | ||
| 252 | if (sym) { | 263 | if (sym) { |
| 253 | *addr = sym->value; | 264 | *addr = sym->value; |
| 265 | preempt_enable(); | ||
| 254 | return 0; | 266 | return 0; |
| 255 | } | 267 | } |
| 268 | preempt_enable(); | ||
| 256 | 269 | ||
| 257 | /* otherwise check if it's in another .o within the patch module */ | 270 | /* otherwise check if it's in another .o within the patch module */ |
| 258 | return klp_find_object_symbol(pmod->name, name, addr); | 271 | return klp_find_object_symbol(pmod->name, name, addr); |
| @@ -314,12 +327,12 @@ static void notrace klp_ftrace_handler(unsigned long ip, | |||
| 314 | rcu_read_lock(); | 327 | rcu_read_lock(); |
| 315 | func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, | 328 | func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, |
| 316 | stack_node); | 329 | stack_node); |
| 317 | rcu_read_unlock(); | ||
| 318 | |||
| 319 | if (WARN_ON_ONCE(!func)) | 330 | if (WARN_ON_ONCE(!func)) |
| 320 | return; | 331 | goto unlock; |
| 321 | 332 | ||
| 322 | klp_arch_set_pc(regs, (unsigned long)func->new_func); | 333 | klp_arch_set_pc(regs, (unsigned long)func->new_func); |
| 334 | unlock: | ||
| 335 | rcu_read_unlock(); | ||
| 323 | } | 336 | } |
| 324 | 337 | ||
| 325 | static int klp_disable_func(struct klp_func *func) | 338 | static int klp_disable_func(struct klp_func *func) |
| @@ -731,7 +744,7 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) | |||
| 731 | func->state = KLP_DISABLED; | 744 | func->state = KLP_DISABLED; |
| 732 | 745 | ||
| 733 | return kobject_init_and_add(&func->kobj, &klp_ktype_func, | 746 | return kobject_init_and_add(&func->kobj, &klp_ktype_func, |
| 734 | obj->kobj, func->old_name); | 747 | obj->kobj, "%s", func->old_name); |
| 735 | } | 748 | } |
| 736 | 749 | ||
| 737 | /* parts of the initialization that is done only when the object is loaded */ | 750 | /* parts of the initialization that is done only when the object is loaded */ |
| @@ -766,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | |||
| 766 | return -EINVAL; | 779 | return -EINVAL; |
| 767 | 780 | ||
| 768 | obj->state = KLP_DISABLED; | 781 | obj->state = KLP_DISABLED; |
| 782 | obj->mod = NULL; | ||
| 769 | 783 | ||
| 770 | klp_find_object_module(obj); | 784 | klp_find_object_module(obj); |
| 771 | 785 | ||
| @@ -807,7 +821,7 @@ static int klp_init_patch(struct klp_patch *patch) | |||
| 807 | patch->state = KLP_DISABLED; | 821 | patch->state = KLP_DISABLED; |
| 808 | 822 | ||
| 809 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, | 823 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, |
| 810 | klp_root_kobj, patch->mod->name); | 824 | klp_root_kobj, "%s", patch->mod->name); |
| 811 | if (ret) | 825 | if (ret) |
| 812 | goto unlock; | 826 | goto unlock; |
| 813 | 827 | ||
| @@ -960,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action, | |||
| 960 | 974 | ||
| 961 | mutex_lock(&klp_mutex); | 975 | mutex_lock(&klp_mutex); |
| 962 | 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 | |||
| 963 | list_for_each_entry(patch, &klp_patches, list) { | 986 | list_for_each_entry(patch, &klp_patches, list) { |
| 964 | for (obj = patch->objs; obj->funcs; obj++) { | 987 | for (obj = patch->objs; obj->funcs; obj++) { |
| 965 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) | 988 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) |
