atom_op_calltable() invokes a child ATOM table, forwarding the parent's parameter space with an offset: amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift, ctx->ps_size - ctx->ps_shift); ctx->ps_shift is in dwords (set to ps / 4 in amdgpu_atom_execute_table_locked()), while ctx->ps_size is the remaining capacity in bytes. The subtraction therefore mixes units: a child table requesting 60 bytes (ps_shift = 15 dwords) with only 16 bytes remaining would compute 16 - 15 = 1 instead of the correct 16 - 60 = underflow. Convert ps_shift to bytes (ps_shift * 4) in both the guard and the subtraction so the units are consistent and oversized requests are correctly rejected. Fixes: d38ceaf99ed0 ("drm/amdgpu: add coordinate ATOMBIOS table support") Cc: stable@vger.kernel.org Reported-by: Sashiko Signed-off-by: Aldo Ariel Panzardo --- v2: convert ps_shift to bytes (ps_shift * 4) before comparing with ps_size, fixing the unit mismatch found by Sashiko AI review. drivers/gpu/drm/amd/amdgpu/atom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index e0e585f..0940bfb 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -646,8 +646,8 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]); 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, ctx->ps_size - ctx->ps_shift); + if (U16(ctx->ctx->cmd_table + 4 + 2 * idx) && ctx->ps_shift * 4 <= ctx->ps_size) + r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift, ctx->ps_size - ctx->ps_shift * 4); if (r) { ctx->abort = true; } -- 2.43.0