Prechádzať zdrojové kódy

qcacld-3.0: Fix prevent issues

This change
1.fixes the use of uninitialized
variable in host driver.

2.Adds validation in extract_roam_sync_frame_event_tlv
Where these frame lengths are getting populated,
also at the place where subtraction happens to prevent
overflows

3.Adds NULL check in wma_handle_roam_reason_deauth, to avoid
the null pointer dereference.

Change-Id: I2d5ba61fb109f6d8b497df29cfa2dd572c00adeb
CRs-Fixed: 3297792
Asutosh Mohapatra 2 rokov pred
rodič
commit
d64cb46a9c

+ 4 - 1
components/wmi/src/wmi_unified_roam_tlv.c

@@ -2649,7 +2649,10 @@ extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
 	    synch_frame_event->reassoc_req_len >
 	    param_buf->num_reassoc_req_frame ||
 	    synch_frame_event->reassoc_rsp_len >
-	    param_buf->num_reassoc_rsp_frame) {
+	    param_buf->num_reassoc_rsp_frame ||
+	    synch_frame_event->bcn_probe_rsp_len < sizeof(struct wlan_frame_hdr) ||
+	    synch_frame_event->reassoc_req_len < sizeof(struct wlan_frame_hdr) ||
+	    synch_frame_event->reassoc_rsp_len < sizeof(struct wlan_frame_hdr)) {
 		wmi_err("fixed/actual len err: bcn:%d/%d req:%d/%d rsp:%d/%d",
 			synch_frame_event->bcn_probe_rsp_len,
 			param_buf->num_bcn_probe_rsp_frame,

+ 7 - 3
core/mac/src/pe/lim/lim_api.c

@@ -1934,7 +1934,7 @@ lim_roam_gen_mbssid_beacon(struct mac_context *mac,
 			   uint8_t **ie, uint32_t *ie_len)
 {
 	qdf_list_t *scan_list;
-	struct mgmt_rx_event_params rx_param;
+	struct mgmt_rx_event_params rx_param = {0};
 	uint8_t list_count = 0, i;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 	qdf_list_node_t *next_node = NULL, *cur_node = NULL;
@@ -1953,6 +1953,10 @@ lim_roam_gen_mbssid_beacon(struct mac_context *mac,
 	rx_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(mac->pdev);
 	rx_param.rssi = roam_ind->rssi;
 
+	/* Set all per chain rssi as invalid */
+	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
+		rx_param.rssi_ctl[i] = WLAN_INVALID_PER_CHAIN_RSSI;
+
 	scan_list = util_scan_unpack_beacon_frame(mac->pdev, bcn_prb_ptr,
 						  roam_ind->beaconProbeRespLength,
 						  MGMT_SUBTYPE_BEACON, &rx_param);
@@ -2606,7 +2610,7 @@ lim_gen_link_specific_assoc_rsp(struct mac_context *mac_ctx,
 	}
 
 	lim_process_assoc_rsp_frame(mac_ctx, link_reassoc_rsp.ptr,
-				    link_reassoc_rsp.len,
+				    link_reassoc_rsp.len - SIR_MAC_HDR_LEN_3A,
 				    LIM_REASSOC, session_entry);
 end:
 	qdf_mem_free(link_reassoc_rsp.ptr);
@@ -2802,7 +2806,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 	}
 	else
 		lim_process_assoc_rsp_frame(mac_ctx, reassoc_resp,
-					    roam_sync_ind_ptr->reassocRespLength,
+					    roam_sync_ind_ptr->reassocRespLength - SIR_MAC_HDR_LEN_3A,
 					    LIM_REASSOC, ft_session_ptr);
 
 	lim_check_ft_initial_im_association(roam_sync_ind_ptr, ft_session_ptr);

+ 24 - 16
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -915,8 +915,7 @@ lim_update_vdev_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
  * lim_process_assoc_rsp_frame() - Processes assoc response
  * @mac_ctx: Pointer to Global MAC structure
  * @rx_packet_info    - A pointer to Rx packet info structure
- * @reassoc_frame_length - Valid frame length if its a reassoc response frame
- * else 0
+ * @frame_body_length - frame body length of reassoc/assoc response frame
  * @sub_type - Indicates whether it is Association Response (=0) or
  *                   Reassociation Response (=1) frame
  *
@@ -927,12 +926,11 @@ lim_update_vdev_rate_set(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
  */
 void
 lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
-			    uint32_t reassoc_frame_len,
+			    uint32_t frame_body_len,
 			    uint8_t subtype, struct pe_session *session_entry)
 {
 	uint8_t *body, *ie;
 	uint16_t caps, ie_len;
-	uint32_t frame_len;
 	tSirMacAddr current_bssid;
 	tpSirMacMgmtHdr hdr = NULL;
 	tSirMacCapabilityInfo mac_capab;
@@ -965,11 +963,9 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 	if (lim_is_roam_synch_in_progress(mac_ctx->psoc, session_entry) ||
 	    wlan_vdev_mlme_is_mlo_link_vdev(session_entry->vdev)) {
 		hdr = (tpSirMacMgmtHdr)rx_pkt_info;
-		frame_len = reassoc_frame_len - SIR_MAC_HDR_LEN_3A;
 		rssi = 0;
 	} else {
 		hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
-		frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
 		rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
 	}
 
@@ -1056,18 +1052,30 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		body = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
 	/* parse Re/Association Response frame. */
 	if (sir_convert_assoc_resp_frame2_struct(mac_ctx, session_entry, body,
-		frame_len, assoc_rsp) == QDF_STATUS_E_FAILURE) {
+		frame_body_len, assoc_rsp) == QDF_STATUS_E_FAILURE) {
 		qdf_mem_free(assoc_rsp);
 		pe_err("Parse error Assoc resp subtype: %d" "length: %d",
-			frame_len, subtype);
+			frame_body_len, subtype);
 		qdf_mem_free(beacon);
 		return;
 	}
 
 	if (lim_is_session_eht_capable(session_entry)) {
+		uint8_t ies_offset;
+
+		if (subtype == LIM_ASSOC)
+			ies_offset = WLAN_ASSOC_RSP_IES_OFFSET;
+		else
+			ies_offset = WLAN_REASSOC_REQ_IES_OFFSET;
+
+		if (frame_body_len < ies_offset) {
+			pe_err("frame body length is < ies_offset");
+			return;
+		}
+
 		status = lim_strip_and_decode_eht_op(
-					body + WLAN_ASSOC_RSP_IES_OFFSET,
-					frame_len - WLAN_ASSOC_RSP_IES_OFFSET,
+					body + ies_offset,
+					frame_body_len - ies_offset,
 					&assoc_rsp->eht_op,
 					assoc_rsp->VHTOperation,
 					assoc_rsp->he_op,
@@ -1079,8 +1087,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		}
 
 		status = lim_strip_and_decode_eht_cap(
-					body + WLAN_ASSOC_RSP_IES_OFFSET,
-					frame_len - WLAN_ASSOC_RSP_IES_OFFSET,
+					body + ies_offset,
+					frame_body_len - ies_offset,
 					&assoc_rsp->eht_cap,
 					assoc_rsp->he_cap,
 					session_entry->curr_op_freq);
@@ -1105,15 +1113,15 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 		session_entry->assocRspLen = 0;
 	}
 
-	if (frame_len) {
-		session_entry->assocRsp = qdf_mem_malloc(frame_len);
+	if (frame_body_len) {
+		session_entry->assocRsp = qdf_mem_malloc(frame_body_len);
 		if (session_entry->assocRsp) {
 			/*
 			 * Store the Assoc response. This is sent
 			 * to csr/hdd in join cnf response.
 			 */
-			qdf_mem_copy(session_entry->assocRsp, body, frame_len);
-			session_entry->assocRspLen = frame_len;
+			qdf_mem_copy(session_entry->assocRsp, body, frame_body_len);
+			session_entry->assocRspLen = frame_body_len;
 		}
 	}
 

+ 2 - 2
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1393,7 +1393,7 @@ lim_handle80211_frames(struct mac_context *mac, struct scheduler_msg *limMsg,
 
 		case SIR_MAC_MGMT_ASSOC_RSP:
 			lim_process_assoc_rsp_frame(mac, pRxPacketInfo,
-						    ASSOC_FRAME_LEN,
+						    WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo),
 						    LIM_ASSOC,
 						    pe_session);
 			break;
@@ -1415,7 +1415,7 @@ lim_handle80211_frames(struct mac_context *mac, struct scheduler_msg *limMsg,
 
 		case SIR_MAC_MGMT_REASSOC_RSP:
 			lim_process_assoc_rsp_frame(mac, pRxPacketInfo,
-						    ASSOC_FRAME_LEN,
+						    WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo),
 						    LIM_REASSOC,
 						    pe_session);
 			break;

+ 1 - 1
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -2814,7 +2814,7 @@ lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
 			pe_debug("MLO: process assoc rsp for link vdev");
 			lim_process_assoc_rsp_frame(mac_ctx,
 						    link_assoc_rsp.ptr,
-						    link_assoc_rsp.len,
+						    (link_assoc_rsp.len - SIR_MAC_HDR_LEN_3A),
 						    LIM_ASSOC,
 						    session_entry);
 			qdf_mem_free(link_assoc_rsp.ptr);

+ 0 - 1
core/mac/src/pe/lim/lim_types.h

@@ -581,7 +581,6 @@ QDF_STATUS lim_send_mlm_assoc_ind(struct mac_context *mac,
 				  tpDphHashNode sta,
 				  struct pe_session *pe_session);
 
-#define ASSOC_FRAME_LEN 0
 /**
  * lim_process_assoc_rsp_frame() - Processes assoc response
  * @mac_ctx:              Pointer to Global MAC structure

+ 5 - 0
core/wma/src/wma_scan_roam.c

@@ -2766,6 +2766,11 @@ void cm_handle_roam_reason_deauth(uint8_t vdev_id, uint32_t notif_params,
 				  uint8_t *deauth_disassoc_frame,
 				  uint32_t frame_len)
 {
+	if (!deauth_disassoc_frame) {
+		wma_debug("deauth_disassoc_frame is NULL");
+		return;
+	}
+
 	wma_handle_roam_reason_deauth(vdev_id, notif_params, frame_len,
 				      deauth_disassoc_frame);
 }