Subject: bin/26917: fdisk(8) wrong calculation on getting translated geometry
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 09/12/2004 13:27:19
>Number:         26917
>Category:       bin
>Synopsis:       fdisk(8) wrong calculation on getting translated geometry
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Sep 12 04:28:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Izumi Tsutsui
>Release:        NetBSD 2.0G
>Organization:
>Environment:
System: NetBSD 2.0G, but maybe 2.0-release/1.6-release also affected
Architecture: i386, mipsel, but maybe on all ports
Machine: i386, cobalt, and maybe others

>Description:
There is a wrong calculation on intuit_translated_geometry()
so if the first partition starts at sector 1, fdisk(8) dumps
core, and on the other case translated geometry may also be wrong.

>How-To-Repeat:
Try fdisk(8) for the disk with the following partition:

---
Partition table:
0: Linux native (sysid 131)
    start 1, size 1024127 (500 MB, Cyls 0/0/2-63/191/1)
1: Linux swap or Prime or Solaris (sysid 130)
    start 1024128, size 263088 (128 MB, Cyls 63/191/1-80/32/1)
2: Linux native (sysid 131)
    start 1287216, size 410256 (200 MB, Cyls 80/32/1-105/169/1)
3: NetBSD (sysid 169)
    start 1697472, size 31324608 (15295 MB, Cyls 105/169/1-2055/135/1)
---

(on cobalt)
---
# fdisk wd0
Trace/BPT trap (core dumped)
#
---

(on i386)
---
# fdisk vnd0
Floating point exception (core dumped)
# 
---

>Fix:
Don't adjust the start sector number more than once
in intuit_translated_geometry():

Index: fdisk.c
===================================================================
RCS file: /cvsroot/src/sbin/fdisk/fdisk.c,v
retrieving revision 1.81
diff -u -r1.81 fdisk.c
--- fdisk.c	30 Jul 2004 23:42:29 -0000	1.81
+++ fdisk.c	12 Sep 2004 04:08:02 -0000
@@ -1380,10 +1380,10 @@
 	for (i = 0; i < MBR_PART_COUNT * 2 - 1; i++) {
 		if (get_mapping(i, &c1, &h1, &s1, &a1) < 0)
 			continue;
+		a1 -= s1;
 		for (j = i + 1; j < MBR_PART_COUNT * 2; j++) {
 			if (get_mapping(j, &c2, &h2, &s2, &a2) < 0)
 				continue;
-			a1 -= s1;
 			a2 -= s2;
 			num = (uint64_t)h1 * a2 - (uint64_t)h2 * a1;
 			denom = (uint64_t)c2 * a1 - (uint64_t)c1 * a2;
>Release-Note:
>Audit-Trail:
>Unformatted: