diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-07 16:00:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-07 16:00:25 +0200 |
commit | 798b94518e61ced3f7be7766727705df4859878c (patch) | |
tree | af26ec7b4cb178933e6a76decb9561739933288d | |
parent | b34eb4a591fa4dbbc091524a1c1159e2743134c8 (diff) | |
download | busybox-w32-798b94518e61ced3f7be7766727705df4859878c.tar.gz busybox-w32-798b94518e61ced3f7be7766727705df4859878c.tar.bz2 busybox-w32-798b94518e61ced3f7be7766727705df4859878c.zip |
ubi tools: ubiupdatevol supports "-" input and actually respects -s SIZE
Decided to not make any flash applets NOEXEC.
Minor robustifications here and there. Better error messages. Save on strings:
function old new delta
ubi_tools_main 1235 1288 +53
ubi_get_volid_by_name 125 133 +8
ubirename_main 198 204 +6
get_num_from_file 90 94 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 71/0) Total: 71 bytes
text data bss dec hex filename
915696 485 6880 923061 e15b5 busybox_old
915670 485 6880 923035 e159b busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | NOFORK_NOEXEC.lst | 22 | ||||
-rw-r--r-- | libbb/ubi.c | 1 | ||||
-rw-r--r-- | miscutils/flash_eraseall.c | 1 | ||||
-rw-r--r-- | miscutils/flash_lock_unlock.c | 1 | ||||
-rw-r--r-- | miscutils/flashcp.c | 1 | ||||
-rw-r--r-- | miscutils/ubi_tools.c | 63 | ||||
-rw-r--r-- | miscutils/ubirename.c | 6 |
7 files changed, 59 insertions, 36 deletions
diff --git a/NOFORK_NOEXEC.lst b/NOFORK_NOEXEC.lst index d54c206fe..981a10192 100644 --- a/NOFORK_NOEXEC.lst +++ b/NOFORK_NOEXEC.lst | |||
@@ -123,10 +123,10 @@ fgconsole - noexec. leaks: get_console_fd_or_die() may open a new fd, or return | |||
123 | fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory) | 123 | fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory) |
124 | find - noexec. runner | 124 | find - noexec. runner |
125 | findfs - suid | 125 | findfs - suid |
126 | flash_eraseall | 126 | flash_eraseall - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
127 | flash_lock | 127 | flash_lock - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
128 | flash_unlock | 128 | flash_unlock - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
129 | flashcp - needs ^C. flash writing may be slow, better to free memory by execing | 129 | flashcp - needs ^C. could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
130 | flock - spawner, changes state (file locks), let's play safe and not be noexec | 130 | flock - spawner, changes state (file locks), let's play safe and not be noexec |
131 | fold - noexec. runner | 131 | fold - noexec. runner |
132 | free - nofork candidate(struct globals, needs to close /proc/meminfo fd) | 132 | free - nofork candidate(struct globals, needs to close /proc/meminfo fd) |
@@ -366,13 +366,13 @@ tty - NOFORK | |||
366 | ttysize - NOFORK | 366 | ttysize - NOFORK |
367 | tunctl - noexec | 367 | tunctl - noexec |
368 | tune2fs - noexec. leaks: open+xfunc | 368 | tune2fs - noexec. leaks: open+xfunc |
369 | ubiattach | 369 | ubiattach - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
370 | ubidetach | 370 | ubidetach - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
371 | ubimkvol | 371 | ubimkvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
372 | ubirename | 372 | ubirename - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
373 | ubirmvol | 373 | ubirmvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
374 | ubirsvol | 374 | ubirsvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
375 | ubiupdatevol | 375 | ubiupdatevol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs) |
376 | udhcpc - daemon | 376 | udhcpc - daemon |
377 | udhcpd - daemon | 377 | udhcpd - daemon |
378 | udpsvd - daemon | 378 | udpsvd - daemon |
diff --git a/libbb/ubi.c b/libbb/ubi.c index 34595d797..a90016acf 100644 --- a/libbb/ubi.c +++ b/libbb/ubi.c | |||
@@ -35,6 +35,7 @@ int FAST_FUNC ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) | |||
35 | if (open_read_close(fname, buf, sizeof(buf)) <= 0) | 35 | if (open_read_close(fname, buf, sizeof(buf)) <= 0) |
36 | continue; | 36 | continue; |
37 | 37 | ||
38 | buf[UBI_MAX_VOLUME_NAME] = '\0'; | ||
38 | strchrnul(buf, '\n')[0] = '\0'; | 39 | strchrnul(buf, '\n')[0] = '\0'; |
39 | if (strcmp(vol_name, buf) == 0) | 40 | if (strcmp(vol_name, buf) == 0) |
40 | return i; | 41 | return i; |
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c index af9ebea24..3ddd9dd99 100644 --- a/miscutils/flash_eraseall.c +++ b/miscutils/flash_eraseall.c | |||
@@ -17,6 +17,7 @@ | |||
17 | //config: This utility is used to erase the whole MTD device. | 17 | //config: This utility is used to erase the whole MTD device. |
18 | 18 | ||
19 | //applet:IF_FLASH_ERASEALL(APPLET(flash_eraseall, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 19 | //applet:IF_FLASH_ERASEALL(APPLET(flash_eraseall, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
20 | /* not NOEXEC: if flash operation stalls, use less memory in "hung" process */ | ||
20 | 21 | ||
21 | //kbuild:lib-$(CONFIG_FLASH_ERASEALL) += flash_eraseall.o | 22 | //kbuild:lib-$(CONFIG_FLASH_ERASEALL) += flash_eraseall.o |
22 | 23 | ||
diff --git a/miscutils/flash_lock_unlock.c b/miscutils/flash_lock_unlock.c index 374eed5f6..6f2c049f4 100644 --- a/miscutils/flash_lock_unlock.c +++ b/miscutils/flash_lock_unlock.c | |||
@@ -20,6 +20,7 @@ | |||
20 | // APPLET_ODDNAME:name main location suid_type help | 20 | // APPLET_ODDNAME:name main location suid_type help |
21 | //applet:IF_FLASH_LOCK( APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock)) | 21 | //applet:IF_FLASH_LOCK( APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock)) |
22 | //applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock)) | 22 | //applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock)) |
23 | /* not NOEXEC: if flash operation stalls, use less memory in "hung" process */ | ||
23 | 24 | ||
24 | //kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o | 25 | //kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o |
25 | //kbuild:lib-$(CONFIG_FLASH_UNLOCK) += flash_lock_unlock.o | 26 | //kbuild:lib-$(CONFIG_FLASH_UNLOCK) += flash_lock_unlock.o |
diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c index d4ac62df4..c10b96ee8 100644 --- a/miscutils/flashcp.c +++ b/miscutils/flashcp.c | |||
@@ -14,6 +14,7 @@ | |||
14 | //config: This utility is used to copy images into a MTD device. | 14 | //config: This utility is used to copy images into a MTD device. |
15 | 15 | ||
16 | //applet:IF_FLASHCP(APPLET(flashcp, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 16 | //applet:IF_FLASHCP(APPLET(flashcp, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
17 | /* not NOEXEC: if flash operation stalls, use less memory in "hung" process */ | ||
17 | 18 | ||
18 | //kbuild:lib-$(CONFIG_FLASHCP) += flashcp.o | 19 | //kbuild:lib-$(CONFIG_FLASHCP) += flashcp.o |
19 | 20 | ||
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index 494718ccf..123551e94 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c | |||
@@ -52,6 +52,7 @@ | |||
52 | //applet:IF_UBIRMVOL( APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol)) | 52 | //applet:IF_UBIRMVOL( APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol)) |
53 | //applet:IF_UBIRSVOL( APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol)) | 53 | //applet:IF_UBIRSVOL( APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol)) |
54 | //applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol)) | 54 | //applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol)) |
55 | /* not NOEXEC: if flash operation stalls, use less memory in "hung" process */ | ||
55 | 56 | ||
56 | //kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o | 57 | //kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o |
57 | //kbuild:lib-$(CONFIG_UBIDETACH) += ubi_tools.o | 58 | //kbuild:lib-$(CONFIG_UBIDETACH) += ubi_tools.o |
@@ -83,16 +84,16 @@ | |||
83 | #define do_rsvol (ENABLE_UBIRSVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 's')) | 84 | #define do_rsvol (ENABLE_UBIRSVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 's')) |
84 | #define do_update (ENABLE_UBIUPDATEVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 'p')) | 85 | #define do_update (ENABLE_UBIUPDATEVOL && (UBI_APPLET_CNT == 1 || applet_name[4] == 'p')) |
85 | 86 | ||
86 | static unsigned get_num_from_file(const char *path, unsigned max, const char *errmsg) | 87 | static unsigned get_num_from_file(const char *path, unsigned max) |
87 | { | 88 | { |
88 | char buf[sizeof(long long)*3]; | 89 | char buf[sizeof(long long)*3]; |
89 | unsigned long long num; | 90 | unsigned long long num; |
90 | 91 | ||
91 | if (open_read_close(path, buf, sizeof(buf)) < 0) | 92 | if (open_read_close(path, buf, sizeof(buf)) < 0) |
92 | bb_perror_msg_and_die(errmsg, path); | 93 | bb_perror_msg_and_die("can't open '%s'", path); |
93 | /* It can be \n terminated, xatoull won't work well */ | 94 | /* It can be \n terminated, xatoull won't work well */ |
94 | if (sscanf(buf, "%llu", &num) != 1 || num > max) | 95 | if (sscanf(buf, "%llu", &num) != 1 || num > max) |
95 | bb_error_msg_and_die(errmsg, path); | 96 | bb_error_msg_and_die("number in '%s' is malformed or too large", path); |
96 | return num; | 97 | return num; |
97 | } | 98 | } |
98 | 99 | ||
@@ -226,10 +227,10 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
226 | p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); | 227 | p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); |
227 | 228 | ||
228 | strcpy(p, "avail_eraseblocks"); | 229 | strcpy(p, "avail_eraseblocks"); |
229 | leb_avail = get_num_from_file(path, UINT_MAX, "Can't get available eraseblocks from '%s'"); | 230 | leb_avail = get_num_from_file(path, UINT_MAX); |
230 | 231 | ||
231 | strcpy(p, "eraseblock_size"); | 232 | strcpy(p, "eraseblock_size"); |
232 | leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get eraseblock size from '%s'"); | 233 | leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK); |
233 | 234 | ||
234 | size_bytes = leb_avail * (unsigned long long)leb_size; | 235 | size_bytes = leb_avail * (unsigned long long)leb_size; |
235 | //if (size_bytes <= 0) | 236 | //if (size_bytes <= 0) |
@@ -241,16 +242,19 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
241 | if (!(opts & OPTION_N)) | 242 | if (!(opts & OPTION_N)) |
242 | bb_error_msg_and_die("name not specified"); | 243 | bb_error_msg_and_die("name not specified"); |
243 | 244 | ||
245 | /* the structure is memset(0) above */ | ||
244 | mkvol_req.vol_id = vol_id; | 246 | mkvol_req.vol_id = vol_id; |
245 | mkvol_req.vol_type = UBI_DYNAMIC_VOLUME; | 247 | mkvol_req.vol_type = UBI_DYNAMIC_VOLUME; |
246 | if ((opts & OPTION_t) && type[0] == 's') | 248 | if ((opts & OPTION_t) && type[0] == 's') |
247 | mkvol_req.vol_type = UBI_STATIC_VOLUME; | 249 | mkvol_req.vol_type = UBI_STATIC_VOLUME; |
248 | mkvol_req.alignment = alignment; | 250 | mkvol_req.alignment = alignment; |
249 | mkvol_req.bytes = size_bytes; /* signed int64_t */ | 251 | mkvol_req.bytes = size_bytes; /* signed int64_t */ |
250 | strncpy(mkvol_req.name, vol_name, UBI_MAX_VOLUME_NAME); | 252 | /* strnlen avoids overflow of 16-bit field (paranoia) */ |
251 | mkvol_req.name_len = strlen(vol_name); | 253 | mkvol_req.name_len = strnlen(vol_name, UBI_MAX_VOLUME_NAME+1); |
252 | if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME) | 254 | if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME) |
253 | bb_error_msg_and_die("volume name too long: '%s'", vol_name); | 255 | bb_error_msg_and_die("volume name too long: '%s'", vol_name); |
256 | /* this is safe: .name[] is UBI_MAX_VOLUME_NAME+1 bytes */ | ||
257 | strcpy(mkvol_req.name, vol_name); | ||
254 | 258 | ||
255 | xioctl(fd, UBI_IOCMKVOL, &mkvol_req); | 259 | xioctl(fd, UBI_IOCMKVOL, &mkvol_req); |
256 | } else | 260 | } else |
@@ -315,38 +319,49 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
315 | else { | 319 | else { |
316 | unsigned ubinum, volnum; | 320 | unsigned ubinum, volnum; |
317 | unsigned leb_size; | 321 | unsigned leb_size; |
318 | ssize_t len; | 322 | char *buf; |
319 | char *input_data; | ||
320 | 323 | ||
321 | /* Assume that device is in normal format. */ | 324 | /* Assume that device is in normal format. */ |
322 | /* Removes need for scanning sysfs tree as full libubi does. */ | 325 | /* Removes need for scanning sysfs tree as full libubi does. */ |
323 | if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2) | 326 | if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2) |
324 | bb_error_msg_and_die("wrong format of UBI device name"); | 327 | bb_error_msg_and_die("UBI device name '%s' is not /dev/ubiN_M", ubi_ctrl); |
325 | 328 | ||
326 | sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum); | 329 | sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum); |
327 | leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get usable eraseblock size from '%s'"); | 330 | leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK); |
328 | 331 | ||
329 | if (!(opts & OPTION_t)) { | 332 | if (!*argv) |
330 | if (!*argv) | 333 | bb_show_usage(); |
331 | bb_show_usage(); | 334 | if (NOT_LONE_DASH(*argv)) /* mtd-utils supports "-" as stdin */ |
332 | xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO); | 335 | xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO); |
333 | if (!(opts & OPTION_s)) { | 336 | |
334 | struct stat st; | 337 | if (!(opts & OPTION_s)) { |
335 | xfstat(STDIN_FILENO, &st, *argv); | 338 | struct stat st; |
336 | size_bytes = st.st_size; | 339 | xfstat(STDIN_FILENO, &st, *argv); |
337 | } | 340 | size_bytes = st.st_size; |
338 | } | 341 | } |
339 | 342 | ||
340 | bytes64 = size_bytes; | 343 | bytes64 = size_bytes; |
341 | /* this ioctl expects signed int64_t* parameter */ | 344 | /* this ioctl expects signed int64_t* parameter */ |
342 | xioctl(fd, UBI_IOCVOLUP, &bytes64); | 345 | xioctl(fd, UBI_IOCVOLUP, &bytes64); |
343 | 346 | ||
344 | input_data = xmalloc(leb_size); | 347 | /* can't use bb_copyfd_exact_size(): copy in blocks of exactly leb_size */ |
345 | while ((len = full_read(STDIN_FILENO, input_data, leb_size)) > 0) { | 348 | buf = xmalloc(leb_size); |
346 | xwrite(fd, input_data, len); | 349 | while (size_bytes != 0) { |
350 | int len = full_read(STDIN_FILENO, buf, leb_size); | ||
351 | if (len <= 0) { | ||
352 | if (len < 0) | ||
353 | bb_perror_msg_and_die("read error from '%s'", *argv); | ||
354 | break; | ||
355 | } | ||
356 | if ((unsigned)len > size_bytes) { | ||
357 | /* for this case: "ubiupdatevol -s 1024000 $UBIDEV /dev/urandom" */ | ||
358 | len = size_bytes; | ||
359 | } | ||
360 | xwrite(fd, buf, len); | ||
361 | size_bytes -= len; | ||
347 | } | 362 | } |
348 | if (len < 0) | 363 | if (ENABLE_FEATURE_CLEAN_UP) |
349 | bb_perror_msg_and_die("UBI volume update failed"); | 364 | free(buf); |
350 | } | 365 | } |
351 | } | 366 | } |
352 | 367 | ||
diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c index 786c4b9fa..ecc8fe137 100644 --- a/miscutils/ubirename.c +++ b/miscutils/ubirename.c | |||
@@ -14,6 +14,7 @@ | |||
14 | //config: Utility to rename UBI volumes | 14 | //config: Utility to rename UBI volumes |
15 | 15 | ||
16 | //applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 16 | //applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
17 | /* not NOEXEC: if flash operation stalls, use less memory in "hung" process */ | ||
17 | 18 | ||
18 | //kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o | 19 | //kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o |
19 | 20 | ||
@@ -80,9 +81,12 @@ int ubirename_main(int argc, char **argv) | |||
80 | argv += 2; | 81 | argv += 2; |
81 | while (argv[0]) { | 82 | while (argv[0]) { |
82 | rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]); | 83 | rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]); |
83 | rnvol->ents[n].name_len = strlen(argv[1]); | 84 | |
85 | /* strnlen avoids overflow of 16-bit field (paranoia) */ | ||
86 | rnvol->ents[n].name_len = strnlen(argv[1], sizeof(rnvol->ents[n].name)); | ||
84 | if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) | 87 | if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) |
85 | bb_error_msg_and_die("new name '%s' is too long", argv[1]); | 88 | bb_error_msg_and_die("new name '%s' is too long", argv[1]); |
89 | |||
86 | strcpy(rnvol->ents[n].name, argv[1]); | 90 | strcpy(rnvol->ents[n].name, argv[1]); |
87 | n++; | 91 | n++; |
88 | argv += 2; | 92 | argv += 2; |