Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Sep 2021 13:36:23 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 8dbe4fadcaf6 - stable/13 - graid: Avoid tasting devices with small sector sizes
Message-ID:  <202109071336.187DaNQ3008015@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=8dbe4fadcaf6fe98e7b70616d11ff3e1530231f2

commit 8dbe4fadcaf6fe98e7b70616d11ff3e1530231f2
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-08-31 21:09:52 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-09-07 13:36:18 +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
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 9e9ba9c73de9206d82b8390c47b07f71470d001a)
---
 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?202109071336.187DaNQ3008015>