From: Thomas Huth <thuth@redhat.com>
To: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>
Cc: kraxel@redhat.com,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
qemu-stable@nongnu.org,
"Daniel P . Berrange" <berrange@redhat.com>
Subject: [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access
Date: Mon, 20 Jul 2026 15:48:09 +0200 [thread overview]
Message-ID: <20260720134809.573757-1-thuth@redhat.com> (raw)
From: Thomas Huth <thuth@redhat.com>
The stream ID is under control of the guest, and some spots in the
code currently use it for indexing into the status3[] array without
checking it for being in range first, so the code accesses the heap
beyond the limit of the status3 array.
Since our status delivery code depends on having a valid stream ID,
we must not try to generate a fake sense code in this situation.
Simply log a guest error and return early in usb_uas_command().
And to make sure that we really cannot access the status3[] array
beyond its limit anymore, add some assert() statements in the
affected functions, too.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3612
Reported-by: Reported-by: huntr bubble
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3986
Reported-by: Tristan Madani <tristan@talencesecurity.com>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
v2: Refuse illegal tags already in usb_uas_command()
hw/usb/dev-uas.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 8576dfec96f..963c0433b38 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -362,6 +362,7 @@ static void usb_uas_send_status_bh(void *opaque)
while ((st = QTAILQ_FIRST(&uas->results)) != NULL) {
if (uas_using_streams(uas)) {
+ assert(st->stream <= UAS_MAX_STREAMS);
p = uas->status3[st->stream];
uas->status3[st->stream] = NULL;
} else {
@@ -383,8 +384,14 @@ static void usb_uas_send_status_bh(void *opaque)
static void usb_uas_queue_status(UASDevice *uas, UASStatus *st, int length)
{
- USBPacket *p = uas_using_streams(uas) ?
- uas->status3[st->stream] : uas->status2;
+ USBPacket *p;
+
+ if (uas_using_streams(uas)) {
+ assert(st->stream <= UAS_MAX_STREAMS);
+ p = uas->status3[st->stream];
+ } else {
+ p = uas->status2;
+ }
st->length += length;
QTAILQ_INSERT_TAIL(&uas->results, st, next);
@@ -700,14 +707,22 @@ static void usb_uas_command(UASDevice *uas, uas_iu *iu)
uint16_t tag = be16_to_cpu(iu->hdr.tag);
size_t cdb_len = sizeof(iu->command.cdb) + iu->command.add_cdb_length;
+ if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
+ /*
+ * Our status delivery only works with valid tags, so in case the
+ * stream ID is out of bounds, we have to return immediately here
+ * without sending a fake sense_code_INVALID_TAG to the guest.
+ */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "invalid tag 0x%x for USB UAS command\n", tag);
+ return;
+ }
+
if (iu->command.add_cdb_length > 0) {
qemu_log_mask(LOG_UNIMP, "additional adb length not yet supported\n");
goto unsupported_len;
}
- if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
- goto invalid_tag;
- }
req = usb_uas_find_request(uas, tag);
if (req) {
goto overlapped_tag;
@@ -744,10 +759,6 @@ unsupported_len:
usb_uas_queue_fake_sense(uas, tag, sense_code_INVALID_PARAM_VALUE);
return;
-invalid_tag:
- usb_uas_queue_fake_sense(uas, tag, sense_code_INVALID_TAG);
- return;
-
overlapped_tag:
usb_uas_queue_fake_sense(uas, tag, sense_code_OVERLAPPED_COMMANDS);
return;
--
2.55.0
next reply other threads:[~2026-07-20 13:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 13:48 Thomas Huth [this message]
2026-07-20 13:53 ` [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access Peter Maydell
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=20260720134809.573757-1-thuth@redhat.com \
--to=thuth@redhat.com \
--cc=berrange@redhat.com \
--cc=kraxel@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.