drivers/gpu/drm/amd/amdgpu/atom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
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 <sashiko-bot@kernel.org>
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
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
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@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
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
© 2016 - 2026 Red Hat, Inc.