.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
The GSP sequencer RPC contains a variable command stream. The handler
currently walks commands using the stream header length without first
proving that the stream, each command payload, or a register-save slot
fits in the received RPC and its fixed save area.
Validate the stream and each command against the RPC payload before
walking it, and reject register-save indexes beyond the fixed save
array.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index f544afa12b6b..00417bbccc12 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -1010,15 +1010,30 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc)
struct nvkm_subdev *subdev = &gsp->subdev;
struct nvkm_device *device = subdev->device;
rpc_run_cpu_sequencer_v17_00 *seq = repv;
- int ptr = 0, ret;
+ u32 ptr = 0, payload;
+ int ret;
+
+ if (repc < offsetof(rpc_run_cpu_sequencer_v17_00, commandBuffer) ||
+ seq->cmdIndex >
+ (repc - offsetof(rpc_run_cpu_sequencer_v17_00, commandBuffer)) /
+ sizeof(seq->commandBuffer[0])) {
+ nvkm_error(subdev, "invalid sequencer command buffer size\n");
+ return -EINVAL;
+ }
nvkm_debug(subdev, "seq: %08x %08x\n", seq->bufferSizeDWord, seq->cmdIndex);
while (ptr < seq->cmdIndex) {
GSP_SEQUENCER_BUFFER_CMD *cmd = (void *)&seq->commandBuffer[ptr];
+ payload = GSP_SEQUENCER_PAYLOAD_SIZE_DWORDS(cmd->opCode);
+ if (seq->cmdIndex - ptr < payload + 1) {
+ nvkm_error(subdev, "truncated sequencer command\n");
+ return -EINVAL;
+ }
+
ptr += 1;
- ptr += GSP_SEQUENCER_PAYLOAD_SIZE_DWORDS(cmd->opCode);
+ ptr += payload;
switch (cmd->opCode) {
case GSP_SEQ_BUF_OPCODE_REG_WRITE: {
@@ -1064,6 +1079,9 @@ r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc)
u32 addr = cmd->payload.regStore.addr;
u32 slot = cmd->payload.regStore.index;
+ if (slot >= ARRAY_SIZE(seq->regSaveArea))
+ return -EINVAL;
+
seq->regSaveArea[slot] = nvkm_rd32(device, addr);
nvkm_trace(subdev, "seq save %08x -> %d: %08x\n", addr, slot,
seq->regSaveArea[slot]);
--
2.43.0
On Wed, 2026-07-22 at 12:21 +0800, Pengpeng Hou wrote: > The GSP sequencer RPC contains a variable command stream. The handler > currently walks commands using the stream header length without first > proving that the stream, each command payload, or a register-save slot > fits in the received RPC and its fixed save area. > > Validate the stream and each command against the RPC payload before > walking it, and reject register-save indexes beyond the fixed save > array. > > Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Does this fix an known bug, or is it just something that an AI told you could be a problem?
© 2016 - 2026 Red Hat, Inc.