[PATCH] wifi: mac80211: verify if AP_VLAN belongs to the correct AP
From: Slawomir Stepien
Date: Thu Sep 10 2026 - 04:16:41 EST
The get_vlan() only checks if NL80211_ATTR_STA_VLAN target is an
AP/AP_VLAN/P2P_GO interface on the same wiphy. It has no notion of which
specific AP a given AP_VLAN belongs to. Without a check in mac80211
itself, NL80211_CMD_NEW_STATION and NL80211_CMD_SET_STATION could
add/move a station onto an AP_VLAN interface that actually belongs to a
different AP on the same wiphy.
Reject the userspace request unless the VLAN interface's bss pointer
matches the bss of the interface the station is being added to/belongs
to.
Signed-off-by: Slawomir Stepien <sst@xxxxxxxxx>
Reported-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/all/22e7ddfc50d7a6a16c437b876dab5fe223799610.camel@xxxxxxxxxxxxxxxx/
---
net/mac80211/cfg.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 23f4f9ec86d0..920681eb2e87 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2637,19 +2637,25 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct wireless_dev *wdev,
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct sta_info *sta;
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
int err;
lockdep_assert_wiphy(local->hw.wiphy);
if (params->vlan) {
- sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
+ struct ieee80211_sub_if_data *vlansdata =
+ IEEE80211_DEV_TO_SUB_IF(params->vlan);
- if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_AP)
+ if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+ vlansdata->vif.type != NL80211_IFTYPE_AP)
+ return -EINVAL;
+
+ /* the VLAN must belong to the AP we're adding the station to */
+ if (vlansdata->bss != sdata->bss)
return -EINVAL;
- } else
- sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+
+ sdata = vlansdata;
+ }
if (ether_addr_equal(mac, sdata->vif.addr))
return -EINVAL;
@@ -2845,6 +2851,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
if (params->vlan && params->vlan != sta->sdata->dev) {
vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
+ /* the VLAN must belong to the AP the station is on */
+ if (vlansdata->bss != sdata->bss)
+ return -EINVAL;
+
if (params->vlan->ieee80211_ptr->use_4addr) {
err = ieee80211_set_sta_4addr(local, vlansdata, sta);
if (err)
--
2.55.0