[PATCH] wifi: wext: fix SIOCGIWESSID length handling in compat path

From: 薛 枫

Date: Mon Oct 26 2026 - 10:33:16 EST


From: Xuefeng <xuefeng64@xxxxxxxxxxx>
Date: Mon, 26 Oct 2026 22:07:40 +0800
Subject: [PATCH] wifi: wext: fix SIOCGIWESSID length handling in compat path

Wireless Extensions userspace older than WE 21 passes iwp->length as
IW_ESSID_MAX_SIZE + 1 for SIOCGIWESSID, because its buffer has room for
the trailing NUL. ioctl_standard_iw_point() notices that and sets
essid_compat, then unconditionally does

iwp->length -= essid_compat;

for both directions. This is right for SET, where the handler has to see
the logical ESSID length without the NUL, but wrong for GET: there
iwp->length is the physical size of the userspace buffer, and it is saved
into user_length before being replaced by max_tokens. Shrinking it makes
user_length one token too small, so a full length 32 byte SSID fails the

if (user_length < iwp->length)

check after the handler ran and the ioctl returns -E2BIG. On top of that,
extra is allocated from max_tokens alone while copy_to_user() afterwards
copies max_tokens + 1 tokens, i.e. one byte past the end of the
allocation.

Apply the compat adjustment only for SET. For GET keep iwp->length as is
so user_length stays the real buffer size, and grow extra_size by one
token to make room for the NUL that legacy userspace expects; kzalloc()
already zero fills it.

Signed-off-by: Xuefeng <xuefeng64@xxxxxxxxxxx>
---
net/wireless/wext-core.c | 14 ++++++++++++--
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -777,7 +777,19 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
break;
}

- iwp->length -= essid_compat;
+ /* ESSID compat adjustment:
+ * SET: subtract compat so handler sees logical length
+ * without trailing NUL.
+ * GET: leave iwp->length untouched; it is the physical
+ * user buffer size and equals user_length for copy check.
+ * Grow extra_size by one token so kzalloc() zero-fills
+ * the trailing NUL that old WE expects.
+ */
+ if (IW_IS_SET(cmd))
+ iwp->length -= essid_compat;
+
+ if (essid_compat && IW_IS_GET(cmd))
+ extra_size += descr->token_size;

/* Check what user space is giving us */
if (IW_IS_SET(cmd)) {