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.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 217b39d71176..2dbd355cee07 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -348,11 +348,11 @@ static unsigned long klp_get_ftrace_location(unsigned long faddr)
348} 348}
349#endif 349#endif
350 350
351static void klp_disable_func(struct klp_func *func) 351static void klp_unpatch_func(struct klp_func *func)
352{ 352{
353 struct klp_ops *ops; 353 struct klp_ops *ops;
354 354
355 if (WARN_ON(func->state != KLP_ENABLED)) 355 if (WARN_ON(!func->patched))
356 return; 356 return;
357 if (WARN_ON(!func->old_addr)) 357 if (WARN_ON(!func->old_addr))
358 return; 358 return;
@@ -378,10 +378,10 @@ static void klp_disable_func(struct klp_func *func)
378 list_del_rcu(&func->stack_node); 378 list_del_rcu(&func->stack_node);
379 } 379 }
380 380
381 func->state = KLP_DISABLED; 381 func->patched = false;
382} 382}
383 383
384static int klp_enable_func(struct klp_func *func) 384static int klp_patch_func(struct klp_func *func)
385{ 385{
386 struct klp_ops *ops; 386 struct klp_ops *ops;
387 int ret; 387 int ret;
@@ -389,7 +389,7 @@ static int klp_enable_func(struct klp_func *func)
389 if (WARN_ON(!func->old_addr)) 389 if (WARN_ON(!func->old_addr))
390 return -EINVAL; 390 return -EINVAL;
391 391
392 if (WARN_ON(func->state != KLP_DISABLED)) 392 if (WARN_ON(func->patched))
393 return -EINVAL; 393 return -EINVAL;
394 394
395 ops = klp_find_ops(func->old_addr); 395 ops = klp_find_ops(func->old_addr);
@@ -437,7 +437,7 @@ static int klp_enable_func(struct klp_func *func)
437 list_add_rcu(&func->stack_node, &ops->func_stack); 437 list_add_rcu(&func->stack_node, &ops->func_stack);
438 } 438 }
439 439
440 func->state = KLP_ENABLED; 440 func->patched = true;
441 441
442 return 0; 442 return 0;
443 443
@@ -448,36 +448,36 @@ err:
448 return ret; 448 return ret;
449} 449}
450 450
451static void klp_disable_object(struct klp_object *obj) 451static void klp_unpatch_object(struct klp_object *obj)
452{ 452{
453 struct klp_func *func; 453 struct klp_func *func;
454 454
455 klp_for_each_func(obj, func) 455 klp_for_each_func(obj, func)
456 if (func->state == KLP_ENABLED) 456 if (func->patched)
457 klp_disable_func(func); 457 klp_unpatch_func(func);
458 458
459 obj->state = KLP_DISABLED; 459 obj->patched = false;
460} 460}
461 461
462static int klp_enable_object(struct klp_object *obj) 462static int klp_patch_object(struct klp_object *obj)
463{ 463{
464 struct klp_func *func; 464 struct klp_func *func;
465 int ret; 465 int ret;
466 466
467 if (WARN_ON(obj->state != KLP_DISABLED)) 467 if (WARN_ON(obj->patched))
468 return -EINVAL; 468 return -EINVAL;
469 469
470 if (WARN_ON(!klp_is_object_loaded(obj))) 470 if (WARN_ON(!klp_is_object_loaded(obj)))
471 return -EINVAL; 471 return -EINVAL;
472 472
473 klp_for_each_func(obj, func) { 473 klp_for_each_func(obj, func) {
474 ret = klp_enable_func(func); 474 ret = klp_patch_func(func);
475 if (ret) { 475 if (ret) {
476 klp_disable_object(obj); 476 klp_unpatch_object(obj);
477 return ret; 477 return ret;
478 } 478 }
479 } 479 }
480 obj->state = KLP_ENABLED; 480 obj->patched = true;
481 481
482 return 0; 482 return 0;
483} 483}
@@ -488,17 +488,17 @@ static int __klp_disable_patch(struct klp_patch *patch)
488 488
489 /* enforce stacking: only the last enabled patch can be disabled */ 489 /* enforce stacking: only the last enabled patch can be disabled */
490 if (!list_is_last(&patch->list, &klp_patches) && 490 if (!list_is_last(&patch->list, &klp_patches) &&
491 list_next_entry(patch, list)->state == KLP_ENABLED) 491 list_next_entry(patch, list)->enabled)
492 return -EBUSY; 492 return -EBUSY;
493 493
494 pr_notice("disabling patch '%s'\n", patch->mod->name); 494 pr_notice("disabling patch '%s'\n", patch->mod->name);
495 495
496 klp_for_each_object(patch, obj) { 496 klp_for_each_object(patch, obj) {
497 if (obj->state == KLP_ENABLED) 497 if (obj->patched)
498 klp_disable_object(obj); 498 klp_unpatch_object(obj);
499 } 499 }
500 500
501 patch->state = KLP_DISABLED; 501 patch->enabled = false;
502 502
503 return 0; 503 return 0;
504} 504}
@@ -522,7 +522,7 @@ int klp_disable_patch(struct klp_patch *patch)
522 goto err; 522 goto err;
523 } 523 }
524 524
525 if (patch->state == KLP_DISABLED) { 525 if (!patch->enabled) {
526 ret = -EINVAL; 526 ret = -EINVAL;
527 goto err; 527 goto err;
528 } 528 }
@@ -540,12 +540,12 @@ static int __klp_enable_patch(struct klp_patch *patch)
540 struct klp_object *obj; 540 struct klp_object *obj;
541 int ret; 541 int ret;
542 542
543 if (WARN_ON(patch->state != KLP_DISABLED)) 543 if (WARN_ON(patch->enabled))
544 return -EINVAL; 544 return -EINVAL;
545 545
546 /* enforce stacking: only the first disabled patch can be enabled */ 546 /* enforce stacking: only the first disabled patch can be enabled */
547 if (patch->list.prev != &klp_patches && 547 if (patch->list.prev != &klp_patches &&
548 list_prev_entry(patch, list)->state == KLP_DISABLED) 548 !list_prev_entry(patch, list)->enabled)
549 return -EBUSY; 549 return -EBUSY;
550 550
551 pr_notice("enabling patch '%s'\n", patch->mod->name); 551 pr_notice("enabling patch '%s'\n", patch->mod->name);
@@ -554,12 +554,12 @@ static int __klp_enable_patch(struct klp_patch *patch)
554 if (!klp_is_object_loaded(obj)) 554 if (!klp_is_object_loaded(obj))
555 continue; 555 continue;
556 556
557 ret = klp_enable_object(obj); 557 ret = klp_patch_object(obj);
558 if (ret) 558 if (ret)
559 goto unregister; 559 goto unregister;
560 } 560 }
561 561
562 patch->state = KLP_ENABLED; 562 patch->enabled = true;
563 563
564 return 0; 564 return 0;
565 565
@@ -617,20 +617,20 @@ static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr,
617 if (ret) 617 if (ret)
618 return -EINVAL; 618 return -EINVAL;
619 619
620 if (val != KLP_DISABLED && val != KLP_ENABLED) 620 if (val > 1)
621 return -EINVAL; 621 return -EINVAL;
622 622
623 patch = container_of(kobj, struct klp_patch, kobj); 623 patch = container_of(kobj, struct klp_patch, kobj);
624 624
625 mutex_lock(&klp_mutex); 625 mutex_lock(&klp_mutex);
626 626
627 if (val == patch->state) { 627 if (patch->enabled == val) {
628 /* already in requested state */ 628 /* already in requested state */
629 ret = -EINVAL; 629 ret = -EINVAL;
630 goto err; 630 goto err;
631 } 631 }
632 632
633 if (val == KLP_ENABLED) { 633 if (val) {
634 ret = __klp_enable_patch(patch); 634 ret = __klp_enable_patch(patch);
635 if (ret) 635 if (ret)
636 goto err; 636 goto err;
@@ -655,7 +655,7 @@ static ssize_t enabled_show(struct kobject *kobj,
655 struct klp_patch *patch; 655 struct klp_patch *patch;
656 656
657 patch = container_of(kobj, struct klp_patch, kobj); 657 patch = container_of(kobj, struct klp_patch, kobj);
658 return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->state); 658 return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->enabled);
659} 659}
660 660
661static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); 661static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled);
@@ -749,7 +749,7 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func)
749 return -EINVAL; 749 return -EINVAL;
750 750
751 INIT_LIST_HEAD(&func->stack_node); 751 INIT_LIST_HEAD(&func->stack_node);
752 func->state = KLP_DISABLED; 752 func->patched = false;
753 753
754 /* The format for the sysfs directory is <function,sympos> where sympos 754 /* The format for the sysfs directory is <function,sympos> where sympos
755 * is the nth occurrence of this symbol in kallsyms for the patched 755 * is the nth occurrence of this symbol in kallsyms for the patched
@@ -804,7 +804,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
804 if (!obj->funcs) 804 if (!obj->funcs)
805 return -EINVAL; 805 return -EINVAL;
806 806
807 obj->state = KLP_DISABLED; 807 obj->patched = false;
808 obj->mod = NULL; 808 obj->mod = NULL;
809 809
810 klp_find_object_module(obj); 810 klp_find_object_module(obj);
@@ -845,7 +845,7 @@ static int klp_init_patch(struct klp_patch *patch)
845 845
846 mutex_lock(&klp_mutex); 846 mutex_lock(&klp_mutex);
847 847
848 patch->state = KLP_DISABLED; 848 patch->enabled = false;
849 849
850 ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, 850 ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch,
851 klp_root_kobj, "%s", patch->mod->name); 851 klp_root_kobj, "%s", patch->mod->name);
@@ -891,7 +891,7 @@ int klp_unregister_patch(struct klp_patch *patch)
891 goto out; 891 goto out;
892 } 892 }
893 893
894 if (patch->state == KLP_ENABLED) { 894 if (patch->enabled) {
895 ret = -EBUSY; 895 ret = -EBUSY;
896 goto out; 896 goto out;
897 } 897 }
@@ -978,13 +978,13 @@ int klp_module_coming(struct module *mod)
978 goto err; 978 goto err;
979 } 979 }
980 980
981 if (patch->state == KLP_DISABLED) 981 if (!patch->enabled)
982 break; 982 break;
983 983
984 pr_notice("applying patch '%s' to loading module '%s'\n", 984 pr_notice("applying patch '%s' to loading module '%s'\n",
985 patch->mod->name, obj->mod->name); 985 patch->mod->name, obj->mod->name);
986 986
987 ret = klp_enable_object(obj); 987 ret = klp_patch_object(obj);
988 if (ret) { 988 if (ret) {
989 pr_warn("failed to apply patch '%s' to module '%s' (%d)\n", 989 pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
990 patch->mod->name, obj->mod->name, ret); 990 patch->mod->name, obj->mod->name, ret);
@@ -1035,10 +1035,10 @@ void klp_module_going(struct module *mod)
1035 if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 1035 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
1036 continue; 1036 continue;
1037 1037
1038 if (patch->state != KLP_DISABLED) { 1038 if (patch->enabled) {
1039 pr_notice("reverting patch '%s' on unloading module '%s'\n", 1039 pr_notice("reverting patch '%s' on unloading module '%s'\n",
1040 patch->mod->name, obj->mod->name); 1040 patch->mod->name, obj->mod->name);
1041 klp_disable_object(obj); 1041 klp_unpatch_object(obj);
1042 } 1042 }
1043 1043
1044 klp_free_object_loaded(obj); 1044 klp_free_object_loaded(obj);