History

livepatch/module: remove livepatch module notifier

Remove the livepatch module notifier in favor of directly enabling and disabling patches to modules in the module loader. Hard-coding the function calls ensures that ftrace_module_enable() is run before klp_module_coming() during module load, and that klp_module_going() is run before ftrace_release_mod() during module unload. This way, ftrace and livepatch code is run in the correct order during the module load/unload sequence without dependence on the module notifier call chain.

Jessica Yu committed 10 years ago

Commit 7e545d61 parent 4c973d13 files · +94 −76Browse files

Showing the changes to kernel/livepatch (1 of 3 files). Show all

Unified · Split

kernel/livepatch/core.c+71−76
@@ -99,12 +99,12 @@ static void klp_find_object_module(struct klp_object *obj) · 98 unmodified lines
99 /*99 /*
100 * We do not want to block removal of patched modules and therefore100 * We do not want to block removal of patched modules and therefore
101 * we do not take a reference here. The patches are removed by101 * we do not take a reference here. The patches are removed by
102 * a going module handler instead.102 * klp_module_going() instead.
103 */103 */
104 mod = find_module(obj->name);104 mod = find_module(obj->name);
105 /*105 /*
106 * Do not mess work of the module coming and going notifiers.106 * Do not mess work of klp_module_coming() and klp_module_going().
107 * Note that the patch might still be needed before the going handler107 * Note that the patch might still be needed before klp_module_going()
108 * is called. Module functions can be called even in the GOING state108 * is called. Module functions can be called even in the GOING state
109 * until mod->exit() finishes. This is especially important for109 * until mod->exit() finishes. This is especially important for
110 * patches that modify semantic of the functions.110 * patches that modify semantic of the functions.
@@ -866,103 +866,108 @@ int klp_register_patch(struct klp_patch *patch) · 755 unmodified lines
866}866}
867EXPORT_SYMBOL_GPL(klp_register_patch);867EXPORT_SYMBOL_GPL(klp_register_patch);
868 868
869static int klp_module_notify_coming(struct klp_patch *patch,869int klp_module_coming(struct module *mod)
870 struct klp_object *obj)
871{870{
872 struct module *pmod = patch->mod;
873 struct module *mod = obj->mod;
874 int ret;871 int ret;
872 struct klp_patch *patch;
873 struct klp_object *obj;
875 874
876 ret = klp_init_object_loaded(patch, obj);875 if (WARN_ON(mod->state != MODULE_STATE_COMING))
877 if (ret) {876 return -EINVAL;
878 pr_warn("failed to initialize patch '%s' for module '%s' (%d)\n",
879 pmod->name, mod->name, ret);
880 return ret;
881 }
882 877
883 if (patch->state == KLP_DISABLED)878 mutex_lock(&klp_mutex);
884 return 0;879 /*
880 * Each module has to know that klp_module_coming()
881 * has been called. We never know what module will
882 * get patched by a new patch.
883 */
884 mod->klp_alive = true;
885 885
886 pr_notice("applying patch '%s' to loading module '%s'\n",886 list_for_each_entry(patch, &klp_patches, list) {
887 pmod->name, mod->name);887 klp_for_each_object(patch, obj) {
888 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
889 continue;
888 890
889 ret = klp_enable_object(obj);891 obj->mod = mod;
890 if (ret)
891 pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
892 pmod->name, mod->name, ret);
893 return ret;
894}
895 892
896static void klp_module_notify_going(struct klp_patch *patch,893 ret = klp_init_object_loaded(patch, obj);
897 struct klp_object *obj)894 if (ret) {
898{895 pr_warn("failed to initialize patch '%s' for module '%s' (%d)\n",
899 struct module *pmod = patch->mod;896 patch->mod->name, obj->mod->name, ret);
900 struct module *mod = obj->mod;897 goto err;
898 }
901 899
902 if (patch->state == KLP_DISABLED)900 if (patch->state == KLP_DISABLED)
903 goto disabled;901 break;
902
903 pr_notice("applying patch '%s' to loading module '%s'\n",
904 patch->mod->name, obj->mod->name);
905
906 ret = klp_enable_object(obj);
907 if (ret) {
908 pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
909 patch->mod->name, obj->mod->name, ret);
910 goto err;
911 }
912
913 break;
914 }
915 }
904 916
905 pr_notice("reverting patch '%s' on unloading module '%s'\n",917 mutex_unlock(&klp_mutex);
906 pmod->name, mod->name);
907 918
908 klp_disable_object(obj);919 return 0;
909 920
910disabled:921err:
922 /*
923 * If a patch is unsuccessfully applied, return
924 * error to the module loader.
925 */
926 pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n",
927 patch->mod->name, obj->mod->name, obj->mod->name);
928 mod->klp_alive = false;
911 klp_free_object_loaded(obj);929 klp_free_object_loaded(obj);
930 mutex_unlock(&klp_mutex);
931
932 return ret;
912}933}
913 934
914static int klp_module_notify(struct notifier_block *nb, unsigned long action,935void klp_module_going(struct module *mod)
915 void *data)
916{936{
917 int ret;
918 struct module *mod = data;
919 struct klp_patch *patch;937 struct klp_patch *patch;
920 struct klp_object *obj;938 struct klp_object *obj;
921 939
922 if (action != MODULE_STATE_COMING && action != MODULE_STATE_GOING)940 if (WARN_ON(mod->state != MODULE_STATE_GOING &&
923 return 0;941 mod->state != MODULE_STATE_COMING))
942 return;
924 943
925 mutex_lock(&klp_mutex);944 mutex_lock(&klp_mutex);
926
927 /*945 /*
928 * Each module has to know that the notifier has been called.946 * Each module has to know that klp_module_going()
929 * We never know what module will get patched by a new patch.947 * has been called. We never know what module will
948 * get patched by a new patch.
930 */949 */
931 if (action == MODULE_STATE_COMING)950 mod->klp_alive = false;
932 mod->klp_alive = true;
933 else /* MODULE_STATE_GOING */
934 mod->klp_alive = false;
935 951
936 list_for_each_entry(patch, &klp_patches, list) {952 list_for_each_entry(patch, &klp_patches, list) {
937 klp_for_each_object(patch, obj) {953 klp_for_each_object(patch, obj) {
938 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))954 if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
939 continue;955 continue;
940 956
941 if (action == MODULE_STATE_COMING) {957 if (patch->state != KLP_DISABLED) {
942 obj->mod = mod;958 pr_notice("reverting patch '%s' on unloading module '%s'\n",
943 ret = klp_module_notify_coming(patch, obj);959 patch->mod->name, obj->mod->name);
944 if (ret) {960 klp_disable_object(obj);
945 obj->mod = NULL;961 }
946 pr_warn("patch '%s' is in an inconsistent state!\n",
947 patch->mod->name);
948 }
949 } else /* MODULE_STATE_GOING */
950 klp_module_notify_going(patch, obj);
951 962
963 klp_free_object_loaded(obj);
952 break;964 break;
953 }965 }
954 }966 }
955 967
956 mutex_unlock(&klp_mutex);968 mutex_unlock(&klp_mutex);
957
958 return 0;
959}969}
960 970
961static struct notifier_block klp_module_nb = {
962 .notifier_call = klp_module_notify,
963 .priority = INT_MIN+1, /* called late but before ftrace notifier */
964};
965
966static int __init klp_init(void)971static int __init klp_init(void)
967{972{
968 int ret;973 int ret;
@@ -973,21 +978,11 @@ static int __init klp_init(void) · 4 unmodified lines
973 return -EINVAL;978 return -EINVAL;
974 }979 }
975 980
976 ret = register_module_notifier(&klp_module_nb);
977 if (ret)
978 return ret;
979
980 klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);981 klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
981 if (!klp_root_kobj) {982 if (!klp_root_kobj)
982 ret = -ENOMEM;983 return -ENOMEM;
983 goto unregister;
984 }
985 984
986 return 0;985 return 0;
987
988unregister:
989 unregister_module_notifier(&klp_module_nb);
990 return ret;
991}986}
992 987
993module_init(klp_init);988module_init(klp_init);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t