]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: clamp out-of-range d_npartitions in bsd_readlabel
authoraizu-m <aizumusheer2@gmail.com>
Tue, 9 Jun 2026 19:24:04 +0000 (00:54 +0530)
committeraizu-m <aizumusheer2@gmail.com>
Tue, 9 Jun 2026 19:24:04 +0000 (00:54 +0530)
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>
libfdisk/src/bsd.c

index c916db2a76533fe6f1cc793036f4d5658d2a8db6..cb988f04157f947742f33fd3bbc8b3509fcf2abc 100644 (file)
@@ -858,9 +858,11 @@ static int bsd_readlabel(struct fdisk_context *cxt)
                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;