From 5402baa5b5d14819101e1e847df66b02cedf1639 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 7 Sep 2021 09:46:58 -0400 Subject: [PATCH] g_label: Handle small sector sizes when tasting Make sure that the provider sector size is large enough to contain a valid label before trying to read it. We performed this check already for most label types, but not for several filesystem labels. Reported by: syzbot+f52918174cdf193ae29c@syzkaller.appspotmail.com MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/geom/label/g_label.c | 2 ++ sys/geom/label/g_label_ext2fs.c | 4 +++- sys/geom/label/g_label_iso9660.c | 5 +++-- sys/geom/label/g_label_ntfs.c | 6 +++++- sys/geom/label/g_label_reiserfs.c | 4 +++- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/geom/label/g_label.c b/sys/geom/label/g_label.c index 026f5318b4e..1df7e799b01 100644 --- a/sys/geom/label/g_label.c +++ b/sys/geom/label/g_label.c @@ -310,6 +310,8 @@ g_label_read_metadata(struct g_consumer *cp, struct g_label_metadata *md) int error; pp = cp->provider; + if (pp->sectorsize < sizeof(*md)) + return (EINVAL); buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, &error); if (buf == NULL) diff --git a/sys/geom/label/g_label_ext2fs.c b/sys/geom/label/g_label_ext2fs.c index 2003d9b631f..3420efb7ca3 100644 --- a/sys/geom/label/g_label_ext2fs.c +++ b/sys/geom/label/g_label_ext2fs.c @@ -64,8 +64,10 @@ g_label_ext2fs_taste(struct g_consumer *cp, char *label, size_t size) if ((EXT2FS_SB_OFFSET % pp->sectorsize) != 0) return; + if (pp->sectorsize < sizeof(*fs)) + return; - fs = (e2sb_t *)g_read_data(cp, EXT2FS_SB_OFFSET, pp->sectorsize, NULL); + fs = g_read_data(cp, EXT2FS_SB_OFFSET, pp->sectorsize, NULL); if (fs == NULL) return; diff --git a/sys/geom/label/g_label_iso9660.c b/sys/geom/label/g_label_iso9660.c index bd44a38cb97..b46a47bbd36 100644 --- a/sys/geom/label/g_label_iso9660.c +++ b/sys/geom/label/g_label_iso9660.c @@ -54,8 +54,9 @@ g_label_iso9660_taste(struct g_consumer *cp, char *label, size_t size) if ((ISO9660_OFFSET % pp->sectorsize) != 0) return; - sector = (char *)g_read_data(cp, ISO9660_OFFSET, pp->sectorsize, - NULL); + if (pp->sectorsize < 0x28 + VOLUME_LEN) + return; + sector = g_read_data(cp, ISO9660_OFFSET, pp->sectorsize, NULL); if (sector == NULL) return; if (bcmp(sector, ISO9660_MAGIC, sizeof(ISO9660_MAGIC) - 1) != 0) { diff --git a/sys/geom/label/g_label_ntfs.c b/sys/geom/label/g_label_ntfs.c index dee105bcc83..f78d4d28b96 100644 --- a/sys/geom/label/g_label_ntfs.c +++ b/sys/geom/label/g_label_ntfs.c @@ -108,9 +108,13 @@ g_label_ntfs_taste(struct g_consumer *cp, char *label, size_t size) label[0] = '\0'; pp = cp->provider; + bf = NULL; filerecp = NULL; - bf = (struct ntfs_bootfile *)g_read_data(cp, 0, pp->sectorsize, NULL); + if (pp->sectorsize < sizeof(*bf)) + goto done; + + bf = g_read_data(cp, 0, pp->sectorsize, NULL); if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0) goto done; diff --git a/sys/geom/label/g_label_reiserfs.c b/sys/geom/label/g_label_reiserfs.c index 4ed04f63232..d6f9a0428b6 100644 --- a/sys/geom/label/g_label_reiserfs.c +++ b/sys/geom/label/g_label_reiserfs.c @@ -61,8 +61,10 @@ g_label_reiserfs_read_super(struct g_consumer *cp, off_t offset) if ((offset % secsize) != 0) return (NULL); + if (secsize < sizeof(*fs)) + return (NULL); - fs = (reiserfs_sb_t *)g_read_data(cp, offset, secsize, NULL); + fs = g_read_data(cp, offset, secsize, NULL); if (fs == NULL) return (NULL); -- 2.45.2