[git commit] fdisk: eliminate static variables, fix GPT disk size (32x32->32 overflow)

Denys Vlasenko vda.linux at googlemail.com
Sun Feb 1 12:44:54 UTC 2026


commit: https://git.busybox.net/busybox/commit/?id=7ac2bd69175d4216f0b53b16b132c1df806ac8b5
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
verify_sun                                           481     508     +27
.rodata                                           107016  107022      +6
verify_sun_cmp                                        51      54      +3
sun_other_endian                                       1       -      -1
scsi_disk                                              1       -      -1
floppy                                                 1       -      -1
xbsd_print_disklabel                                 838     836      -2
xbsd_new_part                                        479     477      -2
xbsd_write_bootstrap                                 397     394      -3
set_sun_partition                                    103     100      -3
delete_partition                                     435     432      -3
xbsd_part_index                                        4       -      -4
xbsd_part                                              4       -      -4
verify_sun_starts                                      4       -      -4
part_entry_len                                         4       -      -4
part_array                                             4       -      -4
n_parts                                                4       -      -4
gpt_hdr                                                4       -      -4
check_sun_label                                      214     208      -6
list_table                                          1433    1423     -10
fetch_sun                                            233     219     -14
bsd_select                                          1564    1546     -18
get_geometry                                         691     665     -26
get_boot                                            1539    1513     -26
fdisk_main                                          4737    4674     -63
------------------------------------------------------------------------------
(add/remove: 0/10 grow/shrink: 3/12 up/down: 36/-207)        Total: -171 bytes
   text	   data	    bss	    dec	    hex	filename
1078472	    555	   5088	1084115	 108ad3	busybox_old
1078332	    555	   5056	1083943	 108a27	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 util-linux/fdisk.c     | 27 +++++++++++++++++-
 util-linux/fdisk_gpt.c | 74 ++++++++++++++++++++++++------------------------
 util-linux/fdisk_osf.c | 28 +++++++++----------
 util-linux/fdisk_sun.c | 76 ++++++++++++++++++++++++++------------------------
 4 files changed, 116 insertions(+), 89 deletions(-)

diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 96e2abffe..abd48ec9b 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -170,8 +170,10 @@ typedef unsigned long long ullong;
 typedef uint32_t sector_t;
 #if UINT_MAX == 0xffffffff
 # define SECT_FMT ""
+# define SECT_TYPE unsigned
 #elif ULONG_MAX == 0xffffffff
 # define SECT_FMT "l"
+# define SECT_TYPE unsigned long
 #else
 # error Cant detect sizeof(uint32_t)
 #endif
@@ -412,6 +414,10 @@ enum {
 	dev_fd = 3                  /* the disk */
 };
 
