aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-19 14:45:10 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-19 14:45:10 +0000
commitdfce08f281c9fbe2595413bbc36f905222a6f9b6 (patch)
treeec2130bf9d4a9bf8ef9c7dd627519c7f08947b01
parentbd852076b9f6600d039e75d646a6965b5b092606 (diff)
downloadbusybox-w32-dfce08f281c9fbe2595413bbc36f905222a6f9b6.tar.gz
busybox-w32-dfce08f281c9fbe2595413bbc36f905222a6f9b6.tar.bz2
busybox-w32-dfce08f281c9fbe2595413bbc36f905222a6f9b6.zip
fdisk: bb_common_bufsiz1 is too small for globals on 64-bit CPU
-rw-r--r--util-linux/fdisk.c352
1 files changed, 177 insertions, 175 deletions
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 493c6740b..9d7bd4e2c 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -16,6 +16,8 @@
16# define USE_FEATURE_FDISK_BLKSIZE(a) 16# define USE_FEATURE_FDISK_BLKSIZE(a)
17#endif 17#endif
18 18
19#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
20
19#define DEFAULT_SECTOR_SIZE 512 21#define DEFAULT_SECTOR_SIZE 512
20#define MAX_SECTOR_SIZE 2048 22#define MAX_SECTOR_SIZE 2048
21#define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 23#define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */
@@ -32,14 +34,6 @@
32#define LINUX_LVM 0x8e 34#define LINUX_LVM 0x8e
33#define LINUX_RAID 0xfd 35#define LINUX_RAID 0xfd
34 36
35#define IS_EXTENDED(i) \
36 ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
37
38#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
39
40#define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
41#define scround(x) (((x)+units_per_sector-1)/units_per_sector)
42
43struct hd_geometry { 37struct hd_geometry {
44 unsigned char heads; 38 unsigned char heads;
45 unsigned char sectors; 39 unsigned char sectors;
@@ -91,6 +85,7 @@ enum failure {
91enum label_type { 85enum label_type {
92 label_dos, label_sun, label_sgi, label_aix, label_osf 86 label_dos, label_sun, label_sgi, label_aix, label_osf
93}; 87};
88
94#define LABEL_IS_DOS (label_dos == current_label_type) 89#define LABEL_IS_DOS (label_dos == current_label_type)
95 90
96#if ENABLE_FEATURE_SUN_LABEL 91#if ENABLE_FEATURE_SUN_LABEL
@@ -150,30 +145,6 @@ static int get_boot(enum action what);
150#define PLURAL 0 145#define PLURAL 0
151#define SINGULAR 1 146#define SINGULAR 1
152 147
153#define hex_val(c) ({ \
154 char _c = (c); \
155 isdigit(_c) ? _c - '0' : \
156 tolower(_c) + 10 - 'a'; \
157 })
158
159#define LINE_LENGTH 80
160#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
161 (n) * sizeof(struct partition)))
162#define sector(s) ((s) & 0x3f)
163#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))
164
165#define hsc2sector(h,s,c) (sector(s) - 1 + sectors * \
166 ((h) + heads * cylinder(s,c)))
167#define set_hsc(h,s,c,sector) \
168 do { \
169 s = sector % sectors + 1; \
170 sector /= sectors; \
171 h = sector % heads; \
172 sector /= heads; \
173 c = sector & 0xff; \
174 s |= (sector >> 2) & 0xc0; \
175 } while (0)
176
177static unsigned get_start_sect(const struct partition *p); 148static unsigned get_start_sect(const struct partition *p);
178static unsigned get_nr_sects(const struct partition *p); 149static unsigned get_nr_sects(const struct partition *p);
179 150
@@ -188,25 +159,190 @@ static unsigned get_nr_sects(const struct partition *p);
188struct pte { 159struct pte {
189 struct partition *part_table; /* points into sectorbuffer */ 160 struct partition *part_table; /* points into sectorbuffer */
190 struct partition *ext_pointer; /* points into sectorbuffer */ 161 struct partition *ext_pointer; /* points into sectorbuffer */
162 off_t offset; /* disk sector number */
163 char *sectorbuffer; /* disk sector contents */
191#if ENABLE_FEATURE_FDISK_WRITABLE 164#if ENABLE_FEATURE_FDISK_WRITABLE
192 char changed; /* boolean */ 165 char changed; /* boolean */
193#endif 166#endif
194 off_t offset; /* disk sector number */
195 char *sectorbuffer; /* disk sector contents */
196}; 167};
197 168
169/* DOS partition types */
170
171static const char *const i386_sys_types[] = {
172 "\x00" "Empty",
173 "\x01" "FAT12",
174 "\x04" "FAT16 <32M",
175 "\x05" "Extended", /* DOS 3.3+ extended partition */
176 "\x06" "FAT16", /* DOS 16-bit >=32M */
177 "\x07" "HPFS/NTFS", /* OS/2 IFS, eg, HPFS or NTFS or QNX */
178 "\x0a" "OS/2 Boot Manager",/* OS/2 Boot Manager */
179 "\x0b" "Win95 FAT32",
180 "\x0c" "Win95 FAT32 (LBA)",/* LBA really is 'Extended Int 13h' */
181 "\x0e" "Win95 FAT16 (LBA)",
182 "\x0f" "Win95 Ext'd (LBA)",
183 "\x11" "Hidden FAT12",
184 "\x12" "Compaq diagnostics",
185 "\x14" "Hidden FAT16 <32M",
186 "\x16" "Hidden FAT16",
187 "\x17" "Hidden HPFS/NTFS",
188 "\x1b" "Hidden Win95 FAT32",
189 "\x1c" "Hidden W95 FAT32 (LBA)",
190 "\x1e" "Hidden W95 FAT16 (LBA)",
191 "\x3c" "Part.Magic recovery",
192 "\x41" "PPC PReP Boot",
193 "\x42" "SFS",
194 "\x63" "GNU HURD or SysV", /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
195 "\x80" "Old Minix", /* Minix 1.4a and earlier */
196 "\x81" "Minix / old Linux",/* Minix 1.4b and later */
197 "\x82" "Linux swap", /* also Solaris */
198 "\x83" "Linux",
199 "\x84" "OS/2 hidden C: drive",
200 "\x85" "Linux extended",
201 "\x86" "NTFS volume set",
202 "\x87" "NTFS volume set",
203 "\x8e" "Linux LVM",
204 "\x9f" "BSD/OS", /* BSDI */
205 "\xa0" "Thinkpad hibernation",
206 "\xa5" "FreeBSD", /* various BSD flavours */
207 "\xa6" "OpenBSD",
208 "\xa8" "Darwin UFS",
209 "\xa9" "NetBSD",
210 "\xab" "Darwin boot",
211 "\xb7" "BSDI fs",
212 "\xb8" "BSDI swap",
213 "\xbe" "Solaris boot",
214 "\xeb" "BeOS fs",
215 "\xee" "EFI GPT", /* Intel EFI GUID Partition Table */
216 "\xef" "EFI (FAT-12/16/32)", /* Intel EFI System Partition */
217 "\xf0" "Linux/PA-RISC boot", /* Linux/PA-RISC boot loader */
218 "\xf2" "DOS secondary", /* DOS 3.3+ secondary */
219 "\xfd" "Linux raid autodetect", /* New (2.2.x) raid partition with
220 autodetect using persistent
221 superblock */
222#if 0 /* ENABLE_WEIRD_PARTITION_TYPES */
223 "\x02" "XENIX root",
224 "\x03" "XENIX usr",
225 "\x08" "AIX", /* AIX boot (AIX -- PS/2 port) or SplitDrive */
226 "\x09" "AIX bootable", /* AIX data or Coherent */
227 "\x10" "OPUS",
228 "\x18" "AST SmartSleep",
229 "\x24" "NEC DOS",
230 "\x39" "Plan 9",
231 "\x40" "Venix 80286",
232 "\x4d" "QNX4.x",
233 "\x4e" "QNX4.x 2nd part",
234 "\x4f" "QNX4.x 3rd part",
235 "\x50" "OnTrack DM",
236 "\x51" "OnTrack DM6 Aux1", /* (or Novell) */
237 "\x52" "CP/M", /* CP/M or Microport SysV/AT */
238 "\x53" "OnTrack DM6 Aux3",
239 "\x54" "OnTrackDM6",
240 "\x55" "EZ-Drive",
241 "\x56" "Golden Bow",
242 "\x5c" "Priam Edisk",
243 "\x61" "SpeedStor",
244 "\x64" "Novell Netware 286",
245 "\x65" "Novell Netware 386",
246 "\x70" "DiskSecure Multi-Boot",
247 "\x75" "PC/IX",
248 "\x93" "Amoeba",
249 "\x94" "Amoeba BBT", /* (bad block table) */
250 "\xa7" "NeXTSTEP",
251 "\xbb" "Boot Wizard hidden",
252 "\xc1" "DRDOS/sec (FAT-12)",
253 "\xc4" "DRDOS/sec (FAT-16 < 32M)",
254 "\xc6" "DRDOS/sec (FAT-16)",
255 "\xc7" "Syrinx",
256 "\xda" "Non-FS data",
257 "\xdb" "CP/M / CTOS / ...",/* CP/M or Concurrent CP/M or
258 Concurrent DOS or CTOS */
259 "\xde" "Dell Utility", /* Dell PowerEdge Server utilities */
260 "\xdf" "BootIt", /* BootIt EMBRM */
261 "\xe1" "DOS access", /* DOS access or SpeedStor 12-bit FAT
262 extended partition */
263 "\xe3" "DOS R/O", /* DOS R/O or SpeedStor */
264 "\xe4" "SpeedStor", /* SpeedStor 16-bit FAT extended
265 partition < 1024 cyl. */
266 "\xf1" "SpeedStor",
267 "\xf4" "SpeedStor", /* SpeedStor large partition */
268 "\xfe" "LANstep", /* SpeedStor >1024 cyl. or LANstep */
269 "\xff" "BBT", /* Xenix Bad Block Table */
270#endif
271 NULL
272};
273
274
275/* Globals */
276
198struct globals { 277struct globals {
278 char *line_ptr;
279 char line_buffer[80];
280 char partname_buffer[80];
281 jmp_buf listingbuf;
199 /* Raw disk label. For DOS-type partition tables the MBR, 282 /* Raw disk label. For DOS-type partition tables the MBR,
200 * with descriptions of the primary partitions. */ 283 * with descriptions of the primary partitions. */
201 char MBRbuffer[MAX_SECTOR_SIZE]; 284 char MBRbuffer[MAX_SECTOR_SIZE];
202 /* Partition tables */ 285 /* Partition tables */
203 struct pte ptes[MAXIMUM_PARTS]; 286 struct pte ptes[MAXIMUM_PARTS];
204}; 287};
288/* bb_common_bufsiz1 is too small for this on 64 bit CPUs */
289#define G (*ptr_to_globals)
290
291#define line_ptr (G.line_ptr)
292#define listingbuf (G.listingbuf)
293#define line_buffer (G.line_buffer)
294#define partname_buffer (G.partname_buffer)
295#define MBRbuffer (G.MBRbuffer)
296#define ptes (G.ptes)
297
298
299/* Code */
300
301#define IS_EXTENDED(i) \
302 ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
205 303
206#define G (*(struct globals*)bb_common_bufsiz1) 304#define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
207#define MBRbuffer (G.MBRbuffer) 305
208#define ptes (G.ptes) 306#define scround(x) (((x)+units_per_sector-1)/units_per_sector)
209 307
308#define pt_offset(b, n) \
309 ((struct partition *)((b) + 0x1be + (n) * sizeof(struct partition)))
310
311#define sector(s) ((s) & 0x3f)
312
313#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))
314
315#define hsc2sector(h,s,c) \
316 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c)))
317
318#define set_hsc(h,s,c,sector) \
319 do { \
320 s = sector % sectors + 1; \
321 sector /= sectors; \
322 h = sector % heads; \
323 sector /= heads; \
324 c = sector & 0xff; \
325 s |= (sector >> 2) & 0xc0; \
326 } while (0)
327
328/* read line; return 0 or first printable char */
329static int
330read_line(const char *prompt)
331{
332 int sz;
333
334 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
335 if (sz <= 0)
336 exit(0); /* Ctrl-D or Ctrl-C */
337
338 if (line_buffer[sz-1] == '\n')
339 line_buffer[--sz] = '\0';
340
341 line_ptr = line_buffer;
342 while (*line_ptr && !isgraph(*line_ptr))
343 line_ptr++;
344 return *line_ptr;
345}
210 346
211/* 347/*
212 * return partition name - uses static storage 348 * return partition name - uses static storage
@@ -214,14 +350,13 @@ struct globals {
214static const char * 350static const char *
215partname(const char *dev, int pno, int lth) 351partname(const char *dev, int pno, int lth)
216{ 352{
217 static char buffer[80];
218 const char *p; 353 const char *p;
219 int w, wp; 354 int w, wp;
220 int bufsiz; 355 int bufsiz;
221 char *bufp; 356 char *bufp;
222 357
223 bufp = buffer; 358 bufp = partname_buffer;
224 bufsiz = sizeof(buffer); 359 bufsiz = sizeof(partname_buffer);
225 360
226 w = strlen(dev); 361 w = strlen(dev);
227 p = ""; 362 p = "";
@@ -292,28 +427,6 @@ write_part_table_flag(char *b)
292 b[511] = 0xaa; 427 b[511] = 0xaa;
293} 428}
294 429
295static char line_buffer[LINE_LENGTH];
296static char *line_ptr;
297
298/* read line; return 0 or first printable char */
299static int
300read_line(const char *prompt)
301{
302 int sz;
303
304 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
305 if (sz <= 0)
306 exit(0); /* Ctrl-D or Ctrl-C */
307
308 if (line_buffer[sz-1] == '\n')
309 line_buffer[--sz] = '\0';
310
311 line_ptr = line_buffer;
312 while (*line_ptr && !isgraph(*line_ptr))
313 line_ptr++;
314 return *line_ptr;
315}
316
317static char 430static char
318read_nonempty(const char *mesg) 431read_nonempty(const char *mesg)
319{ 432{
@@ -439,112 +552,6 @@ STATIC_SUN void verify_sun(void);
439STATIC_SUN void sun_write_table(void); 552STATIC_SUN void sun_write_table(void);
440#include "fdisk_sun.c" 553#include "fdisk_sun.c"
441 554
442/* DOS partition types */
443
444static const char *const i386_sys_types[] = {
445 "\x00" "Empty",
446 "\x01" "FAT12",
447 "\x04" "FAT16 <32M",
448 "\x05" "Extended", /* DOS 3.3+ extended partition */
449 "\x06" "FAT16", /* DOS 16-bit >=32M */
450 "\x07" "HPFS/NTFS", /* OS/2 IFS, eg, HPFS or NTFS or QNX */
451 "\x0a" "OS/2 Boot Manager",/* OS/2 Boot Manager */
452 "\x0b" "Win95 FAT32",
453 "\x0c" "Win95 FAT32 (LBA)",/* LBA really is 'Extended Int 13h' */
454 "\x0e" "Win95 FAT16 (LBA)",
455 "\x0f" "Win95 Ext'd (LBA)",
456 "\x11" "Hidden FAT12",
457 "\x12" "Compaq diagnostics",
458 "\x14" "Hidden FAT16 <32M",
459 "\x16" "Hidden FAT16",
460 "\x17" "Hidden HPFS/NTFS",
461 "\x1b" "Hidden Win95 FAT32",
462 "\x1c" "Hidden W95 FAT32 (LBA)",
463 "\x1e" "Hidden W95 FAT16 (LBA)",
464 "\x3c" "Part.Magic recovery",
465 "\x41" "PPC PReP Boot",
466 "\x42" "SFS",
467 "\x63" "GNU HURD or SysV", /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
468 "\x80" "Old Minix", /* Minix 1.4a and earlier */
469 "\x81" "Minix / old Linux",/* Minix 1.4b and later */
470 "\x82" "Linux swap", /* also Solaris */
471 "\x83" "Linux",
472 "\x84" "OS/2 hidden C: drive",
473 "\x85" "Linux extended",
474 "\x86" "NTFS volume set",
475 "\x87" "NTFS volume set",
476 "\x8e" "Linux LVM",
477 "\x9f" "BSD/OS", /* BSDI */
478 "\xa0" "Thinkpad hibernation",
479 "\xa5" "FreeBSD", /* various BSD flavours */
480 "\xa6" "OpenBSD",
481 "\xa8" "Darwin UFS",
482 "\xa9" "NetBSD",
483 "\xab" "Darwin boot",
484 "\xb7" "BSDI fs",
485 "\xb8" "BSDI swap",
486 "\xbe" "Solaris boot",
487 "\xeb" "BeOS fs",
488 "\xee" "EFI GPT", /* Intel EFI GUID Partition Table */
489 "\xef" "EFI (FAT-12/16/32)", /* Intel EFI System Partition */
490 "\xf0" "Linux/PA-RISC boot", /* Linux/PA-RISC boot loader */
491 "\xf2" "DOS secondary", /* DOS 3.3+ secondary */
492 "\xfd" "Linux raid autodetect", /* New (2.2.x) raid partition with
493 autodetect using persistent
494 superblock */
495#if 0 /* ENABLE_WEIRD_PARTITION_TYPES */
496 "\x02" "XENIX root",
497 "\x03" "XENIX usr",
498 "\x08" "AIX", /* AIX boot (AIX -- PS/2 port) or SplitDrive */
499 "\x09" "AIX bootable", /* AIX data or Coherent */
500 "\x10" "OPUS",
501 "\x18" "AST SmartSleep",
502 "\x24" "NEC DOS",
503 "\x39" "Plan 9",
504 "\x40" "Venix 80286",
505 "\x4d" "QNX4.x",
506 "\x4e" "QNX4.x 2nd part",
507 "\x4f" "QNX4.x 3rd part",
508 "\x50" "OnTrack DM",
509 "\x51" "OnTrack DM6 Aux1", /* (or Novell) */
510 "\x52" "CP/M", /* CP/M or Microport SysV/AT */
511 "\x53" "OnTrack DM6 Aux3",
512 "\x54" "OnTrackDM6",
513 "\x55" "EZ-Drive",
514 "\x56" "Golden Bow",
515 "\x5c" "Priam Edisk",
516 "\x61" "SpeedStor",
517 "\x64" "Novell Netware 286",
518 "\x65" "Novell Netware 386",
519 "\x70" "DiskSecure Multi-Boot",
520 "\x75" "PC/IX",
521 "\x93" "Amoeba",
522 "\x94" "Amoeba BBT", /* (bad block table) */
523 "\xa7" "NeXTSTEP",
524 "\xbb" "Boot Wizard hidden",
525 "\xc1" "DRDOS/sec (FAT-12)",
526 "\xc4" "DRDOS/sec (FAT-16 < 32M)",
527 "\xc6" "DRDOS/sec (FAT-16)",
528 "\xc7" "Syrinx",
529 "\xda" "Non-FS data",
530 "\xdb" "CP/M / CTOS / ...",/* CP/M or Concurrent CP/M or
531 Concurrent DOS or CTOS */
532 "\xde" "Dell Utility", /* Dell PowerEdge Server utilities */
533 "\xdf" "BootIt", /* BootIt EMBRM */
534 "\xe1" "DOS access", /* DOS access or SpeedStor 12-bit FAT
535 extended partition */
536 "\xe3" "DOS R/O", /* DOS R/O or SpeedStor */
537 "\xe4" "SpeedStor", /* SpeedStor 16-bit FAT extended
538 partition < 1024 cyl. */
539 "\xf1" "SpeedStor",
540 "\xf4" "SpeedStor", /* SpeedStor large partition */
541 "\xfe" "LANstep", /* SpeedStor >1024 cyl. or LANstep */
542 "\xff" "BBT", /* Xenix Bad Block Table */
543#endif
544 NULL
545};
546
547
548#if ENABLE_FEATURE_FDISK_WRITABLE 555#if ENABLE_FEATURE_FDISK_WRITABLE
549/* start_sect and nr_sects are stored little endian on all machines */ 556/* start_sect and nr_sects are stored little endian on all machines */
550/* moreover, they are not aligned correctly */ 557/* moreover, they are not aligned correctly */
@@ -615,8 +622,6 @@ static off_t extended_offset; /* offset of link pointers */
615static unsigned long long total_number_of_sectors; 622static unsigned long long total_number_of_sectors;
616 623
617 624
618static jmp_buf listingbuf;
619
620static void fdisk_fatal(enum failure why) 625static void fdisk_fatal(enum failure why)
621{ 626{
622 const char *message; 627 const char *message;
@@ -2379,7 +2384,7 @@ new_partition(void)
2379 printf("You must delete some partition and add " 2384 printf("You must delete some partition and add "
2380 "an extended partition first\n"); 2385 "an extended partition first\n");
2381 } else { 2386 } else {
2382 char c, line[LINE_LENGTH]; 2387 char c, line[80];
2383 snprintf(line, sizeof(line), 2388 snprintf(line, sizeof(line),
2384 "Command action\n" 2389 "Command action\n"
2385 " %s\n" 2390 " %s\n"
@@ -2761,8 +2766,6 @@ unknown_command(int c)
2761} 2766}
2762#endif 2767#endif
2763 2768
2764void BUG_fdisk_globals_overflow(void);
2765
2766int fdisk_main(int argc, char **argv); 2769int fdisk_main(int argc, char **argv);
2767int fdisk_main(int argc, char **argv) 2770int fdisk_main(int argc, char **argv)
2768{ 2771{
@@ -2786,8 +2789,7 @@ int fdisk_main(int argc, char **argv)
2786 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 2789 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE,
2787 }; 2790 };
2788 2791
2789 if (sizeof(G) > sizeof(bb_common_bufsiz1)) 2792 PTR_TO_GLOBALS = xzalloc(sizeof(G));
2790 BUG_fdisk_globals_overflow();
2791 2793
2792 opt = getopt32(argc, argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), 2794 opt = getopt32(argc, argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"),
2793 &str_b, &str_C, &str_H, &str_S); 2795 &str_b, &str_C, &str_H, &str_S);