From: Lizhi Hou <lizhi.hou@amd.com>
To: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>,
<jeff.hugo@oss.qualcomm.com>, <carl.vanderlip@oss.qualcomm.com>,
<troy.hanson@oss.qualcomm.com>,
<zachary.mckevitt@oss.qualcomm.com>
Cc: <ogabbay@kernel.org>, <karol.wachowski@linux.intel.com>,
<linux-arm-msm@vger.kernel.org>,
<dri-devel@lists.freedesktop.org>, Ruikai Peng <ruikai@pwno.io>
Subject: Re: [PATCH] accel/qaic: Address potential out-of-bounds read in resp_worker()
Date: Wed, 15 Apr 2026 09:52:21 -0700 [thread overview]
Message-ID: <78a955ce-8990-8594-1ebc-e7d4da14dce0@amd.com> (raw)
In-Reply-To: <20260414173249.3672053-1-youssef.abdulrahman@oss.qualcomm.com>
On 4/14/26 10:32, Youssef Samir wrote:
> Although 'commit 2feec5ae5df7 ("accel/qaic: Handle DBC deactivation if the
> owner went away")' fixes the scenario it was intended for by walking the
> message and only decoding QAIC_TRANS_DEACTIVATE_FROM_DEV, if present, it
> skipped over the bounds checking code that is included in decode_message().
> This could lead to issues such as reading past the slab allocation's end,
> infinite loops or kernel panics. For those issues to happen, a malformed
> wire message is needed to be sent from the device.
>
> Instead of duplicating the bounds checking code already present in
> decode_message(), use the function inside resp_worker().
>
> Reported-by: Ruikai Peng <ruikai@pwno.io>
> Fixes: 2feec5ae5df7 ("accel/qaic: Handle DBC deactivation if the owner went away")
> Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
> ---
> drivers/accel/qaic/qaic_control.c | 48 ++++++++++++++++---------------
> 1 file changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c
> index b21e6b5b3a10..818a77adde2a 100644
> --- a/drivers/accel/qaic/qaic_control.c
> +++ b/drivers/accel/qaic/qaic_control.c
> @@ -1075,11 +1075,13 @@ static int decode_status(struct qaic_device *qdev, void *trans, struct manage_ms
>
> static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
> struct wire_msg *msg, struct ioctl_resources *resources,
> - struct qaic_user *usr)
> + struct qaic_user *usr, bool orphaned_deactivate)
> {
> + u32 msg_hdr_count = le32_to_cpu(msg->hdr.count);
> u32 msg_hdr_len = le32_to_cpu(msg->hdr.len);
> struct wire_trans_hdr *trans_hdr;
> u32 msg_len = 0;
> + int trans_type;
> int ret;
> int i;
>
> @@ -1089,13 +1091,15 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
> return -EINVAL;
> }
>
> - user_msg->len = 0;
> - user_msg->count = le32_to_cpu(msg->hdr.count);
> + if (user_msg) {
> + user_msg->len = 0;
> + user_msg->count = msg_hdr_count;
> + }
>
> trace_qaic_manage_dbg(qdev->qddev, "Number of transaction to decode is %llu.",
> - user_msg->count);
> + msg_hdr_count);
>
> - for (i = 0; i < user_msg->count; ++i) {
> + for (i = 0; i < msg_hdr_count; ++i) {
> u32 hdr_len;
>
> if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
> @@ -1110,7 +1114,20 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
> trace_qaic_manage_dbg(qdev->qddev, "Decoding transaction %llu.",
> le32_to_cpu(trans_hdr->type));
>
> - switch (le32_to_cpu(trans_hdr->type)) {
> + trans_type = le32_to_cpu(trans_hdr->type);
> + /*
> + * orphaned_deactivate is the case where a deactivate response
> + * is received from the device after the user owning the DBC,
> + * and the message requesting deactivation, has gone away.
> + * In this case, only process QAIC_TRANS_DEACTIVATE_FROM_DEV
> + * transaction and skip the others.
> + */
> + if (orphaned_deactivate && trans_type != QAIC_TRANS_DEACTIVATE_FROM_DEV) {
> + msg_len += hdr_len;
> + continue;
> + }
> +
> + switch (trans_type) {
> case QAIC_TRANS_PASSTHROUGH_FROM_DEV:
> ret = decode_passthrough(qdev, trans_hdr, user_msg, &msg_len);
> break;
> @@ -1430,7 +1447,7 @@ static int qaic_manage(struct qaic_device *qdev, struct qaic_user *usr, struct m
> goto dma_cont_failed;
> }
>
> - ret = decode_message(qdev, user_msg, rsp, &resources, usr);
> + ret = decode_message(qdev, user_msg, rsp, &resources, usr, false);
>
> dma_cont_failed:
> free_dbc_buf(qdev, &resources);
> @@ -1607,22 +1624,7 @@ static void resp_worker(struct work_struct *work)
> * response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
> * otherwise, the user can issue an soc_reset to the device.
> */
> - u32 msg_count = le32_to_cpu(msg->hdr.count);
> - u32 msg_len = le32_to_cpu(msg->hdr.len);
> - u32 len = 0;
> - int j;
> -
> - for (j = 0; j < msg_count && len < msg_len; ++j) {
> - struct wire_trans_hdr *trans_hdr;
> -
> - trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
> - if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
> - if (decode_deactivate(qdev, trans_hdr, &len, NULL))
> - len += le32_to_cpu(trans_hdr->len);
> - } else {
> - len += le32_to_cpu(trans_hdr->len);
> - }
> - }
> + decode_message(qdev, NULL, msg, NULL, NULL, true);
This seems changing the previous behavior. The original code will
continue the loop when decode_deactivate() returns error. And
decode_message() will error immediately when decode_deactivate() returns
error.
Lizhi
> /* request must have timed out, drop packet */
> trace_qaic_manage(NULL, "Packet dropped.", -ETIME);
> kfree(msg);
next prev parent reply other threads:[~2026-04-15 16:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-14 17:32 [PATCH] accel/qaic: Address potential out-of-bounds read in resp_worker() Youssef Samir
2026-04-15 16:52 ` Lizhi Hou [this message]
2026-05-12 16:29 ` Jeff Hugo
2026-05-13 16:51 ` Lizhi Hou
2026-05-12 16:30 ` Jeff Hugo
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=78a955ce-8990-8594-1ebc-e7d4da14dce0@amd.com \
--to=lizhi.hou@amd.com \
--cc=carl.vanderlip@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jeff.hugo@oss.qualcomm.com \
--cc=karol.wachowski@linux.intel.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=ogabbay@kernel.org \
--cc=ruikai@pwno.io \
--cc=troy.hanson@oss.qualcomm.com \
--cc=youssef.abdulrahman@oss.qualcomm.com \
--cc=zachary.mckevitt@oss.qualcomm.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