DragonFlyBSD Kernel Audit
DF-1542 / 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
@@ -60,10 +60,12 @@
 	unsigned last_jump;
 	unsigned long last_jump_jiffies;
 	bool abort;
+	int recursion_depth;
 } atom_exec_context;
 
 int amdgpu_atom_debug = 0;
-static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
+static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index,
+							    uint32_t * params, int recursion_depth);
 
 static uint32_t atom_arg_mask[8] =
     { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
@@ -617,7 +619,8 @@
 	else
 		SDEBUG("   table: %d\n", idx);
 	if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-		r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+		r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift,
+							    ctx->recursion_depth + 1);
 	if (r) {
 		ctx->abort = true;
 	}
@@ -1195,7 +1198,8 @@
 	atom_op_div32, ATOM_ARG_WS},
 };
 
-static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
+static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index,
+							    uint32_t * params, int recursion_depth)
 {
 	int base = CU16(ctx->cmd_table + 4 + 2 * index);
 	int len, ws, ps, ptr;
@@ -1203,6 +1207,9 @@
 	atom_exec_context ectx;
 	int ret = 0;
 
+	if (recursion_depth > 20)
+		return -EINVAL;
+
 	if (!base)
 		return -EINVAL;
 
@@ -1272,7 +1279,7 @@
 	/* reset divmul */
 	ctx->divmul[0] = 0;
 	ctx->divmul[1] = 0;
-	r = amdgpu_atom_execute_table_locked(ctx, index, params);
+	r = amdgpu_atom_execute_table_locked(ctx, index, params, 0);
 	mutex_unlock(&ctx->mutex);
 	return r;
 }