All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.