diff options
author | Srinivas Girigowda <sgirigow@codeaurora.org> | 2017-12-05 15:29:05 -0800 |
---|---|---|
committer | Thierry Strudel <tstrudel@google.com> | 2017-12-06 19:34:04 +0000 |
commit | 25966c546824a4068b8efaf236f59be49f42deb0 (patch) | |
tree | bc5c146612e2c8a4abd7625cc471d74b48570001 | |
parent | 585aad3ea2d048466d1da226ff200a82d16f0689 (diff) |
qcacld-2.0: Fix potential buffer overwrite in wma_roam_synch_event_handlerandroid-8.1.0_r0.22
In the function wma_roam_synch_event_handler, vdev_id is received from
the fw and is used to access member of the array wma->interfaces without
validating the max of the vdev_id received from the fw
Add check to make sure vdev_id is less than max_bssid before using it
Change-Id: I3b940e183ab66680891cb7351af4537b50afce1d
CRs-Fixed: 2147083
Bug: 68992434
Signed-off-by: Srinivas Girigowda <sgirigow@codeaurora.org>
-rw-r--r-- | drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c index 147da5a1c6ad..eaa9a37fd224 100644 --- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c +++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c @@ -6606,6 +6606,7 @@ static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t wmi_key_material *key = NULL; int size=0; tSirRoamOffloadSynchInd *pRoamOffloadSynchInd; + uint32_t roam_synch_data_len; WMA_LOGD("LFR3:%s", __func__); if (!event) { @@ -6625,6 +6626,12 @@ static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t return -EINVAL; } + if (synch_event->vdev_id >= wma->max_bssid) { + WMA_LOGE("%s: received invalid vdev_id %d", + __func__, synch_event->vdev_id); + return -EINVAL; + } + if(wma->interfaces[synch_event->vdev_id].roam_synch_in_progress == VOS_TRUE) { WMA_LOGE("%s: Ignoring RSI since one is already in progress", @@ -6632,29 +6639,43 @@ static int wma_roam_synch_event_handler(void *handle, u_int8_t *event, u_int32_t return -EINVAL; } + WMA_LOGD("synch payload: LEN bcn:%d, req:%d, rsp:%d", + synch_event->bcn_probe_rsp_len, + synch_event->reassoc_req_len, + synch_event->reassoc_rsp_len); + + if (synch_event->bcn_probe_rsp_len > WMA_SVC_MSG_MAX_SIZE) + return -EINVAL; + if (synch_event->reassoc_rsp_len > + (WMA_SVC_MSG_MAX_SIZE - synch_event->bcn_probe_rsp_len)) + return -EINVAL; + if (synch_event->reassoc_req_len > + WMA_SVC_MSG_MAX_SIZE - (synch_event->bcn_probe_rsp_len + + synch_event->reassoc_rsp_len)) + return -EINVAL; + + roam_synch_data_len = synch_event->bcn_probe_rsp_len + + synch_event->reassoc_rsp_len + + synch_event->reassoc_req_len; /* - * All below length fields are unsigned and hence positive numbers. - * Maximum number during the addition would be (3 * MAX_LIMIT(UINT32) + - * few fixed fields). + * Below is the check for the entire size of the message received from' + * the firmware. */ - if ((sizeof(*synch_event) + synch_event->bcn_probe_rsp_len + - synch_event->reassoc_rsp_len + - sizeof(wmi_channel) + sizeof(wmi_key_material) + - sizeof(uint32_t)) > WMA_SVC_MSG_MAX_SIZE) { - WMA_LOGE("excess synch payload: LEN bcn:%d, rsp:%d", - synch_event->bcn_probe_rsp_len, - synch_event->reassoc_rsp_len); - VOS_ASSERT(0); + if (roam_synch_data_len > WMA_SVC_MSG_MAX_SIZE - + (sizeof(*synch_event) + sizeof(wmi_channel) + + sizeof(wmi_key_material) + sizeof(uint32_t))) return -EINVAL; - } + + if (sizeof(tSirRoamOffloadSynchInd) > + (WMA_SVC_MSG_MAX_SIZE - roam_synch_data_len)) + return -EINVAL; + roam_synch_data_len += sizeof(tSirRoamOffloadSynchInd); adf_os_spin_lock_bh(&wma->roam_synch_lock); wma->interfaces[synch_event->vdev_id].roam_synch_in_progress = VOS_TRUE; adf_os_spin_unlock_bh(&wma->roam_synch_lock); - len = sizeof(tSirRoamOffloadSynchInd) + - synch_event->bcn_probe_rsp_len + - synch_event->reassoc_rsp_len; - pRoamOffloadSynchInd = (tSirRoamOffloadSynchInd *)vos_mem_malloc(len); + pRoamOffloadSynchInd = + (tSirRoamOffloadSynchInd *)vos_mem_malloc(roam_synch_data_len); if (!pRoamOffloadSynchInd) { WMA_LOGE("%s: failed to allocate memory for roam_synch_event", __func__); return -ENOMEM; |