qcacld-3.0: Validate and Rectify RSN IE in probe response frame

qcacld-2.0 to qcacld-3.0 propagation

There are some Access points that have not included the
capability field in the RSN ie's though the length for the
RSN ie's indicate for the presence of this field. This shall
result in the next byte after this RSN ie as the capability
field, thus resulting in the improper interpretation of this
field, the end result being a failure to connect to such AP's.
This commit introduces a work around to interop with such AP's
by appending the capability field with 0 value to the obtained ie.
It updates MPDU length of received RxPacket based on addition of
RSN Capability if it is missing in Probe response.

Change-Id: Ic599c8bdb19e368fefb13293499451e7ab38d517
CRs-Fixed: 667983
此提交包含在:
Padma, Santhosh Kumar
2016-08-10 17:30:45 +05:30
提交者 Nishank Aggarwal
父節點 eb0191f574
當前提交 209c195927
共有 3 個檔案被更改,包括 114 行新增6 行删除

查看文件

@@ -59,6 +59,13 @@
#define NSS_2x2_MODE 2
#define MBO_IE_ASSOC_DISALLOWED_SUBATTR_ID 0x04
#define SIZE_OF_FIXED_PARAM 12
#define SIZE_OF_TAG_PARAM_NUM 1
#define SIZE_OF_TAG_PARAM_LEN 1
#define RSNIEID 0x30
#define RSNIE_CAPABILITY_LEN 2
#define DEFAULT_RSNIE_CAP_VAL 0x00
#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
#define QCOM_VENDOR_IE_MCC_AVOID_CH 0x01
@@ -951,4 +958,10 @@ tSirRetStatus populate_dot11f_timing_advert_frame(tpAniSirGlobal pMac,
void populate_dot11_supp_operating_classes(tpAniSirGlobal mac_ptr,
tDot11fIESuppOperatingClasses *dot_11_ptr, tpPESession session_entry);
tSirRetStatus
sir_validate_and_rectify_ies(tpAniSirGlobal mac_ctx,
uint8_t *mgmt_frame,
uint32_t frame_bytes,
uint32_t *missing_rsn_bytes);
#endif /* __PARSE_H__ */

查看文件

@@ -52,14 +52,42 @@
#include "parser_api.h"
tSirRetStatus lim_validate_ie_information_in_probe_rsp_frame(uint8_t *pRxPacketInfo)
/**
* lim_validate_ie_information_in_probe_rsp_frame () - validates ie
* information in probe response.
* @mac_ctx: mac context
* @pRxPacketInfo: Rx packet info
*
* Return: 0 on success, one on failure
*/
tSirRetStatus
lim_validate_ie_information_in_probe_rsp_frame(tpAniSirGlobal mac_ctx,
uint8_t *pRxPacketInfo)
{
tSirRetStatus status = eSIR_SUCCESS;
uint8_t *pframe;
uint32_t nframe;
uint32_t missing_rsn_bytes;
/*
* Validate a Probe response frame for malformed frame.
* If the frame is malformed then do not consider as it
* may cause problem fetching wrong IE values
*/
if (WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) <
(SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) {
status = eSIR_FAILURE;
}
(SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN))
return eSIR_FAILURE;
pframe = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
nframe = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
missing_rsn_bytes = 0;
status = sir_validate_and_rectify_ies(mac_ctx,
pframe, nframe, &missing_rsn_bytes);
if (status == eSIR_SUCCESS)
WMA_GET_RX_MPDU_LEN(pRxPacketInfo) += missing_rsn_bytes;
return status;
}
@@ -116,7 +144,8 @@ lim_process_probe_rsp_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_Packet_info,
MAC_ADDR_ARRAY(header->sa));
/* Validate IE information before processing Probe Response Frame */
if (lim_validate_ie_information_in_probe_rsp_frame(rx_Packet_info) !=
if (lim_validate_ie_information_in_probe_rsp_frame(mac_ctx,
rx_Packet_info) !=
eSIR_SUCCESS) {
lim_log(mac_ctx, LOG1,
FL("Parse error ProbeResponse, length=%d"), frame_len);
@@ -346,7 +375,8 @@ lim_process_probe_rsp_frame_no_session(tpAniSirGlobal mac_ctx,
lim_print_mac_addr(mac_ctx, header->sa, LOG2);
/* Validate IE information before processing Probe Response Frame */
if (lim_validate_ie_information_in_probe_rsp_frame(rx_packet_info) !=
if (lim_validate_ie_information_in_probe_rsp_frame(mac_ctx,
rx_packet_info) !=
eSIR_SUCCESS) {
lim_log(mac_ctx, LOG1,
FL("Parse error ProbeResponse, length=%d"), frame_len);

查看文件

@@ -2225,6 +2225,71 @@ sir_convert_probe_req_frame2_struct(tpAniSirGlobal pMac,
return eSIR_SUCCESS;
} /* End sir_convert_probe_req_frame2_struct. */
/**
* sir_validate_and_rectify_ies() - API to check malformed frame
* @mac_ctx: mac context
* @mgmt_frame: pointer to management frame
* @frame_bytes: no of bytes in frame
* @missing_rsn_bytes: missing rsn bytes
*
* The frame would contain fixed IEs of 12 bytes followed by variable IEs
* (Tagged elements). Every Tagged IE has tag number, tag length and data.
* Tag length indicates the size of data in bytes.
* This function checks for size of Frame received with the sum of all IEs.
* And also rectifies missing optional fields in IE.
*
* NOTE : Presently this function rectifies RSN capability in RSN IE, can
* be extended to rectify other optional fields in other IEs.
*
* Return: 0 on success, error number otherwise.
*/
tSirRetStatus
sir_validate_and_rectify_ies(tpAniSirGlobal mac_ctx,
uint8_t *mgmt_frame,
uint32_t frame_bytes,
uint32_t *missing_rsn_bytes)
{
uint32_t length = SIZE_OF_FIXED_PARAM;
uint8_t *ref_frame;
/* Frame contains atleast one IE */
if (frame_bytes > (SIZE_OF_FIXED_PARAM +
SIZE_OF_TAG_PARAM_NUM + SIZE_OF_TAG_PARAM_LEN)) {
while (length < frame_bytes) {
/* ref frame points to next IE */
ref_frame = mgmt_frame + length;
length += (uint32_t)(SIZE_OF_TAG_PARAM_NUM +
SIZE_OF_TAG_PARAM_LEN +
(*(ref_frame + SIZE_OF_TAG_PARAM_NUM)));
}
if (length != frame_bytes) {
/*
* Workaround : Some APs may not include RSN
* Capability but the length of which is included in
* RSN IE length. This may cause in updating RSN
* Capability with junk value. To avoid this, add RSN
* Capability value with default value.
*/
if ((*ref_frame == RSNIEID) &&
(length == (frame_bytes +
RSNIE_CAPABILITY_LEN))) {
/* Assume RSN Capability as 00 */
qdf_mem_set((uint8_t *)(mgmt_frame +
(frame_bytes)),
RSNIE_CAPABILITY_LEN,
DEFAULT_RSNIE_CAP_VAL);
*missing_rsn_bytes = RSNIE_CAPABILITY_LEN;
lim_log(mac_ctx, LOG1,
FL("Added RSN Capability to RSNIE as 0x00 0x00"));
return eSIR_SUCCESS;
}
return eSIR_FAILURE;
}
}
return eSIR_SUCCESS;
}
tSirRetStatus sir_convert_probe_frame2_struct(tpAniSirGlobal pMac,
uint8_t *pFrame,
uint32_t nFrame,