summaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorSarika Sharma <quic_sarishar@quicinc.com>2025-07-14 14:14:05 +0530
committerJohannes Berg <johannes.berg@intel.com>2025-07-15 11:05:13 +0200
commit9a44b5e36cd699fdd2150a63fab225ac510c1971 (patch)
treeda6d9fbd83d2d01a0d1d84a07ac5e52b1339e70a /net/wireless
parente9a896d498506af16d52ee33b80c1cdb4f36350d (diff)
wifi: cfg80211: fix double free for link_sinfo in nl80211_station_dump()
Currently, the link_sinfo structure is being freed twice in nl80211_dump_station(), once after the send_station() call and again in the error handling path. This results in a double free of both link_sinfo and link_sinfo->pertid, which might lead to undefined behavior or kernel crashes. Hence, fix by ensuring cfg80211_sinfo_release_content() is only invoked once during execution of nl80211_station_dump(). Fixes: 49e47223ecc4 ("wifi: cfg80211: allocate memory for link_station info structure") Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Closes: https://lore.kernel.org/all/81f30515-a83d-4b05-a9d1-e349969df9e9@sabinyo.mountain/ Reported-by: syzbot+4ba6272678aa468132c8@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68655325.a70a0220.5d25f.0316.GAE@google.com Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com> Link: https://patch.msgid.link/20250714084405.178066-1-quic_sarishar@quicinc.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e1df03e8ed5c..63f015ce9ad4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7451,6 +7451,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
struct wireless_dev *wdev;
u8 mac_addr[ETH_ALEN];
int sta_idx = cb->args[2];
+ bool sinfo_alloc = false;
int err, i;
err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
@@ -7479,6 +7480,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
err = -ENOMEM;
goto out_err;
}
+ sinfo_alloc = true;
}
err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
@@ -7491,6 +7493,11 @@ static int nl80211_dump_station(struct sk_buff *skb,
if (sinfo.valid_links)
cfg80211_sta_set_mld_sinfo(&sinfo);
+ /* reset the sinfo_alloc flag as nl80211_send_station()
+ * always releases sinfo
+ */
+ sinfo_alloc = false;
+
if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -7505,7 +7512,8 @@ static int nl80211_dump_station(struct sk_buff *skb,
cb->args[2] = sta_idx;
err = skb->len;
out_err:
- cfg80211_sinfo_release_content(&sinfo);
+ if (sinfo_alloc)
+ cfg80211_sinfo_release_content(&sinfo);
wiphy_unlock(&rdev->wiphy);
return err;