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@xxxxxxxxxx> Closes: https://lore.kernel.org/all/81f30515-a83d-4b05-a9d1-e349969df9e9@sabinyo.mountain/ Reported-by: syzbot+4ba6272678aa468132c8@xxxxxxxxxxxxxxxxxxxxxxxxx Closes: https://lore.kernel.org/all/68655325.a70a0220.5d25f.0316.GAE@xxxxxxxxxx Signed-off-by: Sarika Sharma <quic_sarishar@xxxxxxxxxxx> --- v2: - Change the logic to fix double free issue. --- net/wireless/nl80211.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4e6c0a4e2a82..0cdfdf007210 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; base-commit: 0cad34fb7c5d12a9b61862744e7130e9ce3bc58f -- 2.34.1