aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/livepatch/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r--kernel/livepatch/core.c99
1 files changed, 43 insertions, 56 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 01ca08804f51..284e2691e380 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 */
90static void klp_find_object_module(struct klp_object *obj) 90static 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
@@ -323,32 +335,20 @@ unlock:
323 rcu_read_unlock(); 335 rcu_read_unlock();
324} 336}
325 337
326static int klp_disable_func(struct klp_func *func) 338static void klp_disable_func(struct klp_func *func)
327{ 339{
328 struct klp_ops *ops; 340 struct klp_ops *ops;
329 int ret;
330 341
331 if (WARN_ON(func->state != KLP_ENABLED)) 342 WARN_ON(func->state != KLP_ENABLED);
332 return -EINVAL; 343 WARN_ON(!func->old_addr);
333
334 if (WARN_ON(!func->old_addr))
335 return -EINVAL;
336 344
337 ops = klp_find_ops(func->old_addr); 345 ops = klp_find_ops(func->old_addr);
338 if (WARN_ON(!ops)) 346 if (WARN_ON(!ops))
339 return -EINVAL; 347 return;
340 348
341 if (list_is_singular(&ops->func_stack)) { 349 if (list_is_singular(&ops->func_stack)) {
342 ret = unregister_ftrace_function(&ops->fops); 350 WARN_ON(unregister_ftrace_function(&ops->fops));
343 if (ret) { 351 WARN_ON(ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0));
344 pr_err("failed to unregister ftrace handler for function '%s' (%d)\n",
345 func->old_name, ret);
346 return ret;
347 }
348
349 ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0);
350 if (ret)
351 pr_warn("function unregister succeeded but failed to clear the filter\n");
352 352
353 list_del_rcu(&func->stack_node); 353 list_del_rcu(&func->stack_node);
354 list_del(&ops->node); 354 list_del(&ops->node);
@@ -358,8 +358,6 @@ static int klp_disable_func(struct klp_func *func)
358 } 358 }
359 359
360 func->state = KLP_DISABLED; 360 func->state = KLP_DISABLED;
361
362 return 0;
363} 361}
364 362
365static int klp_enable_func(struct klp_func *func) 363static int klp_enable_func(struct klp_func *func)
@@ -420,23 +418,15 @@ err:
420 return ret; 418 return ret;
421} 419}
422 420
423static int klp_disable_object(struct klp_object *obj) 421static void klp_disable_object(struct klp_object *obj)
424{ 422{
425 struct klp_func *func; 423 struct klp_func *func;
426 int ret;
427
428 for (func = obj->funcs; func->old_name; func++) {
429 if (func->state != KLP_ENABLED)
430 continue;
431 424
432 ret = klp_disable_func(func); 425 for (func = obj->funcs; func->old_name; func++)
433 if (ret) 426 if (func->state == KLP_ENABLED)
434 return ret; 427 klp_disable_func(func);
435 }
436 428
437 obj->state = KLP_DISABLED; 429 obj->state = KLP_DISABLED;
438
439 return 0;
440} 430}
441 431
442static int klp_enable_object(struct klp_object *obj) 432static int klp_enable_object(struct klp_object *obj)
@@ -452,22 +442,19 @@ static int klp_enable_object(struct klp_object *obj)
452 442
453 for (func = obj->funcs; func->old_name; func++) { 443 for (func = obj->funcs; func->old_name; func++) {
454 ret = klp_enable_func(func); 444 ret = klp_enable_func(func);
455 if (ret) 445 if (ret) {
456 goto unregister; 446 klp_disable_object(obj);
447 return ret;
448 }
457 } 449 }
458 obj->state = KLP_ENABLED; 450 obj->state = KLP_ENABLED;
459 451
460 return 0; 452 return 0;
461
462unregister:
463 WARN_ON(klp_disable_object(obj));
464 return ret;
465} 453}
466 454
467static int __klp_disable_patch(struct klp_patch *patch) 455static int __klp_disable_patch(struct klp_patch *patch)
468{ 456{
469 struct klp_object *obj; 457 struct klp_object *obj;
470 int ret;
471 458
472 /* enforce stacking: only the last enabled patch can be disabled */ 459 /* enforce stacking: only the last enabled patch can be disabled */
473 if (!list_is_last(&patch->list, &klp_patches) && 460 if (!list_is_last(&patch->list, &klp_patches) &&
@@ -477,12 +464,8 @@ static int __klp_disable_patch(struct klp_patch *patch)
477 pr_notice("disabling patch '%s'\n", patch->mod->name); 464 pr_notice("disabling patch '%s'\n", patch->mod->name);
478 465
479 for (obj = patch->objs; obj->funcs; obj++) { 466 for (obj = patch->objs; obj->funcs; obj++) {
480 if (obj->state != KLP_ENABLED) 467 if (obj->state == KLP_ENABLED)
481 continue; 468 klp_disable_object(obj);
482
483 ret = klp_disable_object(obj);
484 if (ret)
485 return ret;
486 } 469 }
487 470
488 patch->state = KLP_DISABLED; 471 patch->state = KLP_DISABLED;
@@ -541,8 +524,6 @@ static int __klp_enable_patch(struct klp_patch *patch)
541 pr_notice("enabling patch '%s'\n", patch->mod->name); 524 pr_notice("enabling patch '%s'\n", patch->mod->name);
542 525
543 for (obj = patch->objs; obj->funcs; obj++) { 526 for (obj = patch->objs; obj->funcs; obj++) {
544 klp_find_object_module(obj);
545
546 if (!klp_is_object_loaded(obj)) 527 if (!klp_is_object_loaded(obj))
547 continue; 528 continue;
548 529
@@ -767,6 +748,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
767 return -EINVAL; 748 return -EINVAL;
768 749
769 obj->state = KLP_DISABLED; 750 obj->state = KLP_DISABLED;
751 obj->mod = NULL;
770 752
771 klp_find_object_module(obj); 753 klp_find_object_module(obj);
772 754
@@ -932,7 +914,6 @@ static void klp_module_notify_going(struct klp_patch *patch,
932{ 914{
933 struct module *pmod = patch->mod; 915 struct module *pmod = patch->mod;
934 struct module *mod = obj->mod; 916 struct module *mod = obj->mod;
935 int ret;
936 917
937 if (patch->state == KLP_DISABLED) 918 if (patch->state == KLP_DISABLED)
938 goto disabled; 919 goto disabled;
@@ -940,10 +921,7 @@ static void klp_module_notify_going(struct klp_patch *patch,
940 pr_notice("reverting patch '%s' on unloading module '%s'\n", 921 pr_notice("reverting patch '%s' on unloading module '%s'\n",
941 pmod->name, mod->name); 922 pmod->name, mod->name);
942 923
943 ret = klp_disable_object(obj); 924 klp_disable_object(obj);
944 if (ret)
945 pr_warn("failed to revert patch '%s' on module '%s' (%d)\n",
946 pmod->name, mod->name, ret);
947 925
948disabled: 926disabled:
949 klp_free_object_loaded(obj); 927 klp_free_object_loaded(obj);
@@ -961,6 +939,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action,
961 939
962 mutex_lock(&klp_mutex); 940 mutex_lock(&klp_mutex);
963 941
942 /*
943 * Each module has to know that the notifier has been called.
944 * We never know what module will get patched by a new patch.
945 */
946 if (action == MODULE_STATE_COMING)
947 mod->klp_alive = true;
948 else /* MODULE_STATE_GOING */
949 mod->klp_alive = false;
950
964 list_for_each_entry(patch, &klp_patches, list) { 951 list_for_each_entry(patch, &klp_patches, list) {
965 for (obj = patch->objs; obj->funcs; obj++) { 952 for (obj = patch->objs; obj->funcs; obj++) {
966 if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 953 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))