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