From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 85CA8F532C3 for ; Tue, 24 Mar 2026 01:00:25 +0000 (UTC) Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4ffsCX0ZSxz2yhZ; Tue, 24 Mar 2026 12:00:24 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip=172.105.4.254 ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1774314024; cv=none; b=DY2OJubrYLP/6regqg5XREIZbDO+K9rAgVsWXUBeO7FGOGZLru9k6ztolo24bGgtoEUlpvQWz5qK8vGt6jVB6sLj1kl7zmgODjpgGOO+8yfaScBMGGw2I4xhuAVeetcZpu14t842kcS5KjXLE4+Z+O3cK+mc2cKABPMmVSibGCT0AOa6iu/GusCVxL/u0tEHJJoR8C4xkYZP62A3GMJ/bFLpg2cAVKpJTppkaOWen1ezFkTUn6erhYRsDUQaM7hbD5pOHCuxBgINK8A5/R7/WhNOZR0bglC2QA3NImpta5AI1gJadtlQ6pfpaIkwoDw5+U2Nkp+kPgKR6ocwDhUOSQ== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1774314024; c=relaxed/relaxed; bh=UeBOeBvG8Jeys02kJSFgZxf+uoEjZl6S2BBJgW2am34=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TCeTPJfS8FzISdE718FQRrZvev/8kITYT4XiV78M0oH1k9c5KUZpKl8xdtF3Mn0E2PtTiS27hctlNaYdrS0wfblnVTzzCuZLiNLb+scqqtBgFyxZpki4JmnTalglGF5dlGv2rJA0/seEIRZmwK2n1/eEp0csG8Jf8V/wcrO46xiSRrr6l0zlh1bKxZbuqJ+GcrEuol+CYsnav7tqSk2Rm22qVmvfZDtTJQV7ImTLG6rhpCsx5gZml0M7JfoBp7gffppVfqSZfdzr6krzixulFxTOZwGqEtQtKfwgwzKxT6//tzzywG9VLqbDu/0PoWdCMJhDXxdCZHJ2i6LTEa7XZw== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=QIEgBZSe; dkim-atps=neutral; spf=pass (client-ip=172.105.4.254; helo=tor.source.kernel.org; envelope-from=dakr@kernel.org; receiver=lists.ozlabs.org) smtp.mailfrom=kernel.org Authentication-Results: lists.ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=kernel.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=k20201202 header.b=QIEgBZSe; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=kernel.org (client-ip=172.105.4.254; helo=tor.source.kernel.org; envelope-from=dakr@kernel.org; receiver=lists.ozlabs.org) Received: from tor.source.kernel.org (tor.source.kernel.org [172.105.4.254]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4ffsCW1FVGz2yVB for ; Tue, 24 Mar 2026 12:00:23 +1100 (AEDT) Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id 0775E60103; Tue, 24 Mar 2026 01:00:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88E74C2BCB0; Tue, 24 Mar 2026 01:00:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774314020; bh=zi0v4zurXgdLP04GC9K8onaZXN/N3Qlem6TWYef3iJk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QIEgBZSeprBd8eco5o8dw+zg/Y5BKWKjmLND8s3b+DopMyWSHVyEjpTlL4MeXNu6J X/vMHl5tcRAtlKG5k4UUt+iHGlqdNZ7OAGIqIUnN+AuKhAX5Gfvn1RJ2JN+B+b/8oV Dnw348XctBIWTV33IkRHOMoqJWQCsfR8SsPVZoMNEUBzpdW4p6GRIYIot6LJvdMFsS 3QbEZOR+DnIpCdhzlekCzLxRc423a9T2znnXXKY+47An9vD8vHI4TrhpijQMqnokV+ 3RMAL22cwN1WStl+aUt4vfTVte+eCLX64fU0XiBT76DmRE+t61UwtJ1wkOziB9Utd8 OLcnfwwHxuprw== From: Danilo Krummrich To: Russell King , Greg Kroah-Hartman , "Rafael J. Wysocki" , Ioana Ciornei , Nipun Gupta , Nikhil Agarwal , "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , Dexuan Cui , Long Li , Bjorn Helgaas , Armin Wolf , Bjorn Andersson , Mathieu Poirier , Vineeth Vijayan , Peter Oberparleiter , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Sven Schnelle , Harald Freudenberger , Holger Dengler , Mark Brown , "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Alex Williamson , Juergen Gross , Stefano Stabellini , Oleksandr Tyshchenko , "Christophe Leroy (CS GROUP)" Cc: linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, linuxppc-dev@lists.ozlabs.org, linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-s390@vger.kernel.org, linux-spi@vger.kernel.org, virtualization@lists.linux.dev, kvm@vger.kernel.org, xen-devel@lists.xenproject.org, linux-arm-kernel@lists.infradead.org, Danilo Krummrich , Gui-Dong Han Subject: [PATCH 05/12] PCI: use generic driver_override infrastructure Date: Tue, 24 Mar 2026 01:59:09 +0100 Message-ID: <20260324005919.2408620-6-dakr@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260324005919.2408620-1-dakr@kernel.org> References: <20260324005919.2408620-1-dakr@kernel.org> X-Mailing-List: linuxppc-dev@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , List-Unsubscribe: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF. Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally. Note that calling match() from __driver_attach() without the device lock held is intentional. [1] Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1] Reported-by: Gui-Dong Han Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 Fixes: 782a985d7af2 ("PCI: Introduce new device binding path using pci_dev.driver_override") Signed-off-by: Danilo Krummrich --- drivers/pci/pci-driver.c | 11 +++++++---- drivers/pci/pci-sysfs.c | 28 ---------------------------- drivers/pci/probe.c | 1 - drivers/vfio/pci/vfio_pci_core.c | 5 ++--- drivers/xen/xen-pciback/pci_stub.c | 6 ++++-- include/linux/pci.h | 6 ------ 6 files changed, 13 insertions(+), 44 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index dd9075403987..d10ece0889f0 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -138,9 +138,11 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv, { struct pci_dynid *dynid; const struct pci_device_id *found_id = NULL, *ids; + int ret; /* When driver_override is set, only bind to the matching driver */ - if (dev->driver_override && strcmp(dev->driver_override, drv->name)) + ret = device_match_driver_override(&dev->dev, &drv->driver); + if (ret == 0) return NULL; /* Look at the dynamic ids first, before the static ones */ @@ -164,7 +166,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv, * matching. */ if (found_id->override_only) { - if (dev->driver_override) + if (ret > 0) return found_id; } else { return found_id; @@ -172,7 +174,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv, } /* driver_override will always match, send a dummy id */ - if (dev->driver_override) + if (ret > 0) return &pci_device_id_any; return NULL; } @@ -452,7 +454,7 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) static inline bool pci_device_can_probe(struct pci_dev *pdev) { return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe || - pdev->driver_override); + device_has_driver_override(&pdev->dev)); } #else static inline bool pci_device_can_probe(struct pci_dev *pdev) @@ -1722,6 +1724,7 @@ static const struct cpumask *pci_device_irq_get_affinity(struct device *dev, const struct bus_type pci_bus_type = { .name = "pci", + .driver_override = true, .match = pci_bus_match, .uevent = pci_uevent, .probe = pci_device_probe, diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 16eaaf749ba9..a9006cf4e9c8 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -615,33 +615,6 @@ static ssize_t devspec_show(struct device *dev, static DEVICE_ATTR_RO(devspec); #endif -static ssize_t driver_override_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - int ret; - - ret = driver_set_override(dev, &pdev->driver_override, buf, count); - if (ret) - return ret; - - return count; -} - -static ssize_t driver_override_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - ssize_t len; - - device_lock(dev); - len = sysfs_emit(buf, "%s\n", pdev->driver_override); - device_unlock(dev); - return len; -} -static DEVICE_ATTR_RW(driver_override); - static struct attribute *pci_dev_attrs[] = { &dev_attr_power_state.attr, &dev_attr_resource.attr, @@ -669,7 +642,6 @@ static struct attribute *pci_dev_attrs[] = { #ifdef CONFIG_OF &dev_attr_devspec.attr, #endif - &dev_attr_driver_override.attr, &dev_attr_ari_enabled.attr, NULL, }; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index bccc7a4bdd79..b4707640e102 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2488,7 +2488,6 @@ static void pci_release_dev(struct device *dev) pci_release_of_node(pci_dev); pcibios_release_device(pci_dev); pci_bus_put(pci_dev->bus); - kfree(pci_dev->driver_override); bitmap_free(pci_dev->dma_alias_mask); dev_dbg(dev, "device released\n"); kfree(pci_dev); diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index d43745fe4c84..460852f79f29 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1987,9 +1987,8 @@ static int vfio_pci_bus_notifier(struct notifier_block *nb, pdev->is_virtfn && physfn == vdev->pdev) { pci_info(vdev->pdev, "Captured SR-IOV VF %s driver_override\n", pci_name(pdev)); - pdev->driver_override = kasprintf(GFP_KERNEL, "%s", - vdev->vdev.ops->name); - WARN_ON(!pdev->driver_override); + WARN_ON(device_set_driver_override(&pdev->dev, + vdev->vdev.ops->name)); } else if (action == BUS_NOTIFY_BOUND_DRIVER && pdev->is_virtfn && physfn == vdev->pdev) { struct pci_driver *drv = pci_dev_driver(pdev); diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index e4b27aecbf05..79a2b5dfd694 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -598,6 +598,8 @@ static int pcistub_seize(struct pci_dev *dev, return err; } +static struct pci_driver xen_pcibk_pci_driver; + /* Called when 'bind'. This means we must _NOT_ call pci_reset_function or * other functions that take the sysfs lock. */ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -609,8 +611,8 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) match = pcistub_match(dev); - if ((dev->driver_override && - !strcmp(dev->driver_override, PCISTUB_DRIVER_NAME)) || + if (device_match_driver_override(&dev->dev, + &xen_pcibk_pci_driver.driver) > 0 || match) { if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL diff --git a/include/linux/pci.h b/include/linux/pci.h index 1c270f1d5123..57e9463e4347 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -575,12 +575,6 @@ struct pci_dev { u8 supported_speeds; /* Supported Link Speeds Vector */ phys_addr_t rom; /* Physical address if not from BAR */ size_t romlen; /* Length if not from BAR */ - /* - * Driver name to force a match. Do not set directly, because core - * frees it. Use driver_set_override() to set or clear it. - */ - const char *driver_override; - unsigned long priv_flags; /* Private flags for the PCI driver */ /* These methods index pci_reset_fn_methods[] */ -- 2.53.0