Search Linux Wireless

[PATCH wireless-next v2] wifi: cfg80211: fix double free for link_sinfo in nl80211_station_dump()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux