diff mbox series

[RFC] wifi: cfg80211: allow NULL buf with wiphy-locked debugfs

Message ID 20241112123724.5213bdd067b4.Ieb1b56f2bf094b1359f52a8a6ef462424cd11790@changeid (mailing list archive)
State New
Delegated to: Johannes Berg
Headers show
Series [RFC] wifi: cfg80211: allow NULL buf with wiphy-locked debugfs | expand

Commit Message

Johannes Berg Nov. 12, 2024, 11:37 a.m. UTC
From: Johannes Berg <johannes.berg@intel.com>

Allow passing NULL for the buf to allocate the needed size
(bufsize is still passed). In case the needed size is more
than would easily fit on the stack we can handle that here
instead of requiring each user to do it.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/cfg80211.h |  6 ++++--
 net/wireless/debugfs.c | 28 +++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 27acf1292a5c..ad9b938aad29 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -9715,7 +9715,8 @@  void cfg80211_schedule_channels_check(struct wireless_dev *wdev);
  * wiphy_locked_debugfs_read - do a locked read in debugfs
  * @wiphy: the wiphy to use
  * @file: the file being read
- * @buf: the buffer to fill and then read from
+ * @buf: the buffer to fill and then read from, can be %NULL
+ *	to allocate a buffer of @bufsize size
  * @bufsize: size of the buffer
  * @userbuf: the user buffer to copy to
  * @count: read count
@@ -9740,7 +9741,8 @@  ssize_t wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file,
  * wiphy_locked_debugfs_write - do a locked write in debugfs
  * @wiphy: the wiphy to use
  * @file: the file being written to
- * @buf: the buffer to copy the user data to
+ * @buf: the buffer to copy the user data to, can be %NULL
+ *	to allocate a buffer of @bufsize size
  * @bufsize: size of the buffer
  * @userbuf: the user buffer to copy from
  * @count: read count
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 40e49074e2ee..e78013cbf43a 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -160,7 +160,6 @@  ssize_t wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file,
 		.handler = handler,
 		.wiphy = wiphy,
 		.file = file,
-		.buf = buf,
 		.bufsize = bufsize,
 		.data = data,
 		.ret = -ENODEV,
@@ -170,10 +169,19 @@  ssize_t wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file,
 		.cancel = wiphy_locked_debugfs_read_cancel,
 		.cancel_data = &work,
 	};
+	void *tmp __free(kfree) = NULL;
 
-	/* don't leak stack data or whatever */
-	memset(buf, 0, bufsize);
+	if (buf) {
+		/* don't leak stack data or whatever */
+		memset(buf, 0, bufsize);
+	} else {
+		tmp = kzalloc(bufsize, GFP_KERNEL);
+		if (!tmp)
+			return -ENOMEM;
+		buf = tmp;
+	}
 
+	work.buf = buf;
 	wiphy_work_init(&work.work, wiphy_locked_debugfs_read_work);
 	wiphy_work_queue(wiphy, &work.work);
 
@@ -239,7 +247,6 @@  ssize_t wiphy_locked_debugfs_write(struct wiphy *wiphy,
 		.handler = handler,
 		.wiphy = wiphy,
 		.file = file,
-		.buf = buf,
 		.count = count,
 		.data = data,
 		.ret = -ENODEV,
@@ -249,12 +256,23 @@  ssize_t wiphy_locked_debugfs_write(struct wiphy *wiphy,
 		.cancel = wiphy_locked_debugfs_write_cancel,
 		.cancel_data = &work,
 	};
+	void *tmp __free(kfree) = NULL;
 
 	/* mostly used for strings so enforce NUL-termination for safety */
 	if (count >= bufsize)
 		return -EINVAL;
 
-	memset(buf, 0, bufsize);
+	if (buf) {
+		/* don't leak stack data or whatever */
+		memset(buf, 0, bufsize);
+	} else {
+		tmp = kzalloc(bufsize, GFP_KERNEL);
+		if (!tmp)
+			return -ENOMEM;
+		buf = tmp;
+	}
+
+	work.buf = buf;
 
 	if (copy_from_user(buf, userbuf, count))
 		return -EFAULT;