Re: [PATCH v3] drm/amdgpu: prevent parameter-space underflow in nested ATOM table calls
From: Alex Deucher
Date: Thu Sep 24 2026 - 17:54:50 EST
Applied. Thanks!
On Wed, Sep 23, 2026 at 11:44 AM Aldo Ariel Panzardo <qwe.aldo@xxxxxxxxx> wrote:
>
> 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. Abort the interpreter when
> the request exceeds the available space so the parent table does not
> continue with stale or uninitialized data.
>
> Fixes: d38ceaf99ed0 ("drm/amdgpu: add coordinate ATOMBIOS table support")
> Cc: stable@xxxxxxxxxxxxxxx
> Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
> Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@xxxxxxxxx>
> ---
> v3: abort the interpreter (ctx->abort = true + return) when the
> child table's parameter space exceeds the parent's remaining
> capacity, instead of silently skipping execution (found by
> Sashiko AI review on v2).
> 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 | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index e0e585f..af283cd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -646,8 +646,13 @@ 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)) {
> + if (ctx->ps_shift * 4 > ctx->ps_size) {
> + ctx->abort = true;
> + return;
> + }
> + 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