[PATCH v2] wifi: cfg80211: verify if AP_VLAN belongs to the correct AP

From: Slawomir Stepien

Date: Mon Sep 14 2026 - 04:20:34 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.

Fix that by comparing the ethernet addresses of the two net devices.
Given VLAN A' must have the same address as AP A. Otherwise, return
error code.

Signed-off-by: Slawomir Stepien <sst@xxxxxxxxx>
Reported-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/all/22e7ddfc50d7a6a16c437b876dab5fe223799610.camel@xxxxxxxxxxxxxxxx/
---
v2:
* Move the logic to cfg80211 and use ether MAC address compare as suggested (from the beginning!) by
Johannes
* Update the subject and commit message

v1:
* https://lore.kernel.org/all/20260910080454.725913-1-sst@xxxxxxxxx/
---
net/wireless/nl80211.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 899b6374c550..0f3388312ccd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8966,10 +8966,12 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
EXPORT_SYMBOL(cfg80211_check_station_change);

/*
- * Get vlan interface making sure it is running and on the right wiphy.
+ * Get vlan interface making sure it is running, on the right wiphy
+ * and actually belongs to the given AP/P2P_GO interface.
*/
static struct net_device *get_vlan(struct genl_info *info,
- struct cfg80211_registered_device *rdev)
+ struct cfg80211_registered_device *rdev,
+ struct net_device *dev)
{
struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
struct net_device *v;
@@ -8999,6 +9001,12 @@ static struct net_device *get_vlan(struct genl_info *info,
goto error;
}

+ /* Check if the VLAN interface belongs to the AP interface */
+ if (!dev || !ether_addr_equal(v->dev_addr, dev->dev_addr)) {
+ ret = -EINVAL;
+ goto error;
+ }
+
return v;
error:
dev_put(v);
@@ -9296,7 +9304,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;

- params.vlan = get_vlan(info, rdev);
+ params.vlan = get_vlan(info, rdev, dev);
if (IS_ERR(params.vlan))
return PTR_ERR(params.vlan);

@@ -9597,7 +9605,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
}

/* must be last in here for error handling */
- params.vlan = get_vlan(info, rdev);
+ params.vlan = get_vlan(info, rdev, dev);
if (IS_ERR(params.vlan))
return PTR_ERR(params.vlan);
break;
--
2.55.0