From owner-freebsd-bugs Thu Jan 6 15: 0: 5 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 8B28714CE2 for ; Thu, 6 Jan 2000 15:00:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id PAA12698; Thu, 6 Jan 2000 15:00:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from alcanet.com.au (border.alcanet.com.au [203.62.196.10]) by hub.freebsd.org (Postfix) with ESMTP id 16CDC156FC for ; Thu, 6 Jan 2000 14:58:44 -0800 (PST) (envelope-from jeremyp@gsmx07.alcatel.com.au) Received: by border.alcanet.com.au id <40327>; Fri, 7 Jan 2000 09:51:15 +1100 Message-Id: <00Jan7.095115est.40327@border.alcanet.com.au> Date: Fri, 7 Jan 2000 09:51:14 +1100 From: peter.jeremy@alcatel.com.au To: freefall-gnats@gsmx07.alcatel.com.au X-Send-Pr-Version: 3.2 Subject: kern/15956: Off-by-1 error in diskstrategy() triggers bug in ATA Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 15956 >Category: kern >Synopsis: Off-by-1 error in diskstrategy() >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jan 6 15:00:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Peter Jeremy >Release: FreeBSD 4.0-CURRENT i386 >Organization: >Environment: cvs-cur 5961 >Description: The I/O request range check in /sys/kern/subr_disk.c does not correctly handle an EOF return from dscheck() - instead of terminating the I/O (returning EOF to the caller), it passes a zero-length request to the underlying d_strategy() - which at least for the ATA device can't handle it. >How-To-Repeat: # dd if=/dev/rad0c of=/dev/null bs=128k will report an error at the end of the slice (even if the slice is a multiple of 128k). The problem does not occur with the old wd driver (and it shouldn't appear with the wfd, ida or vn drivers), but appears to affect all other disk devices. >Fix: 1) Don't pass zero-length requests to the underlying device: Index: subr_disk.c =================================================================== RCS file: /home/CVSROOT/src/sys/kern/subr_disk.c,v retrieving revision 1.16 diff -u -r1.16 subr_disk.c --- subr_disk.c 1999/12/19 12:36:41 1.16 +++ subr_disk.c 2000/01/06 21:39:34 @@ -193,7 +193,7 @@ return; } - if (dscheck(bp, dp->d_slice) < 0) { + if (dscheck(bp, dp->d_slice) <= 0) { biodone(bp); return; } 2) Add belt-and-braces checks to ATA device (this code compiles and links, but I haven't booted from the resultant kernel): Index: ata-disk.c =================================================================== RCS file: /home/CVSROOT/src/sys/dev/ata/ata-disk.c,v retrieving revision 1.47 diff -u -r1.47 ata-disk.c --- ata-disk.c 1999/12/21 20:18:55 1.47 +++ ata-disk.c 2000/01/06 22:13:09 @@ -301,6 +301,9 @@ struct ad_softc *adp = bp->b_dev->si_drv1; int32_t s; + if (!bp || !bp->b_bcount) + return; + s = splbio(); bufqdisksort(&adp->queue, bp); ad_start(adp); @@ -375,7 +378,7 @@ struct buf *bp = bufq_first(&adp->queue); struct ad_request *request; - if (!bp) + if (!bp || !bp->b_bcount) return; if (!(request = malloc(sizeof(struct ad_request), M_AD, M_NOWAIT))) { >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message