DF-0108 / fix.diff
diff --git a/sys/kern/subr_disklabel32.c b/sys/kern/subr_disklabel32.c --- a/sys/kern/subr_disklabel32.c +++ b/sys/kern/subr_disklabel32.c @@ -332,6 +332,16 @@ if (lp->d_partitions[RAW_PART].p_offset != 0) return (EXDEV); /* not quite right */ + /* + * Validate d_secsize before allocating the pbuf and using it as a + * transfer length. Without this a crafted label with an oversized + * d_secsize drives bp->b_bcount > bp->b_bufsize (the KKASSERT below + * is a no-op on production kernels without INVARIANTS). Check before + * getpbuf_mem() so we don't leak a pbuf on the error path. + */ + if (lp->d_secsize < DEV_BSIZE || lp->d_secsize > MAXPHYS) + return (EINVAL); + bp = getpbuf_mem(NULL); KKASSERT((int)lp->d_secsize <= bp->b_bufsize); bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * lp->d_secsize; |