From nobody Sun Nov 16 01:14:24 2025 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=huawei.com ARC-Seal: i=1; a=rsa-sha256; t=1762249361; cv=none; d=zohomail.com; s=zohoarc; b=RyKgugDIh8ryPW95UjcuI2i+pkn2QZ68D8Rmmpj8zULRqAZGQSh4Q06Q67CjbIuTYd1g60NW/DLHsNewnhm3G+LTtkAB0gcxyw1L8RGJKAOTRh9ZEqwkm37r70muHm+LPf4NHumamSnczE8VWzl81B1uKcc8yRyWq/IN+wUUzfs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1762249361; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=iPpYtZ/lTtwmH62GzLLo/whDCVzM7t2N22oAv2IRjMg=; b=jYjhqedNDvrylAZwbzxKpZuvSoHrW8MwwNkhAXdEv/pE2q/mOhRUMq3Y1ini08VZ+99nkVOlZCEjjOkTPctZ8XBdELzhLAR4RmqYIe4rgEsRhOgkdCCLkhBcJD0rWcPQsh6r8m1CGhAOM5YKKM0RrTPmChqj7nSpP419fZfVT00= 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 lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 176224936111826.01831802402205; Tue, 4 Nov 2025 01:42:41 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vGDYT-0002fI-Hp; Tue, 04 Nov 2025 04:42:21 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vGDYR-0002eo-Dh for qemu-devel@nongnu.org; Tue, 04 Nov 2025 04:42:19 -0500 Received: from canpmsgout07.his.huawei.com ([113.46.200.222]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vGDYO-0004X5-1l for qemu-devel@nongnu.org; Tue, 04 Nov 2025 04:42:19 -0500 Received: from mail.maildlp.com (unknown [172.19.162.112]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4d13N70XN3zLlSN; Tue, 4 Nov 2025 17:40:23 +0800 (CST) Received: from kwepemf200001.china.huawei.com (unknown [7.202.181.227]) by mail.maildlp.com (Postfix) with ESMTPS id 54110140230; Tue, 4 Nov 2025 17:41:57 +0800 (CST) Received: from huawei.com (10.175.104.170) by kwepemf200001.china.huawei.com (7.202.181.227) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Tue, 4 Nov 2025 17:41:56 +0800 dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=iPpYtZ/lTtwmH62GzLLo/whDCVzM7t2N22oAv2IRjMg=; b=VdTmKM5Jax/X2DIEOCGcTzJdbNDSPW5JRSis4KxkEY94FtUjvSEzyUlKalylfkmoei6mhayJF bNtL4xcG/MZkr74D4raE63JH3UBQNpsXnVe1hnFTCf5+OuZi9I7PvsN28SXUpXQfcR8SvAfe29x J80Wpu4lCBmeFssg/VkwnBw= From: zoudongjie To: CC: , , , , , , , , , , , Subject: [PATCH] hw/usb/host-libusb: cancel the processing of inflight packets correctly Date: Tue, 4 Nov 2025 17:41:51 +0800 Message-ID: <20251104094151.2218252-1-zoudongjie@huawei.com> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.175.104.170] X-ClientProxiedBy: kwepems500002.china.huawei.com (7.221.188.17) To kwepemf200001.china.huawei.com (7.202.181.227) 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=lists.gnu.org; Received-SPF: pass client-ip=113.46.200.222; envelope-from=zoudongjie@huawei.com; helo=canpmsgout07.his.huawei.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, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 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: 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 @huawei.com) X-ZM-MESSAGEID: 1762249364408158500 The EHCI controller in QEMU seems to cause a UAF (Use-After-Free) issue when handling packets from abnormal USB devices. Specifically, when the USB devi= ce's firmware behaves abnormally and causes some initialization requests to block and time out, passing that USB device through to QEMU's EHCI controller app= ears to make the do-while loop in ehci_advance_state repeatedly submit multiple requests to handle the same packet (this do-while loop is quite complex; I confirmed the issue by adding logs in usb_host_cancel_packet). When the virtual machine restarts, QEMU receives the IADD instruction issued by the VM's kernel and will clean up in-flight packets in ehci_advance_asyn= c_state: ehci_advance_async_state =E2=94=94=E2=94=80=E2=94=80 ehci_queues_rip_unseen =E2=94=94=E2=94=80=E2=94=80 ehci_free_queue =E2=94=94=E2=94=80=E2=94=80 ehci_cancel_queue =E2=94=94=E2=94=80=E2=94=80 ehci_free_packet =E2=94=94=E2=94=80=E2=94=80 usb_cancel_packet =E2=94=94=E2=94=80=E2=94=80 usb_device_cancel_packet =E2=94=94=E2=94=80=E2=94=80 usb_host_cancel_packet The cleanup actions in usb_host_cancel_packet mainly include: 1. Finding the first request in the device corresponding to the packet 2. Setting r->p of that request to NULL 3. Calling libusb_cancel_transfer for asynchronous cleanup In the callback function usb_host_req_complete_ctrl registered to r->xfer, = r->p is checked, and if r->p is NULL, the corresponding handling is skipped. How= ever, since usb_host_cancel_packet only cleans up the first request handling the corresponding packet, when there are multiple requests handling the same pa= cket, after the packet is cleared, other requests triggering the callback will ca= use a UAF problem and trigger various QEMU cores. We've verified that canceling all related requests when canceling a packet = can avoid this issue, but we haven't figured out why QEMU submits multiple requ= ests to handle the same packet. Do you have any suggestions? Thank you. Reported by: yefenzheng1@h-partners.com Signed-off-by: zoudongjie --- hw/usb/host-libusb.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index b74670ae25..b5aab12aee 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -406,18 +406,6 @@ static void usb_host_req_free(USBHostRequest *r) g_free(r); } =20 -static USBHostRequest *usb_host_req_find(USBHostDevice *s, USBPacket *p) -{ - USBHostRequest *r; - - QTAILQ_FOREACH(r, &s->requests, next) { - if (r->p =3D=3D p) { - return r; - } - } - return NULL; -} - static void LIBUSB_CALL usb_host_req_complete_ctrl(struct libusb_transfer = *xfer) { USBHostRequest *r =3D xfer->user_data; @@ -1276,7 +1264,7 @@ static void usb_host_unrealize(USBDevice *udev) static void usb_host_cancel_packet(USBDevice *udev, USBPacket *p) { USBHostDevice *s =3D USB_HOST_DEVICE(udev); - USBHostRequest *r; + USBHostRequest *r, *next_entry; =20 if (p->combined) { usb_combined_packet_cancel(udev, p); @@ -1285,10 +1273,17 @@ static void usb_host_cancel_packet(USBDevice *udev,= USBPacket *p) =20 trace_usb_host_req_canceled(s->bus_num, s->addr, p); =20 - r =3D usb_host_req_find(s, p); - if (r && r->p) { - r->p =3D NULL; /* mark as dead */ - libusb_cancel_transfer(r->xfer); + QTAILQ_FOREACH_SAFE(r, &s->requests, next, next_entry) { + if (r->p =3D=3D p) { + if (unlikely(r && r->fake_in_flight)) { + usb_host_req_free(r); + continue; + } + if (r && r->p) { + r->p =3D NULL; /* mark as dead */ + libusb_cancel_transfer(r->xfer); + } + } } } =20 --=20 2.33.0