d_npartitions is a uint16 partition count read straight from an on-disk
BSD disklabel. bsd_readlabel() warns when it is larger than
BSD_MAXPARTITIONS but leaves the value untouched, so the bogus count
survives into the rest of the label handling.
bsd_dkcksum() walks the label up to &lp->d_partitions[d_npartitions]
when the label is written back. d_partitions[] holds 16 entries
(256 bytes); a crafted disklabel can set the count to 65535 and push
that end pointer about 1 MB past the array, an out-of-bounds read.
Clamp the count to BSD_MAXPARTITIONS in the block that already emits the
warning, the same upper bound sun/sgi/gpt enforce on their arrays.
Signed-off-by: aizu-m <aizumusheer2@gmail.com>
d->d_partitions[t].p_fstype = BSD_FS_UNUSED;
}
- if (d->d_npartitions > BSD_MAXPARTITIONS)
+ if (d->d_npartitions > BSD_MAXPARTITIONS) {
fdisk_warnx(cxt, _("Too many partitions (%d, maximum is %d)."),
d->d_npartitions, BSD_MAXPARTITIONS);
+ d->d_npartitions = BSD_MAXPARTITIONS;
+ }
/* let's follow in-PT geometry */
cxt->geom.sectors = d->d_nsectors;