aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Girigowda <sgirigow@codeaurora.org>2017-12-05 15:29:05 -0800
committerThierry Strudel <tstrudel@google.com>2017-12-06 19:34:04 +0000
commit25966c546824a4068b8efaf236f59be49f42deb0 (patch)
treebc5c146612e2c8a4abd7625cc471d74b48570001
parent585aad3ea2d048466d1da226ff200a82d16f0689 (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.c53
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;