Subject: port-i386/5364: floppy driver has off-by-one bug in minor-number conversion
To: None <gnats-bugs@gnats.netbsd.org>
From: None <bgrayson@ece.utexas.edu>
List: netbsd-bugs
Date: 04/25/1998 15:03:52
>Number:         5364
>Category:       port-i386
>Synopsis:       off-by-one error makes it impossible to fdformat >/dev/rfd0[b-h]
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 25 13:05:00 1998
>Last-Modified:
>Originator:     Brian Grayson
>Organization:
	Parallel and Distributed Systems
	Electrical and Computer Engineering
	The University of Texas at Austin
>Release:        Apr 20
>Environment:
NetBSD marvin 1.3E NetBSD 1.3E (MARVIN) #39: Thu Apr 23 10:09:22 CDT 1998     bgrayson@marvin:/a/c3p0/home/c3p0/src/sys/arch/i386/compile/MARVIN i386

>Description:
	In the function fd_dev_to_type(fd,dev) in
	/sys/arch/i386/isa/fd.c, it takes the device minor number
	% 8, and uses this as an offset into the built-in floppy
	table.  Thus, a device with minor 0 is a 1.44M floppy,
	minor 1 is a 1.2M floppy, etc.  However, the code does
	the following, where fd_types[] holds the above array:

	  return type ? &fd_types[type - 1] : fd->sc_deftype;

	Thus, if we are trying to format /dev/rfd0b, it
	calculates a `type' of 1, subtracts 1, and then uses the
	entry for 1.44M!

	Similarly, should the check really look for a zero
	type, and return fd->sc_deftype?  That's the only reason
	fd0a works currently, as otherwise it would use the entry
	fd_types[-1], leading to ``interesting'' problems (and
	possible permanent floppy-drive damage from trying to
	seek beyond 80 cyls).  I'm addressing this and another
	issue or two in another PR.

>How-To-Repeat:
##  Look at the params for fd0a:
# fdformat -f /dev/rfd0a
Ready to format /dev/rfd0a with 80 cylinders, 2 tracks, 18 sectors of 512 bytes
(1440 KB) Yes/no [y]?n
fdformat: formatting abandoned--not confirmed.

##  Now look at params for fd0b:
# fdformat -f /dev/rfd0b
Ready to format /dev/rfd0b with 80 cylinders, 2 tracks, 18 sectors of 512 bytes
(1440 KB) Yes/no [y]?n
fdformat: formatting abandoned--not confirmed.

##  And fd0c:
#fdformat -f /dev/rfd0c
Ready to format /dev/rfd0c with 80 cylinders, 2 tracks, 15 sectors of 512 bytes
(1200 KB) Yes/no [y]?n
fdformat: formatting abandoned--not confirmed.

##  Notice that fd0b is using fd0a's settings, etc.

	
>Fix:
  I don't have FreeBSD code handy -- if their driver is (near)
identical, this ought to be forwarded to them, although someone
from the appropriate group will probably see this on
netbsd-bugs.  Or they may have already fixed it!

--- fd.c.orig   Mon Mar 23 06:13:25 1998
+++ fd.c        Sat Apr 25 14:34:21 1998
@@ -594,7 +594,7 @@
 
        if (type > (sizeof(fd_types) / sizeof(fd_types[0])))
                return NULL;
-       return type ? &fd_types[type - 1] : fd->sc_deftype;
+       return type ? &fd_types[type] : fd->sc_deftype;
 }
 
 void

	
>Audit-Trail:
>Unformatted: