[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-bugs
Subject:    user/948: Revised patch for PR user/947
From:       SUZUKI Hitoshi <sigh () kuzirabekon ! econ ! nagasaki-u ! ac ! jp>
Date:       1999-10-19 6:40:40
[Download RAW message or body]


>Number:         948
>Category:       user
>Synopsis:       patch in PR user/947 has logical mistake.
>Confidential:   yes
>Severity:       serious
>Priority:       high
>Responsible:    bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 19 00:50:01 MDT 1999
>Last-Modified:
>Originator:     SUZUKI Hitoshi
>Organization:
sigh@net.nagasaki-u.ac.jp
Faculty of Economics, Nagasaki Univ.
>Release:        OpenBSD-current/i386
>Environment:
	System      : OpenBSD 2.6
	Architecture: OpenBSD.i386
	Machine     : i386
>Description:
	I made mistake on checking cylinder boundary with head one.
>How-To-Repeat:
	When set parameter by fdisk with patch PR user/947 to large disk (<8G.) will write wrong parameter.
>Fix:
New patch is as bellow.
diff -u /usr/src/sbin/fdisk/cmd.c ./cmd.c
--- /usr/src/sbin/fdisk/cmd.c	Sun Aug 22 07:49:25 1999
+++ ./cmd.c	Mon Oct 18 19:13:21 1999
@@ -169,6 +169,8 @@
 		EDIT("BIOS Ending sector",     ASK_DEC, pp->esect, 1, maxsect, NULL);
 		/* Fix up off/size values */
 		PRT_fix_BN(disk, pp);
+		/* Fix up CHS values for LBA */
+		PRT_fix_CHS(disk, pp);
 	} else {
 		u_int m;
 
diff -u /usr/src/sbin/fdisk/disk.c ./disk.c
--- /usr/src/sbin/fdisk/disk.c	Tue Oct 28 19:06:32 1997
+++ ./disk.c	Tue Oct 19 11:56:59 1999
@@ -211,7 +211,7 @@
 	 * Or we need a mapping from biosdev -> BSD universe.
 	 */
 	if (disk->bios)
-		if (disk->real->cylinders > 1024 || disk->real->heads > 255 ||
+		if (disk->real->cylinders > 262144 || disk->real->heads > 255 ||
 		    disk->real->sectors > 63)
 			disk->real = disk->bios;
 
diff -u /usr/src/sbin/fdisk/fdisk.c ./fdisk.c
--- /usr/src/sbin/fdisk/fdisk.c	Mon Sep 14 12:54:34 1998
+++ ./fdisk.c	Mon Oct 18 20:49:21 1999
@@ -87,12 +87,12 @@
 			break;
 		case 'c':
 			c_arg = atoi(optarg);
-			if (c_arg < 0 || c_arg > 1023)
+			if (c_arg < 1 || c_arg > 262144)
 				errx(1, "Cylinder argument out of range.");
 			break;
 		case 'h':
 			h_arg = atoi(optarg);
-			if (h_arg < 0 || h_arg > 255)
+			if (h_arg < 1 || h_arg > 255)
 				errx(1, "Head argument out of range.");
 			break;
 		case 's':
@@ -117,24 +117,19 @@
 	if (c_arg | h_arg | s_arg) {
 		usermetrics = malloc(sizeof(DISK_metrics));
 		if (usermetrics != NULL) {
-			if (c_arg)
+			if (c_arg && h_arg && s_arg) {
 				usermetrics->cylinders = c_arg;
-			else
-				errx(1, "Please specify a full geometry with [-chs].");
-			if (h_arg)
 				usermetrics->heads = h_arg;
-			else
-				errx(1, "Please specify a full geometry with [-chs].");
-			if (s_arg)
 				usermetrics->sectors = s_arg;
-			else
+				usermetrics->size = c_arg * h_arg * s_arg;
+			} else
 				errx(1, "Please specify a full geometry with [-chs].");
 		}
-		usermetrics->size = c_arg * h_arg * s_arg;
 	} else
 		usermetrics = NULL;
 
 	/* Get the geometry */
+	disk.real = NULL;
 	if (DISK_getmetrics(&disk, usermetrics))
 		errx(1, "Can't get disk geometry, please use [-chs] to specify.");
 
diff -u /usr/src/sbin/fdisk/part.c ./part.c
--- /usr/src/sbin/fdisk/part.c	Fri Jul 23 07:05:55 1999
+++ ./part.c	Tue Oct 19 12:54:14 1999
@@ -137,19 +137,7 @@
 {
 	unsigned char *p = prt;
 	off_t off;
-	int need_fix_chs = 0;
 
-	/* dont check fields 0 and 4, they are flag and id, always preserved */
-	if ((p[1] == 0xff) && 
-	    (p[2] == 0xff) && 
-	    (p[3] == 0xff) && 
-	    (p[5] == 0xff) && 
-	    (p[6] == 0xff) && 
-	    (p[7] == 0xff))
-	{
-		/* CHS values invalid */
-		need_fix_chs =1;
-	}
 	partn->flag = *p++;
 	partn->shead = *p++;
 
@@ -163,15 +151,15 @@
 	partn->ecyl = ((*p << 2) & 0xFF00) | (*(p+1));
 	p += 2;
 
-	off = partn->id != DOSPTYP_EXTEND ? offset : reloff;
+	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
+		off = reloff;
+	else
+		off = offset;
 
 	partn->bs = getlong(p) + off;
 	partn->ns = getlong(p+4);
 
-	if (need_fix_chs == 1) {
-		printf("warning MBR CHS values invalid, translating LBA values\n");
-		PRT_fix_CHS(disk, partn);
-	}
+	PRT_fix_CHS(disk, partn);
 }
 
 int
@@ -197,7 +185,28 @@
 	void *prt;
 {
 	unsigned char *p = prt;
-	off_t off = partn->id != DOSPTYP_EXTEND ? offset : reloff; 
+	prt_t tmp;
+	off_t off;
+
+	tmp.shead = partn->shead;
+	tmp.ssect = (partn->ssect > 1024)? 1023: partn->ssect;
+	tmp.scyl = partn->scyl; 
+	tmp.ehead = partn->ehead;
+	tmp.esect = (partn->ssect > 1024)? 1023: partn->esect;
+	tmp.ecyl = partn->scyl; 
+	if (!PRT_check_chs(partn) && PRT_check_chs(&tmp)) {
+		partn->shead = tmp.shead;
+		partn->ssect = tmp.ssect;
+		partn->scyl = tmp.scyl;
+		partn->ehead = tmp.ehead;
+		partn->esect = tmp.esect;
+		partn->ecyl = tmp.ecyl;
+		printf("Cylinder values are modified to fit in CHS.\n");
+	}
+	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
+		off = reloff;
+	else
+		off = offset;
 
 	if (PRT_check_chs(partn)) {
 		*p++ = partn->flag & 0xFF;
@@ -302,6 +311,10 @@
 	head = (start / spt); start -= (head * spt);
 	sect = (start + 1);
 
+	if (cyl > 1023) {
+		cyl = 1023;
+		printf("Only LBA values are valid in starting cylinder.\n");
+	}
 	part->scyl = cyl;
 	part->shead = head;
 	part->ssect = sect;
@@ -311,6 +324,10 @@
 	head = (end / spt); end -= (head * spt);
 	sect = (end + 1);
 
+	if (cyl > 1023) {
+		cyl = 1023;
+		printf("Only LBA values are valid in ending cylinder.\n");
+	}
 	part->ecyl = cyl;
 	part->ehead = head;
 	part->esect = sect;

>Audit-Trail:
>Unformatted:

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic