bin/103911: [patch] gpt cannot add partitions >2TB on IA32

Mike Hibler mike at cs.utah.edu
Mon Oct 2 09:40:25 PDT 2006


>Number:         103911
>Category:       bin
>Synopsis:       [patch] gpt cannot add partitions >2TB on IA32
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Oct 02 16:40:12 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Mike Hibler
>Release:        FreeBSD 6.2-PRERELEASE i386
>Organization:
University of Utah
>Environment:
System: FreeBSD pc361.emulab.net 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #0: Thu Sep 28 13:51:51 MDT 2006 root at server.server.testbed.emulab.net:/usr/obj/usr/src/sys/OPS i386

>Description:
	The -s and -b command line arguments to gpt are parsed with strtol
	under the assumption that sizeof(long) == sizeof(off_t).
	The result is that partitions greater than 2TB cannot be manipulated.

>How-To-Repeat:
	Use 'gpt create' to create a partition table on a 2TB+ array.
	Use 'gpt add' to add a partition with 4G+ sectors.
	It will succeed but the result is smaller than expected.

>Fix:

	Here is one way, though probably not the best:

Index: add.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/add.c,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 add.c
--- add.c	7 Jul 2006 03:30:37 -0000	1.11.2.2
+++ add.c	29 Sep 2006 01:57:43 -0000
@@ -163,7 +163,7 @@
 		case 'b':
 			if (block > 0)
 				usage_add();
-			block = strtol(optarg, &p, 10);
+			block = strtoofft(optarg, &p, 10);
 			if (*p != 0 || block < 1)
 				usage_add();
 			break;
@@ -177,7 +177,7 @@
 		case 's':
 			if (size > 0)
 				usage_add();
-			size = strtol(optarg, &p, 10);
+			size = strtoofft(optarg, &p, 10);
 			if (*p != 0 || size < 1)
 				usage_add();
 			break;
Index: gpt.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/gpt.c,v
retrieving revision 1.10.2.2
diff -u -r1.10.2.2 gpt.c
--- gpt.c	7 Jul 2006 03:30:37 -0000	1.10.2.2
+++ gpt.c	29 Sep 2006 01:57:08 -0000
@@ -118,6 +118,14 @@
 	return crc ^ ~0U;
 }
 
+off_t
+strtoofft(const char * __restrict nptr, char ** __restrict endptr, int base)
+{
+	if (sizeof(off_t) == sizeof(long))
+		return (strtol(nptr, endptr, base));
+	return (strtoll(nptr, endptr, base));
+}
+
 uint8_t *
 utf16_to_utf8(uint16_t *s16)
 {
Index: gpt.h
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/gpt.h,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 gpt.h
--- gpt.h	7 Jul 2006 03:30:37 -0000	1.7.2.2
+++ gpt.h	29 Sep 2006 01:56:12 -0000
@@ -71,6 +71,7 @@
 int	gpt_open(const char *);
 void*	gpt_read(int, off_t, size_t);
 int	gpt_write(int, map_t *);
+off_t	strtoofft(const char * __restrict, char ** __restrict, int);
 
 uint8_t *utf16_to_utf8(uint16_t *);
 void	utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
Index: label.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/label.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 label.c
--- label.c	7 Jul 2006 03:30:37 -0000	1.1.2.2
+++ label.c	29 Sep 2006 01:58:27 -0000
@@ -184,7 +184,7 @@
 		case 'b':
 			if (block > 0)
 				usage_label();
-			block = strtol(optarg, &p, 10);
+			block = strtoofft(optarg, &p, 10);
 			if (*p != 0 || block < 1)
 				usage_label();
 			break;
@@ -208,7 +208,7 @@
 		case 's':
 			if (size > 0)
 				usage_label();
-			size = strtol(optarg, &p, 10);
+			size = strtoofft(optarg, &p, 10);
 			if (*p != 0 || size < 1)
 				usage_label();
 			break;
Index: remove.c
===================================================================
RCS file: /share/freebsd/CVS/src/sbin/gpt/remove.c,v
retrieving revision 1.4.2.2
diff -u -r1.4.2.2 remove.c
--- remove.c	7 Jul 2006 03:30:37 -0000	1.4.2.2
+++ remove.c	2 Oct 2006 16:16:51 -0000
@@ -155,7 +155,7 @@
 		case 'b':
 			if (block > 0)
 				usage_remove();
-			block = strtol(optarg, &p, 10);
+			block = strtoofft(optarg, &p, 10);
 			if (*p != 0 || block < 1)
 				usage_remove();
 			break;
@@ -169,7 +169,7 @@
 		case 's':
 			if (size > 0)
 				usage_remove();
-			size = strtol(optarg, &p, 10);
+			size = strtoofft(optarg, &p, 10);
 			if (*p != 0 || size < 1)
 				usage_remove();
 			break;



>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list