DragonFlyBSD Kernel Audit
DF-2068 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/amd/display/dc/basics/vector.c b/sys/dev/drm/amd/display/dc/basics/vector.c
--- a/sys/dev/drm/amd/display/dc/basics/vector.c
+++ b/sys/dev/drm/amd/display/dc/basics/vector.c
@@ -40,6 +40,15 @@
 		return false;
 	}
 
+	/* Defense-in-depth: capacity * struct_size would overflow uint32_t
+	 * in the kcalloc() macro (linux/slab.h:44), yielding a tiny buffer
+	 * while vector->capacity retains the attacker-supplied count and
+	 * later dal_vector_deposit()/append() writes out of bounds. */
+	if (capacity > 0xffffffffu / struct_size) {
+		BREAK_TO_DEBUGGER();
+		return false;
+	}
+
 	vector->container = kcalloc(capacity, struct_size, GFP_KERNEL);
 	if (vector->container == NULL)
 		return false;
@@ -68,6 +77,12 @@
 		return false;
 	}
 
+	/* Defense-in-depth: same overflow guard as dal_vector_construct(). */
+	if (count > 0xffffffffu / struct_size) {
+		BREAK_TO_DEBUGGER();
+		return false;
+	}
+
 	vector->container = kcalloc(count, struct_size, GFP_KERNEL);
 
 	if (vector->container == NULL)
@@ -290,6 +305,12 @@
 	if (capacity <= vector->capacity)
 		return true;
 
+	/* Defense-in-depth: same overflow guard as dal_vector_construct().
+	 * krealloc() takes the byte count directly and would happily
+	 * allocate a wrapped (tiny) buffer if this multiply overflows. */
+	if (capacity > 0xffffffffu / vector->struct_size)
+		return false;
+
 	new_container = krealloc(vector->container,
 				 capacity * vector->struct_size, M_DRM, GFP_KERNEL);