aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2017-01-12 06:58:31 +0000
committerConrad Meyer <cem@FreeBSD.org>2017-01-12 06:58:31 +0000
commitb28ea2c250f410bcbff858a013aa9dd7400dec7f (patch)
tree6a2e1050f6d8508b2e2ce04a675031e72274a674 /sys/geom
parent8e712af70b3604f2684b31ea9918548eb819219b (diff)
downloadsrc-b28ea2c250f410bcbff858a013aa9dd7400dec7f.tar.gz
src-b28ea2c250f410bcbff858a013aa9dd7400dec7f.zip
g_raid: Prevent tasters from attempting excessively large reads
Some g_raid tasters attempt metadata reads in multiples of the provider sectorsize. Reads larger than MAXPHYS are invalid, so detect and abort in such situations. Spiritually similar to r217305 / PR 147851. PR: 214721 Sponsored by: Dell EMC Isilon
Notes
Notes: svn path=/head/; revision=311964
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/raid/md_ddf.c10
-rw-r--r--sys/geom/raid/md_promise.c5
2 files changed, 15 insertions, 0 deletions
diff --git a/sys/geom/raid/md_ddf.c b/sys/geom/raid/md_ddf.c
index df58a1e8da03..87da8feedf9f 100644
--- a/sys/geom/raid/md_ddf.c
+++ b/sys/geom/raid/md_ddf.c
@@ -1161,6 +1161,16 @@ hdrerror:
(GET16(meta, hdr->Configuration_Record_Length) * ss - 512) / 12));
}
+ if (GET32(meta, hdr->cd_length) * ss >= MAXPHYS ||
+ GET32(meta, hdr->pdr_length) * ss >= MAXPHYS ||
+ GET32(meta, hdr->vdr_length) * ss >= MAXPHYS ||
+ GET32(meta, hdr->cr_length) * ss >= MAXPHYS ||
+ GET32(meta, hdr->pdd_length) * ss >= MAXPHYS ||
+ GET32(meta, hdr->bbmlog_length) * ss >= MAXPHYS) {
+ G_RAID_DEBUG(1, "%s: Blocksize is too big.", pp->name);
+ goto hdrerror;
+ }
+
/* Read controller data. */
buf = g_read_data(cp, (lba + GET32(meta, hdr->cd_section)) * ss,
GET32(meta, hdr->cd_length) * ss, &error);
diff --git a/sys/geom/raid/md_promise.c b/sys/geom/raid/md_promise.c
index 245cd74f7dbb..258b4d30ec19 100644
--- a/sys/geom/raid/md_promise.c
+++ b/sys/geom/raid/md_promise.c
@@ -341,6 +341,11 @@ promise_meta_read(struct g_consumer *cp, struct promise_raid_conf **metaarr)
pp = cp->provider;
subdisks = 0;
+
+ if (pp->sectorsize * 4 > MAXPHYS) {
+ G_RAID_DEBUG(1, "%s: Blocksize is too big.", pp->name);
+ return (subdisks);
+ }
next:
/* Read metadata block. */
buf = g_read_data(cp, pp->mediasize - pp->sectorsize *