From c05f8e47be8a80a426c1059d6b7366c57771fe4d Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Fri, 16 Nov 2018 18:06:07 +0530 Subject: [PATCH] qcacmn: Avoid possible integer overflow In function init_deinit_chainmask_table_alloc, alloc size is declared as uint32 and is assigned the value the multiplying non zero value sizeof(struct wlan_psoc_host_chainmask_capabilities) and uint32 value ser_ext_par->chainmask_table[i].num_valid_chainmasks. This can lead to overflow as multiplies value can be more than uint32. Change-Id: I9a886d9ee5213ae8989a2c5d4502336cc275418a CRs-Fixed: 2347650 --- .../init_deinit/src/service_ready_util.c | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/target_if/init_deinit/src/service_ready_util.c b/target_if/init_deinit/src/service_ready_util.c index 218852c02cee..60182d69bfe1 100644 --- a/target_if/init_deinit/src/service_ready_util.c +++ b/target_if/init_deinit/src/service_ready_util.c @@ -31,25 +31,32 @@ QDF_STATUS init_deinit_chainmask_table_alloc( { int i; uint32_t alloc_size; - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_SUCCESS; - if (ser_ext_par->num_chainmask_tables > 0) { - status = QDF_STATUS_SUCCESS; - for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { - alloc_size = - (sizeof(struct wlan_psoc_host_chainmask_capabilities) * - ser_ext_par->chainmask_table[i].num_valid_chainmasks); + if (ser_ext_par->num_chainmask_tables == 0) + return QDF_STATUS_E_NOSUPPORT; - ser_ext_par->chainmask_table[i].cap_list = - qdf_mem_alloc_outline(NULL, alloc_size); - if (!ser_ext_par->chainmask_table[i].cap_list) { - init_deinit_chainmask_table_free(ser_ext_par); - status = QDF_STATUS_E_NOMEM; - break; - } + for (i = 0; i < ser_ext_par->num_chainmask_tables; i++) { + if (ser_ext_par->chainmask_table[i].num_valid_chainmasks > + (UINT_MAX / sizeof( + struct wlan_psoc_host_chainmask_capabilities))) { + target_if_err("invalid valid chanmask num %d", + ser_ext_par->chainmask_table[i]. + num_valid_chainmasks); + status = QDF_STATUS_E_FAILURE; + break; + } + alloc_size = + (sizeof(struct wlan_psoc_host_chainmask_capabilities) * + ser_ext_par->chainmask_table[i].num_valid_chainmasks); + + ser_ext_par->chainmask_table[i].cap_list = + qdf_mem_alloc_outline(NULL, alloc_size); + if (!ser_ext_par->chainmask_table[i].cap_list) { + init_deinit_chainmask_table_free(ser_ext_par); + status = QDF_STATUS_E_NOMEM; + break; } - } else { - status = QDF_STATUS_E_NOSUPPORT; } return status;