aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-06-20 10:59:06 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-06-20 11:02:40 +0200
commit5c3e060604444b18303f55e631637c28d889704f (patch)
tree6afe8c3d5292b171149f79393a4b2ca293dafa84
parent0ad872baf30b660ffb87265470d29f14cfc4b2d4 (diff)
downloadbusybox-w32-5c3e060604444b18303f55e631637c28d889704f.tar.gz
busybox-w32-5c3e060604444b18303f55e631637c28d889704f.tar.bz2
busybox-w32-5c3e060604444b18303f55e631637c28d889704f.zip
modprobe-small: fix bogus handling of unpack errors
"modprobe minix; echo $?" Was: modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz': No such file or directory modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz': No such file or directory modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz' modprobe: 'kernel/fs/minix/minix.ko.xz': Success 0 Now: modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz' 1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--modutils/modprobe-small.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index ffb46e6be..5936e48cf 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -45,6 +45,7 @@ typedef struct module_info {
45 char *pathname; 45 char *pathname;
46 char *aliases; 46 char *aliases;
47 char *deps; 47 char *deps;
48 smallint open_read_failed;
48} module_info; 49} module_info;
49 50
50/* 51/*
@@ -222,7 +223,8 @@ static int load_module(const char *fname, const char *options)
222#endif 223#endif
223} 224}
224 225
225static void parse_module(module_info *info, const char *pathname) 226/* Returns !0 if open/read was unsuccessful */
227static int parse_module(module_info *info, const char *pathname)
226{ 228{
227 char *module_image; 229 char *module_image;
228 char *ptr; 230 char *ptr;
@@ -231,6 +233,7 @@ static void parse_module(module_info *info, const char *pathname)
231 dbg1_error_msg("parse_module('%s')", pathname); 233 dbg1_error_msg("parse_module('%s')", pathname);
232 234
233 /* Read (possibly compressed) module */ 235 /* Read (possibly compressed) module */
236 errno = 0;
234 len = 64 * 1024 * 1024; /* 64 Mb at most */ 237 len = 64 * 1024 * 1024; /* 64 Mb at most */
235 module_image = xmalloc_open_zipped_read_close(pathname, &len); 238 module_image = xmalloc_open_zipped_read_close(pathname, &len);
236 /* module_image == NULL is ok here, find_keyword handles it */ 239 /* module_image == NULL is ok here, find_keyword handles it */
@@ -298,9 +301,11 @@ static void parse_module(module_info *info, const char *pathname)
298 dbg2_error_msg("dep:'%s'", ptr); 301 dbg2_error_msg("dep:'%s'", ptr);
299 append(ptr); 302 append(ptr);
300 } 303 }
304 free(module_image);
301 info->deps = copy_stringbuf(); 305 info->deps = copy_stringbuf();
302 306
303 free(module_image); 307 info->open_read_failed = (module_image == NULL);
308 return info->open_read_failed;
304} 309}
305 310
306static FAST_FUNC int fileAction(const char *pathname, 311static FAST_FUNC int fileAction(const char *pathname,
@@ -331,7 +336,8 @@ static FAST_FUNC int fileAction(const char *pathname,
331 336
332 dbg1_error_msg("'%s' module name matches", pathname); 337 dbg1_error_msg("'%s' module name matches", pathname);
333 module_found_idx = cur; 338 module_found_idx = cur;
334 parse_module(&modinfo[cur], pathname); 339 if (parse_module(&modinfo[cur], pathname) != 0)
340 return TRUE; /* failed to open/read it, no point in trying loading */
335 341
336 if (!(option_mask32 & OPT_r)) { 342 if (!(option_mask32 & OPT_r)) {
337 if (load_module(pathname, module_load_options) == 0) { 343 if (load_module(pathname, module_load_options) == 0) {
@@ -608,13 +614,14 @@ static int rmmod(const char *filename)
608#define process_module(a,b) process_module(a) 614#define process_module(a,b) process_module(a)
609#define cmdline_options "" 615#define cmdline_options ""
610#endif 616#endif
611static void process_module(char *name, const char *cmdline_options) 617static int process_module(char *name, const char *cmdline_options)
612{ 618{
613 char *s, *deps, *options; 619 char *s, *deps, *options;
614 module_info **infovec; 620 module_info **infovec;
615 module_info *info; 621 module_info *info;
616 int infoidx; 622 int infoidx;
617 int is_remove = (option_mask32 & OPT_r) != 0; 623 int is_remove = (option_mask32 & OPT_r) != 0;
624 int exitcode = EXIT_SUCCESS;
618 625
619 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); 626 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);
620 627
@@ -628,7 +635,7 @@ static void process_module(char *name, const char *cmdline_options)
628 * (compat note: this allows and strips .ko suffix) 635 * (compat note: this allows and strips .ko suffix)
629 */ 636 */
630 rmmod(name); 637 rmmod(name);
631 return; 638 return EXIT_SUCCESS;
632 } 639 }
633 640
634 /* 641 /*
@@ -639,7 +646,7 @@ static void process_module(char *name, const char *cmdline_options)
639 */ 646 */
640 if (!is_remove && already_loaded(name)) { 647 if (!is_remove && already_loaded(name)) {
641 dbg1_error_msg("nothing to do for '%s'", name); 648 dbg1_error_msg("nothing to do for '%s'", name);
642 return; 649 return EXIT_SUCCESS;
643 } 650 }
644 651
645 options = NULL; 652 options = NULL;
@@ -741,6 +748,11 @@ static void process_module(char *name, const char *cmdline_options)
741 dbg1_error_msg("'%s': blacklisted", info->pathname); 748 dbg1_error_msg("'%s': blacklisted", info->pathname);
742 continue; 749 continue;
743 } 750 }
751 if (info->open_read_failed) {
752 /* We already tried it, didn't work. Don't try load again */
753 exitcode = EXIT_FAILURE;
754 continue;
755 }
744 errno = 0; 756 errno = 0;
745 if (load_module(info->pathname, options) != 0) { 757 if (load_module(info->pathname, options) != 0) {
746 if (EEXIST != errno) { 758 if (EEXIST != errno) {
@@ -752,13 +764,14 @@ static void process_module(char *name, const char *cmdline_options)
752 info->pathname, 764 info->pathname,
753 moderror(errno)); 765 moderror(errno));
754 } 766 }
767 exitcode = EXIT_FAILURE;
755 } 768 }
756 } 769 }
757 ret: 770 ret:
758 free(infovec); 771 free(infovec);
759 free(options); 772 free(options);
760//TODO: return load attempt result from process_module. 773
761//If dep didn't load ok, continuing makes little sense. 774 return exitcode;
762} 775}
763#undef cmdline_options 776#undef cmdline_options
764 777
@@ -865,6 +878,7 @@ The following options are useful for people managing distributions:
865int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 878int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
866int modprobe_main(int argc UNUSED_PARAM, char **argv) 879int modprobe_main(int argc UNUSED_PARAM, char **argv)
867{ 880{
881 int exitcode;
868 struct utsname uts; 882 struct utsname uts;
869 char applet0 = applet_name[0]; 883 char applet0 = applet_name[0];
870 IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) 884 IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;)
@@ -970,21 +984,23 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
970 bb_error_msg_and_die("can't insert '%s': %s", 984 bb_error_msg_and_die("can't insert '%s': %s",
971 *argv, moderror(errno)); 985 *argv, moderror(errno));
972 } 986 }
973 return 0; 987 return EXIT_SUCCESS;
974 } 988 }
975 989
976 /* Try to load modprobe.dep.bb */ 990 /* Try to load modprobe.dep.bb */
977 if ('r' != applet0) /* not rmmod */ 991 if ('r' != applet0) { /* not rmmod */
978 load_dep_bb(); 992 load_dep_bb();
993 }
979 994
980 /* Load/remove modules. 995 /* Load/remove modules.
981 * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */ 996 * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */
997 exitcode = EXIT_SUCCESS;
982 do { 998 do {
983 process_module(*argv, options); 999 exitcode |= process_module(*argv, options);
984 } while (*++argv); 1000 } while (*++argv);
985 1001
986 if (ENABLE_FEATURE_CLEAN_UP) { 1002 if (ENABLE_FEATURE_CLEAN_UP) {
987 IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) 1003 IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);)
988 } 1004 }
989 return EXIT_SUCCESS; 1005 return exitcode;
990} 1006}