DragonFlyBSD Kernel Audit
DF-1537 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/radeon/atom.c b/sys/dev/drm/radeon/atom.c
--- a/sys/dev/drm/radeon/atom.c
+++ b/sys/dev/drm/radeon/atom.c
@@ -55,6 +55,7 @@
 typedef struct {
 	struct atom_context *ctx;
 	uint32_t *ps, *ws;
+	uint8_t ws_size;	/* DF-1537: track allocated WS slots */
 	int ps_shift;
 	uint16_t start;
 	unsigned last_jump;
@@ -233,6 +234,11 @@
 	case ATOM_ARG_WS:
 		idx = U8(*ptr);
 		(*ptr)++;
+		/* DF-1537: validate idx against the WS allocation. */
+		if (idx >= ctx->ws_size) {
+			DRM_ERROR("ATOM: WS index %u OOB (ws=%u)\n", idx, ctx->ws_size);
+			return 0;
+		}
 		if (print)
 			ATOM_DEBUG_PRINT("WS[0x%02X]", idx);
 		switch (idx) {
@@ -507,6 +513,11 @@
 	case ATOM_ARG_WS:
 		idx = U8(*ptr);
 		(*ptr)++;
+		/* DF-1537: validate idx against the WS allocation. */
+		if (idx >= ctx->ws_size) {
+			DRM_ERROR("ATOM: WS write index %u OOB (ws=%u)\n", idx, ctx->ws_size);
+			return;
+		}
 		ATOM_DEBUG_PRINT("WS[0x%02X]", idx);
 		switch (idx) {
 		case ATOM_WS_QUOTIENT:
@@ -1184,9 +1195,12 @@
 	ectx.ps = params;
 	ectx.abort = false;
 	ectx.last_jump = 0;
-	if (ws)
+	ectx.ws_size = ws;
+	if (ws) {
 		ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
-	else
+		if (!ectx.ws)
+			ectx.ws_size = 0;
+	} else
 		ectx.ws = NULL;
 
 	debug_depth++;