wifi: ieee80211: add helper to validate ML element type and size
authorBenjamin Berg <benjamin.berg@intel.com>
Sun, 18 Jun 2023 18:49:46 +0000 (21:49 +0300)
committerChristian Lamparter <chunkeey@gmail.com>
Sat, 16 Sep 2023 21:48:57 +0000 (23:48 +0200)
The helper functions to retrieve the EML capabilities and medium
synchronization delay both assume that the type is correct. Instead of
assuming the length is correct and still checking the type, add a new
helper to check both and don't do any verification.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230618214435.1b50e7a3b3cf.I9385514d8eb6d6d3c82479a6fa732ef65313e554@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
include/linux/ieee80211.h

index 01f42291a7ab65587bb53e135c4a2a8623d1e0e3..f6c9e2b46b11e896b3d0a5859edefa50f555f490 100644 (file)
@@ -4567,10 +4567,10 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
  * ieee80211_mle_get_eml_sync_delay - returns the medium sync delay
  * @data: pointer to the multi link EHT IE
  *
- * The element is assumed to be big enough. This must be checked by
- * ieee80211_mle_size_ok().
- * If the medium synchronization can't be found (the type is not basic, or
- * the medium sync presence bit is clear), 0 will be returned.
+ * The element is assumed to be of the correct type (BASIC) and big enough,
+ * this must be checked using ieee80211_mle_type_ok().
+ *
+ * If the medium synchronization is not present, then 0 is returned.
  */
 static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data)
 {
@@ -4578,13 +4578,7 @@ static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data)
        u16 control = le16_to_cpu(mle->control);
        const u8 *common = mle->variable;
 
-       if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) !=
-           IEEE80211_ML_CONTROL_TYPE_BASIC)
-               return 0;
-
-       /* common points now at the beginning of
-        * ieee80211_mle_basic_common_info
-        */
+       /* common points now at the beginning of ieee80211_mle_basic_common_info */
        common += sizeof(struct ieee80211_mle_basic_common_info);
 
        if (!(control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY))
@@ -4602,10 +4596,10 @@ static inline u16 ieee80211_mle_get_eml_med_sync_delay(const u8 *data)
  * ieee80211_mle_get_eml_cap - returns the EML capability
  * @data: pointer to the multi link EHT IE
  *
- * The element is assumed to be big enough. This must be checked by
- * ieee80211_mle_size_ok().
- * If the EML capability can't be found (the type is not basic, or
- * the EML capability presence bit is clear), 0 will be returned.
+ * The element is assumed to be of the correct type (BASIC) and big enough,
+ * this must be checked using ieee80211_mle_type_ok().
+ *
+ * If the EML capability is not present, 0 will be returned.
  */
 static inline u16 ieee80211_mle_get_eml_cap(const u8 *data)
 {
@@ -4613,10 +4607,6 @@ static inline u16 ieee80211_mle_get_eml_cap(const u8 *data)
        u16 control = le16_to_cpu(mle->control);
        const u8 *common = mle->variable;
 
-       if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) !=
-           IEEE80211_ML_CONTROL_TYPE_BASIC)
-               return 0;
-
        /* common points now at the beginning of ieee80211_mle_basic_common_info */
        common += sizeof(struct ieee80211_mle_basic_common_info);
 
@@ -4701,6 +4691,28 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
        return mle->variable[0] >= common;
 }
 
+/**
+ * ieee80211_mle_type_ok - validate multi-link element type and size
+ * @data: pointer to the element data
+ * @type: expected type of the element
+ * @len: length of the containing element
+ */
+static inline bool ieee80211_mle_type_ok(const u8 *data, u8 type, size_t len)
+{
+       const struct ieee80211_multi_link_elem *mle = (const void *)data;
+       u16 control;
+
+       if (!ieee80211_mle_size_ok(data, len))
+               return false;
+
+       control = le16_to_cpu(mle->control);
+
+       if (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE) == type)
+               return true;
+
+       return false;
+}
+
 enum ieee80211_mle_subelems {
        IEEE80211_MLE_SUBELEM_PER_STA_PROFILE           = 0,
        IEEE80211_MLE_SUBELEM_FRAGMENT                  = 254,