DF-3165 / fix.diff
--- a/sys/vfs/udf/udf_vfsops.c +++ b/sys/vfs/udf/udf_vfsops.c @@ -371,6 +371,16 @@ */ sector = udfmp->root_icb.loc.lb_num + udfmp->part_start; size = udfmp->root_icb.len; + /* + * The root file entry is at most one logical block; larger (or + * wrapped) on-disk lengths would panic getblk ("size > MAXBSIZE") + * or hand udf_readlblks() a negative int size. + */ + if (size == 0 || size > MAXBSIZE) { + kprintf("Invalid root file entry length %u\n", size); + error = EINVAL; + goto bail; + } if ((error = udf_readlblks(udfmp, sector, size, &bp)) != 0) { kprintf("Cannot read sector %d\n", sector); goto bail; @@ -659,6 +669,16 @@ } pms = &pmap->pms; + /* + * st_size is an on-disk u32: unchecked it flows into + * kmalloc() and udf_readlblks() -> bread() -> getblk(), + * which panics once the rounded size exceeds MAXBSIZE. + */ + if (pms->st_size == 0 || pms->st_size > MAXBSIZE) { + kprintf("Invalid sparing table size %u\n", + pms->st_size); + return (1); + } udfmp->s_table = kmalloc(pms->st_size, M_UDFMOUNT, M_WAITOK | M_ZERO); |