summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2015-07-19 18:03:04 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2015-07-19 18:03:04 +0000
commit40118847e4c0cbaf71f1e869e4e01ee7d9531fff (patch)
treec740628b3483f6a5e8426b69c77ad3fb5b17e956
parent5640253e6a858c1287ea930b6ccc7a05ecf3e1b3 (diff)
Change some obviously incorrect usages of daddr_t (a DEV_BSIZE
address) to 64 signed or unsigned ints. Add some paranoia checks during partition size calculations to account for the fact that partition sizes (DL_GETPSIZE()) are unsigned values. More daddr_t rectification to do. ok jsing@
-rw-r--r--sys/dev/softraid.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index ec2a5939aad..b0fb99b26b2 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.356 2015/07/19 17:04:31 krw Exp $ */
+/* $OpenBSD: softraid.c,v 1.357 2015/07/19 18:03:03 krw Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -42,6 +42,7 @@
#include <sys/task.h>
#include <sys/kthread.h>
#include <sys/dkio.h>
+#include <sys/stdint.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
@@ -1549,7 +1550,7 @@ sr_meta_native_probe(struct sr_softc *sc, struct sr_chunk *ch_entry)
struct disklabel label;
char *devname;
int error, part;
- daddr_t size;
+ u_int64_t size;
DNPRINTF(SR_D_META, "%s: sr_meta_native_probe(%s)\n",
DEVNAME(sc), ch_entry->src_devname);
@@ -1583,13 +1584,18 @@ sr_meta_native_probe(struct sr_softc *sc, struct sr_chunk *ch_entry)
goto unwind;
}
- size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) -
- SR_DATA_OFFSET;
- if (size <= 0) {
+ size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part]));
+ if (size <= SR_DATA_OFFSET) {
DNPRINTF(SR_D_META, "%s: %s partition too small\n", DEVNAME(sc),
devname);
goto unwind;
}
+ size -= SR_DATA_OFFSET;
+ if (size > INT64_MAX) {
+ DNPRINTF(SR_D_META, "%s: %s partition too large\n", DEVNAME(sc),
+ devname);
+ goto unwind;
+ }
ch_entry->src_size = size;
DNPRINTF(SR_D_META, "%s: probe found %s size %lld\n", DEVNAME(sc),
@@ -2603,7 +2609,8 @@ sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv)
int vol = -1, rv = EINVAL;
struct sr_discipline *sd;
struct sr_chunk *hotspare;
- daddr_t rb, sz;
+ daddr_t rb;
+ int64_t sz;
TAILQ_FOREACH(sd, &sc->sc_dis_list, sd_link) {
vol++;
@@ -2885,8 +2892,18 @@ sr_hotspare(struct sr_softc *sc, dev_t dev)
}
/* Calculate partition size. */
- size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) -
- SR_DATA_OFFSET;
+ size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part]));
+ if (size <= SR_DATA_OFFSET) {
+ DNPRINTF(SR_D_META, "%s: %s partition too small\n", DEVNAME(sc),
+ devname);
+ goto fail;
+ }
+ size -= SR_DATA_OFFSET;
+ if (size > INT64_MAX) {
+ DNPRINTF(SR_D_META, "%s: %s partition too large\n", DEVNAME(sc),
+ devname);
+ goto fail;
+ }
/*
* Create and populate chunk metadata.
@@ -3107,7 +3124,8 @@ sr_rebuild_init(struct sr_discipline *sd, dev_t dev, int hotspare)
struct sr_meta_chunk *meta;
struct disklabel label;
struct vnode *vn;
- daddr_t size, csize;
+ u_int64_t size;
+ int64_t csize;
char devname[32];
int rv = EINVAL, open = 0;
int cid, i, part, status;
@@ -3188,8 +3206,18 @@ sr_rebuild_init(struct sr_discipline *sd, dev_t dev, int hotspare)
}
/* Is the partition large enough? */
- size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part])) -
- sd->sd_meta->ssd_data_offset;
+ size = DL_SECTOBLK(&label, DL_GETPSIZE(&label.d_partitions[part]));
+ if (size <= sd->sd_meta->ssd_data_offset) {
+ sr_error(sc, "%s: %s partition too small\n", DEVNAME(sc),
+ devname);
+ goto done;
+ }
+ size -= sd->sd_meta->ssd_data_offset;
+ if (size > INT64_MAX) {
+ sr_error(sc, "%s: %s partition too large\n", DEVNAME(sc),
+ devname);
+ goto done;
+ }
if (size < csize) {
sr_error(sc, "%s partition too small, at least %lld bytes "
"required", devname, (long long)(csize << DEV_BSHIFT));
@@ -4622,8 +4650,8 @@ void
sr_rebuild(struct sr_discipline *sd)
{
struct sr_softc *sc = sd->sd_sc;
- daddr_t whole_blk, partial_blk, blk, sz, lba;
- daddr_t psz, rb, restart;
+ u_int64_t sz, psz, whole_blk, partial_blk, blk, restart;
+ daddr_t lba, rb;
struct sr_workunit *wu_r, *wu_w;
struct scsi_xfer xs_r, xs_w;
struct scsi_rw_16 *cr, *cw;