Date: Tue, 31 Aug 2021 21:10:09 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 9e9ba9c73de9 - main - graid: Avoid tasting devices with small sector sizes Message-ID: <202108312110.17VLA93f040883@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=9e9ba9c73de9206d82b8390c47b07f71470d001a commit 9e9ba9c73de9206d82b8390c47b07f71470d001a Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-08-31 21:09:52 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-08-31 21:09:52 +0000 graid: Avoid tasting devices with small sector sizes The RAID metadata parsers effectively assume a sector size of 512 bytes or larger, but md(4) devices can be created with a sector size that's any power of 2. Add some seatbelts to graid tasting routines to ensure that the requested sector(s) are large enough for the device to plausibly contain RAID metadata. Reported by: syzbot+f43583c9bf8357c8b56f@syzkaller.appspotmail.com Reported by: syzbot+537dd9f22b91b698e161@syzkaller.appspotmail.com Reported by: syzbot+51509dd48871c57c6e47@syzkaller.appspotmail.com Reported by: syzbot+c882a31037ea2a54ff63@syzkaller.appspotmail.com MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/geom/raid/md_ddf.c | 3 +++ sys/geom/raid/md_intel.c | 3 ++- sys/geom/raid/md_jmicron.c | 3 ++- sys/geom/raid/md_nvidia.c | 3 ++- sys/geom/raid/md_promise.c | 2 ++ sys/geom/raid/md_sii.c | 3 ++- 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/geom/raid/md_ddf.c b/sys/geom/raid/md_ddf.c index 0a3ec6637337..d4ceae343447 100644 --- a/sys/geom/raid/md_ddf.c +++ b/sys/geom/raid/md_ddf.c @@ -1046,8 +1046,11 @@ ddf_meta_read(struct g_consumer *cp, struct ddf_meta *meta) uint32_t val; ddf_meta_free(meta); + pp = cp->provider; ss = meta->sectorsize = pp->sectorsize; + if (ss < sizeof(*hdr)) + return (ENXIO); /* Read anchor block. */ abuf = g_read_data(cp, pp->mediasize - ss, ss, &error); if (abuf == NULL) { diff --git a/sys/geom/raid/md_intel.c b/sys/geom/raid/md_intel.c index 80ec182c53be..54fa7535bc0e 100644 --- a/sys/geom/raid/md_intel.c +++ b/sys/geom/raid/md_intel.c @@ -593,7 +593,8 @@ intel_meta_read(struct g_consumer *cp) uint32_t checksum, *ptr; pp = cp->provider; - + if (pp->sectorsize < sizeof(*meta)) + return (NULL); /* Read the anchor sector. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize * 2, pp->sectorsize, &error); diff --git a/sys/geom/raid/md_jmicron.c b/sys/geom/raid/md_jmicron.c index d0387bef4de0..02da9e1f02ab 100644 --- a/sys/geom/raid/md_jmicron.c +++ b/sys/geom/raid/md_jmicron.c @@ -270,7 +270,8 @@ jmicron_meta_read(struct g_consumer *cp) uint16_t checksum, *ptr; pp = cp->provider; - + if (pp->sectorsize < sizeof(*meta)) + return (NULL); /* Read the anchor sector. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, &error); diff --git a/sys/geom/raid/md_nvidia.c b/sys/geom/raid/md_nvidia.c index 1c758df5157d..79ec18fe17d7 100644 --- a/sys/geom/raid/md_nvidia.c +++ b/sys/geom/raid/md_nvidia.c @@ -250,7 +250,8 @@ nvidia_meta_read(struct g_consumer *cp) uint32_t checksum, *ptr; pp = cp->provider; - + if (pp->sectorsize < sizeof(*meta)) + return (NULL); /* Read the anchor sector. */ buf = g_read_data(cp, pp->mediasize - 2 * pp->sectorsize, pp->sectorsize, &error); diff --git a/sys/geom/raid/md_promise.c b/sys/geom/raid/md_promise.c index aacf0106ea15..dc9f444f2ac4 100644 --- a/sys/geom/raid/md_promise.c +++ b/sys/geom/raid/md_promise.c @@ -344,6 +344,8 @@ promise_meta_read(struct g_consumer *cp, struct promise_raid_conf **metaarr) pp = cp->provider; subdisks = 0; + if (pp->sectorsize * 4 < sizeof(*meta)) + return (subdisks); if (pp->sectorsize * 4 > maxphys) { G_RAID_DEBUG(1, "%s: Blocksize is too big.", pp->name); return (subdisks); diff --git a/sys/geom/raid/md_sii.c b/sys/geom/raid/md_sii.c index c8de0c8db8e9..06d58d45fe30 100644 --- a/sys/geom/raid/md_sii.c +++ b/sys/geom/raid/md_sii.c @@ -271,7 +271,8 @@ sii_meta_read(struct g_consumer *cp) uint16_t checksum, *ptr; pp = cp->provider; - + if (pp->sectorsize < sizeof(*meta)) + return (NULL); /* Read the anchor sector. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, &error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108312110.17VLA93f040883>