From nobody Mon Jun 8 09:49:55 2026 Received: from mail-m155101.qiye.163.com (mail-m155101.qiye.163.com [101.71.155.101]) (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 EEA4F2701CB; Thu, 4 Jun 2026 03:58:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=101.71.155.101 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545491; cv=none; b=tOwGGTq/BnDPsJFN5Cg0AETifcBwD2idW4EVUSEEXsmcb/H4jjvLJRQ7w7s/uJ2W8OfjEkTIkX2dvHwp/PX0min8oIvcorbT+00BJ3+d2INcFBupHDIFlf99GfpoqGL2u+rjuShekpawXWOITjEuTjNH209tDYLE8MiTBEDR4DU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545491; c=relaxed/simple; bh=mNZ1GDdeH4uwSNEskQtaK3mU/n0GrVC7IQtyPX4yIfg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XKQLnmn92S+6t3DB088jS1RFR/zi49JGSgNnigO0h/KQUqd64PogSujA0b0BovlqKjGuQ6FYkFL4V70hgCZvxn2Bbx9LCjMJzYaheZED5nkPeoTmmotnxCPPYqwHdWGMT9HS+VzkvGvh1HrPzQmGTY1YNVcKrGGtPnj86RdmSUA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn; spf=pass smtp.mailfrom=seu.edu.cn; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b=E3XCGpLT; arc=none smtp.client-ip=101.71.155.101 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b="E3XCGpLT" Received: from PC-202605011814.localdomain (unknown [221.228.238.82]) by smtp.qiye.163.com (Hmail) with ESMTP id 4103cca51; Thu, 4 Jun 2026 11:52:48 +0800 (GMT+08:00) From: Runyu Xiao To: gregkh@linuxfoundation.org, rafael@kernel.org Cc: dakr@kernel.org, driver-core@lists.linux.dev, linux@armlinux.org.uk, andersson@kernel.org, mathieu.poirier@linaro.org, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, nipun.gupta@amd.com, nikhil.agarwal@amd.com, linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, jianhao.xu@seu.edu.cn, runyu.xiao@seu.edu.cn, stable@vger.kernel.org Subject: [PATCH v2 1/4] amba: use generic driver_override infrastructure Date: Thu, 4 Jun 2026 11:52:36 +0800 Message-Id: <20260604035239.1711889-2-runyu.xiao@seu.edu.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> References: <20260602160829.560904-1-runyu.xiao@seu.edu.cn> <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> 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 X-HM-Tid: 0a9e90c3249303a1kunm0f81216d28d05 X-HM-MType: 10 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVkaTR9KVkgfSx0fGBpOSR8ZH1YeHw 5VEwETFhoSFyQUDg9ZV1kYEgtZQVlJSUpVSUlDVUlIQ1VDSVlXWRYaDxIVHRRZQVlPS0hVSktISk 9ITFVKS0tVSkJLS1kG DKIM-Signature: a=rsa-sha256; b=E3XCGpLTScDDYzL6qRyozB8RVSYopFL74DFF4A8qmLU8AT2aFZ0QQtwuqqUsUnKUrtK7ggMN8APCsPqelSqB1EAVZoVmsNtP4rPdhNBYe/ewdu5R7xg3ZovAebsyAYkIgcK07+DYVskkLNQCz+T+jUS/2jj0iDGp2jzb28jFW3M=; s=default; c=relaxed/relaxed; d=seu.edu.cn; v=1; bh=KafM4DmA77CwDJeuq1wWiXL3B4CRMhrjGZoxZOBTnXQ=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" AMBA devices still keep driver_override in bus-private storage. The sysfs write side updates that string through driver_set_override(), which replaces the pointer and frees the old value. However, driver_match_device() can call amba_match() from __driver_attach() without holding the device lock, and amba_match() still dereferences that private pointer directly. That means a bind/unbind or reprobe path can race with a concurrent driver_override update and make amba_match() compare against freed memory. Fix this by switching AMBA to the driver-core driver_override infrastructure. This lets the core own the sysfs attribute and storage, and uses device_match_driver_override() for the locked read in the match path. Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel= .org/ Fixes: 3cf385713460 ("ARM: 8256/1: driver coamba: add device binding path '= driver_override'") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao --- drivers/amba/bus.c | 35 +++++------------------------------ include/linux/amba/bus.h | 5 ----- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 6d479caf89cb..df8333f90906 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,6 +181,7 @@ static int amba_match(struct device *dev, const struct = 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) { @@ -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; } @@ -435,6 +409,7 @@ static const struct dev_pm_ops amba_pm =3D { */ const struct bus_type amba_bustype =3D { .name =3D "amba", + .driver_override =3D true, .dev_groups =3D amba_dev_groups, .match =3D amba_match, .uevent =3D amba_uevent, 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.34.1 From nobody Mon Jun 8 09:49:55 2026 Received: from mail-m49198.qiye.163.com (mail-m49198.qiye.163.com [45.254.49.198]) (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 9196A385D64; Thu, 4 Jun 2026 03:58:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.254.49.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545492; cv=none; b=V7XTQ2m/K7X1M9boFJK1lmcn2C1ZijAO8LfdP3zDYiTO0iMSeDwq7DGbwcNo8X2VJoCVWCTRP4EHPwBe9ozlgLx2xSQsRsDrikVSBD8TnLu8b0/FPrz4DgoGJDcY+GDcn+cBiXiEn+P55PJsmQx4lda31L5AizEtVJ3KeShw4cc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545492; c=relaxed/simple; bh=SMAFTtvZKj1tGxbRkVNkrcfNuKUXUgt/xlwD1tg2SEo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ggSZ2Vx1lWENjbMhAJuKQsxWbUTwQWhRoTBXvQ7uhd+KWFKodJQUofgXx/9KtgcfMzVEzyPlLcJeLpTFWSwraqp6bj/toVxNGaNXohYabfq/dyUjQ/7tPlCQAVtcqNzypviI2nSFd8TIc6ELmY3qvp2LH/D57MTxQDzaMJIlHBc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn; spf=pass smtp.mailfrom=seu.edu.cn; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b=Z+ZpfeIl; arc=none smtp.client-ip=45.254.49.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b="Z+ZpfeIl" Received: from PC-202605011814.localdomain (unknown [221.228.238.82]) by smtp.qiye.163.com (Hmail) with ESMTP id 4103cca53; Thu, 4 Jun 2026 11:52:50 +0800 (GMT+08:00) From: Runyu Xiao To: gregkh@linuxfoundation.org, rafael@kernel.org Cc: dakr@kernel.org, driver-core@lists.linux.dev, linux@armlinux.org.uk, andersson@kernel.org, mathieu.poirier@linaro.org, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, nipun.gupta@amd.com, nikhil.agarwal@amd.com, linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, jianhao.xu@seu.edu.cn, runyu.xiao@seu.edu.cn, stable@vger.kernel.org Subject: [PATCH v2 2/4] rpmsg: core: use generic driver_override infrastructure Date: Thu, 4 Jun 2026 11:52:37 +0800 Message-Id: <20260604035239.1711889-3-runyu.xiao@seu.edu.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> References: <20260602160829.560904-1-runyu.xiao@seu.edu.cn> <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> 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 X-HM-Tid: 0a9e90c32b3b03a1kunm0f81216d28d0c X-HM-MType: 10 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVlCQ01KVk5CSBhIGEwZTktMSlYeHw 5VEwETFhoSFyQUDg9ZV1kYEgtZQVlJSUpVSUlDVUlIQ1VDSVlXWRYaDxIVHRRZQVlPS0hVSktISk 9ITFVKS0tVSkJLS1kG DKIM-Signature: a=rsa-sha256; b=Z+ZpfeIlcsyakIp+2dJdmyLiafu+Q1ewvgfSJUPRMq1+iFblMZVbCm2i+mrbvCaWqy5XqZJY3RnWSI4Mb2tDiE/1iHtdla+5Lxr8GEAO+YCShf0DEbXws4w8FrzBlYSjYrbRrsK2uariKlpARqKL0qqAPE6XxKIFH7QlFE6qsh0=; s=default; c=relaxed/relaxed; d=seu.edu.cn; v=1; bh=4m5lAv5Y2vm0X6WsxxKQwzOypiG0pQhWs1EBrVLkQNM=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" RPMSG still keeps driver_override in bus-private storage. That private pointer can be updated from the sysfs driver_override attribute, and also from rpmsg_register_device_override(). Both paths replace the pointer and can free the old value. However, driver_match_device() can call rpmsg_dev_match() from __driver_attach() without holding the device lock, and rpmsg_dev_match() still dereferences that private pointer directly. This leaves the match path racing with concurrent driver_override updates, with the usual risk of comparing against freed memory. Switch rpmsg to the driver-core driver_override infrastructure. This removes the private storage, uses device_match_driver_override() for the locked read in rpmsg_dev_match(), and converts rpmsg_register_device_override() to device_set_driver_override() so the in-kernel override path uses the same core-managed storage. With that storage now owned by struct device, drop the remaining rpmsg transport release-path frees of rpdev->driver_override as well. Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel= .org/ Fixes: 39e47767ec9b ("rpmsg: Add driver_override device attribute for rpmsg= _device") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao --- drivers/rpmsg/qcom_glink_native.c | 2 -- drivers/rpmsg/rpmsg_core.c | 41 ++++++------------------------------= -- drivers/rpmsg/virtio_rpmsg_bus.c | 1 - include/linux/rpmsg.h | 4 ---- 4 files changed, 6 insertions(+), 42 deletions(-) diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index e7f7831d37f8..11d3007db5cd 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++) @@ -533,6 +507,7 @@ static void rpmsg_dev_remove(struct device *dev) =20 static const struct bus_type rpmsg_bus =3D { .name =3D "rpmsg", + .driver_override =3D true, .match =3D rpmsg_dev_match, .dev_groups =3D rpmsg_dev_groups, .uevent =3D rpmsg_uevent, @@ -560,9 +535,7 @@ 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); put_device(dev); @@ -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/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/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.34.1 From nobody Mon Jun 8 09:49:55 2026 Received: from mail-m49197.qiye.163.com (mail-m49197.qiye.163.com [45.254.49.197]) (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 336A03AFB01; Thu, 4 Jun 2026 03:58:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.254.49.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545502; cv=none; b=okK4/0BXi0AEGuBmwkIFNpKIFCVh4ftimJPjEWlXzWwMDMdrZs1RluD3gD6GpRPLiy5xDjiR7Bs+zXxQdV29FnNwf6fuJtXhWOspURDlk/Nc6yc0DJe+dmuKLng2NQhl3LViB57OjckVRCg2ltIAfHLbWMI+/C589cyTLBVOCr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545502; c=relaxed/simple; bh=m2r3NnCy/KZ84xotuXv71W3230SYAAJzBbEbXOOXLXA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LPnzivW9BnNkyyG2AxmVwcJjvCgosfgrLBz79TE2ubz8jz5Sh7eL5qj+UyCSiDhZlfYTXqyNcfHPpSVB6Gd+yE3G9plqT+qqU57qKjzxFSkElgfjktnbvDxHbGAJ/lFX4wH/nyZiOaAaul+wm/ZrFmzzVAE7B06ElbxgCM7FX+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn; spf=pass smtp.mailfrom=seu.edu.cn; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b=LSLVJ0ra; arc=none smtp.client-ip=45.254.49.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b="LSLVJ0ra" Received: from PC-202605011814.localdomain (unknown [221.228.238.82]) by smtp.qiye.163.com (Hmail) with ESMTP id 4103cca56; Thu, 4 Jun 2026 11:52:53 +0800 (GMT+08:00) From: Runyu Xiao To: gregkh@linuxfoundation.org, rafael@kernel.org Cc: dakr@kernel.org, driver-core@lists.linux.dev, linux@armlinux.org.uk, andersson@kernel.org, mathieu.poirier@linaro.org, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, nipun.gupta@amd.com, nikhil.agarwal@amd.com, linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, jianhao.xu@seu.edu.cn, runyu.xiao@seu.edu.cn, stable@vger.kernel.org Subject: [PATCH v2 3/4] vmbus: use generic driver_override infrastructure Date: Thu, 4 Jun 2026 11:52:38 +0800 Message-Id: <20260604035239.1711889-4-runyu.xiao@seu.edu.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> References: <20260602160829.560904-1-runyu.xiao@seu.edu.cn> <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> 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 X-HM-Tid: 0a9e90c337db03a1kunm0f81216d28d16 X-HM-MType: 10 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVkZQ0xJVk5NH05JSk0YH08ZH1YeHw 5VEwETFhoSFyQUDg9ZV1kYEgtZQVlJSUpVSUlDVUlIQ1VDSVlXWRYaDxIVHRRZQVlPS0hVSktISk 9ITFVKS0tVSkJLS1kG DKIM-Signature: a=rsa-sha256; b=LSLVJ0raer3sjupnvQRNaKHY/z4PoUoLkIehpjSWd0fRNN+6OkVsCv3khotgx6wZa7J6GZKBfvF17jJhZess5RurpNSUWU2llTJFBo1D6kTW7Bl7XBRg6y2cvxNGw4FUPkq5jzCwNJXGHpIVkOIs0/CzHHIWetOpMUQODPuZ5rE=; s=default; c=relaxed/relaxed; d=seu.edu.cn; v=1; bh=1saAZ4M5FGw32ryywngoGqoPoT+AUfoWbT4m71a/aNs=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" VMBUS devices still keep driver_override in bus-private storage. The sysfs write side updates that string through driver_set_override(), which replaces the pointer and frees the old value. However, driver_match_device() can call into hv_vmbus_get_id() from __driver_attach() without holding the device lock, and hv_vmbus_get_id() still dereferences that private pointer directly. That means a bind/reprobe path can race with a concurrent driver_override update and make the match logic inspect freed memory. Switch vmbus to the driver-core driver_override infrastructure. This removes the private driver_override storage and uses device_match_driver_override() for the locked read in the match path. Keep the existing vmbus semantics intact: if driver_override matches but no dynamic or static device ID matches, continue to return the dummy vmbus_device_null ID so override-only binding still works as before. Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel= .org/ Fixes: d765edbb301c ("vmbus: add driver_override support") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao --- drivers/hv/vmbus_drv.c | 36 +++++------------------------------- include/linux/hyperv.h | 6 ------ 2 files changed, 5 insertions(+), 37 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index d28ff45d4cfd..a81e2b097636 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)) + 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 */ @@ -719,7 +692,7 @@ static const struct hv_vmbus_device_id *hv_vmbus_get_id= (const struct hv_driver * 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 (!id && ret > 0) id =3D &vmbus_device_null; =20 return id; @@ -1021,6 +994,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..f9ede569602d 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1272,12 +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; - struct vmbus_channel *channel; struct kset *channels_kset; struct device_dma_parameters dma_parms; --=20 2.34.1 From nobody Mon Jun 8 09:49:55 2026 Received: from mail-m49198.qiye.163.com (mail-m49198.qiye.163.com [45.254.49.198]) (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 2A17D72617; Thu, 4 Jun 2026 03:58:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.254.49.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545493; cv=none; b=AwbVnnLPQBLEFE2GxMAwt5L/1GUEbqxmmkjBPJb5LHT1VcAq7bIDksZmKomOyHZb3zzW761sbk95Re9QuPp/d2pXd9k1hK4kWa1xoS6wSLxvsP2aCEKcBdQ+x+mCZg+oUOwDLRYXpVHqDjJI/XHyi36nk+XLMkCtUrlFSLwjZCk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780545493; c=relaxed/simple; bh=aZLwY/9EDQ02XdFP+3inxUVP43n/84nghC9Ko7Zn+tA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jeSu9bc0rSifw5nEsUHK0C+WWICpEzIn2XHf4VBebIb18GLB4rkWgOISpjpR4xs78zsy3+hy6lAOV7EK+kloqtlJWLwJAnBltoxPqWjY/7WmoH9B279Uyt40BN3cSXGJsRsC++uDjOn38ySal6zyHoQI7Y8ev8Ch4O93IZQWB0M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn; spf=pass smtp.mailfrom=seu.edu.cn; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b=L0ePJB2Z; arc=none smtp.client-ip=45.254.49.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seu.edu.cn Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=seu.edu.cn header.i=@seu.edu.cn header.b="L0ePJB2Z" Received: from PC-202605011814.localdomain (unknown [221.228.238.82]) by smtp.qiye.163.com (Hmail) with ESMTP id 4103cca57; Thu, 4 Jun 2026 11:52:56 +0800 (GMT+08:00) From: Runyu Xiao To: gregkh@linuxfoundation.org, rafael@kernel.org Cc: dakr@kernel.org, driver-core@lists.linux.dev, linux@armlinux.org.uk, andersson@kernel.org, mathieu.poirier@linaro.org, kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, longli@microsoft.com, nipun.gupta@amd.com, nikhil.agarwal@amd.com, linux-remoteproc@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, jianhao.xu@seu.edu.cn, runyu.xiao@seu.edu.cn, stable@vger.kernel.org Subject: [PATCH v2 4/4] cdx: use generic driver_override infrastructure Date: Thu, 4 Jun 2026 11:52:39 +0800 Message-Id: <20260604035239.1711889-5-runyu.xiao@seu.edu.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> References: <20260602160829.560904-1-runyu.xiao@seu.edu.cn> <20260604035239.1711889-1-runyu.xiao@seu.edu.cn> 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 X-HM-Tid: 0a9e90c3458003a1kunm0f81216d28d1b X-HM-MType: 10 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVkZTEsdVkoYGh8eHkMaQ0NPSVYeHw 5VEwETFhoSFyQUDg9ZV1kYEgtZQVlJSUpVSUlDVUlIQ1VDSVlXWRYaDxIVHRRZQVlPS0hVSktISk 9ITFVKS0tVSkJLS1kG DKIM-Signature: a=rsa-sha256; b=L0ePJB2Zgla5W6w8PmnPsi0MIHdQdH/3TgkcwGvhOJdJw8MD7UEzgg0Vyn3r8/0Rf97EMJrK8ONmOTIxiNTNsqcguPSKNzBsF/cbNK1YOc41xQsIelpXuxocnGbCywF7j3u4MNjSb1/THblDMq/4qp4AMtXXF6skWSjr6g9aQkQ=; s=default; c=relaxed/relaxed; d=seu.edu.cn; v=1; bh=0XPOIhxg2F68hBRjE6rRRrqxSXoozAE1hg6WZ/Tun+U=; h=date:mime-version:subject:message-id:from; Content-Type: text/plain; charset="utf-8" CDX devices still keep driver_override in bus-private storage. The sysfs write side updates that string through driver_set_override(), which replaces the pointer and frees the old value. However, driver_match_device() can call cdx_bus_match() from __driver_attach() without holding the device lock, and cdx_bus_match() still dereferences that private pointer directly. That means the CDX match path can race with a concurrent driver_override update and compare against freed memory. Switch CDX to the driver-core driver_override infrastructure. This removes the private driver_override storage, lets the core provide the sysfs attribute, and uses device_match_driver_override() for the locked read in cdx_bus_match(). Preserve the existing CDX override_only semantics: entries marked override_only still require a matching driver_override, but ordinary ID matches continue to work unchanged. Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel= .org/ Fixes: 48a6c7bced2a ("cdx: add device attributes") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao --- drivers/cdx/cdx.c | 40 +++++-------------------------------- include/linux/cdx/cdx_bus.h | 1 - 2 files changed, 5 insertions(+), 36 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..f1a107b232da 100644 --- a/include/linux/cdx/cdx_bus.h +++ b/include/linux/cdx/cdx_bus.h @@ -165,7 +165,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.34.1