mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Eva Crystal <0xiviel@gmail.com>
To: Min Ma <mamin506@gmail.com>, Lizhi Hou <lizhi.hou@amd.com>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	Eva Crystal <0xiviel@gmail.com>
Subject: [PATCH 1/4] accel/amdxdna: validate the command payload regardless of the size argument
Date: Sat, 12 Sep 2026 20:10:09 +1200	[thread overview]
Message-ID: <20260912081012.2274075-2-0xiviel@gmail.com> (raw)
In-Reply-To: <20260912081012.2274075-1-0xiviel@gmail.com>

amdxdna_cmd_get_payload() performs its bounds check - that the command
header's count field does not describe a payload larger than the command
BO - only when the caller asks for a size:

	if (size) {
		count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header);
		if (unlikely(count <= num_masks || ...  > abo->mem.size)) {
			*size = 0;
			return NULL;
		}
		*size = (count - num_masks) * sizeof(u32);
	}
	return &cmd->data[num_masks];

A caller passing NULL therefore receives a pointer into the command BO
that has never been checked against the BO's size, and no way to learn
that the header was malformed. The count field is written by user space:
the command BO is mapped into the submitting process and can be rewritten
after submission.

The one such caller today is amdxdna_cmd_set_error(), which reads
cc->command_count, writes cc->error_index and reads cc->data[0] - offsets
4, 12 and 28 into the payload. That is safe as things stand, because a
command BO is created through drm_gem_shmem_create() and its size is
always PAGE_ALIGN()ed, so any BO that can be vmap()ed is at least
PAGE_SIZE; a zero-sized BO fails vmap() and is rejected by the !cmd test
one line earlier. This is not a fix for a reachable bug.

It is, however, a validation step that a caller can silently opt out of,
guarding a structure whose contents user space controls, and the safety
of the only NULL caller rests on a page-alignment invariant established
three call levels away. Make the check unconditional and report the
failure to every caller, so that the guarantee does not depend on which
arguments the caller happened to pass.

amdxdna_cmd_set_error() is updated to handle the NULL it can now receive.

Signed-off-by: Eva Crystal <0xiviel@gmail.com>
---
 drivers/accel/amdxdna/amdxdna_ctx.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c
index 5315466..163b5fc 100644
--- a/drivers/accel/amdxdna/amdxdna_ctx.c
+++ b/drivers/accel/amdxdna/amdxdna_ctx.c
@@ -106,17 +106,19 @@ void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size)
 	else
 		num_masks = 1 + FIELD_GET(AMDXDNA_CMD_EXTRA_CU_MASK, cmd->header);
 
-	if (size) {
-		count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header);
-		if (unlikely(count <= num_masks ||
-			     count * sizeof(u32) +
-			     offsetof(struct amdxdna_cmd, data[0]) >
-			     abo->mem.size)) {
+	count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header);
+	if (unlikely(count <= num_masks ||
+		     count * sizeof(u32) +
+		     offsetof(struct amdxdna_cmd, data[0]) >
+		     abo->mem.size)) {
+		if (size)
 			*size = 0;
-			return NULL;
-		}
-		*size = (count - num_masks) * sizeof(u32);
+		return NULL;
 	}
+
+	if (size)
+		*size = (count - num_masks) * sizeof(u32);
+
 	return &cmd->data[num_masks];
 }
 
@@ -159,6 +161,9 @@ int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
 
 	if (amdxdna_cmd_get_op(abo) == ERT_CMD_CHAIN) {
 		cc = amdxdna_cmd_get_payload(abo, NULL);
+		if (!cc)
+			return -EINVAL;
+
 		cc->error_index = (cmd_idx < cc->command_count) ? cmd_idx : 0;
 		abo = amdxdna_gem_get_obj(client, cc->data[0], AMDXDNA_BO_SHARE);
 		if (!abo)
-- 
2.53.0


  reply	other threads:[~2026-09-12  8:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-12  8:10 [PATCH 0/4] accel/amdxdna: harden command BO payload validation Eva Crystal
2026-09-12  8:10 ` Eva Crystal [this message]
2026-09-12  8:10 ` [PATCH 2/4] accel/amdxdna: bound the command error payload length Eva Crystal
2026-09-12  8:10 ` [PATCH 3/4] accel/amdxdna: release the chained command BO when vmap fails Eva Crystal
2026-09-12  8:10 ` [PATCH 4/4] accel/amdxdna: check the command payload before using it in the exec requests Eva Crystal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260912081012.2274075-2-0xiviel@gmail.com \
    --to=0xiviel@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizhi.hou@amd.com \
    --cc=mamin506@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®