wifi: nl80211: move WPA version validation to policy
authorJohannes Berg <johannes.berg@intel.com>
Mon, 29 Jan 2024 18:54:21 +0000 (19:54 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 2 Feb 2024 13:20:43 +0000 (14:20 +0100)
For a contiguous mask (starting with bit 0) of allowed values
in a bitmap, it's equivalent to check "!(val & ~mask)" and
"val ∈ [0, mask]". Use that to move the WPA versions check to
the policy, for better error reporting.

Reviewed-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Link: https://msgid.link/20240129195421.e8cae9866ccb.I2539b395e3476307d702c6867e51a937e52e57a0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index e4f41f86e295df519e6dbf22d17c9b5d822a8208..68c20409eca65bed32a603841a94139f8dd3f460 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
  * Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2023 Intel Corporation
+ * Copyright (C) 2018-2024 Intel Corporation
  */
 
 #include <linux/if.h>
@@ -581,7 +581,11 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
        [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
        [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
-       [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
+       [NL80211_ATTR_WPA_VERSIONS] =
+               NLA_POLICY_RANGE(NLA_U32, 0,
+                                NL80211_WPA_VERSION_1 |
+                                NL80211_WPA_VERSION_2 |
+                                NL80211_WPA_VERSION_3),
        [NL80211_ATTR_PID] = { .type = NLA_U32 },
        [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
        [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
@@ -10604,13 +10608,6 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
        return res;
 }
 
-static bool nl80211_valid_wpa_versions(u32 wpa_versions)
-{
-       return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
-                                 NL80211_WPA_VERSION_2 |
-                                 NL80211_WPA_VERSION_3));
-}
-
 static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -10836,12 +10833,9 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
                        return -EINVAL;
        }
 
-       if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
+       if (info->attrs[NL80211_ATTR_WPA_VERSIONS])
                settings->wpa_versions =
                        nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
-               if (!nl80211_valid_wpa_versions(settings->wpa_versions))
-                       return -EINVAL;
-       }
 
        if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
                void *data;