lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260201093002.1281858-3-ming.li@zohomail.com>
Date: Sun,  1 Feb 2026 17:30:02 +0800
From: Li Ming <ming.li@...omail.com>
To: dave@...olabs.net,
	jonathan.cameron@...wei.com,
	dave.jiang@...el.com,
	alison.schofield@...el.com,
	vishal.l.verma@...el.com,
	ira.weiny@...el.com,
	dan.j.williams@...el.com
Cc: linux-cxl@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Li Ming <ming.li@...omail.com>
Subject: [PATCH 2/2] cxl/core: Hold grandparent port lock while dport adding

When CXL subsystem adds a cxl port to a hierarchy, there is a small
window where the new port becomes visible before it is bound to a
driver. This happens because device_add() adds a device to bus device
list before bus_probe_device() binds it to a driver.
So if two cxl memdevs are trying to add a dport to a same port via
devm_cxl_enumerate_ports(), the second cxl memdev may observe the port
and attempt to add a dport, but fails because the port has not yet been
attached to cxl port driver.
the sequence is like:

CPU 0					CPU 1
devm_cxl_enumerate_ports()
  # port not found, add it
  add_port_attach_ep()
    # hold the parent port lock
    # to add the new port
    devm_cxl_create_port()
      device_add()
	# Add dev to bus devs list
	bus_add_device()
					devm_cxl_enumerate_ports()
					# found the port
					find_cxl_port_by_uport()
					# hold port lock to add a dport
					device_lock(the port)
					find_or_add_dport()
					  cxl_port_add_dport()
					    return -ENXIO because port->dev.driver is NULL
					device_unlock(the port)
	bus_probe_device()
	  # hold the port lock
	  # for attaching
	  device_lock(the port)
	    attaching the new port
	  device_unlock(the port)

To fix this race, require that dport addition holds the parent port lock
of the target port. The CXL subsystem already requires holding the
parent port lock while attaching a new port. Therefore, successfully
acquiring the parent port lock ganrantees that port attaching has
completed.

Fixes: 4f06d81e7c6a ("cxl: Defer dport allocation for switch ports")
Signed-off-by: Li Ming <ming.li@...omail.com>
---
 drivers/cxl/core/port.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 54f72452fb06..fef2fe913e1f 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1817,8 +1817,12 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd)
 			/*
 			 * RP port enumerated by cxl_acpi without dport will
 			 * have the dport added here.
+			 *
+			 * Hold the parent port lock here to in case that the
+			 * port can be observed but has not been attached yet.
 			 */
-			scoped_guard(device, &port->dev) {
+			scoped_guard(device, &parent_port_of(port)->dev) {
+				guard(device)(&port->dev);
 				dport = find_or_add_dport(port, dport_dev);
 				if (IS_ERR(dport)) {
 					if (PTR_ERR(dport) == -EAGAIN)
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