diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-17 01:52:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-04-17 01:52:28 +0000 |
commit | c033d5196d863edaabf9d02531a12daa77cc48c7 (patch) | |
tree | 191eaf5851762ea1254757685eb15e885e070c5f | |
parent | 4437d19fb4d7bd7cd9d8acd5e67d85c8751a6e93 (diff) | |
download | busybox-c033d5196d863edaabf9d02531a12daa77cc48c7.tar.gz |
fdisk: fix a case where we can inadvertently close /proc/partitions fd early
-rw-r--r-- | util-linux/fdisk.c | 46 | ||||
-rw-r--r-- | util-linux/fdisk_osf.c | 2 |
2 files changed, 29 insertions, 19 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 57d4d653e..50ab48dab 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -36,6 +36,18 @@ #define LINUX_LVM 0x8e #define LINUX_RAID 0xfd + +enum { + OPT_b = 1 << 0, + OPT_C = 1 << 1, + OPT_H = 1 << 2, + OPT_l = 1 << 3, + OPT_S = 1 << 4, + OPT_u = 1 << 5, + OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, +}; + + /* Used for sector numbers. Today's disk sizes make it necessary */ typedef unsigned long long ullong; @@ -366,6 +378,13 @@ static ullong bb_BLKGETSIZE_sectors(int fd) s |= (sector >> 2) & 0xc0; \ } while (0) +static void +close_dev_fd(void) +{ + /* Not really closing, but making sure it is open, and to harmless place */ + xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); +} + #if ENABLE_FEATURE_FDISK_WRITABLE /* read line; return 0 or first printable char */ static int @@ -660,7 +679,7 @@ static ullong total_number_of_sectors; static void fdisk_fatal(const char *why) { if (listing) { - close(dev_fd); + close_dev_fd(); longjmp(listingbuf, 1); } bb_error_msg_and_die(why, disk_device); @@ -1280,12 +1299,12 @@ static int get_boot(void) return 1; fdisk_fatal(unable_to_open); } - xmove_fd(fd, dev_fd); printf("'%s' is opened for read only\n", disk_device); } + xmove_fd(fd, dev_fd); if (512 != read(dev_fd, MBRbuffer, 512)) { if (what == TRY_ONLY) { - close(dev_fd); + close_dev_fd(); return 1; } fdisk_fatal(unable_to_read); @@ -2466,7 +2485,7 @@ reread_partition_table(int leave) if (leave) { if (ENABLE_FEATURE_CLEAN_UP) - close(dev_fd); + close_dev_fd(); exit(i != 0); } } @@ -2599,7 +2618,7 @@ xselect(void) break; case 'q': if (ENABLE_FEATURE_CLEAN_UP) - close(dev_fd); + close_dev_fd(); bb_putchar('\n'); exit(0); case 'r': @@ -2708,7 +2727,7 @@ open_list_and_close(const char *device, int user_specified) #endif } ret: - close(dev_fd); + close_dev_fd(); } /* for fdisk -l: try all things in /proc/partitions @@ -2758,19 +2777,9 @@ int fdisk_main(int argc, char **argv) * * Options -C, -H, -S set the geometry. */ - enum { - OPT_b = 1 << 0, - OPT_C = 1 << 1, - OPT_H = 1 << 2, - OPT_l = 1 << 3, - OPT_S = 1 << 4, - OPT_u = 1 << 5, - OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, - }; - INIT_G(); - close(dev_fd); /* just in case */ + close_dev_fd(); /* needed: fd 3 must not stay closed */ opt_complementary = "b+:C+:H+:S+"; /* numeric params */ opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), @@ -2933,7 +2942,8 @@ int fdisk_main(int argc, char **argv) list_table(0); break; case 'q': - close(dev_fd); + if (ENABLE_FEATURE_CLEAN_UP) + close_dev_fd(); bb_putchar('\n'); return 0; case 's': diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index ba01a7f0c..e281ea5d9 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c @@ -414,7 +414,7 @@ bsd_select(void) break; case 'q': if (ENABLE_FEATURE_CLEAN_UP) - close(dev_fd); + close_dev_fd(); exit(EXIT_SUCCESS); case 'r': return; |