diff --git a/sys/dev/disk/nata/ata-raid.c b/sys/dev/disk/nata/ata-raid.c --- a/sys/dev/disk/nata/ata-raid.c +++ b/sys/dev/disk/nata/ata-raid.c @@ -152,8 +152,17 @@ ata_raid_config_changed(rdp, writeback); /* sanitize arrays total_size % (width * interleave) == 0 */ + /* DF-1174: crafted metadata can set interleave or width to 0, which + * would make rounddown() divide by zero (#DE panic). Reject the array + * before the division. */ if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 || rdp->type == AR_T_RAID5) { + if (rdp->interleave == 0 || rdp->width == 0) { + kprintf("ar%d: invalid RAID geometry (interleave=%u width=%u), " + "refusing to attach\n", rdp->lun, + rdp->interleave, rdp->width); + return; + } rdp->total_sectors = rounddown(rdp->total_sectors, rdp->interleave * rdp->width); ksprintf(buffer, " (stripe %d KB)", @@ -1025,7 +1034,10 @@ } status->interleave = rdp->interleave; status->status = rdp->status; - status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; + /* DF-1174: total_sectors may be 0 from crafted metadata; guard the + * division to avoid a #DE panic. */ + status->progress = (rdp->total_sectors != 0) ? + (100 * rdp->rebuild_lba / rdp->total_sectors) : 0; return 0; }