All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access
@ 2026-07-20 13:48 Thomas Huth
  2026-07-20 13:53 ` Peter Maydell
  0 siblings, 1 reply; 2+ messages in thread
From: Thomas Huth @ 2026-07-20 13:48 UTC (permalink / raw)
  To: qemu-devel, Peter Maydell
  Cc: kraxel, Philippe Mathieu-Daudé, qemu-stable,
	Daniel P . Berrange

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



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access
  2026-07-20 13:48 [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access Thomas Huth
@ 2026-07-20 13:53 ` Peter Maydell
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Maydell @ 2026-07-20 13:53 UTC (permalink / raw)
  To: Thomas Huth
  Cc: qemu-devel, kraxel, Philippe Mathieu-Daudé, qemu-stable,
	Daniel P . Berrange

On Mon, 20 Jul 2026 at 14:50, Thomas Huth <thuth@redhat.com> wrote:
>
> 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()

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-20 13:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 13:48 [PATCH v2] hw/usb/dev-uas: Fix guest-triggerable heap OOB access Thomas Huth
2026-07-20 13:53 ` Peter Maydell

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.