Commit 12d8ee9d53 for qemu.org

commit 12d8ee9d5358cd8cdd2c2193081b4d7fea4b6098
Author: Feifan Qian <bea1e@proton.me>
Date:   Fri Apr 24 13:20:00 2026 +0200

    hw/usb/xhci: clamp interval exponent to avoid UB shift in xhci_init_epctx()

    The xHCI endpoint context dword 0 bits 23:16 ("Interval") are written
    by the guest and passed directly as the shift amount in:

        epctx->interval = 1 << ((ctx[0] >> 16) & 0xff);

    The shift amount can be 0-255.  Shifting a 32-bit `int` left by >= 32
    is undefined behaviour under C11 §6.5.7p4.  With UBSan
    (halt_on_error=1) this causes QEMU to abort; with aggressive compiler
    optimisations that assume UB is unreachable the result is
    unpredictable.

    Clamp the exponent to [0, 18] with MIN() before the shift, and use
    `1u` (unsigned) to avoid shifting a signed integer.  The xHCI
    specification defines a maximum meaningful Interval value of 18 for
    most endpoint types; thus clamping to 18 is a safe fix that
    preserves the full unsigned 32-bit range for any compliant value.

    Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3703
    Reported-by: Feifan Qian <bea1e@proton.me>
    Signed-off-by: Feifan Qian <bea1e@proton.me>
    [thuth: Clamp to 18 instead of 31]
    Signed-off-by: Thomas Huth <thuth@redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index c7e050e38f..47b7484d53 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1121,7 +1121,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx,
         epctx->ring.ccs = ctx[2] & 1;
     }

-    epctx->interval = 1 << ((ctx[0] >> 16) & 0xff);
+    epctx->interval = 1u << MIN((ctx[0] >> 16) & 0xffu, 18u);
 }

 static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,