Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev validate length for discard operation and split oper...
details: https://anonhg.NetBSD.org/src/rev/958552d58d95
branches: trunk
changeset: 355776:958552d58d95
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sun Aug 13 22:23:16 2017 +0000
description:
validate length for discard operation and split operation when byte length
doesn't fit into 'int'.
diffstat:
sys/dev/dksubr.c | 40 +++++++++++++++++++++++++---------------
1 files changed, 25 insertions(+), 15 deletions(-)
diffs (72 lines):
diff -r 187a812476d3 -r 958552d58d95 sys/dev/dksubr.c
--- a/sys/dev/dksubr.c Sun Aug 13 22:19:56 2017 +0000
+++ b/sys/dev/dksubr.c Sun Aug 13 22:23:16 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dksubr.c,v 1.97 2017/04/27 17:07:22 jdolecek Exp $ */
+/* $NetBSD: dksubr.c,v 1.98 2017/08/13 22:23:16 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.97 2017/04/27 17:07:22 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.98 2017/08/13 22:23:16 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -497,7 +497,7 @@
const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver;
unsigned secsize = dksc->sc_dkdev.dk_geom.dg_secsize;
struct buf tmp, *bp = &tmp;
- int error;
+ int maxsz, error;
DPRINTF_FOLLOW(("%s(%s, %p, 0x"PRIx64", %jd, %jd)\n", __func__,
dksc->sc_xname, dksc, (intmax_t)pos, (intmax_t)len));
@@ -507,22 +507,32 @@
return ENXIO;
}
- if (secsize == 0 || (pos % secsize) != 0)
+ if (secsize == 0 || (pos % secsize) != 0 || (len % secsize) != 0)
return EINVAL;
- /* enough data to please the bounds checking code */
- bp->b_dev = dev;
- bp->b_blkno = (daddr_t)(pos / secsize);
- bp->b_bcount = len;
- bp->b_flags = B_WRITE;
+ /* largest value that b_bcount can store */
+ maxsz = rounddown(INT_MAX, secsize);
+
+ while (len > 0) {
+ /* enough data to please the bounds checking code */
+ bp->b_dev = dev;
+ bp->b_blkno = (daddr_t)(pos / secsize);
+ bp->b_bcount = min(len, maxsz);
+ bp->b_flags = B_WRITE;
- error = dk_translate(dksc, bp);
- if (error >= 0)
- return error;
+ error = dk_translate(dksc, bp);
+ if (error >= 0)
+ break;
- error = dkd->d_discard(dksc->sc_dev,
- (off_t)bp->b_rawblkno * secsize,
- (off_t)bp->b_bcount);
+ error = dkd->d_discard(dksc->sc_dev,
+ (off_t)bp->b_rawblkno * secsize,
+ (off_t)bp->b_bcount);
+ if (error)
+ break;
+
+ pos += bp->b_bcount;
+ len -= bp->b_bcount;
+ }
return error;
}
Home |
Main Index |
Thread Index |
Old Index