Subject: Re: kern/35447: Panic by write to raw cgd device
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 01/22/2007 01:55:01
The following reply was made to PR kern/35447; it has been noted by GNATS.

From: Christian Biere <christianbiere@gmx.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/35447: Panic by write to raw cgd device
Date: Mon, 22 Jan 2007 02:56:38 +0100

 The following patch fixes the problem for me. I've added one check from
 src/sys/dev/ata/wd.c to prevent write attempts with an amount of bytes that
 isn't a multiple of the sector size. This affects more than just cgd though,
 so I'm not sure whether this check was just forgotten or whether it's omitted
 for a good reason.
 
 --- src/sys/dev/dksubr.c.orig	2006-12-26 15:46:32.000000000 +0100
 +++ src/sys/dev/dksubr.c	2007-01-22 01:56:43.000000000 +0100
 @@ -195,10 +195,8 @@
  
  	if (!(dksc->sc_flags & DKF_INITED)) {
  		DPRINTF_FOLLOW(("dk_strategy: not inited\n"));
 -		bp->b_error  = ENXIO;
 -		bp->b_flags |= B_ERROR;
 -		biodone(bp);
 -		return;
 +		bp->b_error = ENXIO;
 +		goto bad;
  	}
  
  	/* XXX look for some more errors, c.f. ld.c */
 @@ -206,17 +204,18 @@
  	bp->b_resid = bp->b_bcount;
  
  	/* If there is nothing to do, then we are done */
 -	if (bp->b_bcount == 0) {
 -		biodone(bp);
 -		return;
 +	if (bp->b_bcount == 0)
 +		goto done;
 +
 +	if (bp->b_bcount % dksc->sc_dkdev.dk_label->d_secsize) {
 +		bp->b_error = EINVAL;
 +		goto bad;
  	}
  
  	wlabel = dksc->sc_flags & (DKF_WLABEL|DKF_LABELLING);
  	if (DISKPART(bp->b_dev) != RAW_PART &&
 -	    bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0) {
 -		biodone(bp);
 -		return;
 -	}
 +	    bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0)
 +		goto done;
  
  	blkno = bp->b_blkno;
  	if (DISKPART(bp->b_dev) != RAW_PART) {
 @@ -237,6 +236,10 @@
  	dk_start(di, dksc);
  	splx(s);
  	return;
 +bad:
 +	bp->b_flags |= B_ERROR;
 +done:
 +	biodone(bp);
  }
  
  void