Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching

Pull livepatching fix from Jiri Kosina:

- bugfix for handling of coming modules (incorrect handling of failure)
from Joe Lawrence

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching:
livepatch: unpatch all klp_objects if klp_module_coming fails

+37 -23
+37 -23
kernel/livepatch/core.c
··· 830 830 } 831 831 EXPORT_SYMBOL_GPL(klp_register_patch); 832 832 833 + /* 834 + * Remove parts of patches that touch a given kernel module. The list of 835 + * patches processed might be limited. When limit is NULL, all patches 836 + * will be handled. 837 + */ 838 + static void klp_cleanup_module_patches_limited(struct module *mod, 839 + struct klp_patch *limit) 840 + { 841 + struct klp_patch *patch; 842 + struct klp_object *obj; 843 + 844 + list_for_each_entry(patch, &klp_patches, list) { 845 + if (patch == limit) 846 + break; 847 + 848 + klp_for_each_object(patch, obj) { 849 + if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 850 + continue; 851 + 852 + /* 853 + * Only unpatch the module if the patch is enabled or 854 + * is in transition. 855 + */ 856 + if (patch->enabled || patch == klp_transition_patch) { 857 + pr_notice("reverting patch '%s' on unloading module '%s'\n", 858 + patch->mod->name, obj->mod->name); 859 + klp_unpatch_object(obj); 860 + } 861 + 862 + klp_free_object_loaded(obj); 863 + break; 864 + } 865 + } 866 + } 867 + 833 868 int klp_module_coming(struct module *mod) 834 869 { 835 870 int ret; ··· 929 894 pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n", 930 895 patch->mod->name, obj->mod->name, obj->mod->name); 931 896 mod->klp_alive = false; 932 - klp_free_object_loaded(obj); 897 + klp_cleanup_module_patches_limited(mod, patch); 933 898 mutex_unlock(&klp_mutex); 934 899 935 900 return ret; ··· 937 902 938 903 void klp_module_going(struct module *mod) 939 904 { 940 - struct klp_patch *patch; 941 - struct klp_object *obj; 942 - 943 905 if (WARN_ON(mod->state != MODULE_STATE_GOING && 944 906 mod->state != MODULE_STATE_COMING)) 945 907 return; ··· 949 917 */ 950 918 mod->klp_alive = false; 951 919 952 - list_for_each_entry(patch, &klp_patches, list) { 953 - klp_for_each_object(patch, obj) { 954 - if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 955 - continue; 956 - 957 - /* 958 - * Only unpatch the module if the patch is enabled or 959 - * is in transition. 960 - */ 961 - if (patch->enabled || patch == klp_transition_patch) { 962 - pr_notice("reverting patch '%s' on unloading module '%s'\n", 963 - patch->mod->name, obj->mod->name); 964 - klp_unpatch_object(obj); 965 - } 966 - 967 - klp_free_object_loaded(obj); 968 - break; 969 - } 970 - } 920 + klp_cleanup_module_patches_limited(mod, NULL); 971 921 972 922 mutex_unlock(&klp_mutex); 973 923 }