+#if ENABLE_FEATURE_GPT_LABEL
+	struct gpt_header;
+#endif
+
 /* Globals */
 struct globals {
 	char *line_ptr;
@@ -434,6 +440,18 @@ struct globals {
 #if ENABLE_FEATURE_FDISK_WRITABLE
 	//int dos_changed;
 	smallint nowarn;                /* no warnings for fdisk -l/-s */
+#endif
+#if ENABLE_FEATURE_SUN_LABEL
+	smallint sun_other_endian;
+	smallint sun_scsi_disk;
+	smallint sun_floppy;
+	unsigned *verify_sun_starts;
+#endif
+#if ENABLE_FEATURE_OSF_LABEL
+# if !defined(__alpha__)
+	struct partition *xbsd_part;
+	unsigned xbsd_part_index;
+# endif
 #endif
 	int ext_index;                  /* the prime extended partition */
 	unsigned user_cylinders, user_heads, user_sectors;
@@ -442,6 +460,13 @@ struct globals {
 	sector_t extended_offset;       /* offset of link pointers */
 	sector_t total_number_of_sectors;
 
+#if ENABLE_FEATURE_GPT_LABEL
+	struct gpt_header *gpt_hdr;
+	char *gpt_part_array;
+	unsigned gpt_n_parts;
+	unsigned gpt_part_entry_len;
+#endif
+
 	jmp_buf listingbuf;
 	char line_buffer[80];
 	/* Raw disk label. For DOS-type partition tables the MBR,
@@ -1391,7 +1416,7 @@ get_geometry(void)
 	get_sectorsize();
 	sec_fac = sector_size / 512;
 #if ENABLE_FEATURE_SUN_LABEL
-	guess_device_type();
+	sun_guess_device_type();
 #endif
 	g_heads = g_cylinders = g_sectors = 0;
 	kern_heads = kern_sectors = 0;
diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c
index 4c30f31f8..60c7c1570 100644
--- a/util-linux/fdisk_gpt.c
+++ b/util-linux/fdisk_gpt.c
@@ -13,7 +13,7 @@ enum {
 	GUID_LEN        = 16,
 };
 
-typedef struct {
+typedef struct gpt_header {
 	uint64_t magic;
 	uint32_t revision;
 	uint32_t hdr_size;
@@ -30,7 +30,7 @@ typedef struct {
 	uint32_t part_array_crc32;
 } gpt_header;
 
-typedef struct {
+typedef struct gpt_partition {
 	uint8_t  type_guid[GUID_LEN];
 	uint8_t  part_guid[GUID_LEN];
 	uint64_t lba_start;
@@ -39,19 +39,13 @@ typedef struct {
 	uint16_t name36[36];
 } gpt_partition;
 
-static gpt_header *gpt_hdr;
-
-static char *part_array;
-static unsigned int n_parts;
-static unsigned int part_entry_len;
-
-static inline gpt_partition *
+static gpt_partition *
 gpt_part(int i)
 {
-	if (i >= n_parts) {
+	if (i >= G.gpt_n_parts) {
 		return NULL;
 	}
-	return (gpt_partition *)&part_array[i * part_entry_len];
+	return (gpt_partition *)&G.gpt_part_array[i * G.gpt_part_entry_len];
 }
 
 static uint32_t
@@ -107,19 +101,27 @@ gpt_list_table(int xtra UNUSED_PARAM)
 {
 	int i;
 	char numstr6[6];
+	unsigned long long total_bytes;
+
+	total_bytes = (unsigned long long)total_number_of_sectors * sector_size;
+	smart_ulltoa5(total_bytes, numstr6, " KMGTPEZY")[0] = '\0';
 
-	smart_ulltoa5(total_number_of_sectors * sector_size, numstr6, " KMGTPEZY")[0] = '\0';
-	printf("Disk %s: %llu sectors, %s\n", disk_device,
-		(unsigned long long)total_number_of_sectors,
-		numstr6);
+	printf("Disk %s: %s, %llu bytes, %"SECT_FMT"u sectors\n", disk_device,
+		skip_whitespace(numstr6),
+		total_bytes,
+		(SECT_TYPE)total_number_of_sectors
+	);
 	printf("Logical sector size: %u\n", sector_size);
 	printf("Disk identifier (GUID): ");
-	gpt_print_guid(gpt_hdr->disk_guid);
+//util-linux 2.41.1 does not print " (GUID)" in above line,
+//we do: keep users less confused what kind of identifier is meant.
+	gpt_print_guid(G.gpt_hdr->disk_guid);
 	printf("\nPartition table holds up to %u entries\n",
-		(int)SWAP_LE32(gpt_hdr->n_parts));
+		(int)SWAP_LE32(G.gpt_hdr->n_parts));
 	printf("First usable sector is %llu, last usable sector is %llu\n\n",
-		(unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
-		(unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
+		(unsigned long long)SWAP_LE64(G.gpt_hdr->first_usable_lba),
+		(unsigned long long)SWAP_LE64(G.gpt_hdr->last_usable_lba)
+	);
 
 /* "GPT fdisk" has a concept of 16-bit extension of the original MBR 8-bit type codes,
  * which it displays here: its output columns are ... Size Code Name
@@ -131,7 +133,7 @@ gpt_list_table(int xtra UNUSED_PARAM)
  */
 	puts("Number  Start (sector)    End (sector)  Size Name");
 	//    123456 123456789012345 123456789012345 12345 abc
-	for (i = 0; i < n_parts; i++) {
+	for (i = 0; i < G.gpt_n_parts; i++) {
 		gpt_partition *p = gpt_part(i);
 		if (p->lba_start) {
 			smart_ulltoa5((1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start)) * sector_size,
@@ -168,9 +170,9 @@ check_gpt_label(void)
 	/* LBA 1 contains the GPT header */
 
 	read_pte(&pe, 1);
-	gpt_hdr = (void *)pe.sectorbuffer;
+	G.gpt_hdr = (void *)pe.sectorbuffer;
 
-	if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
+	if (G.gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
 		current_label_type = LABEL_DOS;
 		return 0;
 	}
@@ -180,32 +182,32 @@ check_gpt_label(void)
 		global_crc32_new_table_le();
 	}
 
-	crc = SWAP_LE32(gpt_hdr->hdr_crc32);
-	gpt_hdr->hdr_crc32 = 0;
-	if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) {
+	crc = SWAP_LE32(G.gpt_hdr->hdr_crc32);
+	G.gpt_hdr->hdr_crc32 = 0;
+	if (gpt_crc32(G.gpt_hdr, SWAP_LE32(G.gpt_hdr->hdr_size)) != crc) {
 		/* FIXME: read the backup table */
 		puts("\nwarning: GPT header CRC is invalid\n");
 	}
 
-	n_parts = SWAP_LE32(gpt_hdr->n_parts);
-	part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len);
-	if (n_parts > GPT_MAX_PARTS
-	 || part_entry_len > GPT_MAX_PART_ENTRY_LEN
-	 || SWAP_LE32(gpt_hdr->hdr_size) > sector_size
+	G.gpt_n_parts = SWAP_LE32(G.gpt_hdr->n_parts);
+	G.gpt_part_entry_len = SWAP_LE32(G.gpt_hdr->part_entry_len);
+	if (G.gpt_n_parts > GPT_MAX_PARTS
+	 || G.gpt_part_entry_len > GPT_MAX_PART_ENTRY_LEN
+	 || SWAP_LE32(G.gpt_hdr->hdr_size) > sector_size
 	) {
-		puts("\nwarning: unable to parse GPT disklabel\n");
+		puts("\nwarning: can't parse GPT disklabel\n");
 		current_label_type = LABEL_DOS;
 		return 0;
 	}
 
-	part_array_len = n_parts * part_entry_len;
-	part_array = xmalloc(part_array_len);
-	seek_sector(SWAP_LE64(gpt_hdr->first_part_lba));
-	if (full_read(dev_fd, part_array, part_array_len) != part_array_len) {
+	part_array_len = G.gpt_n_parts * G.gpt_part_entry_len;
+	G.gpt_part_array = xmalloc(part_array_len);
+	seek_sector(SWAP_LE64(G.gpt_hdr->first_part_lba));
+	if (full_read(dev_fd, G.gpt_part_array, part_array_len) != part_array_len) {
 		fdisk_fatal(unable_to_read);
 	}
 
-	if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) {
+	if (gpt_crc32(G.gpt_part_array, part_array_len) != G.gpt_hdr->part_array_crc32) {
 		/* FIXME: read the backup table */
 		puts("\nwarning: GPT array CRC is invalid\n");
 	}
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 049f0b169..5d6b4cbcf 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -260,8 +260,6 @@ static void alpha_bootblock_checksum(char *boot);
 #if !defined(__alpha__)
 static int xbsd_translate_fstype(int linux_type);
 static void xbsd_link_part(void);
-static struct partition *xbsd_part;
-static int xbsd_part_index;
 #endif
 
 
@@ -356,9 +354,9 @@ bsd_select(void)
 	for (t = 0; t < 4; t++) {
 		p = get_part_table(t);
 		if (p && is_bsd_partition_type(p->sys_ind)) {
-			xbsd_part = p;
-			xbsd_part_index = t;
-			ss = get_start_sect(xbsd_part);
+			G.xbsd_part = p;
+			G.xbsd_part_index = t;
+			ss = get_start_sect(G.xbsd_part);
 			if (ss == 0) {
 				printf("Partition %s has invalid starting sector 0\n",
 					partname(disk_device, t+1, 0));
@@ -366,7 +364,7 @@ bsd_select(void)
 			}
 				printf("Reading disklabel of %s at sector %u\n",
 					partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR);
-			if (xbsd_readlabel(xbsd_part) == 0) {
+			if (xbsd_readlabel(G.xbsd_part) == 0) {
 				if (xbsd_create_disklabel() == 0)
 					return;
 				break;
@@ -463,8 +461,8 @@ xbsd_new_part(void)
 		return;
 
 #if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__)
-	begin = get_start_sect(xbsd_part);
-	end = begin + get_nr_sects(xbsd_part) - 1;
+	begin = get_start_sect(G.xbsd_part);
+	end = begin + get_nr_sects(G.xbsd_part) - 1;
 #else
 	begin = 0;
 	end = xbsd_dlabel.d_secperunit - 1;
@@ -503,7 +501,7 @@ xbsd_print_disklabel(int show_all)
 #if defined(__alpha__)
 		printf("# %s:\n", disk_device);
 #else
-		printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0));
+		printf("# %s:\n", partname(disk_device, G.xbsd_part_index + 1, 0));
 #endif
 		if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1)
 			printf("type: %s\n", xbsd_dktypenames[lp->d_type]);
@@ -593,8 +591,8 @@ xbsd_write_disklabel(void)
 	xbsd_writelabel(NULL);
 #else
 	printf("Writing disklabel to %s\n",
-		partname(disk_device, xbsd_part_index + 1, 0));
-	xbsd_writelabel(xbsd_part);
+		partname(disk_device, G.xbsd_part_index + 1, 0));
+	xbsd_writelabel(G.xbsd_part);
 #endif
 	reread_partition_table(0);      /* no exit yet */
 }
@@ -608,7 +606,7 @@ xbsd_create_disklabel(void)
 	printf("%s contains no disklabel\n", disk_device);
 #else
 	printf("%s contains no disklabel\n",
-		partname(disk_device, xbsd_part_index + 1, 0));
+		partname(disk_device, G.xbsd_part_index + 1, 0));
 #endif
 
 	while (1) {
@@ -619,7 +617,7 @@ xbsd_create_disklabel(void)
 	defined(__s390__) || defined(__s390x__)
 				NULL
 #else
-				xbsd_part
+				G.xbsd_part
 #endif
 			) == 1) {
 				xbsd_print_disklabel(1);
@@ -761,7 +759,7 @@ xbsd_write_bootstrap(void)
 	sector = 0;
 	alpha_bootblock_checksum(disklabelbuffer);
 #else
-	sector = get_start_sect(xbsd_part);
+	sector = get_start_sect(G.xbsd_part);
 #endif
 
 	seek_sector(sector);
@@ -771,7 +769,7 @@ xbsd_write_bootstrap(void)
 	printf("Bootstrap installed on %s\n", disk_device);
 #else
 	printf("Bootstrap installed on %s\n",
-		partname(disk_device, xbsd_part_index+1, 0));
+		partname(disk_device, G.xbsd_part_index + 1, 0));
 #endif
 
 	sync_disks();
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
index 5b7760e8c..955ae1e5e 100644
--- a/util-linux/fdisk_sun.c
+++ b/util-linux/fdisk_sun.c
@@ -19,18 +19,14 @@
 
 #define SUN_LABEL_MAGIC          0xDABE
 #define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
-#define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
-#define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))
+#define SUN_SSWAP16(x) (G.sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))
+#define SUN_SSWAP32(x) (G.sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))
 
 /* Copied from linux/major.h */
 #define FLOPPY_MAJOR    2
 
 #define SCSI_IOCTL_GET_IDLUN 0x5382
 
-static smallint sun_other_endian;
-static smallint scsi_disk;
-static smallint floppy;
-
 #ifndef IDE0_MAJOR
 #define IDE0_MAJOR 3
 #endif
@@ -39,25 +35,28 @@ static smallint floppy;
 #endif
 
 static void
-guess_device_type(void)
+sun_guess_device_type(void)
 {
 	struct stat bootstat;
 
-	if (fstat(dev_fd, &bootstat) < 0) {
-		scsi_disk = 0;
-		floppy = 0;
-	} else if (S_ISBLK(bootstat.st_mode)
-		&& (major(bootstat.st_rdev) == IDE0_MAJOR ||
-		    major(bootstat.st_rdev) == IDE1_MAJOR)) {
-		scsi_disk = 0;
-		floppy = 0;
-	} else if (S_ISBLK(bootstat.st_mode)
-		&& major(bootstat.st_rdev) == FLOPPY_MAJOR) {
-		scsi_disk = 0;
-		floppy = 1;
+	G.sun_scsi_disk = 0;
+	G.sun_floppy = 0;
+	if (fstat(dev_fd, &bootstat) < 0)
+		return;
+	if (S_ISBLK(bootstat.st_mode)) {
+		//if (major(bootstat.st_rdev) == IDE0_MAJOR
+		// || major(bootstat.st_rdev) == IDE1_MAJOR
+		//) {
+		//	G.sun_scsi_disk = 0;
+		//	G.sun_floppy = 0;
+		//}
+		if (major(bootstat.st_rdev) == FLOPPY_MAJOR) {
+			//G.sun_scsi_disk = 0;
+			G.sun_floppy = 1;
+		}
 	} else {
-		scsi_disk = 1;
-		floppy = 0;
+		G.sun_scsi_disk = 1;
+		//G.sun_floppy = 0;
 	}
 }
 
@@ -101,10 +100,10 @@ check_sun_label(void)
 	 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED
 	) {
 		current_label_type = LABEL_DOS;
-		sun_other_endian = 0;
+		G.sun_other_endian = 0;
 		return 0;
 	}
-	sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
+	G.sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
 	ush = ((unsigned short *) (sunlabel + 1)) - 1;
 	for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
 	if (csum) {
@@ -238,10 +237,10 @@ create_sunlabel(void)
 
 	printf(msg_building_new_label, "sun disklabel");
 
-	sun_other_endian = BB_LITTLE_ENDIAN;
+	G.sun_other_endian = BB_LITTLE_ENDIAN;
 	memset(MBRbuffer, 0, sizeof(MBRbuffer));
 	sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
-	if (!floppy) {
+	if (!G.sun_floppy) {
 		unsigned i;
 		puts("Drive type\n"
 		 "   ?   auto configure\n"
@@ -265,7 +264,7 @@ create_sunlabel(void)
 				p = sun_drives + c - 'A';
 				break;
 			}
-			if (c == '?' && scsi_disk) {
+			if (c == '?' && G.sun_scsi_disk) {
 				p = sun_autoconfigure_scsi();
 				if (p)
 					break;
@@ -273,7 +272,7 @@ create_sunlabel(void)
 			}
 		}
 	}
-	if (!p || floppy) {
+	if (!p || G.sun_floppy) {
 		if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) {
 			g_heads = geometry.heads;
 			g_sectors = geometry.sectors;
@@ -283,7 +282,7 @@ create_sunlabel(void)
 			g_sectors = 0;
 			g_cylinders = 0;
 		}
-		if (floppy) {
+		if (G.sun_floppy) {
 			sunlabel->nacyl = 0;
 			sunlabel->pcylcount = SUN_SSWAP16(g_cylinders);
 			sunlabel->rspeed = SUN_SSWAP16(300);
@@ -320,13 +319,13 @@ create_sunlabel(void)
 	snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
 		"%s%s%s cyl %u alt %u hd %u sec %u",
 		p ? p->vendor : "", (p && *p->vendor) ? " " : "",
-		p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"),
+		p ? p->model : (G.sun_floppy ? "3,5\" floppy" : "Linux custom"),
 		g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors);
 
 	sunlabel->ntrks = SUN_SSWAP16(g_heads);
 	sunlabel->nsect = SUN_SSWAP16(g_sectors);
 	sunlabel->ncyl = SUN_SSWAP16(g_cylinders);
-	if (floppy)
+	if (G.sun_floppy)
 		set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE);
 	else {
 		if (g_cylinders * g_heads * g_sectors >= 150 * 2048) {
@@ -392,14 +391,15 @@ fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop)
 	}
 }
 
-static unsigned *verify_sun_starts;
-
 static int
-verify_sun_cmp(int *a, int *b)
+verify_sun_cmp(const void *aa, const void *bb)
 {
+	const int *a = aa;
+	const int *b = bb;
 	if (*a == -1) return 1;
 	if (*b == -1) return -1;
-	if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
+	if (G.verify_sun_starts[*a] > G.verify_sun_starts[*b])
+		return 1;
 	return -1;
 }
 
@@ -410,7 +410,6 @@ verify_sun(void)
 	int i,j,k,starto,endo;
 	int array[8];
 
-	verify_sun_starts = starts;
 	fetch_sun(starts, lens, &start, &stop);
 	for (k = 0; k < 7; k++) {
 		for (i = 0; i < 8; i++) {
@@ -449,8 +448,11 @@ verify_sun(void)
 		else
 			array[i] = -1;
 	}
-	qsort(array, ARRAY_SIZE(array), sizeof(array[0]),
-		(int (*)(const void *,const void *)) verify_sun_cmp);
+//TODO: probably can eliminate the need in G.verify_sun_starts
+//if merge starts[] and lens[] in a single array?
+	G.verify_sun_starts = starts;
+	qsort(array, ARRAY_SIZE(array), sizeof(array[0]), verify_sun_cmp);
+
 	if (array[0] == -1) {
 		printf("No partitions defined\n");
 		return;


More information about the busybox-cvs mailing list