kern/56572: ATAng sees zero sized disk... causes div-by-zero
David Gilbert
freebsd-submit at daveg.ca
Sun Sep 7 13:10:15 PDT 2003
>Number: 56572
>Category: kern
>Synopsis: ATAng sees zero sized disk... causes div-by-zero
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Sep 07 13:10:12 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator: David Gilbert
>Release: FreeBSD 5.1-CURRENT i386
>Organization:
daveg.ca
>Environment:
System: FreeBSD canoe.dclg.ca 5.1-CURRENT FreeBSD 5.1-CURRENT #1: Sun Sep 7 15:46:19 EDT 2003 dgilbert at canoe.dclg.ca:/usr/src/sys/i386/compile/CANOE i386
Dell D800 laptop. Centrino processor, 1G RAM.
>Description:
The Dell has a two channel IDE controller. Channel 0 is the hard drive
and channel 1 is the DVD+R drive. For some reason, ATAng sees a phanotm
ad3 when the DVD+R is inserted (it is not seen when the DVD+R is removed.)
This happens both when the DVD+R is hot-swapped in and when it is in at
boot.
I get a divide-by-zero panic in ad_print in ata-disk.c without the
included patch. The dmesg now says:
ata1: resetting devices ..
acd0: CDRW <PHILIPS DVD+RW SDVD6004> at ata1-master WDMA2
ad3: FAILURE - total sectors 0
>How-To-Repeat:
Boot with -CURRENT on my laptop.
>Fix:
This fix protects against zero length ata devices ... and should likely
be left in regardless (malicious devices hot-swapped in shouldn't
panic the kernel).
This fix does not address why ATAng is detecting a phantom ad3.
The ATA code previous to ATAng did not detect the phantom drive.
--- /sys/dev/ata/ata-disk.orig Sun Sep 7 15:41:06 2003
+++ /sys/dev/ata/ata-disk.c Sun Sep 7 15:53:10 2003
@@ -96,6 +96,16 @@
adp->heads = atadev->param->heads;
adp->sectors = atadev->param->sectors;
adp->total_secs = atadev->param->cylinders * adp->heads * adp->sectors;
+ /* if the total sectors is zero, the size of the disk is zero
+ * and there's little good in attaching it (besides the fact
+ * that this would generate divide by zero errors later.
+ */
+ if (adp->total_secs == 0) {
+ ata_prtdev(atadev, "FAILURE - total sectors 0\n");
+ free(adp, M_AD);
+ atadev->attach = NULL;
+ return;
+ }
if (adp->device->channel->flags & ATA_USE_PC98GEOM &&
adp->total_secs < 17 * 8 * 65536) {
adp->sectors = 17;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list