From 36d282b5d533d444a388d015d7d11130b4f11bf0 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Tue, 3 Nov 2015 14:10:13 -0800 Subject: [PATCH] qcacld-3.0: Add length sanity check in iw_set_keepalive_params Propagation from qcacld-2.0 to qcacld-3.0 Add length sanity check in iw_set_keepalive_params to avoid stack over flow. Change-Id: If59794d1b5f8efad2fe54844fab0e7cea9b1b983 CRs-Fixed: 932466 --- core/hdd/inc/wlan_hdd_wext.h | 10 ------ core/hdd/src/wlan_hdd_wext.c | 67 +++++++++++++++--------------------- 2 files changed, 28 insertions(+), 49 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_wext.h b/core/hdd/inc/wlan_hdd_wext.h index de61e903e6ae..1f78e4916586 100644 --- a/core/hdd/inc/wlan_hdd_wext.h +++ b/core/hdd/inc/wlan_hdd_wext.h @@ -283,16 +283,6 @@ typedef struct ccp_freq_chan_map_s { #define WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 #define WLAN_KEEP_ALIVE_NULL_PKT 1 -/* Offload request. */ -typedef struct { - uint8_t packetType; - uint32_t timePeriod; - uint8_t hostIpv4Addr[4]; - uint8_t destIpv4Addr[4]; - uint8_t destMacAddr[ETH_ALEN]; - uint8_t bssIdx; -} tKeepAliveRequest, *tpKeepAliveRequest; - #define wlan_hdd_get_wps_ie_ptr(ie, ie_len) \ wlan_hdd_get_vendor_oui_ie_ptr(WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE, ie, ie_len) diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 1f7cc4985028..6f7a9ace6efd 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -8434,8 +8434,7 @@ static int __iw_set_keepalive_params(struct net_device *dev, union iwreq_data *wrqu, char *extra) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - tpKeepAliveRequest pRequest = (tpKeepAliveRequest) extra; - tSirKeepAliveReq keepaliveRequest; + tpSirKeepAliveReq request = (tpSirKeepAliveReq) extra; hdd_context_t *hdd_ctx; int ret; @@ -8444,61 +8443,51 @@ static int __iw_set_keepalive_params(struct net_device *dev, if (0 != ret) return ret; - if (pRequest->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) { - hddLog(LOGE, FL("Value of timePeriod %d exceed Max limit %d"), - pRequest->timePeriod, + if (wrqu->data.length != sizeof(*request)) { + hdd_err("Invalid length %d", wrqu->data.length); + return -EINVAL; + } + + if (request->timePeriod > WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX) { + hdd_err("Value of timePeriod %d exceed Max limit %d", + request->timePeriod, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX); return -EINVAL; } /* Debug display of request components. */ - hddLog(CDF_TRACE_LEVEL_INFO, - "%s: Set Keep Alive Request : TimePeriod %d size %zu", - __func__, pRequest->timePeriod, sizeof(tKeepAliveRequest)); + hdd_info("Set Keep Alive Request : TimePeriod %d size %zu", + request->timePeriod, sizeof(tSirKeepAliveReq)); - switch (pRequest->packetType) { + switch (request->packetType) { case WLAN_KEEP_ALIVE_NULL_PKT: - hddLog(CDF_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", - __func__); + hdd_info("Keep Alive Request: Tx NULL"); break; case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP: - hddLog(CDF_TRACE_LEVEL_INFO_HIGH, - "%s: Keep Alive Request: Tx UnSolicited ARP RSP", - __func__); + hdd_info("Keep Alive Request: Tx UnSolicited ARP RSP"); - hddLog(CDF_TRACE_LEVEL_WARN, " Host IP address: %d.%d.%d.%d", - pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1], - pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]); + hdd_info("Host IP address: %d.%d.%d.%d", + request->hostIpv4Addr[0], request->hostIpv4Addr[1], + request->hostIpv4Addr[2], request->hostIpv4Addr[3]); - hddLog(CDF_TRACE_LEVEL_WARN, " Dest IP address: %d.%d.%d.%d", - pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1], - pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]); + hdd_info("Dest IP address: %d.%d.%d.%d", + request->destIpv4Addr[0], request->destIpv4Addr[1], + request->destIpv4Addr[2], request->destIpv4Addr[3]); - hddLog(CDF_TRACE_LEVEL_WARN, - " Dest MAC address: %d:%d:%d:%d:%d:%d", - pRequest->destMacAddr[0], pRequest->destMacAddr[1], - pRequest->destMacAddr[2], pRequest->destMacAddr[3], - pRequest->destMacAddr[4], pRequest->destMacAddr[5]); + hdd_info("Dest MAC address: %d:%d:%d:%d:%d:%d", + request->destMacAddr[0], request->destMacAddr[1], + request->destMacAddr[2], request->destMacAddr[3], + request->destMacAddr[4], request->destMacAddr[5]); break; } - /* Execute keep alive request. The reason that we can copy the - * request information from the ioctl structure to the SME - * structure is that they are laid out exactly the same. - * Otherwise, each piece of information would have to be - * copied individually. - */ - memcpy(&keepaliveRequest, pRequest, wrqu->data.length); - - hddLog(CDF_TRACE_LEVEL_ERROR, "set Keep: TP before SME %d", - keepaliveRequest.timePeriod); + hdd_info("Keep alive period %d", request->timePeriod); if (CDF_STATUS_SUCCESS != sme_set_keep_alive(WLAN_HDD_GET_HAL_CTX(pAdapter), - pAdapter->sessionId, &keepaliveRequest)) { - hddLog(CDF_TRACE_LEVEL_ERROR, - "%s: Failure to execute Keep Alive", __func__); + pAdapter->sessionId, request)) { + hdd_err("Failure to execute Keep Alive"); return -EINVAL; } @@ -10559,7 +10548,7 @@ static const struct iw_priv_args we_private_args[] = { { WLAN_SET_KEEPALIVE_PARAMS, - IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN, + sizeof(tSirKeepAliveReq) | IW_PRIV_SIZE_FIXED, 0, "setKeepAlive" }