From nobody Fri Jun 12 15:30:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B2CD47DD66; Tue, 5 May 2026 13:39:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988393; cv=none; b=dMe/TgZ8eUqBGs52yQVJkbHcaoTd1zyCRXqwN0ikdISLvsNagWTheF7M7K+uoWePd1rMqwpFsZ7LVRAOHLAzfzkkrbW1q2zo454qZKqDaqyvSQ3YOLXcV7uTOTP9fsc3GxU1hiJ5S4TERPuIau+QoSySbPw0aaLxMBnjRSKnr10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988393; c=relaxed/simple; bh=NcRSyq08XzhT27dPM3OyW2/65CqnGGNof3VyzjgXpkY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ldukjYD7i4diaP7QRWGcVQv7X7nDhkUohAvEKIwHRbPFFtAKRNQ9WncpzZCRivkgCOpxpmoL8sioeAsWqkzS80PjFThxwelhSsfRE6/RLwQ/l2Sp05NhytCX+gEnTtXZjGwwHVBYFU6K/2ZWyzFSU5fRHtIIbW2t5y6s+TNXOBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HX2jNred; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HX2jNred" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17C2CC2BCB9; Tue, 5 May 2026 13:39:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777988392; bh=NcRSyq08XzhT27dPM3OyW2/65CqnGGNof3VyzjgXpkY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HX2jNredAUTkneqERbse6tir4Lsoj6nH/q8unuSBYEE703WCP62DLIp3B79XXeRKR 3KBI+rvggdVDcdkGCtgjOqWoSm0z3fYkGNee0pAiAclDQ+eF7HKd4OoigFfhiPl96C YZVDloFrj7BoetPERTvbOC1EPkTwJHSwqHIEu6xisDCPFIqFwrF7r9RIOBSJYWuAwe KsOAFwpdDA6tQKmoLllVRR/IkI9ApElDiS2JJ9zuqo00f1EAjtuaFmVVEm24JvPLFQ dYnxTOb3lvgeeDIelDmdqfKekAxotWYTDvpj9QR2Zo56QDh2T/ARL1Zz7WVsAzOYiU GuAOscXPO+omQ== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, linux@armlinux.org.uk, nipun.gupta@amd.com, nikhil.agarwal@amd.com, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, andersson@kernel.org, mathieu.poirier@linaro.org Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Danilo Krummrich , Gui-Dong Han Subject: [PATCH v2 1/5] amba: use generic driver_override infrastructure Date: Tue, 5 May 2026 15:37:21 +0200 Message-ID: <20260505133935.3772495-2-dakr@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260505133935.3772495-1-dakr@kernel.org> References: <20260505133935.3772495-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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=3D220789 Fixes: 3cf385713460 ("ARM: 8256/1: driver coamba: add device binding path '= driver_override'") Signed-off-by: Danilo Krummrich Reviewed-by: Greg Kroah-Hartman --- drivers/amba/bus.c | 37 ++++++------------------------------- include/linux/amba/bus.h | 5 ----- 2 files changed, 6 insertions(+), 36 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 6d479caf89cb..d721d64a9858 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -82,33 +82,6 @@ static void amba_put_disable_pclk(struct amba_device *pc= dev) } =20 =20 -static ssize_t driver_override_show(struct device *_dev, - struct device_attribute *attr, char *buf) -{ - struct amba_device *dev =3D to_amba_device(_dev); - ssize_t len; - - device_lock(_dev); - len =3D sprintf(buf, "%s\n", dev->driver_override); - device_unlock(_dev); - return len; -} - -static ssize_t driver_override_store(struct device *_dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct amba_device *dev =3D to_amba_device(_dev); - int ret; - - ret =3D driver_set_override(_dev, &dev->driver_override, buf, count); - if (ret) - return ret; - - return count; -} -static DEVICE_ATTR_RW(driver_override); - #define amba_attr_func(name,fmt,arg...) \ static ssize_t name##_show(struct device *_dev, \ struct device_attribute *attr, char *buf) \ @@ -126,7 +99,6 @@ amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n", static struct attribute *amba_dev_attrs[] =3D { &dev_attr_id.attr, &dev_attr_resource.attr, - &dev_attr_driver_override.attr, NULL, }; ATTRIBUTE_GROUPS(amba_dev); @@ -209,10 +181,11 @@ static int amba_match(struct device *dev, const struc= t device_driver *drv) { struct amba_device *pcdev =3D to_amba_device(dev); const struct amba_driver *pcdrv =3D to_amba_driver(drv); + int ret; =20 mutex_lock(&pcdev->periphid_lock); if (!pcdev->periphid) { - int ret =3D amba_read_periphid(pcdev); + ret =3D amba_read_periphid(pcdev); =20 /* * Returning any error other than -EPROBE_DEFER from bus match @@ -230,8 +203,9 @@ static int amba_match(struct device *dev, const struct = device_driver *drv) mutex_unlock(&pcdev->periphid_lock); =20 /* When driver_override is set, only bind to the matching driver */ - if (pcdev->driver_override) - return !strcmp(pcdev->driver_override, drv->name); + ret =3D device_match_driver_override(dev, drv); + if (ret >=3D 0) + return ret; =20 return amba_lookup(pcdrv->id_table, pcdev) !=3D NULL; } @@ -436,6 +410,7 @@ static const struct dev_pm_ops amba_pm =3D { const struct bus_type amba_bustype =3D { .name =3D "amba", .dev_groups =3D amba_dev_groups, + .driver_override =3D true, .match =3D amba_match, .uevent =3D amba_uevent, .probe =3D amba_probe, diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 9946276aff73..6c54d5c0d21f 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -71,11 +71,6 @@ struct amba_device { unsigned int cid; struct amba_cs_uci_id uci; unsigned int irq[AMBA_NR_IRQS]; - /* - * 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; }; =20 struct amba_driver { --=20 2.54.0 From nobody Fri Jun 12 15:30:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D45053F1668; Tue, 5 May 2026 13:39:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988396; cv=none; b=gLBi3xxSWwb3EDksgXPpHbfdvr1o+GMfHJti28TGif/5rY+4McauxG7Kg3VcQcinkUaRF0VEFfCf2q4r7yTTDYzelJJYLPushuhUU9gyPt4rAWz+Z02aRJacTQ7H50Baryg20yDbP52cIYmF8eKrp3bsjcJtVJ1SKKVelmpDILQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988396; c=relaxed/simple; bh=kcjC/HW2HNG3Ncw9EG7raccDRsFJ6UdMh53CNSoiCUo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d6gE7z0a5WRBSvcAoPpeU8JbdX3mgNNIslhxDGGBnTgA9vpABMOgTO1IO8BOYI0ikBKuitFQXEZKMiANfbNS57NwnsDJEU0X6CwLiEPMuVEhDUfsdytrsSEG1iZvJoNNIMyqUAhzX5FoEWZvwvAR3a4x8DVcU8btD5pFuIOAyEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UJkdMEcM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UJkdMEcM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 23D77C2BCC7; Tue, 5 May 2026 13:39:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777988396; bh=kcjC/HW2HNG3Ncw9EG7raccDRsFJ6UdMh53CNSoiCUo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UJkdMEcMbB0ZInoqZtF8Lz16OhqvF0tVkjjLp70E0yP+jbd1xYCvyLq0vNC85+sGx EEKdlKd1uuQn6NF4G4GmK9A0EjwVnPGT+EKB7OZ2hVzxPFA+dh7gcwoTDnVPiZQpQ1 BhlviWzgsRGVtUfZvusHJB/I34Q9I1Vpysg+Dai8M/DVFRQy+jRwUEeutXfceg7bZS MCZvPxESr8RIBlxfMC0HnuFvaauOHgLpHA8+TDjVBbSdOnY6ivDWMSx1Z8VOAHzX8K sa8Je8oz2wn0rR4L3D7CgGAm4Bj449I44squSv43DQcrcuV8P7b5/SknzxD0hca3Fr Fp8pqGOEea5KA== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, linux@armlinux.org.uk, nipun.gupta@amd.com, nikhil.agarwal@amd.com, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, andersson@kernel.org, mathieu.poirier@linaro.org Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Danilo Krummrich , Gui-Dong Han Subject: [PATCH v2 2/5] cdx: use generic driver_override infrastructure Date: Tue, 5 May 2026 15:37:22 +0200 Message-ID: <20260505133935.3772495-3-dakr@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260505133935.3772495-1-dakr@kernel.org> References: <20260505133935.3772495-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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=3D220789 Fixes: 2959ab247061 ("cdx: add the cdx bus driver") Signed-off-by: Danilo Krummrich Reviewed-by: Greg Kroah-Hartman --- drivers/cdx/cdx.c | 40 +++++-------------------------------- include/linux/cdx/cdx_bus.h | 4 ---- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index 9196dc50a48d..d3d230247262 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -156,8 +156,6 @@ static int cdx_unregister_device(struct device *dev, } else { cdx_destroy_res_attr(cdx_dev, MAX_CDX_DEV_RESOURCES); debugfs_remove_recursive(cdx_dev->debugfs_dir); - kfree(cdx_dev->driver_override); - cdx_dev->driver_override =3D NULL; } =20 /* @@ -268,6 +266,7 @@ static int cdx_bus_match(struct device *dev, const stru= ct device_driver *drv) const struct cdx_driver *cdx_drv =3D to_cdx_driver(drv); const struct cdx_device_id *found_id =3D NULL; const struct cdx_device_id *ids; + int ret; =20 if (cdx_dev->is_bus) return false; @@ -275,7 +274,8 @@ static int cdx_bus_match(struct device *dev, const stru= ct device_driver *drv) ids =3D cdx_drv->match_id_table; =20 /* When driver_override is set, only bind to the matching driver */ - if (cdx_dev->driver_override && strcmp(cdx_dev->driver_override, drv->nam= e)) + ret =3D device_match_driver_override(dev, drv); + if (ret =3D=3D 0) return false; =20 found_id =3D cdx_match_id(ids, cdx_dev); @@ -289,7 +289,7 @@ static int cdx_bus_match(struct device *dev, const stru= ct device_driver *drv) */ if (!found_id->override_only) return true; - if (cdx_dev->driver_override) + if (ret > 0) return true; =20 ids =3D found_id + 1; @@ -453,36 +453,6 @@ static ssize_t modalias_show(struct device *dev, struc= t device_attribute *attr, } static DEVICE_ATTR_RO(modalias); =20 -static ssize_t driver_override_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cdx_device *cdx_dev =3D to_cdx_device(dev); - int ret; - - if (WARN_ON(dev->bus !=3D &cdx_bus_type)) - return -EINVAL; - - ret =3D driver_set_override(dev, &cdx_dev->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 cdx_device *cdx_dev =3D to_cdx_device(dev); - ssize_t len; - - device_lock(dev); - len =3D sysfs_emit(buf, "%s\n", cdx_dev->driver_override); - device_unlock(dev); - return len; -} -static DEVICE_ATTR_RW(driver_override); - static ssize_t enable_store(struct device *dev, struct device_attribute *a= ttr, const char *buf, size_t count) { @@ -552,7 +522,6 @@ static struct attribute *cdx_dev_attrs[] =3D { &dev_attr_class.attr, &dev_attr_revision.attr, &dev_attr_modalias.attr, - &dev_attr_driver_override.attr, NULL, }; =20 @@ -646,6 +615,7 @@ ATTRIBUTE_GROUPS(cdx_bus); =20 const struct bus_type cdx_bus_type =3D { .name =3D "cdx", + .driver_override =3D true, .match =3D cdx_bus_match, .probe =3D cdx_probe, .remove =3D cdx_remove, diff --git a/include/linux/cdx/cdx_bus.h b/include/linux/cdx/cdx_bus.h index b1ba97f6c9ad..f54770f110bc 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -137,9 +137,6 @@ struct cdx_controller { * @enabled: is this bus enabled * @msi_dev_id: MSI Device ID associated with CDX device * @num_msi: Number of MSI's supported by the device - * @driver_override: driver name to force a match; do not set directly, - * because core frees it; use driver_set_override() to - * set or clear it. * @irqchip_lock: lock to synchronize irq/msi configuration * @msi_write_pending: MSI write pending for this device */ @@ -165,7 +162,6 @@ struct cdx_device { bool enabled; u32 msi_dev_id; u32 num_msi; - const char *driver_override; struct mutex irqchip_lock; bool msi_write_pending; }; --=20 2.54.0 From nobody Fri Jun 12 15:30:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B28B4611CE; Tue, 5 May 2026 13:40:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988401; cv=none; b=SPW9i3uUkhP9WdOTlyfN/w63Gp6Dyp2489E1xnkNjK3OuXbfPbodBmMaGKesN5C+HOs9sGmyhRdfGxw3jQaYktfs1qNu6wwXr47ydkGX2voQBXLwTnpuYOTbt32F3Oq0tos7Q5JEKIuVyPCdxJQdyBjLGpnqwihNbRfYPDsD7IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988401; c=relaxed/simple; bh=8nwAo5XtwEc62prLYY61UbO6xY3/LUc3g4wHglEB8qA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tWqNmk90NKZBYU4hEJb5FP/QooyoVdlPZPOYWpNWc9zPYseOhoCYggFIZkF0o3yoDDeQKnOcjs/n2RZE5cv9xvJGgyOQ6xfmv0ughQkuXbNaDSVPcmJ/A8ojHN14faSReSX9qiZ68d2V2Y7d3KEFsNIZIs4el2r+R/JtpodxdxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D/8waH2J; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D/8waH2J" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2F258C2BCC7; Tue, 5 May 2026 13:39:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777988401; bh=8nwAo5XtwEc62prLYY61UbO6xY3/LUc3g4wHglEB8qA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D/8waH2J1efm3fz0FDPq1FWabuHQdeYVyf04A4+C1Lk2U0W8OECYgW/qGFk3xqne5 usouBZ3i/ChP6xllN8Uon1wMibaDaKUNUpWzH33tN6qnf7EF6k0Irp4OsCnUt2q6PK YqczwSGevx6Ep+SVKR4K4Y8cdx7WAb6wqiouwrNBZiK3m7e3lGzQ/mq9apxdOss9OR zy1jzRqNT5qPpxqygjbOTfr1YaET//D8hgdyB+QQH2s/nZ1XqiRpVJwZrpRVr79KjA 7KA5n8XW8fkGBmHV4UcQ4EhFLRAN7rmyZl+9Sn49uLfe6Q0YcRQa5s9xRUrEVIuZHY iTTexuMz0FB8w== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, linux@armlinux.org.uk, nipun.gupta@amd.com, nikhil.agarwal@amd.com, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, andersson@kernel.org, mathieu.poirier@linaro.org Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Danilo Krummrich , Michael Kelley , Gui-Dong Han Subject: [PATCH v2 3/5] Drivers: hv: vmbus: use generic driver_override infrastructure Date: Tue, 5 May 2026 15:37:23 +0200 Message-ID: <20260505133935.3772495-4-dakr@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260505133935.3772495-1-dakr@kernel.org> References: <20260505133935.3772495-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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] Tested-by: Michael Kelley Reviewed-by: Michael Kelley 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=3D220789 Fixes: d765edbb301c ("vmbus: add driver_override support") Signed-off-by: Danilo Krummrich Reviewed-by: Greg Kroah-Hartman --- drivers/hv/vmbus_drv.c | 43 ++++++++++-------------------------------- include/linux/hyperv.h | 5 ----- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index d28ff45d4cfd..acfb579828c5 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -538,34 +538,6 @@ static ssize_t device_show(struct device *dev, } static DEVICE_ATTR_RO(device); =20 -static ssize_t driver_override_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct hv_device *hv_dev =3D device_to_hv_device(dev); - int ret; - - ret =3D driver_set_override(dev, &hv_dev->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 hv_device *hv_dev =3D device_to_hv_device(dev); - ssize_t len; - - device_lock(dev); - len =3D sysfs_emit(buf, "%s\n", hv_dev->driver_override); - device_unlock(dev); - - return len; -} -static DEVICE_ATTR_RW(driver_override); - /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct attribute *vmbus_dev_attrs[] =3D { &dev_attr_id.attr, @@ -596,7 +568,6 @@ static struct attribute *vmbus_dev_attrs[] =3D { &dev_attr_channel_vp_mapping.attr, &dev_attr_vendor.attr, &dev_attr_device.attr, - &dev_attr_driver_override.attr, NULL, }; =20 @@ -708,9 +679,11 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_i= d(const struct hv_driver * { const guid_t *guid =3D &dev->dev_type; const struct hv_vmbus_device_id *id; + int ret; =20 - /* When driver_override is set, only bind to the matching driver */ - if (dev->driver_override && strcmp(dev->driver_override, drv->name)) + /* If a driver override is set, only bind to the matching driver */ + ret =3D device_match_driver_override(&dev->device, &drv->driver); + if (ret =3D=3D 0) return NULL; =20 /* Look at the dynamic ids first, before the static ones */ @@ -718,8 +691,11 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_i= d(const struct hv_driver * if (!id) id =3D hv_vmbus_dev_match(drv->id_table, guid); =20 - /* driver_override will always match, send a dummy id */ - if (!id && dev->driver_override) + /* + * If there's a matching driver override, this function should succeed, + * thus return a dummy device ID if no matching ID is found. + */ + if (!id && ret > 0) id =3D &vmbus_device_null; =20 return id; @@ -1021,6 +997,7 @@ static const struct dev_pm_ops vmbus_pm =3D { /* The one and only one */ static const struct bus_type hv_bus =3D { .name =3D "vmbus", + .driver_override =3D true, .match =3D vmbus_match, .shutdown =3D vmbus_shutdown, .remove =3D vmbus_remove, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 964f1be8150c..c054d7eff622 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1272,11 +1272,6 @@ struct hv_device { u16 device_id; =20 struct device device; - /* - * 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; =20 struct vmbus_channel *channel; struct kset *channels_kset; --=20 2.54.0 From nobody Fri Jun 12 15:30:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 795B247DD78; Tue, 5 May 2026 13:40:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988405; cv=none; b=K4tVHYxhNUoj1HUhi8fR+KlqDrHSjfb68JlAUGsTjzUO3vUcpyet8R79vRu/HJhVVv80ggG62uNfh8P3CBvfO4RrGVBFK853UNZ6ClMq1ZMepxPx1ZrreRBN0lzn7I19AB3Ud47vNGYeDneBGpMB+rtzH1m64ifn+DPRykUGO9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988405; c=relaxed/simple; bh=LK8IkkFTgLbdStn+mktChL466NCohdt3Re2nhTssJgA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gofMVOcIvnGwnlNqrNsWwBmOQH9iIZp1MBWwz9ptqHHmOM4ifpVN5/W+yWIqPrS7N6AAnaRK+T3wTcoEhGOiepDFg2SWbn6ngjdO6zdi44NX7EQGEyaUGvv8JOIK0SCnYy5AB3Sa9sSZ/qon2n+94EWm5E/kIKSAxNnRYORTkfc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q6NuB8Aq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q6NuB8Aq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 724B6C2BCB9; Tue, 5 May 2026 13:40:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777988405; bh=LK8IkkFTgLbdStn+mktChL466NCohdt3Re2nhTssJgA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q6NuB8AqXkJshNwcvRpB1BLObhW0Lj7jVeTW3slo3BSDzoa8cTMYjELe0iVcsjSEw tGr0NTl/PurgEPmfXKrktXZb8A0bUw6IblxAVNO+ovPVmNtH/rZTqARqg4yUwQVYbO RPQ1ofQ06xMqnsTd7UkjSyG0gveQioTNT6nyASSkAJpCsPzG16ytU5DJPXQEKvwAqY PlE41SEXTVG+z3uVdr6chCJRRLg88t+6VGofcAgMmjb7qq9LVtnSbHZbB/XpkAK0cx GCaIi/+a+K8BOOpuLS1dnTSCQDlMY13kWM7G57kmv0GCRNAD4gF24dXcLW9n4Cxe0s CWTZI2XUQpzAA== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, linux@armlinux.org.uk, nipun.gupta@amd.com, nikhil.agarwal@amd.com, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, andersson@kernel.org, mathieu.poirier@linaro.org Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Danilo Krummrich , Gui-Dong Han Subject: [PATCH v2 4/5] rpmsg: use generic driver_override infrastructure Date: Tue, 5 May 2026 15:37:24 +0200 Message-ID: <20260505133935.3772495-5-dakr@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260505133935.3772495-1-dakr@kernel.org> References: <20260505133935.3772495-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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=3D220789 Fixes: e95060478244 ("rpmsg: Introduce a driver override mechanism") Reviewed-by: Mathieu Poirier Signed-off-by: Danilo Krummrich Reviewed-by: Greg Kroah-Hartman --- drivers/rpmsg/qcom_glink_native.c | 2 -- drivers/rpmsg/rpmsg_core.c | 43 +++++-------------------------- drivers/rpmsg/virtio_rpmsg_bus.c | 1 - include/linux/rpmsg.h | 4 --- 4 files changed, 7 insertions(+), 43 deletions(-) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_n= ative.c index 401a4ece0c97..d9d4468e4cbd 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1626,7 +1626,6 @@ static void qcom_glink_rpdev_release(struct device *d= ev) { struct rpmsg_device *rpdev =3D to_rpmsg_device(dev); =20 - kfree(rpdev->driver_override); kfree(rpdev); } =20 @@ -1862,7 +1861,6 @@ static void qcom_glink_device_release(struct device *= dev) =20 /* Release qcom_glink_alloc_channel() reference */ kref_put(&channel->refcount, qcom_glink_channel_release); - kfree(rpdev->driver_override); kfree(rpdev); } =20 diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index e7f7831d37f8..c56f69c22e42 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -358,33 +358,6 @@ rpmsg_show_attr(src, src, "0x%x\n"); rpmsg_show_attr(dst, dst, "0x%x\n"); rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n"); =20 -static ssize_t driver_override_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct rpmsg_device *rpdev =3D to_rpmsg_device(dev); - int ret; - - ret =3D driver_set_override(dev, &rpdev->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 rpmsg_device *rpdev =3D to_rpmsg_device(dev); - ssize_t len; - - device_lock(dev); - len =3D sysfs_emit(buf, "%s\n", rpdev->driver_override); - device_unlock(dev); - return len; -} -static DEVICE_ATTR_RW(driver_override); - static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -405,7 +378,6 @@ static struct attribute *rpmsg_dev_attrs[] =3D { &dev_attr_dst.attr, &dev_attr_src.attr, &dev_attr_announce.attr, - &dev_attr_driver_override.attr, NULL, }; ATTRIBUTE_GROUPS(rpmsg_dev); @@ -424,9 +396,11 @@ static int rpmsg_dev_match(struct device *dev, const s= truct device_driver *drv) const struct rpmsg_driver *rpdrv =3D to_rpmsg_driver(drv); const struct rpmsg_device_id *ids =3D rpdrv->id_table; unsigned int i; + int ret; =20 - if (rpdev->driver_override) - return !strcmp(rpdev->driver_override, drv->name); + ret =3D device_match_driver_override(dev, drv); + if (ret >=3D 0) + return ret; =20 if (ids) for (i =3D 0; ids[i].name[0]; i++) @@ -535,6 +509,7 @@ static const struct bus_type rpmsg_bus =3D { .name =3D "rpmsg", .match =3D rpmsg_dev_match, .dev_groups =3D rpmsg_dev_groups, + .driver_override =3D true, .uevent =3D rpmsg_uevent, .probe =3D rpmsg_dev_probe, .remove =3D rpmsg_dev_remove, @@ -560,11 +535,9 @@ int rpmsg_register_device_override(struct rpmsg_device= *rpdev, =20 device_initialize(dev); if (driver_override) { - ret =3D driver_set_override(dev, &rpdev->driver_override, - driver_override, - strlen(driver_override)); + ret =3D device_set_driver_override(dev, driver_override); if (ret) { - dev_err(dev, "device_set_override failed: %d\n", ret); + dev_err(dev, "device_set_driver_override() failed: %d\n", ret); put_device(dev); return ret; } @@ -573,8 +546,6 @@ int rpmsg_register_device_override(struct rpmsg_device = *rpdev, ret =3D device_add(dev); if (ret) { dev_err(dev, "device_add failed: %d\n", ret); - kfree(rpdev->driver_override); - rpdev->driver_override =3D NULL; put_device(dev); } =20 diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_= bus.c index 5ae15111fb4f..1b8bb05924af 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -374,7 +374,6 @@ static void virtio_rpmsg_release_device(struct device *= dev) struct rpmsg_device *rpdev =3D to_rpmsg_device(dev); struct virtio_rpmsg_channel *vch =3D to_virtio_rpmsg_channel(rpdev); =20 - kfree(rpdev->driver_override); kfree(vch); } =20 diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 83266ce14642..2e40eb54155e 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -41,9 +41,6 @@ struct rpmsg_channel_info { * rpmsg_device - device that belong to the rpmsg bus * @dev: the device struct * @id: device id (used to match between rpmsg drivers and devices) - * @driver_override: driver name to force a match; do not set directly, - * because core frees it; use driver_set_override() to - * set or clear it. * @src: local address * @dst: destination address * @ept: the rpmsg endpoint of this channel @@ -53,7 +50,6 @@ struct rpmsg_channel_info { struct rpmsg_device { struct device dev; struct rpmsg_device_id id; - const char *driver_override; u32 src; u32 dst; struct rpmsg_endpoint *ept; --=20 2.54.0 From nobody Fri Jun 12 15:30:50 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5752047DFBF; Tue, 5 May 2026 13:40:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988409; cv=none; b=BI/vJ7pFEyqmrqfsw3GdM/NuAweIRQL1SHOT3li7Scuj4dXyEJ7XjyscF4KRQLOXxmXj/lPKRA+diYoG7COe65rfcZnOxXypG1tXyt5hQVoijUx9d7D7IPjLlb+bQsokE/jaoMefZeYBrWzkPaY4kwkzB+8/obkuLhIzAmNbuPg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777988409; c=relaxed/simple; bh=enQ/kAE46gHWFkx72vT1p5afv0nIyc37eTTmR0xPPp0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NHTuAHFqrBEK6LQEf4EusjOV3q/hx1eml7TPtMTNiOt9uMUE9Xpav1oTwDi1jRTOR45J/AkWsXcyTF6wMzFiGLAoWdfvhVeNM9wE8uD65i8NxZ7itfT3IF1cX+nchdeLdh56QGKg6Q6mWUy2kcM1sNhoavlhxdm80avCm6dqw1o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hgTWVgBn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hgTWVgBn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E726C2BCB4; Tue, 5 May 2026 13:40:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777988408; bh=enQ/kAE46gHWFkx72vT1p5afv0nIyc37eTTmR0xPPp0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hgTWVgBn2k2vD++6osj/Kv2LEBVXP4pPJ00tFXFMWSXzbfrkgludFr/5/BH6DB7ci 9f7IkJPx12KmXwtpbVwftKqmXqMPjC6Selkp+WVf7O72fm9lrCVEUhpqqMToEywMZx whznVCgNNsmRenBLfdzUEXWBN3DcqVyrKxsjZ/I8nqfnmUPwnI4x2V88PqNFS2sNXA dl8a5obHr8hzsiaQikP/gD+wMuC5mPjl3Ag1pTSNaJezCguayYitHTn55riXn9GG22 wHjBuF9gvFDs0pmR75xr9GMB20lcSFS3oK5uBRhGlPKQRjOvjMn9duO26CMuvNcSfe fgdroxm2KJXYQ== From: Danilo Krummrich To: gregkh@linuxfoundation.org, rafael@kernel.org, linux@armlinux.org.uk, nipun.gupta@amd.com, nikhil.agarwal@amd.com, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, andersson@kernel.org, mathieu.poirier@linaro.org Cc: driver-core@lists.linux.dev, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Danilo Krummrich Subject: [PATCH v2 5/5] driver core: remove driver_set_override() Date: Tue, 5 May 2026 15:37:25 +0200 Message-ID: <20260505133935.3772495-6-dakr@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260505133935.3772495-1-dakr@kernel.org> References: <20260505133935.3772495-1-dakr@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" All buses have been converted from driver_set_override() to the generic driver_override infrastructure introduced in commit cb3d1049f4ea ("driver core: generalize driver_override in struct device"). Buses now either opt into the generic sysfs callbacks via the bus_type::driver_override flag, or use device_set_driver_override() / __device_set_driver_override() directly. Thus, remove the now-unused driver_set_override() helper. Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D220789 Reviewed-by: Greg Kroah-Hartman Signed-off-by: Danilo Krummrich --- drivers/base/driver.c | 75 ----------------------------------- include/linux/device/driver.h | 2 - 2 files changed, 77 deletions(-) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 8ab010ddf709..7ed834f7199c 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -30,81 +30,6 @@ static struct device *next_device(struct klist_iter *i) return dev; } =20 -/** - * driver_set_override() - Helper to set or clear driver override. - * @dev: Device to change - * @override: Address of string to change (e.g. &device->driver_override); - * The contents will be freed and hold newly allocated override. - * @s: NUL-terminated string, new driver name to force a match, pass empty - * string to clear it ("" or "\n", where the latter is only for sysfs - * interface). - * @len: length of @s - * - * Helper to set or clear driver override in a device, intended for the ca= ses - * when the driver_override field is allocated by driver/bus code. - * - * Returns: 0 on success or a negative error code on failure. - */ -int driver_set_override(struct device *dev, const char **override, - const char *s, size_t len) -{ - const char *new, *old; - char *cp; - - if (!override || !s) - return -EINVAL; - - /* - * The stored value will be used in sysfs show callback (sysfs_emit()), - * which has a length limit of PAGE_SIZE and adds a trailing newline. - * Thus we can store one character less to avoid truncation during sysfs - * show. - */ - if (len >=3D (PAGE_SIZE - 1)) - return -EINVAL; - - /* - * Compute the real length of the string in case userspace sends us a - * bunch of \0 characters like python likes to do. - */ - len =3D strlen(s); - - if (!len) { - /* Empty string passed - clear override */ - device_lock(dev); - old =3D *override; - *override =3D NULL; - device_unlock(dev); - kfree(old); - - return 0; - } - - cp =3D strnchr(s, len, '\n'); - if (cp) - len =3D cp - s; - - new =3D kstrndup(s, len, GFP_KERNEL); - if (!new) - return -ENOMEM; - - device_lock(dev); - old =3D *override; - if (cp !=3D s) { - *override =3D new; - } else { - /* "\n" passed - clear override */ - kfree(new); - *override =3D NULL; - } - device_unlock(dev); - - kfree(old); - - return 0; -} -EXPORT_SYMBOL_GPL(driver_set_override); - /** * driver_for_each_device - Iterator for devices bound to a driver. * @drv: Driver we're iterating. diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index bbc67ec513ed..aa3465a369f0 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -160,8 +160,6 @@ int __must_check driver_create_file(const struct device= _driver *driver, void driver_remove_file(const struct device_driver *driver, const struct driver_attribute *attr); =20 -int driver_set_override(struct device *dev, const char **override, - const char *s, size_t len); int __must_check driver_for_each_device(struct device_driver *drv, struct = device *start, void *data, device_iter_t fn); struct device *driver_find_device(const struct device_driver *drv, --=20 2.54.0