* [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file
@ 2026-09-14 12:18 Guixin Liu
2026-09-14 12:32 ` sashiko-bot
2026-09-14 21:06 ` Dave Jiang
0 siblings, 2 replies; 4+ messages in thread
From: Guixin Liu @ 2026-09-14 12:18 UTC (permalink / raw)
To: Davidlohr Bueso, Jonathan Cameron, Dave Jiang, Alison Schofield,
Vishal Verma, Dan Williams, Ira Weiny, Li Ming
Cc: linux-cxl
The per-dport einj_inject debugfs file retains a pointer to the
'struct cxl_dport', but its lifetime is not tied to the dport. Unbinding
the dport host frees the dport and leaves einj_inject behind, so writing
the file dereferences freed memory.
The stale directory also prevents recreation on rebind.
Remove the per-dport debugfs directory when the dport host is released.
Found by code inspection, then reproduced on a QEMU CXL topology with
KASAN (the einj_cxl_is_initialized() guard had to be forced open, as
QEMU emits no EINJ table). Unpatched, writing the leftover file after
unbind gives a KASAN slab-use-after-free report in cxl_einj_inject(),
and rebind hits "already exists in 'cxl'". Patched, the directory goes
away with the dport and rebind recreates a working einj_inject.
Fixes: 8039804cfa73 ("cxl/core: Add CXL EINJ debugfs files")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Reviewed-by: Richard Cheng <icheng@nvidia.com>
Reviewed-by: Li Ming <ming.li@zohomail.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
---
v3: https://lore.kernel.org/linux-cxl/20260828074752.3336779-1-kanie@linux.alibaba.com/
v3->v4:
- move the devm_add_action_or_reset() call next to the directory creation
(Jonathan Cameron)
- drop the KASAN stack from the commit message (Alison Schofield)
- rebase onto master (v7.3-rc2), per Dave's request for patches against
Linus's tags rather than cxl/next
drivers/cxl/core/port.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 625e4aa427db..82513b46f634 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -814,6 +814,11 @@ static int cxl_einj_inject(void *data, u64 type)
DEFINE_DEBUGFS_ATTRIBUTE(cxl_einj_inject_fops, NULL, cxl_einj_inject,
"0x%llx\n");
+static void remove_debugfs(void *dentry)
+{
+ debugfs_remove_recursive(dentry);
+}
+
static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
{
struct cxl_port *parent = parent_port_of(dport->port);
@@ -832,6 +837,8 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
dir = cxl_debugfs_create_dir(dev_name(dport->dport_dev));
+ devm_add_action_or_reset(dport_to_host(dport), remove_debugfs, dir);
+
debugfs_create_file("einj_inject", 0200, dir, dport,
&cxl_einj_inject_fops);
}
base-commit: 50d05c7c76c96b90462f24debacca971d2e86713
--
2.43.7
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file
2026-09-14 12:18 [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file Guixin Liu
@ 2026-09-14 12:32 ` sashiko-bot
2026-09-14 21:06 ` Dave Jiang
1 sibling, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-09-14 12:32 UTC (permalink / raw)
To: Guixin Liu; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Ignoring the return value of devm_add_action_or_reset() leads to a use-after-free of the debugfs directory dentry on the error path.
--
commit acaad538920d3905d33312c0501a79695900337c
Author: Guixin Liu <kanie@linux.alibaba.com>
cxl/core: Fix dport use-after-free via the einj_inject debugfs file
This commit fixes a use-after-free when accessing the per-dport einj_inject
debugfs file after unbinding the dport host. It registers a devm action to
remove the debugfs directory when the dport host is released.
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 625e4aa427db0..82513b46f6347 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
[ ... ]
> @@ -832,6 +837,8 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
>
> dir = cxl_debugfs_create_dir(dev_name(dport->dport_dev));
>
> + devm_add_action_or_reset(dport_to_host(dport), remove_debugfs, dir);
> +
[Severity: High]
If devm_add_action_or_reset() fails, will this lead to a use-after-free of
the dir dentry?
When devm_add_action_or_reset() fails to allocate memory for the devres
node, it immediately executes the registered action before returning an
error. In this case, remove_debugfs() would be called, which runs
debugfs_remove_recursive(dir) and drops the reference to the dentry,
potentially freeing it.
Since cxl_debugfs_create_dport_dir() ignores the return value of
devm_add_action_or_reset(), it proceeds to call debugfs_create_file(),
passing the freed dir pointer as the parent directory.
Should this check the return value and return early if the devm action
fails to register?
> debugfs_create_file("einj_inject", 0200, dir, dport,
> &cxl_einj_inject_fops);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260914121843.718493-1-kanie@linux.alibaba.com?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file
2026-09-14 12:18 [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file Guixin Liu
2026-09-14 12:32 ` sashiko-bot
@ 2026-09-14 21:06 ` Dave Jiang
2026-09-15 5:53 ` Guixin Liu
1 sibling, 1 reply; 4+ messages in thread
From: Dave Jiang @ 2026-09-14 21:06 UTC (permalink / raw)
To: Guixin Liu, Davidlohr Bueso, Jonathan Cameron, Alison Schofield,
Vishal Verma, Dan Williams, Ira Weiny, Li Ming
Cc: linux-cxl
On 9/14/26 5:18 AM, Guixin Liu wrote:
> The per-dport einj_inject debugfs file retains a pointer to the
> 'struct cxl_dport', but its lifetime is not tied to the dport. Unbinding
> the dport host frees the dport and leaves einj_inject behind, so writing
> the file dereferences freed memory.
>
> The stale directory also prevents recreation on rebind.
>
> Remove the per-dport debugfs directory when the dport host is released.
>
> Found by code inspection, then reproduced on a QEMU CXL topology with
> KASAN (the einj_cxl_is_initialized() guard had to be forced open, as
> QEMU emits no EINJ table). Unpatched, writing the leftover file after
> unbind gives a KASAN slab-use-after-free report in cxl_einj_inject(),
> and rebind hits "already exists in 'cxl'". Patched, the directory goes
> away with the dport and rebind recreates a working einj_inject.
>
> Fixes: 8039804cfa73 ("cxl/core: Add CXL EINJ debugfs files")
> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
> Reviewed-by: Richard Cheng <icheng@nvidia.com>
> Reviewed-by: Li Ming <ming.li@zohomail.com>
> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Applied to cxl/next
9185b1a3043c
Can you send a follow up to address the sashiko complaint if needed? Thanks!
> ---
> v3: https://lore.kernel.org/linux-cxl/20260828074752.3336779-1-kanie@linux.alibaba.com/
>
> v3->v4:
> - move the devm_add_action_or_reset() call next to the directory creation
> (Jonathan Cameron)
> - drop the KASAN stack from the commit message (Alison Schofield)
> - rebase onto master (v7.3-rc2), per Dave's request for patches against
> Linus's tags rather than cxl/next
>
> drivers/cxl/core/port.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 625e4aa427db..82513b46f634 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -814,6 +814,11 @@ static int cxl_einj_inject(void *data, u64 type)
> DEFINE_DEBUGFS_ATTRIBUTE(cxl_einj_inject_fops, NULL, cxl_einj_inject,
> "0x%llx\n");
>
> +static void remove_debugfs(void *dentry)
> +{
> + debugfs_remove_recursive(dentry);
> +}
> +
> static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
> {
> struct cxl_port *parent = parent_port_of(dport->port);
> @@ -832,6 +837,8 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
>
> dir = cxl_debugfs_create_dir(dev_name(dport->dport_dev));
>
> + devm_add_action_or_reset(dport_to_host(dport), remove_debugfs, dir);
> +
> debugfs_create_file("einj_inject", 0200, dir, dport,
> &cxl_einj_inject_fops);
> }
>
> base-commit: 50d05c7c76c96b90462f24debacca971d2e86713
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file
2026-09-14 21:06 ` Dave Jiang
@ 2026-09-15 5:53 ` Guixin Liu
0 siblings, 0 replies; 4+ messages in thread
From: Guixin Liu @ 2026-09-15 5:53 UTC (permalink / raw)
To: Dave Jiang, Davidlohr Bueso, Jonathan Cameron, Alison Schofield,
Vishal Verma, Dan Williams, Ira Weiny, Li Ming
Cc: linux-cxl
在 2026/9/15 05:06, Dave Jiang 写道:
>
> On 9/14/26 5:18 AM, Guixin Liu wrote:
>> The per-dport einj_inject debugfs file retains a pointer to the
>> 'struct cxl_dport', but its lifetime is not tied to the dport. Unbinding
>> the dport host frees the dport and leaves einj_inject behind, so writing
>> the file dereferences freed memory.
>>
>> The stale directory also prevents recreation on rebind.
>>
>> Remove the per-dport debugfs directory when the dport host is released.
>>
>> Found by code inspection, then reproduced on a QEMU CXL topology with
>> KASAN (the einj_cxl_is_initialized() guard had to be forced open, as
>> QEMU emits no EINJ table). Unpatched, writing the leftover file after
>> unbind gives a KASAN slab-use-after-free report in cxl_einj_inject(),
>> and rebind hits "already exists in 'cxl'". Patched, the directory goes
>> away with the dport and rebind recreates a working einj_inject.
>>
>> Fixes: 8039804cfa73 ("cxl/core: Add CXL EINJ debugfs files")
>> Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
>> Reviewed-by: Richard Cheng <icheng@nvidia.com>
>> Reviewed-by: Li Ming <ming.li@zohomail.com>
>> Reviewed-by: Alison Schofield <alison.schofield@intel.com>
> Applied to cxl/next
> 9185b1a3043c
>
> Can you send a follow up to address the sashiko complaint if needed? Thanks!
I'm sorry, I messed up, sashiko is right, I will send a bugfix patch for
this.
I should check the devm_add_action_or_reset()'s return value.
Best Regards,
Guixin Liu
>> ---
>> v3: https://lore.kernel.org/linux-cxl/20260828074752.3336779-1-kanie@linux.alibaba.com/
>>
>> v3->v4:
>> - move the devm_add_action_or_reset() call next to the directory creation
>> (Jonathan Cameron)
>> - drop the KASAN stack from the commit message (Alison Schofield)
>> - rebase onto master (v7.3-rc2), per Dave's request for patches against
>> Linus's tags rather than cxl/next
>>
>> drivers/cxl/core/port.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
>> index 625e4aa427db..82513b46f634 100644
>> --- a/drivers/cxl/core/port.c
>> +++ b/drivers/cxl/core/port.c
>> @@ -814,6 +814,11 @@ static int cxl_einj_inject(void *data, u64 type)
>> DEFINE_DEBUGFS_ATTRIBUTE(cxl_einj_inject_fops, NULL, cxl_einj_inject,
>> "0x%llx\n");
>>
>> +static void remove_debugfs(void *dentry)
>> +{
>> + debugfs_remove_recursive(dentry);
>> +}
>> +
>> static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
>> {
>> struct cxl_port *parent = parent_port_of(dport->port);
>> @@ -832,6 +837,8 @@ static void cxl_debugfs_create_dport_dir(struct cxl_dport *dport)
>>
>> dir = cxl_debugfs_create_dir(dev_name(dport->dport_dev));
>>
>> + devm_add_action_or_reset(dport_to_host(dport), remove_debugfs, dir);
>> +
>> debugfs_create_file("einj_inject", 0200, dir, dport,
>> &cxl_einj_inject_fops);
>> }
>>
>> base-commit: 50d05c7c76c96b90462f24debacca971d2e86713
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-15 5:53 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-14 12:18 [PATCH v4] cxl/core: Fix dport use-after-free via the einj_inject debugfs file Guixin Liu
2026-09-14 12:32 ` sashiko-bot
2026-09-14 21:06 ` Dave Jiang
2026-09-15 5:53 ` Guixin Liu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.