aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-07 16:00:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-07 16:00:25 +0200
commit798b94518e61ced3f7be7766727705df4859878c (patch)
treeaf26ec7b4cb178933e6a76decb9561739933288d
parentb34eb4a591fa4dbbc091524a1c1159e2743134c8 (diff)
downloadbusybox-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.lst22
-rw-r--r--libbb/ubi.c1
-rw-r--r--miscutils/flash_eraseall.c1
-rw-r--r--miscutils/flash_lock_unlock.c1
-rw-r--r--miscutils/flashcp.c1
-rw-r--r--miscutils/ubi_tools.c63
-rw-r--r--miscutils/ubirename.c6
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
123fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory) 123fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory)
124find - noexec. runner 124find - noexec. runner
125findfs - suid 125findfs - suid
126flash_eraseall 126flash_eraseall - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
127flash_lock 127flash_lock - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
128flash_unlock 128flash_unlock - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
129flashcp - needs ^C. flash writing may be slow, better to free memory by execing 129flashcp - needs ^C. could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
130flock - spawner, changes state (file locks), let's play safe and not be noexec 130flock - spawner, changes state (file locks), let's play safe and not be noexec
131fold - noexec. runner 131fold - noexec. runner
132free - nofork candidate(struct globals, needs to close /proc/meminfo fd) 132free - nofork candidate(struct globals, needs to close /proc/meminfo fd)
@@ -366,13 +366,13 @@ tty - NOFORK
366ttysize - NOFORK 366ttysize - NOFORK
367tunctl - noexec 367tunctl - noexec
368tune2fs - noexec. leaks: open+xfunc 368tune2fs - noexec. leaks: open+xfunc
369ubiattach 369ubiattach - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
370ubidetach 370ubidetach - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
371ubimkvol 371ubimkvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
372ubirename 372ubirename - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
373ubirmvol 373ubirmvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
374ubirsvol 374ubirsvol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
375ubiupdatevol 375ubiupdatevol - could be noexec, but I feel flash ops are risky (prone to hw/fw/sw bugs)
376udhcpc - daemon 376udhcpc - daemon
377udhcpd - daemon 377udhcpd - daemon
378udpsvd - daemon 378udpsvd - 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
86static unsigned get_num_from_file(const char *path, unsigned max, const char *errmsg) 87static 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;