git: 8dbe4fadcaf6 - stable/13 - graid: Avoid tasting devices with small sector sizes

Mark Johnston markj at FreeBSD.org
Tue Sep 7 13:36:24 UTC 2021


The branch stable/13 has been updated by markj:

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

commit 8dbe4fadcaf6fe98e7b70616d11ff3e1530231f2
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-08-31 21:09:52 +0000
Commit:     Mark Johnston <markj at 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 at syzkaller.appspotmail.com
    Reported by:    syzbot+537dd9f22b91b698e161 at syzkaller.appspotmail.com
    Reported by:    syzbot+51509dd48871c57c6e47 at syzkaller.appspotmail.com
    Reported by:    syzbot+c882a31037ea2a54ff63 at 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);


More information about the dev-commits-src-branches mailing list