aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-31 02:04:28 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-31 02:04:28 +0000
commitbb26db49b1b3a6cbc4b72c0cc6948432e3e77996 (patch)
tree33a7976a4b4f41839b3f4f175ac4b472daac2619
parentb9b344aa44ba6221edc8f09398325399049bf388 (diff)
downloadbusybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.tar.gz
busybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.tar.bz2
busybox-w32-bb26db49b1b3a6cbc4b72c0cc6948432e3e77996.zip
modprobe: fix a segfault when modprobe is called with no arguments at all
function old new delta modprobe_main 559 535 -24
-rw-r--r--modutils/modprobe.c52
-rw-r--r--modutils/modutils.c2
2 files changed, 29 insertions, 25 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 20b9a74aa..40a1e6627 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -203,18 +203,17 @@ int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
203int modprobe_main(int argc UNUSED_PARAM, char **argv) 203int modprobe_main(int argc UNUSED_PARAM, char **argv)
204{ 204{
205 struct utsname uts; 205 struct utsname uts;
206 int num_modules, i, rc; 206 int rc;
207 unsigned opt;
207 llist_t *options = NULL; 208 llist_t *options = NULL;
208 parser_t *parser;
209 209
210 opt_complementary = "q-v:v-q"; 210 opt_complementary = "q-v:v-q";
211 getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS, 211 opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS,
212 NULL, NULL); 212 NULL, NULL);
213 argv += optind; 213 argv += optind;
214 argc -= optind;
215 214
216 if (option_mask32 & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY | 215 if (opt & (MODPROBE_OPT_DUMP_ONLY | MODPROBE_OPT_LIST_ONLY |
217 MODPROBE_OPT_SHOW_ONLY)) 216 MODPROBE_OPT_SHOW_ONLY))
218 bb_error_msg_and_die("not supported"); 217 bb_error_msg_and_die("not supported");
219 218
220 /* goto modules location */ 219 /* goto modules location */
@@ -222,40 +221,44 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
222 uname(&uts); 221 uname(&uts);
223 xchdir(uts.release); 222 xchdir(uts.release);
224 223
225 if (option_mask32 & (MODPROBE_OPT_REMOVE | MODPROBE_OPT_INSERT_ALL)) { 224 if (!argv[0]) {
226 /* each parameter is a module name */ 225 if (opt & MODPROBE_OPT_REMOVE) {
227 num_modules = argc;
228 if (num_modules == 0) {
229 if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0) 226 if (bb_delete_module(NULL, O_NONBLOCK|O_EXCL) != 0)
230 bb_perror_msg_and_die("rmmod"); 227 bb_perror_msg_and_die("rmmod");
231 return EXIT_SUCCESS;
232 } 228 }
233 } else { 229 return EXIT_SUCCESS;
234 /* the only module, the rest of parameters are options */ 230 }
235 num_modules = 1; 231 if (!(opt & MODPROBE_OPT_INSERT_ALL)) {
232 /* If not -a, we have only one module name,
233 * the rest of parameters are options */
236 add_option(&options, NULL, parse_cmdline_module_options(argv)); 234 add_option(&options, NULL, parse_cmdline_module_options(argv));
235 argv[1] = NULL;
237 } 236 }
238 237
239 /* cache modules */ 238 /* cache modules */
240 parser = config_open2("/proc/modules", fopen_for_read); 239 {
241 if (parser) {
242 char *s; 240 char *s;
241 parser_t *parser = config_open2("/proc/modules", fopen_for_read);
243 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) 242 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY))
244 llist_add_to(&loaded, xstrdup(s)); 243 llist_add_to(&loaded, xstrdup(s));
245 config_close(parser); 244 config_close(parser);
246 } 245 }
247 246
248 for (i = 0; i < num_modules; i++) { 247 while (*argv) {
248 const char *arg = *argv;
249 struct modprobe_conf *conf; 249 struct modprobe_conf *conf;
250 250
251 conf = xzalloc(sizeof(struct modprobe_conf)); 251 conf = xzalloc(sizeof(*conf));
252 conf->options = options; 252 conf->options = options;
253 filename2modname(argv[i], conf->probename); 253 filename2modname(arg, conf->probename);
254 read_config(conf, "/etc/modprobe.conf"); 254 read_config(conf, "/etc/modprobe.conf");
255 read_config(conf, "/etc/modprobe.d"); 255 read_config(conf, "/etc/modprobe.d");
256 if (ENABLE_FEATURE_MODUTILS_SYMBOLS && 256 if (ENABLE_FEATURE_MODUTILS_SYMBOLS
257 conf->aliases == NULL && strncmp(argv[i], "symbol:", 7) == 0) 257 && conf->aliases == NULL
258 && strncmp(arg, "symbol:", 7) == 0
259 ) {
258 read_config(conf, "modules.symbols"); 260 read_config(conf, "modules.symbols");
261 }
259 262
260 if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL) 263 if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL)
261 read_config(conf, "modules.alias"); 264 read_config(conf, "modules.alias");
@@ -263,11 +266,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
263 if (conf->aliases == NULL) { 266 if (conf->aliases == NULL) {
264 /* Try if module by literal name is found; literal 267 /* Try if module by literal name is found; literal
265 * names are blacklist only if '-b' is given. */ 268 * names are blacklist only if '-b' is given. */
266 if (!(option_mask32 & MODPROBE_OPT_BLACKLIST) || 269 if (!(opt & MODPROBE_OPT_BLACKLIST) ||
267 check_blacklist(conf, conf->probename)) { 270 check_blacklist(conf, conf->probename)) {
268 rc = do_modprobe(conf, conf->probename); 271 rc = do_modprobe(conf, conf->probename);
269 if (rc < 0 && !(option_mask32 & INSMOD_OPT_SILENT)) 272 if (rc < 0 && !(opt & INSMOD_OPT_SILENT))
270 bb_error_msg("Module %s not found.", argv[i]); 273 bb_error_msg("Module %s not found.", arg);
271 } 274 }
272 } else { 275 } else {
273 /* Probe all aliases */ 276 /* Probe all aliases */
@@ -279,6 +282,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
279 free(realname); 282 free(realname);
280 } 283 }
281 } 284 }
285 argv++;
282 } 286 }
283 287
284 return EXIT_SUCCESS; 288 return EXIT_SUCCESS;
diff --git a/modutils/modutils.c b/modutils/modutils.c
index 18ea5374e..10b49c901 100644
--- a/modutils/modutils.c
+++ b/modutils/modutils.c
@@ -106,7 +106,7 @@ char * FAST_FUNC parse_cmdline_module_options(char **argv)
106 while (*++argv) { 106 while (*++argv) {
107 options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); 107 options = xrealloc(options, optlen + 2 + strlen(*argv) + 2);
108 /* Spaces handled by "" pairs, but no way of escaping quotes */ 108 /* Spaces handled by "" pairs, but no way of escaping quotes */
109 optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv); 109 optlen += sprintf(options + optlen, (strchr(*argv, ' ') ? "\"%s\" " : "%s "), *argv);
110 } 110 }
111 return options; 111 return options;
112} 112}