From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543960; cv=none; d=zohomail.com; s=zohoarc; b=il53uZ00E/KhuIww0bjJCc/p1Qr/cl9eC/HzI6auxQvhCA+n5pWsYqvfUqfpqSqiwZEpHtWsOVS9spa1EINJ60dCGZlgg7O1dKhwJub1aSYCti47Surg/UMCltKH0tKRWyjMPi77p32BUrFVJ8JiFLsq/g3rxcLws95zK9YJ3LM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543960; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=M1mbDPGNDDYLtz3dAfvpGEwZlm9V4lrrlmh7VeV1lw8=; b=VlZu04c05AFI35CNkeKFsMrJkB5dM+SpjWq9Agcl4sGiQyZykBrvAKyPa2U+qyW1AXSwyrsBuP9rCt65zN8S4lB1D78FRKo3pNuFxWNpPzAV0HROR56HBhR3VhQeWJp8MOPYu9NSCHmuHskINDz1x2Rw6GYQco7TmR1X22sYde4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178454396052922.432209657451722; Mon, 20 Jul 2026 03:39:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOb-0003jX-DS; Mon, 20 Jul 2026 06:38:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOW-0003jE-Ep for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:44 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOU-0008Fp-6C for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:44 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-554-3kCAbUIlPj-JDA4t0J-OAA-1; Mon, 20 Jul 2026 06:38:39 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 08F341944D39; Mon, 20 Jul 2026 10:38:39 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 886C0158E; Mon, 20 Jul 2026 10:38:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543921; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M1mbDPGNDDYLtz3dAfvpGEwZlm9V4lrrlmh7VeV1lw8=; b=OomYSHDdj0o0Ph82TkeM8wnuFeN7wuYSIUQHUlKwCa3ZX47uuMubJVSpiC/2LZlzTqsc8/ P50wj2opToswE4No0KhvRCE4FhAb/0T5a0n2wSkZMqZ0HV+mL1UAMKorZtxUUZTkrgA5Du 1mWin88yvrzAJDQVaLWn7S4AKgYgF+M= X-MC-Unique: 3kCAbUIlPj-JDA4t0J-OAA-1 X-Mimecast-MFC-AGG-ID: 3kCAbUIlPj-JDA4t0J-OAA_1784543919 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Feifan Qian Subject: [PULL 1/7] hw/usb/xhci: clamp interval exponent to avoid UB shift in xhci_init_epctx() Date: Mon, 20 Jul 2026 12:38:27 +0200 Message-ID: <20260720103833.364506-2-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543961601158500 From: Feifan Qian 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 =3D 1 << ((ctx[0] >> 16) & 0xff); The shift amount can be 0-255. Shifting a 32-bit `int` left by >=3D 32 is undefined behaviour under C11 =C2=A76.5.7p4. With UBSan (halt_on_error=3D1) 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 Signed-off-by: Feifan Qian [thuth: Clamp to 18 instead of 31] Signed-off-by: Thomas Huth --- hw/usb/hcd-xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index c7e050e38fd..47b7484d533 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 =3D ctx[2] & 1; } =20 - epctx->interval =3D 1 << ((ctx[0] >> 16) & 0xff); + epctx->interval =3D 1u << MIN((ctx[0] >> 16) & 0xffu, 18u); } =20 static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543961; cv=none; d=zohomail.com; s=zohoarc; b=QN0EXxI3Py+paJp1dBPOI4HHKhVr66XQFeK+ynA67Hg8zMA+aYuRfnedM+WLRy8fcU4w8h4PmdUSmkc5lTIptSbKXFjvICEn38c6vraA/XM4Y2Go3aNfeBbErG8/Az6QfLBb+tIdsFYeVYfgLyEp2IxMjVp3lhbuGjqQnMlAmn4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543961; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zLUsY2VBLGGIb5Mf8uahKqDvB7i9l70WALZmTD9bRZE=; b=EUoZlD+xk03T4hwc0Gl+c8fuGNZHMupjlHSLORv8wFjYPB3k006+oPHE+/brGGWVUecdyff0j+RruEH1OdQEAQ5rwThZDneLobCmE/UwbS0XjglVqyfJ2Qcu19N4Z6K524L/rk+YDektd6jyrJoK62DNdpBMNFok8UO3sgO7Y18= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543961094640.4236952382706; Mon, 20 Jul 2026 03:39:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOj-0003lF-MN; Mon, 20 Jul 2026 06:38:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOd-0003kN-I5 for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOW-0008G8-Qa for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:51 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-558-j3VhDpSrPjaJ9l78zzI4tA-1; Mon, 20 Jul 2026 06:38:42 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 79D3C195607A; Mon, 20 Jul 2026 10:38:41 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7FCA8158E; Mon, 20 Jul 2026 10:38:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543924; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zLUsY2VBLGGIb5Mf8uahKqDvB7i9l70WALZmTD9bRZE=; b=RQ7hN5VFzhU07wFtWwMBLObAYBCAcM2XL1dLfY3lr42fUgGBNR4InsSDTo1Jg9XqUxWB3s f61DB0I7LT26SCWU6izyhYX8XFXyXCHnSwalnf1zwa1AgcIUXm5sykmv9NAgY7ic8uE5Pq fqota4T2pmXMzos3QfgLA/0fCQDda3I= X-MC-Unique: j3VhDpSrPjaJ9l78zzI4tA-1 X-Mimecast-MFC-AGG-ID: j3VhDpSrPjaJ9l78zzI4tA_1784543921 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Xiangfeng Cai , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [PULL 2/7] hw/usb/hcd-xhci-pci: break host link cycle so device_finalize() runs on unplug Date: Mon, 20 Jul 2026 12:38:28 +0200 Message-ID: <20260720103833.364506-3-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543963403158500 From: Xiangfeng Cai The xHCI PCI wrapper embeds an xhci-core child via object_initialize_child() and, in usb_xhci_pci_realize(), points the child's "host" link back at the = PCI device: object_property_set_link(OBJECT(&s->xhci), "host", OBJECT(s), NULL); "host" is a DEFINE_PROP_LINK property, which qdev registers as an OBJ_PROP_LINK_STRONG link. A strong link takes a reference on its target, so this creates a refcount cycle: the PCI device owns the child, and the child= 's strong link pins the PCI device. On unplug (guest ACPI eject or QMP device_del), pci_qdev_unrealize() calls pc->exit() but never unrealizes the no-bus child. object_unparent() then dr= ops only the parent/bus references, leaving the link reference in place. The PCI device stays at refcount 1 forever, so object_finalize()/device_finalize() = is never reached. Symptom observed under gdb after eject: p *((Object *)dev) =3D> ref =3D 1, parent =3D 0x0, realized =3D false p ((XHCIPciState *)dev)->xhci.hostOpaque =3D> points back at dev Fix usb_xhci_pci_exit() to tear down the embedded child explicitly: unreali= ze it first (so the set-link-before-realize check passes), then clear the "hos= t" link. This releases the strong reference, lets the PCI device refcount reac= h 0, and allows device_finalize() to run. Fixes: 8ddab8dd3d81 ("usb/hcd-xhci: Split pci wrapper for xhci base model") Signed-off-by: Xiangfeng Cai Acked-by: Marc-Andr=C3=A9 Lureau Message-ID: <20260618110119.3084296-2-caixiangfeng@bytedance.com> Signed-off-by: Thomas Huth --- hw/usb/hcd-xhci-pci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c index c5446a4a5e1..b124251ae33 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -196,6 +196,18 @@ static void usb_xhci_pci_exit(PCIDevice *dev) && dev->msix_entry_used) { msix_uninit(dev, &s->xhci.mem, &s->xhci.mem); } + /* + * The embedded xhci-core child holds a strong "host" link back to this + * PCI device (set in usb_xhci_pci_realize()), forming a refcount cycl= e: + * the PCI device owns the child, and the child's strong link pins the= PCI + * device. On unplug, object_unparent() only drops the parent/bus refs= , so + * the link ref keeps this device at refcount 1 forever and + * device_finalize() never runs. Unrealize the child first (so the + * realized-check in set_link passes), then clear the link to break the + * cycle. + */ + qdev_unrealize(DEVICE(&s->xhci)); + object_property_set_link(OBJECT(&s->xhci), "host", NULL, &error_abort); } =20 static const VMStateDescription vmstate_xhci_pci =3D { --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543960; cv=none; d=zohomail.com; s=zohoarc; b=QA/gzBKl0jvxV1SSKeHXsW7whP/NzNhgeYlWmu4IIICm9C6OZilUlCz/oxUHtYG9zobSvdw1DNSn1lj7SlDNn2A85V8lcXR4xVdtX95idgQcmxSsf1qy7KrLw1TY3gxnDo6VrbjhP7qZDsCZOkUNAJ2PPq1eBXB4Ent52EY/0SE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543960; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IQPrpkxIioqNtONJjKR1RF/mZ5zqy/yI+BFZyibIAWk=; b=LZJ7+zVHCSOssUbuz+uc3HZ0S68jF/N5MmzzYGJqI8FBy/3dDmx1fhOVwFZ9sTjyuvvnuzpbP3bfTLan7AD3GtImDcxrR9MkIpljPMwkK7xJKoPL8YyJO4UIULkMBSkubERzXrDebemX3VCQQxPFli8lBer0x+HHyCsdSbQLcck= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543960529845.613810813186; Mon, 20 Jul 2026 03:39:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOf-0003kc-JM; Mon, 20 Jul 2026 06:38:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOb-0003k4-Hc for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:49 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOZ-0008GP-QT for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:49 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-479-b6VvOooQOwa9aVHrae4uEw-1; Mon, 20 Jul 2026 06:38:44 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 81B171802564; Mon, 20 Jul 2026 10:38:43 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F0A921588; Mon, 20 Jul 2026 10:38:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543925; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IQPrpkxIioqNtONJjKR1RF/mZ5zqy/yI+BFZyibIAWk=; b=PeKBupRkrDKzBafUU2A1NxHRZTGEkdFwvQaZUWLu4Hy7jlDwumcNFymRcXEMo4dgVX2uBT j1A0RZ/BtKGz8UMKo+JIXKxAK+waD8axpPdpea4WFXyRRv/5LneprVQEJgpue6joSr5VJx 0gXafVJw3kfcEgV7JcZuTMlmyexQGBQ= X-MC-Unique: b6VvOooQOwa9aVHrae4uEw-1 X-Mimecast-MFC-AGG-ID: b6VvOooQOwa9aVHrae4uEw_1784543923 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Xiangfeng Cai Subject: [PULL 3/7] tests/qtest: add xhci-pci unplug finalize regression test Date: Mon, 20 Jul 2026 12:38:29 +0200 Message-ID: <20260720103833.364506-4-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.129.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.01, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543961628158500 Content-Type: text/plain; charset="utf-8" From: Xiangfeng Cai Add a qtest that hot-adds an nec-usb-xhci controller, requests unplug, resets the system to process the request, and waits for DEVICE_DELETED. This covers the xHCI PCI host-link refcount cycle by verifying that device_finalize() runs after unplug. Signed-off-by: Xiangfeng Cai Message-ID: <20260618110119.3084296-3-caixiangfeng@bytedance.com> Signed-off-by: Thomas Huth --- tests/qtest/usb-hcd-xhci-test.c | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/qtest/usb-hcd-xhci-test.c b/tests/qtest/usb-hcd-xhci-tes= t.c index 0cccfd85a64..b58fa1e2dae 100644 --- a/tests/qtest/usb-hcd-xhci-test.c +++ b/tests/qtest/usb-hcd-xhci-test.c @@ -10,6 +10,72 @@ #include "qemu/osdep.h" #include "libqtest-single.h" #include "libqos/usb.h" +#include "qobject/qdict.h" + +static void wait_device_deleted_event(QTestState *qtest, const char *id) +{ + QDict *resp, *data; + const char *device; + + /* + * Other devices might get removed along with the removed device. Skip + * these. The device of interest will be the last one. + */ + for (;;) { + resp =3D qtest_qmp_eventwait_ref(qtest, "DEVICE_DELETED"); + data =3D qdict_get_qdict(resp, "data"); + device =3D data ? qdict_get_try_str(data, "device") : NULL; + if (device && !strcmp(device, id)) { + qobject_unref(resp); + break; + } + qobject_unref(resp); + } +} + +/* + * Regression test for the xHCI-PCI "host" strong-link reference cycle. + * + * The xHCI PCI wrapper embeds an xhci-core child whose strong "host" link + * points back at the PCI device, forming a refcount cycle. If + * usb_xhci_pci_exit() does not break that cycle, the device's refcount ne= ver + * reaches 0 on unplug, device_finalize() never runs, and therefore the + * DEVICE_DELETED event (emitted from device_finalize()) is never sent. + * + * This test hot-plugs an xHCI controller into an ACPI-hotpluggable bus, + * requests its removal and waits for DEVICE_DELETED. Without the fix the = event + * is never delivered (device_finalize() is blocked), so the test would + * hang/time out. + */ +static void test_xhci_unplug_finalize(void) +{ + QTestState *qtest; + const char *arch =3D qtest_get_arch(); + + if (strcmp(arch, "i386") !=3D 0 && strcmp(arch, "x86_64") !=3D 0) { + g_test_skip("Test only runs on x86 (ACPI PCI hotplug)"); + return; + } + if (!qtest_has_device("nec-usb-xhci")) { + g_test_skip("Device nec-usb-xhci not available"); + return; + } + + qtest =3D qtest_initf("-machine pc"); + + qtest_qmp_device_add(qtest, "nec-usb-xhci", "xhci-finalize", "{}"); + + /* + * Request device removal. As the guest is not running, the unplug req= uest + * won't be processed until the next system reset, which performs the + * removal and triggers device_finalize() (and thus DEVICE_DELETED). + */ + qtest_qmp_device_del_send(qtest, "xhci-finalize"); + qtest_system_reset_nowait(qtest); + wait_device_deleted_event(qtest, "xhci-finalize"); + + qtest_quit(qtest); +} =20 static void test_xhci_hotplug(void) { @@ -50,6 +116,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); =20 qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug); + qtest_add_func("/xhci/pci/unplug/finalize", test_xhci_unplug_finalize); if (qtest_has_device("usb-uas")) { qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug); } --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543996; cv=none; d=zohomail.com; s=zohoarc; b=V1XufgFT3LNnW4CN/6kmvKiYbXRK9Xcwm6ETgQXuDWpN2soCFoTwxVal6qneMzMuy2cq0gEtaOlp+GDKnqfNQB4ewT4rVKmwxuo5E+zQ7fsSPkWulvHQa5vi0xFFPAENSjMWIwe2X6anJLbtWVNnDK8enhsxb1kmOZAQhr3lyyg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543996; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=h9gHWXrpug65VRTeYXgdUAFcY9n2qUEl8WfpF47AYrQ=; b=O2i36x43TMPz8Gzk9NAX5mDk04NWy2iTAr7QShK4WTcP0AxUZL6VqoTETpqjYD5Gh61RnCbN6qk+NIfO1vA+SlNVxDsOmCWrQLR/YL98qW6k2oYk8MjtqcfnIdMHEzdfca4beqjWx3QWF4zWnpiI0TPsGT0wLl86cNHyafhoytQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543996650214.43251930302984; Mon, 20 Jul 2026 03:39:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOl-0003m4-RZ; Mon, 20 Jul 2026 06:38:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOc-0003kK-Cv for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOa-0008Gg-Ps for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:50 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-681-xRBc717gMwuvjdn5_m0gNA-1; Mon, 20 Jul 2026 06:38:46 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CF4921955F22; Mon, 20 Jul 2026 10:38:45 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 32D4F158E; Mon, 20 Jul 2026 10:38:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h9gHWXrpug65VRTeYXgdUAFcY9n2qUEl8WfpF47AYrQ=; b=c4CXDDVuIPAg6UUi2l4lBBdH3VLsTBWnhxLzlSC75QNRIF02rydFWpLLjpEYkoeDPABcdg rOSycGXBbooo4NMRDxZisY9Hr8b6uPQMWvkkcjz9S3NhK8M/cGkz875SkztrHVkJlXbz4X q6H+ITmLFYesMowzOqQrRiiIGMglmC8= X-MC-Unique: xRBc717gMwuvjdn5_m0gNA-1 X-Mimecast-MFC-AGG-ID: xRBc717gMwuvjdn5_m0gNA_1784543926 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Feifan Qian , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [PULL 4/7] usbredir: fix use-after-free on buffered bulk packet overflow Date: Mon, 20 Jul 2026 12:38:30 +0200 Message-ID: <20260720103833.364506-5-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.129.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.01, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543997605158501 From: Marc-Andr=C3=A9 Lureau When usbredir_buffered_bulk_packet() splits a multi-fragment buffered bulk packet into max-packet-size chunks, only the final fragment owns the shared parser allocation (via free_on_destroy). If bufp_alloc() drops the final fragment due to queue overflow, it frees the backing buffer while earlier fragments already queued still hold interior pointers into it. Subsequent guest bulk-IN transfers then read from freed heap memory. Fix this by tracking how many fragments were queued during the current packet. When bufp_alloc() fails, remove all already-queued fragments from the tail of the endpoint queue before breaking out of the loop. If the dropped fragment was non-final, free the data buffer explicitly since no fragment took ownership. Fixes: CVE-2026-15705 Fixes: b2d1fe67d09d ("usbredir: Add support for buffered bulk input (v2)") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3808 Reported-by: Feifan Qian Signed-off-by: Marc-Andr=C3=A9 Lureau Message-ID: <20260714185717.1156157-1-marcandre.lureau@redhat.com> Signed-off-by: Thomas Huth --- hw/usb/redirect.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index bde821e214b..284bcbdb34d 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -2138,7 +2138,7 @@ static void usbredir_buffered_bulk_packet(void *priv,= uint64_t id, USBRedirDevice *dev =3D priv; uint8_t status, ep =3D buffered_bulk_packet->endpoint; void *free_on_destroy; - int i, len; + int i, len, queued =3D 0; =20 DPRINTF("buffered-bulk-in status %d ep %02X len %d id %"PRIu64"\n", buffered_bulk_packet->status, ep, data_len, id); @@ -2169,8 +2169,24 @@ static void usbredir_buffered_bulk_packet(void *priv= , uint64_t id, /* bufp_alloc also adds the packet to the ep queue */ r =3D bufp_alloc(dev, data + i, len, status, ep, free_on_destroy); if (r) { + /* + * Earlier fragments from this packet are in the queue + * with interior pointers into data. If the dropped + * fragment was the final one, bufp_alloc already freed + * data so those pointers are dangling. Remove them. + */ + while (queued > 0) { + struct buf_packet *bufp; + bufp =3D QTAILQ_LAST(&dev->endpoint[EP2I(ep)].bufpq); + bufp_free(dev, bufp, ep); + queued--; + } + if (!free_on_destroy) { + free(data); + } break; } + queued++; } =20 if (dev->endpoint[EP2I(ep)].pending_async_packet) { --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543972; cv=none; d=zohomail.com; s=zohoarc; b=k8nsDcnLeBobO1PPerHeMBbBkoQqc894V5dTkm7pArlzVqYX1MzT2MySMg8yjpHA7YN09wdTEVTXU6Hjp/AW2E7AAH5lpy6hkhgLv1tUry6ZJ2elHcSeNl98z4iIffLE43waKv8SpRUBn7S7bLSwTl4pDgx2C2DKbgDEO8o+fS8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543972; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hmMOrL1qy0em1clNfQjUh4hOg8rqOth/0bemYGgGW1Y=; b=dL0+VkT+lbrNkrAHYMFOnyuEm65r/Q2oWfScBNg0oAcVkTRiaDNPr3ZRFeMs/NJty+jLuf5bEKxt9zO7WDYU54ceu1fnKb+bcNTmw6NtlN7ZnZ/A0Ol2B4eGiRiG8c6zh2lZZYz4qf5frzLiD1MrVDcLlPDvLw60OEAQXJHT1H8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543972790456.5703522863065; Mon, 20 Jul 2026 03:39:32 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOo-0003mr-3q; Mon, 20 Jul 2026 06:39:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOf-0003kl-E9 for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:53 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOc-0008H3-Mm for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:52 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-219-wkUA_KIbPvyOda2kUdcJyQ-1; Mon, 20 Jul 2026 06:38:48 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9D4F81944E45 for ; Mon, 20 Jul 2026 10:38:47 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 513611588; Mon, 20 Jul 2026 10:38:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hmMOrL1qy0em1clNfQjUh4hOg8rqOth/0bemYGgGW1Y=; b=AEK866STj6F9FMfIALLrtyT49ulFN4ULkt3sslFWj8A8ni+xAi6KtMKt+slruWG4zqoRNX VUqb7UYbIVyrAu+NjTlzMOddHNa+zxJroQnZy8X4dNa+LNswUV2wu1s472VK8pcvnL6blI f0gfwtJ0L7qvXAiD7sMVIHURJTbOvNs= X-MC-Unique: wkUA_KIbPvyOda2kUdcJyQ-1 X-Mimecast-MFC-AGG-ID: wkUA_KIbPvyOda2kUdcJyQ_1784543927 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [PULL 5/7] usbredir: fix infinite loop and SIGFPE with zero max_packet_size Date: Mon, 20 Jul 2026 12:38:31 +0200 Message-ID: <20260720103833.364506-6-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.129.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.01, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543973434158500 From: Marc-Andr=C3=A9 Lureau A malicious usbredir peer can send an ep_info message resetting max_packet_size to 0 after bulk receiving has started. This causes: - infinite loop in usbredir_buffered_bulk_packet() where the splitting loop increments by max_packet_size (0) - SIGFPE in usbredir_buffered_bulk_in_complete_ftdi() from modulo by 0 - SIGFPE in usbredir_handle_buffered_bulk_in_data() from division by 0 when computing bytes_per_transfer Fix by stopping and disabling bulk receiving in usbredir_ep_info() when max_packet_size is set to 0. Add post-load check, and assert() for the invariant. Fixes: CVE-2026-63319 Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3995 Reported-by: Tristan @TristanInSec Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Thomas Huth Message-ID: <20260716141107.3597076-1-marcandre.lureau@redhat.com> Signed-off-by: Thomas Huth --- hw/usb/redirect.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 284bcbdb34d..dfd9e8bb50c 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -690,6 +690,7 @@ static void usbredir_buffered_bulk_in_complete_ftdi(USB= RedirDevice *dev, struct buf_packet *bulkp; int count; =20 + assert(maxp !=3D 0); while ((bulkp =3D QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq)) && p->actual_length < p->iov.size && p->status =3D=3D USB_RET_SUCC= ESS) { if (bulkp->len < 2) { @@ -739,6 +740,7 @@ static void usbredir_handle_buffered_bulk_in_data(USBRe= dirDevice *dev, .stream_id =3D 0, .no_transfers =3D 5, }; + assert(dev->endpoint[EP2I(ep)].max_packet_size !=3D 0); /* Round bytes_per_transfer up to a multiple of max_packet_size */ bpt =3D 512 + dev->endpoint[EP2I(ep)].max_packet_size - 1; bpt /=3D dev->endpoint[EP2I(ep)].max_packet_size; @@ -793,6 +795,7 @@ static void usbredir_handle_bulk_data(USBRedirDevice *d= ev, USBPacket *p, } =20 if (dev->endpoint[EP2I(ep)].bulk_receiving_enabled) { + assert(maxp !=3D 0); if (size !=3D 0 && (size % maxp) =3D=3D 0) { usbredir_handle_buffered_bulk_in_data(dev, p, ep); return; @@ -1796,6 +1799,17 @@ static void usbredir_ep_info(void *priv, if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_ep_info_max_packet_size= )) { dev->endpoint[i].max_packet_size =3D ep_info->max_packet_size[= i]; + if (ep_info->max_packet_size[i] =3D=3D 0 && + dev->endpoint[i].bulk_receiving_enabled) { + USBPacket *p =3D dev->endpoint[i].pending_async_packet; + usbredir_stop_bulk_receiving(dev, I2EP(i)); + dev->endpoint[i].bulk_receiving_enabled =3D 0; + if (p !=3D NULL) { + dev->endpoint[i].pending_async_packet =3D NULL; + p->status =3D USB_RET_IOERROR; + usb_packet_complete(&dev->dev, p); + } + } } #if USBREDIR_VERSION >=3D 0x000700 if (usbredirparser_peer_has_cap(dev->parser, @@ -2156,6 +2170,7 @@ static void usbredir_buffered_bulk_packet(void *priv,= uint64_t id, } =20 /* Data must be in maxp chunks for buffered_bulk_add_*_data_to_packet = */ + assert(dev->endpoint[EP2I(ep)].max_packet_size !=3D 0); len =3D dev->endpoint[EP2I(ep)].max_packet_size; status =3D usb_redir_success; free_on_destroy =3D NULL; @@ -2239,6 +2254,15 @@ static int usbredir_post_load(void *priv, int versio= n_id) usbredir_setup_usb_eps(dev); usbredir_check_bulk_receiving(dev); =20 + for (int i =3D 0; i < MAX_ENDPOINTS; i++) { + if (dev->endpoint[i].bulk_receiving_started && + dev->endpoint[i].max_packet_size =3D=3D 0) { + error_report("usbredir: endpoint %d has bulk receiving started= " + "with zero max_packet_size", i); + return -EINVAL; + } + } + return 0; } =20 --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543980; cv=none; d=zohomail.com; s=zohoarc; b=G3RSXdW3v6+7TyOiPY2wEu1sfwCJXxhuE5NqujJZ9cG1QCVmkFrSpe6TcQBVt0VqiAP58+5BEpWdPf/tC9J55+OKJJbIkELKgPiWz+xz94mqiXtrT2gtvbElK5vVWdebrzyC/fGBZ7mVCv+NcyaRUT3MBUUVNs4jUgtQeb8UrRw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543980; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=X/AmVS2H7e5pCfszF4amIkYPrIlpVwvF0XwijKV+5Jc=; b=WqXccchFnfYgp6Saj6wdSWokkqR6VDddvotFnbqHOax/jTD44tCWXZJuBij5hbCkHqUt95jh09DeGn0hRqEfgvngrrc1MBFNY8O+4dJcQ9qxUOSet6Vg6UUDQuxDRJ6Le2r1WCUMWxX9XbJ+a6tsG32wzLIFEHzGjISCvXEW0RQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543980433370.11858385887683; Mon, 20 Jul 2026 03:39:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOm-0003mY-NS; Mon, 20 Jul 2026 06:39:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOj-0003lK-K0 for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOh-0008Hn-3X for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:56 -0400 Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-314-663L_OrWPZabOiN-XxclWQ-1; Mon, 20 Jul 2026 06:38:51 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2895E19560B5; Mon, 20 Jul 2026 10:38:50 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1F38B158E; Mon, 20 Jul 2026 10:38:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X/AmVS2H7e5pCfszF4amIkYPrIlpVwvF0XwijKV+5Jc=; b=fLCf5oRig8HsGOhimrHgdRzdPpV/A9UNko6bxuTq9e/F2/p0hebjlD8SHgGvJB6PEkFUDi CDXS6S2xHDxQEJO8sfPjRhb6UjO1jNx46yEy1wzzlAxvInBW8XgPoYZMnKOl8xiSXvBMFD 2RMwDQ3DrO/FiW01LDR8qXtr8in4Pk0= X-MC-Unique: 663L_OrWPZabOiN-XxclWQ-1 X-Mimecast-MFC-AGG-ID: 663L_OrWPZabOiN-XxclWQ_1784543930 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Peter Maydell Subject: [PULL 6/7] hw/usb/hcd-xhci: Fix guest-triggerable assert() in xhci_find_stream() Date: Mon, 20 Jul 2026 12:38:32 +0200 Message-ID: <20260720103833.364506-7-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 12 X-Spam_score: 1.2 X-Spam_bar: + X-Spam_report: (1.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543981520158500 Content-Type: text/plain; charset="utf-8" From: Thomas Huth The assert() statement in xhci_find_stream() can be triggered by the guest (see bug tickets #273, #3895 and #3988 on gitlab.com). Turn it into a qemu_log_mask() instead to fix this problem. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/273 Reviewed-by: Peter Maydell Signed-off-by: Thomas Huth Message-ID: <20260715203357.424556-1-thuth@redhat.com> --- hw/usb/hcd-xhci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 47b7484d533..b94249993a1 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1009,7 +1009,12 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPCon= text *epctx, dma_addr_t base; uint32_t ctx[2], sct; =20 - assert(streamid !=3D 0); + if (!streamid) { + qemu_log_mask(LOG_GUEST_ERROR, "xhci: stream ID is zero\n"); + *cc_error =3D CC_INVALID_STREAM_ID_ERROR; + return NULL; + } + if (epctx->lsa) { if (streamid >=3D epctx->nr_pstreams) { *cc_error =3D CC_INVALID_STREAM_ID_ERROR; --=20 2.55.0 From nobody Sat Jul 25 11:25:13 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1784543971; cv=none; d=zohomail.com; s=zohoarc; b=ieRoeZcUbBgMTFChaisL2udBFAyIGPL4EQUncyqjQgRQFjc5YDnQnoZP9Pg+21WADkR+o1E9hYwAmORhfgJ1GFbFU3p9piQR+521LhvhauZoMKBP5sOis0hlFUBrTCrDSrs/doGKYUc4pFmPuvi3s7gZGpB4bqMdaiTkA/UTOko= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784543971; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=8+FPfCzpRA13rUQiz7x4b9yGDzYKNxGYMOHyt30DAOI=; b=ZT3GSjxrFz7vehnIp0iFzWEXEA80DX1oicys3lbpIjeKj1pHyLA5VOI8JUaDlCjFn0+pa28uaV7TntvBU+dTdZxsU+CW8LNNOyz0IEDBGnfjC0Bk0vxNpPGdvuUdkpxSE81v+uPcsQtpKU2XQHaOZ4f3mJXn9fkUJWLl+F8Qbn0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784543971480282.3384134405559; Mon, 20 Jul 2026 03:39:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wllOo-0003mv-8E; Mon, 20 Jul 2026 06:39:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOm-0003mP-4Y for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:39:00 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wllOk-0008IJ-LV for qemu-devel@nongnu.org; Mon, 20 Jul 2026 06:38:59 -0400 Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-10-QwL3aHqjOvOSYRr307xMfw-1; Mon, 20 Jul 2026 06:38:53 -0400 Received: from mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.95]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 951301802575; Mon, 20 Jul 2026 10:38:52 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.44.34.82]) by mx-prod-int-10.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A7F6C1588; Mon, 20 Jul 2026 10:38:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784543938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8+FPfCzpRA13rUQiz7x4b9yGDzYKNxGYMOHyt30DAOI=; b=i2qu6vEjl2MWiqHMwrtVIJjJmsVMefdpL6Q1dA//rj6BVwxktj2xdeKCh3RcYuiOzkDZX9 3jMhKeHHm7ECW75tBO0HPHWbZvJm4iDPmDIftA/ZQc6q/JGmwXGzdqnSlm4mfC+iVr7GNL Ylo2XPTqo5SZd2Bp5mrh0eA51nAbrdw= X-MC-Unique: QwL3aHqjOvOSYRr307xMfw-1 X-Mimecast-MFC-AGG-ID: QwL3aHqjOvOSYRr307xMfw_1784543932 From: Thomas Huth To: qemu-devel@nongnu.org, Stefan Hajnoczi Cc: Tristan Madani , Peter Maydell Subject: [PULL 7/7] hw/usb/hcd-xhci-sysbus: Fix OOB heap access in xhci_sysbus_intr_raise() Date: Mon, 20 Jul 2026 12:38:33 +0200 Message-ID: <20260720103833.364506-8-thuth@redhat.com> In-Reply-To: <20260720103833.364506-1-thuth@redhat.com> References: <20260720103833.364506-1-thuth@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.6 on 10.30.177.95 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: permerror client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_PASS=-0.001, T_SPF_PERMERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1784543973512158500 Content-Type: text/plain; charset="utf-8" From: Thomas Huth Some machines like the microvm machine instantiate a "sysbus-xhci" device with just 1 interrupt (by setting the "intrs" property to 1). xhci_sysbus_realize() then only allocates the s->irq array with one entry. When the guest writes to the ERDP register of a corresponding XHCI "interrupter", the generic XHCI code calls the xhci_sysbus_intr_raise() function with n > 1, and this function then calls qemu_set_irq() with s->irq[n] pointing to a bad heap address. The qemu_set_irq() then tries to call an IRQ handler via a function pointer in that heap space. This either causes QEMU to die with a segmentation fault (if it's a bad address), or even worse runs some unexpected code if the destination of the pointer is executable code. Looking at the xHCI spec, it is up to the implementation of the host controller how many interrupters are available. So if we only support one or some few interrupters, the registers of the other interrupters should not do anything, i.e. reads should result in zeros and writes should be completely ignored. (big thanks to Peter Maydell for helping with the analyzation of the correct way to fix this here) This way, the xhci_sysbus_intr_raise() function cannot be called with an invalid interrupt number anymore. But for good measure, also add an assert() statement to the xhci_sysbus_intr_raise() function to prevent that similar problems with calling arbitrary function pointers on the heap could occur again. Fixes: CVE-2026-16043 Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4001 Reported-by: Tristan Madani Reviewed-by: Peter Maydell Signed-off-by: Thomas Huth Message-ID: <20260719061528.15587-1-thuth@redhat.com> --- hw/usb/hcd-xhci-sysbus.c | 1 + hw/usb/hcd-xhci.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c index 19664c5985e..bbdd5fd64ab 100644 --- a/hw/usb/hcd-xhci-sysbus.c +++ b/hw/usb/hcd-xhci-sysbus.c @@ -20,6 +20,7 @@ static bool xhci_sysbus_intr_raise(XHCIState *xhci, int n= , bool level) { XHCISysbusState *s =3D container_of(xhci, XHCISysbusState, xhci); =20 + assert(n < xhci->numintrs); qemu_set_irq(s->irq[n], level); =20 return false; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index b94249993a1..569386b8cf1 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3044,6 +3044,12 @@ static uint64_t xhci_runtime_read(void *ptr, hwaddr = reg, } } else { int v =3D (reg - 0x20) / 0x20; + + if (v >=3D xhci->numintrs) { + qemu_log_mask(LOG_GUEST_ERROR, + "xhci: read from nonexistent interrupter %i\n", = v); + goto out_trace; + } XHCIInterrupter *intr =3D &xhci->intr[v]; switch (reg & 0x1f) { case 0x00: /* IMAN */ @@ -3070,6 +3076,7 @@ static uint64_t xhci_runtime_read(void *ptr, hwaddr r= eg, } } =20 +out_trace: trace_usb_xhci_runtime_read(reg, ret); return ret; } @@ -3087,7 +3094,13 @@ static void xhci_runtime_write(void *ptr, hwaddr reg, trace_usb_xhci_unimplemented("runtime write", reg); return; } + v =3D (reg - 0x20) / 0x20; + if (v >=3D xhci->numintrs) { + qemu_log_mask(LOG_GUEST_ERROR, + "xhci: write to nonexistent interrupter %i\n", v); + return; + } intr =3D &xhci->intr[v]; =20 switch (reg & 0x1f) { --=20 2.55.0