From: "Cheatham, Benjamin" <benjamin.cheatham@amd.com>
To: Terry Bowman <terry.bowman@amd.com>,
Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jic23@kernel.org>,
Dave Jiang <dave.jiang@intel.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>, Dan Williams <djb@kernel.org>,
<PradeepVineshReddy.Kodamati@amd.com>, <rrichter@amd.com>
Cc: Kuppuswamy Sathyanarayanan
<sathyanarayanan.kuppuswamy@linux.intel.com>,
"Fabio M . De Francesco" <fabio.m.de.francesco@linux.intel.com>,
Shiju Jose <shiju.jose@huawei.com>,
Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>,
Li Ming <ming.li@zohomail.com>, Tony Luck <tony.luck@intel.com>,
<linux-cxl@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<stable@vger.kernel.org>
Subject: Re: [PATCH] cxl/port: Fix missing port lock in cxl_dport_remove()
Date: Fri, 5 Jun 2026 14:51:33 -0500 [thread overview]
Message-ID: <3e43c933-54b4-4d94-af7d-de8f3e7717b4@amd.com> (raw)
In-Reply-To: <20260605182014.2254410-1-terry.bowman@amd.com>
On 6/5/2026 1:20 PM, Terry Bowman wrote:
> xa_erase() in cxl_dport_remove() runs without the port device lock,
> creating a race with any caller that does xa_load() on port->dports
> and then dereferences the returned dport pointer. A concurrent
> cxl_dport_remove() can erase and free the dport between the xa_load()
> and the caller acquiring the port lock, causing a use-after-free.
>
> For non-root ports the port lock is already held by the caller on two
> paths:
>
> 1. Driver unbind: devres_release_all() is called from
> __device_release_driver() which holds port->dev.mutex.
>
> 2. Dynamic endpoint removal: cxl_detach_ep() takes the port lock
> before calling del_dports() -> del_dport() -> devres_release_group(),
> which synchronously runs cxl_dport_remove().
>
> Use cond_cxl_root_lock/unlock(), which only acquires the port lock when
> the port is a root port and the lock is therefore not already held.
> This matches the pattern used in __devm_cxl_add_dport() for the same
> reason.
>
> Reported-by: Sashiko
> Fixes: 391785859e7e ("cxl/port: Move dport tracking to an xarray")
> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
So I think this is a real bug, but I had to think about it pretty long
and hard to convince myself. The scenario I'm envisioning would be an
error occurs and the driver is force unbound while the error routine is
running. I guess it could also happen if someone does something weird
with force unbinding and rebinding the driver, but I'm not sure that's
possible.
What I guess I'm getting at is this could benefit from an example of
how this can happen in the commit log. With that:
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
> ---
> drivers/cxl/core/port.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 0c5957d1d329..80ce7c4d357c 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -1088,8 +1088,17 @@ static void cxl_dport_remove(void *data)
> struct cxl_dport *dport = data;
> struct cxl_port *port = dport->port;
>
> + /*
> + * For non-root ports the port lock is already held by the caller
> + * (driver unbind via devres_release_all(), or cxl_detach_ep() via
> + * devres_release_group()). Acquiring it again unconditionally would
> + * deadlock. Use cond_cxl_root_lock() which only acquires when the
> + * port is a root port and the lock is therefore not yet held.
> + */
> + cond_cxl_root_lock(port);
> port->nr_dports--;
> xa_erase(&port->dports, (unsigned long) dport->dport_dev);
> + cond_cxl_root_unlock(port);
> put_device(dport->dport_dev);
> }
>
prev parent reply other threads:[~2026-06-05 19:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-05 18:20 Terry Bowman
2026-06-05 19:51 ` Cheatham, Benjamin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3e43c933-54b4-4d94-af7d-de8f3e7717b4@amd.com \
--to=benjamin.cheatham@amd.com \
--cc=PradeepVineshReddy.Kodamati@amd.com \
--cc=Smita.KoralahalliChannabasappa@amd.com \
--cc=alison.schofield@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=djb@kernel.org \
--cc=fabio.m.de.francesco@linux.intel.com \
--cc=ira.weiny@intel.com \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=rrichter@amd.com \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=shiju.jose@huawei.com \
--cc=stable@vger.kernel.org \
--cc=terry.bowman@amd.com \
--cc=tony.luck@intel.com \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®