diff mbox series

[04/20] wifi: ieee80211: add helper to validate ML element type and size

Message ID 20230618214435.1b50e7a3b3cf.I9385514d8eb6d6d3c82479a6fa732ef65313e554@changeid (mailing list archive)
State Accepted
Delegated to: Johannes Berg
Headers show
Series cfg80211/mac80211 patches from our internal tree 2023-06-18 | expand

Commit Message

Greenman, Gregory June 18, 2023, 6:49 p.m. UTC
From: Benjamin Berg <benjamin.berg@intel.com>

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>
---
 include/linux/ieee80211.h | 50 ++++++++++++++++++++++++---------------
 net/mac80211/mlme.c       |  3 ++-
 2 files changed, 33 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 97edc3b404dd..b107f21e1233 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -4639,10 +4639,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)
 {
@@ -4650,13 +4650,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))
@@ -4674,10 +4668,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)
 {
@@ -4685,10 +4679,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);
 
@@ -4773,6 +4763,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,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b8f8220cd9ff..30588703ffd3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4852,7 +4852,8 @@  static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
 
 		/* data + 1 / datalen - 1 since it's an extended element */
 		if (eht_ml_elem &&
-		    ieee80211_mle_size_ok(eht_ml_elem->data + 1,
+		    ieee80211_mle_type_ok(eht_ml_elem->data + 1,
+					  IEEE80211_ML_CONTROL_TYPE_BASIC,
 					  eht_ml_elem->datalen - 1)) {
 			sdata->vif.cfg.eml_cap =
 				ieee80211_mle_get_eml_cap(eht_ml_elem->data + 1);