diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c index 4299aefc20b8..f47cce910f25 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -757,8 +757,16 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
757 | return -EFAULT; | 757 | return -EFAULT; |
758 | name[MODULE_NAME_LEN-1] = '\0'; | 758 | name[MODULE_NAME_LEN-1] = '\0'; |
759 | 759 | ||
760 | if (mutex_lock_interruptible(&module_mutex) != 0) | 760 | /* Create stop_machine threads since free_module relies on |
761 | return -EINTR; | 761 | * a non-failing stop_machine call. */ |
762 | ret = stop_machine_create(); | ||
763 | if (ret) | ||
764 | return ret; | ||
765 | |||
766 | if (mutex_lock_interruptible(&module_mutex) != 0) { | ||
767 | ret = -EINTR; | ||
768 | goto out_stop; | ||
769 | } | ||
762 | 770 | ||
763 | mod = find_module(name); | 771 | mod = find_module(name); |
764 | if (!mod) { | 772 | if (!mod) { |
@@ -817,6 +825,8 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
817 | 825 | ||
818 | out: | 826 | out: |
819 | mutex_unlock(&module_mutex); | 827 | mutex_unlock(&module_mutex); |
828 | out_stop: | ||
829 | stop_machine_destroy(); | ||
820 | return ret; | 830 | return ret; |
821 | } | 831 | } |
822 | 832 | ||
@@ -1875,6 +1885,13 @@ static noinline struct module *load_module(void __user *umod, | |||
1875 | /* vmalloc barfs on "unusual" numbers. Check here */ | 1885 | /* vmalloc barfs on "unusual" numbers. Check here */ |
1876 | if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) | 1886 | if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) |
1877 | return ERR_PTR(-ENOMEM); | 1887 | return ERR_PTR(-ENOMEM); |
1888 | |||
1889 | /* Create stop_machine threads since the error path relies on | ||
1890 | * a non-failing stop_machine call. */ | ||
1891 | err = stop_machine_create(); | ||
1892 | if (err) | ||
1893 | goto free_hdr; | ||
1894 | |||
1878 | if (copy_from_user(hdr, umod, len) != 0) { | 1895 | if (copy_from_user(hdr, umod, len) != 0) { |
1879 | err = -EFAULT; | 1896 | err = -EFAULT; |
1880 | goto free_hdr; | 1897 | goto free_hdr; |
@@ -2258,6 +2275,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2258 | /* Get rid of temporary copy */ | 2275 | /* Get rid of temporary copy */ |
2259 | vfree(hdr); | 2276 | vfree(hdr); |
2260 | 2277 | ||
2278 | stop_machine_destroy(); | ||
2261 | /* Done! */ | 2279 | /* Done! */ |
2262 | return mod; | 2280 | return mod; |
2263 | 2281 | ||
@@ -2280,6 +2298,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2280 | kfree(args); | 2298 | kfree(args); |
2281 | free_hdr: | 2299 | free_hdr: |
2282 | vfree(hdr); | 2300 | vfree(hdr); |
2301 | stop_machine_destroy(); | ||
2283 | return ERR_PTR(err); | 2302 | return ERR_PTR(err); |
2284 | 2303 | ||
2285 | truncated: | 2304 | truncated: |