DF-0863 / fix.diff
diff --git a/sys/vfs/hpfs/hpfs_subr.c b/sys/vfs/hpfs/hpfs_subr.c --- a/sys/vfs/hpfs/hpfs_subr.c +++ b/sys/vfs/hpfs/hpfs_subr.c @@ -225,6 +225,25 @@ cpdsp = (struct cpdsec *)bp->b_data; + if (cpdsp->d_magic != CPD_MAGIC) { + brelse(bp); + return (EINVAL); + } + + /* + * d_cpfirst / d_cpcnt are attacker-controlled on-disk u16 values. + * d_cpdblk[] is a fixed-size array of 3 entries (sys/vfs/hpfs/hpfs.h: + * struct cpdsec.d_cpdblk[3]); an unchecked d_cpcnt drives the loop + * past the array and past the 512-byte DEV_BSIZE bp->b_data buffer + * (DF-0863). Clamp both to the array bounds before iterating. + */ + if (cpdsp->d_cpfirst >= nitems(cpdsp->d_cpdblk)) { + brelse(bp); + return (ENOENT); + } + if (cpdsp->d_cpcnt > nitems(cpdsp->d_cpdblk)) + cpdsp->d_cpcnt = nitems(cpdsp->d_cpdblk); + for (i=cpdsp->d_cpfirst; i<cpdsp->d_cpcnt; i++) { if (cpdsp->d_cpdblk[i].b_cpid == cpibp->b_cpid) { bcopy(cpdsp->d_cpdblk + i, cpdbp, |