The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] debugfs: serialize debugfs_create_str() writers
@ 2026-08-03  6:09 Yichong Chen
  2026-08-03  6:19 ` Greg KH
  0 siblings, 1 reply; 6+ messages in thread
From: Yichong Chen @ 2026-08-03  6:09 UTC (permalink / raw)
  To: gregkh
  Cc: rafael, dakr, djakov, quic_mdtipton, driver-core, linux-kernel,
	Yichong Chen

debugfs_write_file_str() replaces the string pointer backing a
debugfs_create_str() file and frees the old string after
synchronize_rcu().

Concurrent writers can observe the same old pointer before either
replacement is published. They can then both replace the pointer and
both free the same old string, which KASAN reports as a double-free.

Serialize writers with a mutex so only one writer can replace and free
the old string at a time. Also make readers use rcu_read_lock() and
rcu_dereference(), matching the existing RCU grace period before the old
string is freed.

Fixes: 86b5488121db ("debugfs: Add write support to debugfs_create_str()")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 fs/debugfs/file.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 08de6652a4f3..566f9ce976b0 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/atomic.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #include <linux/pm_runtime.h>
 #include <linux/poll.h>
 #include <linux/security.h>
@@ -1014,6 +1015,8 @@ void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
 }
 EXPORT_SYMBOL_GPL(debugfs_create_bool);
 
+static DEFINE_MUTEX(debugfs_str_write_mutex);
+
 ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf,
 			      size_t count, loff_t *ppos)
 {
@@ -1026,15 +1029,18 @@ ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf,
 	if (unlikely(ret))
 		return ret;
 
-	str = *(char **)file->private_data;
+	rcu_read_lock();
+	str = rcu_dereference(*(char __rcu **)file->private_data);
 	len = strlen(str) + 1;
-	copy = kmalloc(len, GFP_KERNEL);
+	copy = kmalloc(len, GFP_ATOMIC);
 	if (!copy) {
+		rcu_read_unlock();
 		debugfs_file_put(dentry);
 		return -ENOMEM;
 	}
 
 	copy_len = strscpy(copy, str, len);
+	rcu_read_unlock();
 	debugfs_file_put(dentry);
 	if (copy_len < 0) {
 		kfree(copy);
@@ -1061,7 +1067,9 @@ static ssize_t debugfs_write_file_str(struct file *file, const char __user *user
 	if (unlikely(r))
 		return r;
 
-	old = *(char **)file->private_data;
+	mutex_lock(&debugfs_str_write_mutex);
+	old = rcu_dereference_protected(*(char __rcu **)file->private_data,
+					lockdep_is_held(&debugfs_str_write_mutex));
 
 	/* only allow strict concatenation */
 	r = -EINVAL;
@@ -1091,11 +1099,13 @@ static ssize_t debugfs_write_file_str(struct file *file, const char __user *user
 	synchronize_rcu();
 	kfree(old);
 
+	mutex_unlock(&debugfs_str_write_mutex);
 	debugfs_file_put(dentry);
 	return count;
 
 error:
 	kfree(new);
+	mutex_unlock(&debugfs_str_write_mutex);
 	debugfs_file_put(dentry);
 	return r;
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-05  8:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03  6:09 [PATCH] debugfs: serialize debugfs_create_str() writers Yichong Chen
2026-08-03  6:19 ` Greg KH
2026-08-03  8:34   ` Yichong Chen
2026-08-03  8:43     ` Greg KH
2026-08-04  5:50       ` Yichong Chen
2026-08-05  8:00         ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox