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 @@ -2795,6 +2795,25 @@ if (testing || bootverbose) ata_raid_lsiv2_print_meta(meta); + /* + * meta->raid_number and meta->disk_number are u_int8_t (0..255) read + * straight off the disk. They index raidp[..] (BSS), + * meta->configs[raid_entry=] (array of 30) and + * raid->disks[] (array of MAX_DISKS=16). Reject any value + * that would index out of bounds: otherwise a crafted disk with + * raid_number>=16 writes a kmalloc'd heap pointer into BSS past + * ata_raid_arrays[] (and reads configs[] OOB), and disk_number>=16 + * overflows raid->disks[] into the trailing ar_softc fields / adjacent + * heap. (DF-1172) + */ + if (meta->raid_number >= MAX_ARRAYS || meta->disk_number >= MAX_DISKS) { + if (testing || bootverbose) + device_printf(parent, + "LSI (v2) metadata raid_number %u / disk_number %u out of range\n", + meta->raid_number, meta->disk_number); + goto lsiv2_out; + } + /* now convert LSI (v2) config meta into our generic form */ for (array = 0; array < MAX_ARRAYS; array++) { int raid_entry, conf_entry;