diff options
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r-- | kernel/livepatch/core.c | 137 |
1 files changed, 92 insertions, 45 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 20589da35194..6f0d9095f662 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
@@ -465,17 +465,15 @@ static struct kobj_type klp_ktype_func = { | |||
465 | .sysfs_ops = &kobj_sysfs_ops, | 465 | .sysfs_ops = &kobj_sysfs_ops, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | /* | 468 | static void klp_free_funcs(struct klp_object *obj) |
469 | * Free all functions' kobjects in the array up to some limit. When limit is | ||
470 | * NULL, all kobjects are freed. | ||
471 | */ | ||
472 | static void klp_free_funcs_limited(struct klp_object *obj, | ||
473 | struct klp_func *limit) | ||
474 | { | 469 | { |
475 | struct klp_func *func; | 470 | struct klp_func *func; |
476 | 471 | ||
477 | for (func = obj->funcs; func->old_name && func != limit; func++) | 472 | klp_for_each_func(obj, func) { |
478 | kobject_put(&func->kobj); | 473 | /* Might be called from klp_init_patch() error path. */ |
474 | if (func->kobj_added) | ||
475 | kobject_put(&func->kobj); | ||
476 | } | ||
479 | } | 477 | } |
480 | 478 | ||
481 | /* Clean up when a patched object is unloaded */ | 479 | /* Clean up when a patched object is unloaded */ |
@@ -489,30 +487,60 @@ static void klp_free_object_loaded(struct klp_object *obj) | |||
489 | func->old_func = NULL; | 487 | func->old_func = NULL; |
490 | } | 488 | } |
491 | 489 | ||
492 | /* | 490 | static void klp_free_objects(struct klp_patch *patch) |
493 | * Free all objects' kobjects in the array up to some limit. When limit is | ||
494 | * NULL, all kobjects are freed. | ||
495 | */ | ||
496 | static void klp_free_objects_limited(struct klp_patch *patch, | ||
497 | struct klp_object *limit) | ||
498 | { | 491 | { |
499 | struct klp_object *obj; | 492 | struct klp_object *obj; |
500 | 493 | ||
501 | for (obj = patch->objs; obj->funcs && obj != limit; obj++) { | 494 | klp_for_each_object(patch, obj) { |
502 | klp_free_funcs_limited(obj, NULL); | 495 | klp_free_funcs(obj); |
503 | kobject_put(&obj->kobj); | 496 | |
497 | /* Might be called from klp_init_patch() error path. */ | ||
498 | if (obj->kobj_added) | ||
499 | kobject_put(&obj->kobj); | ||
504 | } | 500 | } |
505 | } | 501 | } |
506 | 502 | ||
507 | static void klp_free_patch(struct klp_patch *patch) | 503 | /* |
504 | * This function implements the free operations that can be called safely | ||
505 | * under klp_mutex. | ||
506 | * | ||
507 | * The operation must be completed by calling klp_free_patch_finish() | ||
508 | * outside klp_mutex. | ||
509 | */ | ||
510 | static void klp_free_patch_start(struct klp_patch *patch) | ||
508 | { | 511 | { |
509 | klp_free_objects_limited(patch, NULL); | ||
510 | if (!list_empty(&patch->list)) | 512 | if (!list_empty(&patch->list)) |
511 | list_del(&patch->list); | 513 | list_del(&patch->list); |
514 | |||
515 | klp_free_objects(patch); | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * This function implements the free part that must be called outside | ||
520 | * klp_mutex. | ||
521 | * | ||
522 | * It must be called after klp_free_patch_start(). And it has to be | ||
523 | * the last function accessing the livepatch structures when the patch | ||
524 | * gets disabled. | ||
525 | */ | ||
526 | static void klp_free_patch_finish(struct klp_patch *patch) | ||
527 | { | ||
528 | /* | ||
529 | * Avoid deadlock with enabled_store() sysfs callback by | ||
530 | * calling this outside klp_mutex. It is safe because | ||
531 | * this is called when the patch gets disabled and it | ||
532 | * cannot get enabled again. | ||
533 | */ | ||
534 | if (patch->kobj_added) { | ||
535 | kobject_put(&patch->kobj); | ||
536 | wait_for_completion(&patch->finish); | ||
537 | } | ||
512 | } | 538 | } |
513 | 539 | ||
514 | static int klp_init_func(struct klp_object *obj, struct klp_func *func) | 540 | static int klp_init_func(struct klp_object *obj, struct klp_func *func) |
515 | { | 541 | { |
542 | int ret; | ||
543 | |||
516 | if (!func->old_name || !func->new_func) | 544 | if (!func->old_name || !func->new_func) |
517 | return -EINVAL; | 545 | return -EINVAL; |
518 | 546 | ||
@@ -528,9 +556,13 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) | |||
528 | * object. If the user selects 0 for old_sympos, then 1 will be used | 556 | * object. If the user selects 0 for old_sympos, then 1 will be used |
529 | * since a unique symbol will be the first occurrence. | 557 | * since a unique symbol will be the first occurrence. |
530 | */ | 558 | */ |
531 | return kobject_init_and_add(&func->kobj, &klp_ktype_func, | 559 | ret = kobject_init_and_add(&func->kobj, &klp_ktype_func, |
532 | &obj->kobj, "%s,%lu", func->old_name, | 560 | &obj->kobj, "%s,%lu", func->old_name, |
533 | func->old_sympos ? func->old_sympos : 1); | 561 | func->old_sympos ? func->old_sympos : 1); |
562 | if (!ret) | ||
563 | func->kobj_added = true; | ||
564 | |||
565 | return ret; | ||
534 | } | 566 | } |
535 | 567 | ||
536 | /* Arches may override this to finish any remaining arch-specific tasks */ | 568 | /* Arches may override this to finish any remaining arch-specific tasks */ |
@@ -589,9 +621,6 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | |||
589 | int ret; | 621 | int ret; |
590 | const char *name; | 622 | const char *name; |
591 | 623 | ||
592 | if (!obj->funcs) | ||
593 | return -EINVAL; | ||
594 | |||
595 | if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN) | 624 | if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN) |
596 | return -EINVAL; | 625 | return -EINVAL; |
597 | 626 | ||
@@ -605,46 +634,66 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | |||
605 | &patch->kobj, "%s", name); | 634 | &patch->kobj, "%s", name); |
606 | if (ret) | 635 | if (ret) |
607 | return ret; | 636 | return ret; |
637 | obj->kobj_added = true; | ||
608 | 638 | ||
609 | klp_for_each_func(obj, func) { | 639 | klp_for_each_func(obj, func) { |
610 | ret = klp_init_func(obj, func); | 640 | ret = klp_init_func(obj, func); |
611 | if (ret) | 641 | if (ret) |
612 | goto free; | 642 | return ret; |
613 | } | 643 | } |
614 | 644 | ||
615 | if (klp_is_object_loaded(obj)) { | 645 | if (klp_is_object_loaded(obj)) |
616 | ret = klp_init_object_loaded(patch, obj); | 646 | ret = klp_init_object_loaded(patch, obj); |
617 | if (ret) | ||
618 | goto free; | ||
619 | } | ||
620 | |||
621 | return 0; | ||
622 | 647 | ||
623 | free: | ||
624 | klp_free_funcs_limited(obj, func); | ||
625 | kobject_put(&obj->kobj); | ||
626 | return ret; | 648 | return ret; |
627 | } | 649 | } |
628 | 650 | ||
629 | static int klp_init_patch(struct klp_patch *patch) | 651 | static int klp_init_patch_early(struct klp_patch *patch) |
630 | { | 652 | { |
631 | struct klp_object *obj; | 653 | struct klp_object *obj; |
632 | int ret; | 654 | struct klp_func *func; |
633 | 655 | ||
634 | if (!patch->objs) | 656 | if (!patch->objs) |
635 | return -EINVAL; | 657 | return -EINVAL; |
636 | 658 | ||
637 | mutex_lock(&klp_mutex); | 659 | INIT_LIST_HEAD(&patch->list); |
638 | 660 | patch->kobj_added = false; | |
639 | patch->enabled = false; | 661 | patch->enabled = false; |
640 | init_completion(&patch->finish); | 662 | init_completion(&patch->finish); |
641 | 663 | ||
664 | klp_for_each_object(patch, obj) { | ||
665 | if (!obj->funcs) | ||
666 | return -EINVAL; | ||
667 | |||
668 | obj->kobj_added = false; | ||
669 | |||
670 | klp_for_each_func(obj, func) | ||
671 | func->kobj_added = false; | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | static int klp_init_patch(struct klp_patch *patch) | ||
678 | { | ||
679 | struct klp_object *obj; | ||
680 | int ret; | ||
681 | |||
682 | mutex_lock(&klp_mutex); | ||
683 | |||
684 | ret = klp_init_patch_early(patch); | ||
685 | if (ret) { | ||
686 | mutex_unlock(&klp_mutex); | ||
687 | return ret; | ||
688 | } | ||
689 | |||
642 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, | 690 | ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, |
643 | klp_root_kobj, "%s", patch->mod->name); | 691 | klp_root_kobj, "%s", patch->mod->name); |
644 | if (ret) { | 692 | if (ret) { |
645 | mutex_unlock(&klp_mutex); | 693 | mutex_unlock(&klp_mutex); |
646 | return ret; | 694 | return ret; |
647 | } | 695 | } |
696 | patch->kobj_added = true; | ||
648 | 697 | ||
649 | klp_for_each_object(patch, obj) { | 698 | klp_for_each_object(patch, obj) { |
650 | ret = klp_init_object(patch, obj); | 699 | ret = klp_init_object(patch, obj); |
@@ -659,12 +708,11 @@ static int klp_init_patch(struct klp_patch *patch) | |||
659 | return 0; | 708 | return 0; |
660 | 709 | ||
661 | free: | 710 | free: |
662 | klp_free_objects_limited(patch, obj); | 711 | klp_free_patch_start(patch); |
663 | 712 | ||
664 | mutex_unlock(&klp_mutex); | 713 | mutex_unlock(&klp_mutex); |
665 | 714 | ||
666 | kobject_put(&patch->kobj); | 715 | klp_free_patch_finish(patch); |
667 | wait_for_completion(&patch->finish); | ||
668 | 716 | ||
669 | return ret; | 717 | return ret; |
670 | } | 718 | } |
@@ -693,12 +741,11 @@ int klp_unregister_patch(struct klp_patch *patch) | |||
693 | goto err; | 741 | goto err; |
694 | } | 742 | } |
695 | 743 | ||
696 | klp_free_patch(patch); | 744 | klp_free_patch_start(patch); |
697 | 745 | ||
698 | mutex_unlock(&klp_mutex); | 746 | mutex_unlock(&klp_mutex); |
699 | 747 | ||
700 | kobject_put(&patch->kobj); | 748 | klp_free_patch_finish(patch); |
701 | wait_for_completion(&patch->finish); | ||
702 | 749 | ||
703 | return 0; | 750 | return 0; |
704 | err: | 751 | err: |