]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: fix leak if split 6 GHz scanning fails
authorFedor Pchelkin <pchelkin@ispras.ru>
Mon, 1 Jun 2026 09:41:56 +0000 (12:41 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 3 Jun 2026 07:32:45 +0000 (09:32 +0200)
rdev->int_scan_req is leaked if cfg80211_scan() fails.  Note that it's
supposed to be released at ___cfg80211_scan_done() but this doesn't happen
as rdev->scan_req is NULL at that point, too, leading to the early return
from the freeing function.

unreferenced object 0xffff8881161d0800 (size 512):
  comm "wpa_supplicant", pid 379, jiffies 4294749765
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 f0 81 13 16 81 88 ff ff  ................
  backtrace (crc c867fdb6):
    kmemleak_alloc+0x89/0x90
    __kmalloc_noprof+0x2fd/0x410
    cfg80211_scan+0x133/0x730
    nl80211_trigger_scan+0xc69/0x1cc0
    genl_family_rcv_msg_doit+0x204/0x2f0
    genl_rcv_msg+0x431/0x6b0
    netlink_rcv_skb+0x143/0x3f0
    genl_rcv+0x27/0x40
    netlink_unicast+0x4f6/0x820
    netlink_sendmsg+0x797/0xce0
    __sock_sendmsg+0xc4/0x160
    ____sys_sendmsg+0x5e4/0x890
    ___sys_sendmsg+0xf8/0x180
    __sys_sendmsg+0x136/0x1e0
    __x64_sys_sendmsg+0x76/0xc0
    x64_sys_call+0x13f0/0x17d0

Found by Linux Verification Center (linuxtesting.org).

Fixes: c8cb5b854b40 ("nl80211/cfg80211: support 6 GHz scanning")
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
Link: https://patch.msgid.link/20260601094157.92703-1-pchelkin@ispras.ru
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/scan.c

index 358cbc9e43d851df926d220e8789d3831e5a28bb..27a56ee2e8f0b3ce0854c20875daac320d8c5cda 100644 (file)
@@ -1071,6 +1071,7 @@ int cfg80211_scan(struct cfg80211_registered_device *rdev)
        struct cfg80211_scan_request_int *request;
        struct cfg80211_scan_request_int *rdev_req = rdev->scan_req;
        u32 n_channels = 0, idx, i;
+       int err;
 
        if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ)) {
                rdev_req->req.first_part = true;
@@ -1100,8 +1101,14 @@ int cfg80211_scan(struct cfg80211_registered_device *rdev)
 
        rdev_req->req.scan_6ghz = false;
        rdev_req->req.first_part = true;
+       err = rdev_scan(rdev, request);
+       if (err) {
+               kfree(request);
+               return err;
+       }
+
        rdev->int_scan_req = request;
-       return rdev_scan(rdev, request);
+       return 0;
 }
 
 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,