From 34953f9f66d9cd36616c5271a7d285b31d9142c2 Mon Sep 17 00:00:00 2001 From: Mahesh A Saptasagar Date: Thu, 17 Mar 2016 17:15:02 -0700 Subject: qcacld 2.0: Validate WPA and RSN IE for valid length prima to qcacld-2.0 propagation Return failure to applications if genie ioctl is invoked to configure WPS/WPA/RSN IEs with arguments of improper length. Bug: 27104184 Change-Id: I31e288db41e14b24be0e430afed3a5e360da1370 Signed-off-by: Yuan Lin --- drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c index 558fc1b..095aa9d 100644 --- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c @@ -1531,9 +1531,10 @@ static int iw_set_genie(struct net_device *dev, char *extra) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); - u_int8_t *genie; - v_U16_t remLen; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + u_int8_t *genie; + v_U16_t remLen; + int ret = 0; ENTER(); if(!wrqu->data.length) { @@ -1570,7 +1571,10 @@ static int iw_set_genie(struct net_device *dev, { case IE_EID_VENDOR: if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */ - return -EINVAL; + { + ret = -EINVAL; + goto exit; + } if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) { @@ -1583,7 +1587,8 @@ static int iw_set_genie(struct net_device *dev, hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " "Need bigger buffer space\n"); VOS_ASSERT(0); - return -ENOMEM; + ret = -EINVAL; + goto exit; } // save to Additional IE ; it should be accumulated to handle WPS IE + other IE memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); @@ -1592,6 +1597,14 @@ static int iw_set_genie(struct net_device *dev, else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) { hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2); + if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + ret = -EINVAL; + VOS_ASSERT(0); + goto exit; + } memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE; @@ -1608,7 +1621,8 @@ static int iw_set_genie(struct net_device *dev, hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " "Need bigger buffer space\n"); VOS_ASSERT(0); - return -ENOMEM; + ret = -ENOMEM; + goto exit; } // save to Additional IE ; it should be accumulated to handle WPS IE + other IE memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); @@ -1617,6 +1631,14 @@ static int iw_set_genie(struct net_device *dev, break; case DOT11F_EID_RSN: hddLog (LOG1, "%s Set RSN IE (len %d)",__func__, eLen+2); + if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + ret = -EINVAL; + VOS_ASSERT(0); + goto exit; + } memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE; @@ -1625,13 +1647,14 @@ static int iw_set_genie(struct net_device *dev, default: hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, elementId); - return 0; + goto exit; } genie += eLen; remLen -= eLen; } + exit: EXIT(); - return 0; + return ret; } static int iw_get_genie(struct net_device *dev, -- cgit v1.1