qcacld-3.0: Validate sub_ele_len before calculating len
Currently fw is allowed to provide ch_wr_ie len upto 20 bytes. If fw provides ie len > 20 bytes then driver may lead to access invalid memory. To find sub element, subelement len is calculated from total len without any validation. ele may point to invalid address when subelement which is calculated from ie len becomes > len. Fix is to compare ie len provided by fw with max ie len and validate subelement len and then proceed with subelement. Change-Id: I1a833c3828e4afc6e37ed27e008663152b6b5d86 CRs-Fixed: 2995818
This commit is contained in:

committed by
Madan Koyyalamudi

parent
dfef6ace58
commit
b6aa87c291
@@ -79,6 +79,7 @@
|
|||||||
* MCL platform.
|
* MCL platform.
|
||||||
*/
|
*/
|
||||||
#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
|
#define WMA_SET_VDEV_IE_SOURCE_HOST 0x0
|
||||||
|
#define CH_WR_IE_MAX_LEN 20
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Max AMPDU Tx Aggr supported size
|
* Max AMPDU Tx Aggr supported size
|
||||||
@@ -1174,7 +1175,8 @@ wma_parse_ch_switch_wrapper_ie(uint8_t *ch_wr_ie, uint8_t sub_ele_id)
|
|||||||
|
|
||||||
ele = (struct ie_header *)ch_wr_ie;
|
ele = (struct ie_header *)ch_wr_ie;
|
||||||
if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP ||
|
if (ele->ie_id != WLAN_ELEMID_CHAN_SWITCH_WRAP ||
|
||||||
ele->ie_len == 0)
|
ele->ie_len == 0 || ele->ie_len > (CH_WR_IE_MAX_LEN -
|
||||||
|
sizeof(struct ie_header)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = ele->ie_len;
|
len = ele->ie_len;
|
||||||
@@ -1182,6 +1184,11 @@ wma_parse_ch_switch_wrapper_ie(uint8_t *ch_wr_ie, uint8_t sub_ele_id)
|
|||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
sub_ele_len = sizeof(struct ie_header) + ele->ie_len;
|
sub_ele_len = sizeof(struct ie_header) + ele->ie_len;
|
||||||
|
if (sub_ele_len > len) {
|
||||||
|
wma_debug("invalid sub element len :%d id:%d ie len:%d",
|
||||||
|
sub_ele_len, ele->ie_id, ele->ie_len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
len -= sub_ele_len;
|
len -= sub_ele_len;
|
||||||
if (ele->ie_id == sub_ele_id)
|
if (ele->ie_id == sub_ele_id)
|
||||||
return (uint8_t *)ele;
|
return (uint8_t *)ele;
|
||||||
|
Reference in New Issue
Block a user