⬢ DragonFlyBSD Kernel Audit
DF-3597 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/amdgpu/gfx_v8_0.c
+++ b/sys/dev/drm/amd/amdgpu/gfx_v8_0.c
@@ -3988,9 +3988,10 @@
 
 		if (new_entry) {
 			new_entry = false;
+			if (WARN_ON(*offset_count >= max_offset))
+				return;
 			ind_start_offsets[*offset_count] = ind_offset;
 			*offset_count = *offset_count + 1;
-			BUG_ON(*offset_count >= max_offset);
 		}
 
 		if (register_list_format[ind_offset] == 0xFFFFFFFF) {
@@ -3998,6 +3999,17 @@
 			continue;
 		}
 
+		/*
+		 * Truncated entry: its 0xFFFFFFFF terminator lies beyond the
+		 * end of the list; touching [ind_offset + 2] would read and
+		 * write past the kmalloc'd register_list_format buffer.
+		 */
+		if (ind_offset + 2 >= list_size) {
+			DRM_ERROR("gfx8: truncated RLC indirect register list "
+				  "entry at offset %d\n", ind_offset);
+			return;
+		}
+
 		ind_offset += 2;
 
 		/* look for the matching indice */
@@ -4010,11 +4022,12 @@
 		}
 
 		if (indices >= *indices_count) {
+			if (WARN_ON(*indices_count >= max_indices))
+				return;
 			unique_indices[*indices_count] =
 				register_list_format[ind_offset];
 			indices = *indices_count;
 			*indices_count = *indices_count + 1;
-			BUG_ON(*indices_count >= max_indices);
 		}
 
 		register_list_format[ind_offset] = indices;