Răsfoiți Sursa

qcacmn: Add check for frame boundary check in t2lm api

While parsing t2lm ie pass the frame length and add
check for frame boundary.

Change-Id: Iebb2cb5f0756785e4698613b80bfb31d60a2ed80
CRs-Fixed: 3577156
Amruta Kulkarni 1 an în urmă
părinte
comite
712aff4786
2 a modificat fișierele cu 34 adăugiri și 9 ștergeri
  1. 8 2
      umac/mlo_mgr/inc/wlan_mlo_t2lm.h
  2. 26 7
      umac/mlo_mgr/src/wlan_mlo_t2lm.c

+ 8 - 2
umac/mlo_mgr/inc/wlan_mlo_t2lm.h

@@ -552,11 +552,13 @@ QDF_STATUS wlan_mlo_dev_t2lm_notify_link_update(
  * wlan_mlo_parse_t2lm_ie() - API to parse the T2LM IE
  * @t2lm: Pointer to T2LM structure
  * @ie: Pointer to T2LM IE
+ * @frame_len: Action Frame length
  *
  * Return: QDF_STATUS
  */
 QDF_STATUS wlan_mlo_parse_t2lm_ie(
-	struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie);
+	struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
+	uint32_t frame_len);
 
 /**
  * wlan_mlo_add_t2lm_ie() - API to add TID-to-link mapping IE
@@ -586,6 +588,7 @@ QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event(
  * wlan_mlo_parse_t2lm_action_frame() - API to parse T2LM action frame
  * @t2lm: Pointer to T2LM structure
  * @action_frm: Pointer to action frame
+ * @frame_len: Action frame length
  * @category: T2LM action frame category
  *
  * Return: 0 - success, else failure
@@ -593,6 +596,7 @@ QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event(
 int wlan_mlo_parse_t2lm_action_frame(
 		struct wlan_t2lm_onging_negotiation_info *t2lm,
 		struct wlan_action_frame *action_frm,
+		uint32_t frame_len,
 		enum wlan_t2lm_category category);
 
 /**
@@ -745,7 +749,8 @@ wlan_send_peer_level_tid_to_link_mapping(struct wlan_objmgr_vdev *vdev,
 					 struct wlan_objmgr_peer *peer);
 #else
 static inline QDF_STATUS wlan_mlo_parse_t2lm_ie(
-	struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie)
+	struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
+	uint32_t frame_len)
 {
 	return QDF_STATUS_E_FAILURE;
 }
@@ -762,6 +767,7 @@ static inline
 int wlan_mlo_parse_t2lm_action_frame(
 		struct wlan_t2lm_onging_negotiation_info *t2lm,
 		struct wlan_action_frame *action_frm,
+		uint32_t frame_len,
 		enum wlan_t2lm_category category)
 {
 	return 0;

+ 26 - 7
umac/mlo_mgr/src/wlan_mlo_t2lm.c

@@ -188,26 +188,38 @@ QDF_STATUS wlan_mlo_parse_bcn_prbresp_t2lm_ie(
 }
 
 QDF_STATUS wlan_mlo_parse_t2lm_ie(
-		struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie)
+		struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie,
+		uint32_t frame_len)
 {
 	struct extn_ie_header *ext_ie_hdr = NULL;
 	QDF_STATUS retval;
 	enum wlan_t2lm_direction dir;
 	struct wlan_t2lm_info t2lm_info;
+	uint32_t ie_len_parsed = 0;
 
 	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++)
 		t2lm->t2lm_info[dir].direction = WLAN_T2LM_INVALID_DIRECTION;
 
 	for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) {
-		if (!ie) {
-			t2lm_err("ie is null");
+		if (!ie || !frame_len) {
+			t2lm_err("ie is null or len is 0");
 			return QDF_STATUS_E_NULL_VALUE;
 		}
 
+		if (frame_len < (ie_len_parsed + sizeof(struct ie_header))) {
+			t2lm_err("Frame length is lesser than parsed T2LM IE header length");
+			return QDF_STATUS_E_PROTO;
+		}
+
 		ext_ie_hdr = (struct extn_ie_header *)ie;
 
 		if (ext_ie_hdr->ie_id == WLAN_ELEMID_EXTN_ELEM &&
 		    ext_ie_hdr->ie_extn_id == WLAN_EXTN_ELEMID_T2LM) {
+			ie_len_parsed += ext_ie_hdr->ie_len + sizeof(struct ie_header);
+			if (frame_len < ie_len_parsed) {
+				t2lm_err("Frame length is lesser than parsed T2LM IE length");
+				return QDF_STATUS_E_PROTO;
+			}
 			qdf_mem_zero(&t2lm_info, sizeof(t2lm_info));
 			retval = wlan_mlo_parse_t2lm_info(ie, &t2lm_info);
 			if (!retval &&
@@ -425,6 +437,7 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm,
  * frame.
  * @t2lm: Pointer to T2LM structure
  * @action_frm: Pointer to action frame
+ * @frame_len: Received frame pointer
  * @category: T2LM action frame category
  *
  * Return: QDF_STATUS
@@ -432,6 +445,7 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm,
 static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
 		struct wlan_t2lm_onging_negotiation_info *t2lm,
 		struct wlan_action_frame *action_frm,
+		uint32_t frame_len,
 		enum wlan_t2lm_category category)
 {
 	uint8_t *t2lm_action_frm;
@@ -455,7 +469,8 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
 	t2lm->dialog_token = *t2lm_action_frm;
 
 	return wlan_mlo_parse_t2lm_ie(t2lm,
-				      t2lm_action_frm + sizeof(uint8_t));
+				      t2lm_action_frm + sizeof(uint8_t),
+				      frame_len);
 }
 
 /**
@@ -463,6 +478,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
  * action frame.
  * @t2lm: Pointer to T2LM structure
  * @action_frm: Pointer to action frame
+ * @frame_len: Action frame length
  * @category: T2LM action frame category
  *
  * Return: QDF_STATUS
@@ -470,6 +486,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame(
 static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
 		struct wlan_t2lm_onging_negotiation_info *t2lm,
 		struct wlan_action_frame *action_frm,
+		uint32_t frame_len,
 		enum wlan_t2lm_category category)
 {
 	uint8_t *t2lm_action_frm;
@@ -497,7 +514,8 @@ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
 	if (t2lm->t2lm_resp_type ==
 			WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING) {
 		t2lm_action_frm += sizeof(uint8_t) + sizeof(uint16_t);
-		ret_val = wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm);
+		ret_val = wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm,
+						 frame_len);
 	}
 
 	return ret_val;
@@ -506,6 +524,7 @@ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame(
 int wlan_mlo_parse_t2lm_action_frame(
 		struct wlan_t2lm_onging_negotiation_info *t2lm,
 		struct wlan_action_frame *action_frm,
+		uint32_t frame_len,
 		enum wlan_t2lm_category category)
 {
 	QDF_STATUS ret_val = QDF_STATUS_SUCCESS;
@@ -514,13 +533,13 @@ int wlan_mlo_parse_t2lm_action_frame(
 	case WLAN_T2LM_CATEGORY_REQUEST:
 		{
 			ret_val = wlan_mlo_parse_t2lm_request_action_frame(
-					t2lm, action_frm, category);
+					t2lm, action_frm, frame_len, category);
 			return qdf_status_to_os_return(ret_val);
 		}
 	case WLAN_T2LM_CATEGORY_RESPONSE:
 		{
 			ret_val = wlan_mlo_parse_t2lm_response_action_frame(
-					t2lm, action_frm, category);
+					t2lm, action_frm, frame_len, category);
 
 			return qdf_status_to_os_return(ret_val);
 		}