summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2008-04-17 01:52:28 +0000
committerDenis Vlasenko2008-04-17 01:52:28 +0000
commitc033d5196d863edaabf9d02531a12daa77cc48c7 (patch)
tree191eaf5851762ea1254757685eb15e885e070c5f
parent4437d19fb4d7bd7cd9d8acd5e67d85c8751a6e93 (diff)
downloadbusybox-c033d5196d863edaabf9d02531a12daa77cc48c7.zip
busybox-c033d5196d863edaabf9d02531a12daa77cc48c7.tar.gz
fdisk: fix a case where we can inadvertently close /proc/partitions fd early
-rw-r--r--util-linux/fdisk.c46
-rw-r--r--util-linux/fdisk_osf.c2
2 files changed, 29 insertions, 19 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 57d4d65..50ab48d 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 ba01a7f..e281ea5 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;