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,6 +60,7 @@ unsigned last_jump; unsigned long last_jump_jiffies; bool abort; + int ps_size; /* declared param size, bytes */ } atom_exec_context; int amdgpu_atom_debug = 0; @@ -213,6 +214,12 @@ case ATOM_ARG_PS: idx = U8(*ptr); (*ptr)++; + if (idx + 4 > ctx->ps_size) { + DRM_ERROR("ATOM: ps read beyond params: %d vs. %d\n", + idx, ctx->ps_size); + val = 0; + break; + } /* get_unaligned_le32 avoids unaligned accesses from atombios * tables, noticed on a DEC Alpha. */ val = get_unaligned_le32((u32 *)&ctx->ps[idx]); @@ -488,6 +495,11 @@ idx = U8(*ptr); (*ptr)++; DEBUG("PS[0x%02X]", idx); + if (idx + 4 > ctx->ps_size) { + DRM_ERROR("ATOM: ps write beyond params: %d vs. %d\n", + idx, ctx->ps_size); + break; + } ctx->ps[idx] = cpu_to_le32(val); break; case ATOM_ARG_WS: @@ -1215,6 +1227,7 @@ ectx.ctx = ctx; ectx.ps_shift = ps / 4; + ectx.ps_size = ps; ectx.start = base; ectx.ps = params; ectx.abort = false;