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 @@ -2148,8 +2148,12 @@ goto intel_out; } + /* DF-1175: config_size is a u32 from disk; cap the checksum loop to the + * actual 1536-byte kmalloc buffer (ata-raid.c:2132) to prevent an + * OOB read past the allocation. */ for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; - count < (meta->config_size / sizeof(u_int32_t)); count++) { + count < (meta->config_size / sizeof(u_int32_t)) && + count < (1536 / sizeof(u_int32_t)); count++) { checksum += *ptr++; } checksum -= meta->checksum; @@ -2403,8 +2407,12 @@ map->disk_idx[disk] = disk; meta->config_size = (char *)&map->disk_idx[disk] - (char *)meta; + /* DF-1175: config_size is a u32 from disk; cap the checksum loop to the + * actual 1536-byte kmalloc buffer (ata-raid.c:2132) to prevent an + * OOB read past the allocation. */ for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; - count < (meta->config_size / sizeof(u_int32_t)); count++) { + count < (meta->config_size / sizeof(u_int32_t)) && + count < (1536 / sizeof(u_int32_t)); count++) { checksum += *ptr++; } meta->checksum = checksum; @@ -3043,8 +3051,13 @@ } /* check if the checksum is OK */ - for (checksum = 0, ptr = (u_int32_t*)meta, count = 0; - count < meta->config_size; count++) + /* DF-1175: config_size is a u32 from disk; cap the checksum loop to the + * actual kmalloc'd struct size to prevent an OOB read past the + * allocation. */ + for (checksum = 0, ptr = (u_int32_t*)meta, count = 0; + count < meta->config_size && + count < (sizeof(struct nvidia_raid_conf) / sizeof(u_int32_t)); + count++) checksum += *ptr++; if (checksum) { if (testing || bootverbose)