Commit dfff0a0671baf4e69fc676bf8150635407548288
1 parent
82f0cf9b7c
Exists in
master
and in
39 other branches
Revert "Driver core: let request_module() send a /sys/modules/kmod/-uevent"
This reverts commit c353c3fb0700a3c17ea2b0237710a184232ccd7f. It turns out that we end up with a loop trying to load the unix module and calling netfilter to do that. Will redo the patch later to not have this loop. Acked-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 4 changed files with 10 additions and 139 deletions Side-by-side Diff
include/linux/kmod.h
... | ... | @@ -28,10 +28,8 @@ |
28 | 28 | #ifdef CONFIG_KMOD |
29 | 29 | /* modprobe exit status on success, -ve on error. Return value |
30 | 30 | * usually useless though. */ |
31 | -extern void kmod_sysfs_init(void); | |
32 | 31 | extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2))); |
33 | 32 | #else |
34 | -static inline void kmod_sysfs_init(void) {}; | |
35 | 33 | static inline int request_module(const char * name, ...) { return -ENOSYS; } |
36 | 34 | #endif |
37 | 35 |
kernel/kmod.c
... | ... | @@ -36,8 +36,6 @@ |
36 | 36 | #include <linux/resource.h> |
37 | 37 | #include <asm/uaccess.h> |
38 | 38 | |
39 | -extern int delete_module(const char *name, unsigned int flags); | |
40 | - | |
41 | 39 | extern int max_threads; |
42 | 40 | |
43 | 41 | static struct workqueue_struct *khelper_wq; |
... | ... | @@ -48,7 +46,6 @@ |
48 | 46 | modprobe_path is set via /proc/sys. |
49 | 47 | */ |
50 | 48 | char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; |
51 | -static struct module_kobject kmod_mk; | |
52 | 49 | |
53 | 50 | /** |
54 | 51 | * request_module - try to load a kernel module |
... | ... | @@ -78,11 +75,6 @@ |
78 | 75 | static atomic_t kmod_concurrent = ATOMIC_INIT(0); |
79 | 76 | #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ |
80 | 77 | static int kmod_loop_msg; |
81 | - char modalias[16 + MODULE_NAME_LEN] = "MODALIAS="; | |
82 | - char *uevent_envp[2] = { | |
83 | - modalias, | |
84 | - NULL | |
85 | - }; | |
86 | 78 | |
87 | 79 | va_start(args, fmt); |
88 | 80 | ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); |
... | ... | @@ -90,12 +82,6 @@ |
90 | 82 | if (ret >= MODULE_NAME_LEN) |
91 | 83 | return -ENAMETOOLONG; |
92 | 84 | |
93 | - strcpy(&modalias[strlen("MODALIAS=")], module_name); | |
94 | - kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp); | |
95 | - | |
96 | - if (modprobe_path[0] == '\0') | |
97 | - goto out; | |
98 | - | |
99 | 85 | /* If modprobe needs a service that is in a module, we get a recursive |
100 | 86 | * loop. Limit the number of running kmod threads to max_threads/2 or |
101 | 87 | * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method |
102 | 88 | |
... | ... | @@ -122,115 +108,9 @@ |
122 | 108 | |
123 | 109 | ret = call_usermodehelper(modprobe_path, argv, envp, 1); |
124 | 110 | atomic_dec(&kmod_concurrent); |
125 | -out: | |
126 | 111 | return ret; |
127 | 112 | } |
128 | 113 | EXPORT_SYMBOL(request_module); |
129 | - | |
130 | -static ssize_t store_mod_request(struct module_attribute *mattr, | |
131 | - struct module *mod, | |
132 | - const char *buffer, size_t count) | |
133 | -{ | |
134 | - char name[MODULE_NAME_LEN]; | |
135 | - int ret; | |
136 | - | |
137 | - if (count < 1 || count+1 > MODULE_NAME_LEN) | |
138 | - return -EINVAL; | |
139 | - memcpy(name, buffer, count); | |
140 | - name[count] = '\0'; | |
141 | - if (name[count-1] == '\n') | |
142 | - name[count-1] = '\0'; | |
143 | - | |
144 | - ret = request_module(name); | |
145 | - if (ret < 0) | |
146 | - return ret; | |
147 | - return count; | |
148 | -} | |
149 | - | |
150 | -static struct module_attribute mod_request = { | |
151 | - .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE }, | |
152 | - .store = store_mod_request, | |
153 | -}; | |
154 | - | |
155 | -#ifdef CONFIG_MODULE_UNLOAD | |
156 | -static ssize_t store_mod_unload(struct module_attribute *mattr, | |
157 | - struct module *mod, | |
158 | - const char *buffer, size_t count) | |
159 | -{ | |
160 | - char name[MODULE_NAME_LEN]; | |
161 | - int ret; | |
162 | - | |
163 | - if (count < 1 || count+1 > MODULE_NAME_LEN) | |
164 | - return -EINVAL; | |
165 | - memcpy(name, buffer, count); | |
166 | - name[count] = '\0'; | |
167 | - if (name[count-1] == '\n') | |
168 | - name[count-1] = '\0'; | |
169 | - | |
170 | - ret = delete_module(name, O_NONBLOCK); | |
171 | - if (ret < 0) | |
172 | - return ret; | |
173 | - return count; | |
174 | -} | |
175 | - | |
176 | -static struct module_attribute mod_unload = { | |
177 | - .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE }, | |
178 | - .store = store_mod_unload, | |
179 | -}; | |
180 | -#endif | |
181 | - | |
182 | -static ssize_t show_mod_request_helper(struct module_attribute *mattr, | |
183 | - struct module *mod, | |
184 | - char *buffer) | |
185 | -{ | |
186 | - return sprintf(buffer, "%s\n", modprobe_path); | |
187 | -} | |
188 | - | |
189 | -static ssize_t store_mod_request_helper(struct module_attribute *mattr, | |
190 | - struct module *mod, | |
191 | - const char *buffer, size_t count) | |
192 | -{ | |
193 | - if (count < 1 || count+1 > KMOD_PATH_LEN) | |
194 | - return -EINVAL; | |
195 | - memcpy(modprobe_path, buffer, count); | |
196 | - modprobe_path[count] = '\0'; | |
197 | - if (modprobe_path[count-1] == '\n') | |
198 | - modprobe_path[count-1] = '\0'; | |
199 | - return count; | |
200 | -} | |
201 | - | |
202 | -static struct module_attribute mod_request_helper = { | |
203 | - .attr = { | |
204 | - .name = "mod_request_helper", | |
205 | - .mode = S_IWUSR | S_IRUGO, | |
206 | - .owner = THIS_MODULE | |
207 | - }, | |
208 | - .show = show_mod_request_helper, | |
209 | - .store = store_mod_request_helper, | |
210 | -}; | |
211 | - | |
212 | -void __init kmod_sysfs_init(void) | |
213 | -{ | |
214 | - int ret; | |
215 | - | |
216 | - kmod_mk.mod = THIS_MODULE; | |
217 | - kobj_set_kset_s(&kmod_mk, module_subsys); | |
218 | - kobject_set_name(&kmod_mk.kobj, "kmod"); | |
219 | - kobject_init(&kmod_mk.kobj); | |
220 | - ret = kobject_add(&kmod_mk.kobj); | |
221 | - if (ret < 0) | |
222 | - goto out; | |
223 | - | |
224 | - ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr); | |
225 | - ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr); | |
226 | -#ifdef CONFIG_MODULE_UNLOAD | |
227 | - ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr); | |
228 | -#endif | |
229 | - | |
230 | - kobject_uevent(&kmod_mk.kobj, KOBJ_ADD); | |
231 | -out: | |
232 | - return; | |
233 | -} | |
234 | 114 | #endif /* CONFIG_KMOD */ |
235 | 115 | |
236 | 116 | struct subprocess_info { |
kernel/module.c
... | ... | @@ -653,11 +653,20 @@ |
653 | 653 | mutex_lock(&module_mutex); |
654 | 654 | } |
655 | 655 | |
656 | -int delete_module(const char *name, unsigned int flags) | |
656 | +asmlinkage long | |
657 | +sys_delete_module(const char __user *name_user, unsigned int flags) | |
657 | 658 | { |
658 | 659 | struct module *mod; |
660 | + char name[MODULE_NAME_LEN]; | |
659 | 661 | int ret, forced = 0; |
660 | 662 | |
663 | + if (!capable(CAP_SYS_MODULE)) | |
664 | + return -EPERM; | |
665 | + | |
666 | + if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | |
667 | + return -EFAULT; | |
668 | + name[MODULE_NAME_LEN-1] = '\0'; | |
669 | + | |
661 | 670 | if (mutex_lock_interruptible(&module_mutex) != 0) |
662 | 671 | return -EINTR; |
663 | 672 | |
... | ... | @@ -716,21 +725,6 @@ |
716 | 725 | out: |
717 | 726 | mutex_unlock(&module_mutex); |
718 | 727 | return ret; |
719 | -} | |
720 | - | |
721 | -asmlinkage long | |
722 | -sys_delete_module(const char __user *name_user, unsigned int flags) | |
723 | -{ | |
724 | - char name[MODULE_NAME_LEN]; | |
725 | - | |
726 | - if (!capable(CAP_SYS_MODULE)) | |
727 | - return -EPERM; | |
728 | - | |
729 | - if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) | |
730 | - return -EFAULT; | |
731 | - name[MODULE_NAME_LEN-1] = '\0'; | |
732 | - | |
733 | - return delete_module(name, flags); | |
734 | 728 | } |
735 | 729 | |
736 | 730 | static void print_unload_info(struct seq_file *m, struct module *mod) |