From: Johannes Berg <johannes.berg@xxxxxxxxx> 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@xxxxxxxxx> --- include/net/cfg80211.h | 6 ++++-- net/wireless/debugfs.c | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) 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; -- 2.47.0