DragonFlyBSD Kernel Audit
DF-1175 / fix.diff
← back to finding ↓ download raw
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)