wifi: cfg80211: reject bad AP MLD address
[platform/kernel/linux-starfive.git] / net / wireless / nl80211.c
index 597c522..087c0c4 100644 (file)
@@ -3868,6 +3868,9 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
                        struct cfg80211_chan_def chandef = {};
                        int ret;
 
+                       if (!link)
+                               goto nla_put_failure;
+
                        if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
                                goto nla_put_failure;
                        if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
@@ -8812,7 +8815,7 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
                struct cfg80211_chan_def *chandef;
 
                chandef = wdev_chandef(wdev, link_id);
-               if (!chandef)
+               if (!chandef || !chandef->chan)
                        continue;
 
                /*
@@ -10539,6 +10542,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
                if (!info->attrs[NL80211_ATTR_MLD_ADDR])
                        return -EINVAL;
                req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
+               if (!is_valid_ether_addr(req.ap_mld_addr))
+                       return -EINVAL;
        }
 
        req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
@@ -10696,8 +10701,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
 
 static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device *rdev,
                                              const u8 *ssid, int ssid_len,
-                                             struct nlattr **attrs,
-                                             const u8 **bssid_out)
+                                             struct nlattr **attrs)
 {
        struct ieee80211_channel *chan;
        struct cfg80211_bss *bss;
@@ -10724,7 +10728,6 @@ static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device
        if (!bss)
                return ERR_PTR(-ENOENT);
 
-       *bssid_out = bssid;
        return bss;
 }
 
@@ -10734,7 +10737,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
        struct net_device *dev = info->user_ptr[1];
        struct cfg80211_assoc_request req = {};
        struct nlattr **attrs = NULL;
-       const u8 *bssid, *ssid;
+       const u8 *ap_addr, *ssid;
        unsigned int link_id;
        int err, ssid_len;
 
@@ -10871,6 +10874,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        return -EINVAL;
 
                req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
+               ap_addr = req.ap_mld_addr;
 
                attrs = kzalloc(attrsize, GFP_KERNEL);
                if (!attrs)
@@ -10896,8 +10900,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                                goto free;
                        }
                        req.links[link_id].bss =
-                               nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
-                                                 &bssid);
+                               nl80211_assoc_bss(rdev, ssid, ssid_len, attrs);
                        if (IS_ERR(req.links[link_id].bss)) {
                                err = PTR_ERR(req.links[link_id].bss);
                                req.links[link_id].bss = NULL;
@@ -10948,10 +10951,10 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                if (req.link_id >= 0)
                        return -EINVAL;
 
-               req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs,
-                                           &bssid);
+               req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs);
                if (IS_ERR(req.bss))
                        return PTR_ERR(req.bss);
+               ap_addr = req.bss->bssid;
        }
 
        err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
@@ -10964,7 +10967,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                        dev->ieee80211_ptr->conn_owner_nlportid =
                                info->snd_portid;
                        memcpy(dev->ieee80211_ptr->disconnect_bssid,
-                              bssid, ETH_ALEN);
+                              ap_addr, ETH_ALEN);
                }
 
                wdev_unlock(dev->ieee80211_ptr);
@@ -13805,7 +13808,7 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
                return -ERANGE;
        if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
            !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
-             nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
+             nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN))
                return -ERANGE;
 
        rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);