Module Name: src
Committed By: mlelstv
Date: Mon Dec 29 12:03:40 UTC 2014
Modified Files:
src/sys/dev: dksubr.c
Log Message:
align dk_strategy with checks from ld.c
To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/dev/dksubr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/dksubr.c
diff -u src/sys/dev/dksubr.c:1.54 src/sys/dev/dksubr.c:1.55
--- src/sys/dev/dksubr.c:1.54 Tue Nov 4 07:51:54 2014
+++ src/sys/dev/dksubr.c Mon Dec 29 12:03:39 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: dksubr.c,v 1.54 2014/11/04 07:51:54 mlelstv Exp $ */
+/* $NetBSD: dksubr.c,v 1.55 2014/12/29 12:03:39 mlelstv Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.54 2014/11/04 07:51:54 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.55 2014/12/29 12:03:39 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -178,9 +178,13 @@ dk_close(struct dk_intf *di, struct dk_s
void
dk_strategy(struct dk_intf *di, struct dk_softc *dksc, struct buf *bp)
{
- int s;
+ int s, part;
int wlabel;
daddr_t blkno;
+ struct disklabel *lp;
+ struct disk *dk;
+ uint64_t numsecs;
+ unsigned secsize;
DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n",
di->di_dkname, dksc, bp));
@@ -192,10 +196,25 @@ dk_strategy(struct dk_intf *di, struct d
return;
}
- /* XXX look for some more errors, c.f. ld.c */
+ lp = dksc->sc_dkdev.dk_label;
+ dk = &dksc->sc_dkdev;
+
+ part = DISKPART(bp->b_dev);
+ numsecs = dk->dk_geom.dg_secperunit;
+ secsize = dk->dk_geom.dg_secsize;
bp->b_resid = bp->b_bcount;
+ /*
+ * The transfer must be a whole number of blocks and the offset must
+ * not be negative.
+ */
+ if ((bp->b_bcount % secsize) != 0 || bp->b_blkno < 0) {
+ bp->b_error = EINVAL;
+ biodone(bp);
+ return;
+ }
+
/* If there is nothing to do, then we are done */
if (bp->b_bcount == 0) {
biodone(bp);
@@ -203,20 +222,21 @@ dk_strategy(struct dk_intf *di, struct d
}
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;
+ if (part == RAW_PART) {
+ if (bounds_check_with_mediasize(bp, DEV_BSIZE, numsecs) <= 0) {
+ biodone(bp);
+ return;
+ }
+ } else {
+ if (bounds_check_with_label(&dksc->sc_dkdev, bp, wlabel) <= 0) {
+ biodone(bp);
+ return;
+ }
}
blkno = bp->b_blkno;
- if (DISKPART(bp->b_dev) != RAW_PART) {
- struct partition *pp;
-
- pp =
- &dksc->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
- blkno += pp->p_offset;
- }
+ if (part != RAW_PART)
+ blkno += lp->d_partitions[DISKPART(bp->b_dev)].p_offset;
bp->b_rawblkno = blkno;
/*