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
This commit is contained in:
Mark Johnston 2021-09-07 09:46:58 -04:00
parent 173a7a4ee4
commit 5402baa5b5
5 changed files with 16 additions and 5 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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);