diff --git a/sys/dev/disk/advansys/advansys.c b/sys/dev/disk/advansys/advansys.c --- a/sys/dev/disk/advansys/advansys.c +++ b/sys/dev/disk/advansys/advansys.c @@ -438,6 +438,20 @@ int extended; ccg = &ccb->ccg; + /* + * Guard against device-controlled block_size that would make + * the inner constant a multiple of, or larger than, block_size + * (yielding a zero quotient and a divide-by-zero on the outer + * division). The XPT core already rejects block_size==0, but a + * block_size > 1 MiB still drives the inner term to 0 here. + */ + if (ccg->block_size == 0 + || ccg->block_size > (1024L * 1024L) + || (1024L * 1024L) % ccg->block_size != 0) { + ccg->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(ccb); + break; + } size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size); extended = (adv->control & ADV_CNTL_BIOS_GT_1GB) != 0;