[PATCH] drm/nouveau/gsp: validate sequencer command span

Pengpeng Hou posted 1 patch 2 days, 18 hours ago
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
[PATCH] drm/nouveau/gsp: validate sequencer command span
Posted by Pengpeng Hou 2 days, 18 hours ago
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
Re: [PATCH] drm/nouveau/gsp: validate sequencer command span
Posted by Timur Tabi 2 days, 9 hours ago
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?