Subject: bin/33522: fdisk fails with SIGFPE (division by zero) on wrong devices
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <Peter.Bex@xs4all.nl>
List: netbsd-bugs
Date: 05/20/2006 22:45:00
>Number:         33522
>Category:       bin
>Synopsis:       fdisk should fail, but not SIGFPE on floppy disks
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 20 22:45:00 +0000 2006
>Originator:     Peter Bex (with thanks to Sander Bos for reporting the bug)
>Release:        NetBSD 2.1_RC6
>Organization:
>Environment:
	
	
System: NetBSD frohike.homeunix.org 2.1_RC6 NetBSD 2.1_RC6 (GENERIC) #0: Wed Oct 12 17:26:21 UTC 2005 builds@b2.netbsd.org:/home/builds/ab/netbsd-2-1-RC6/amd64/200510121548Z-obj/home/builds/ab/netbsd-2-1-RC6/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
	When running fdisk on /dev/fd0a (and possibly other devices that
	aren't disks with MBRs), it will exit with a floating point exception.

	Of course it's not a very smart thing to do, but fdisk should not
	fail, but exit gracefully with an error message.

>How-To-Repeat:
	Use mtools to format the disk:

	% mformat a:

	then try to run fdisk on it:

	% fdisk /dev/fd0a
	zsh: floating point exception  fdisk /dev/fd0a
	
	Note: The error does not show up when using newfs_msdos -F 12
	but it does show the disk as if it were a normal harddisk, which
	is also incorrect.

>Fix:
	Attached patch works by sanity checking the input.
	Originally the function intuit_translated_geometry returned
	on error.  It should exit instead.

	The patch also fixes the incorrect behaviour on newfs_msdos'ed
	floppies.

Index: fdisk.c
===================================================================
RCS file: /cvsroot/src/sbin/fdisk/fdisk.c,v
retrieving revision 1.99
diff -u -r1.99 fdisk.c
--- fdisk.c	18 Mar 2006 08:36:50 -0000	1.99
+++ fdisk.c	20 May 2006 22:27:22 -0000
@@ -1333,8 +1333,10 @@
 			break;
 	}
 
-	if (xheads == -1)
+	if (xheads == -1) {
+		errx(1, "Could not determine number of heads for device");
 		return;
+	}
 
 	/* Estimate the number of cylinders. */
 	xcylinders = disklabel.d_secperunit / xheads / xsectors;
@@ -1399,6 +1401,9 @@
 	if ((((*cylinder * MAXHEAD) + *head) * MAXSECTOR + *sector) < *absolute)
 		/* cannot be a CHS mapping */
 		return -1;
+	/* Sanity check the data against all zeroes */
+	if ((*cylinder == 0) && (*sector == 0) && (*head == 0))
+		return -1;
 	return 0;
 }
 

>Unformatted: