Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev align dk_strategy with checks from ld.c



details:   https://anonhg.NetBSD.org/src/rev/329ddd892543
branches:  trunk
changeset: 335175:329ddd892543
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Mon Dec 29 12:03:39 2014 +0000

description:
align dk_strategy with checks from ld.c

diffstat:

 sys/dev/dksubr.c |  50 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 35 insertions(+), 15 deletions(-)

diffs (93 lines):

diff -r f956e5955740 -r 329ddd892543 sys/dev/dksubr.c
--- a/sys/dev/dksubr.c  Mon Dec 29 10:38:52 2014 +0000
+++ b/sys/dev/dksubr.c  Mon Dec 29 12:03:39 2014 +0000
@@ -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 @@
 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 @@
                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 @@
        }
 
        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;
 
        /*



Home | Main Index | Thread Index | Old Index