DF-0883 / fix.diff
diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c --- a/sys/vfs/udf/udf_vfsops.c +++ b/sys/vfs/udf/udf_vfsops.c @@ -304,6 +304,21 @@ lvd = (struct logvol_desc *)bp->b_data; if (!udf_checktag(&lvd->tag, TAGID_LOGVOL)) { udfmp->bsize = lvd->lb_size; + /* + * Validate the logical block size: it must be a + * non-zero power of two in [DEV_BSIZE, MAXBSIZE]. + * A zero or non-power-of-2 value drives a divide- + * by-zero (udf_find_partmaps) and corrupts all + * block-masking arithmetic. + */ + if (lvd->lb_size < DEV_BSIZE || + lvd->lb_size > MAXBSIZE || + (lvd->lb_size & (lvd->lb_size - 1)) != 0) { + kprintf("udf: invalid logical block size %u\n", + lvd->lb_size); + error = EINVAL; + goto bail; + } udfmp->bmask = udfmp->bsize - 1; udfmp->bshift = ffs(udfmp->bsize) - 1; fsd_part = lvd->_lvd_use.fsd_loc.loc.part_num; |