diff options
| author | Rajeev Kumar Sirasanagandla <rsirasan@codeaurora.org> | 2017-08-16 20:33:49 +0530 |
|---|---|---|
| committer | snandini <snandini@codeaurora.org> | 2017-08-29 06:53:45 -0700 |
| commit | 2a178aa72dea489f809c913606cfbf24407e227c (patch) | |
| tree | efe6b24ce6d6239e5d3975d93036451324008974 | |
| parent | df538ea0fca8a7971fcbdf61d169a5ce0c7e41e0 (diff) | |
qcacld-2.0: Fix invalid buffer access in send mgmt tx
In __wlan_hdd_mgmt_tx, there is potential buffer over-read in access of
public action frame type due to array index out of bounds.
To address this, check for payload length before
WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET access.
Change-Id: I9e3b4ef0878d934f3425d91bb6ea4a37b1892a3d
CRs-Fixed: 2088768
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_p2p.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index 092d133d3178..fa5fc03fcc6b 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -117,10 +117,13 @@ const char *tdls_action_frame_type[] = {"TDLS Setup Request", extern struct net_device_ops net_ops_struct; -static bool wlan_hdd_is_type_p2p_action( const u8 *buf ) +static bool wlan_hdd_is_type_p2p_action( const u8 *buf, uint32_t len) { const u8 *ouiPtr; + if (len < WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET + 1) + return FALSE; + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] != WLAN_HDD_PUBLIC_ACTION_FRAME ) { return FALSE; @@ -145,11 +148,11 @@ static bool wlan_hdd_is_type_p2p_action( const u8 *buf ) return TRUE; } -static bool hdd_p2p_is_action_type_rsp( const u8 *buf ) +static bool hdd_p2p_is_action_type_rsp( const u8 *buf, uint32_t len ) { tActionFrmType actionFrmType; - if ( wlan_hdd_is_type_p2p_action(buf) ) + if ( wlan_hdd_is_type_p2p_action(buf, len) ) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET]; if ( actionFrmType != WLAN_HDD_INVITATION_REQ && @@ -1936,8 +1939,8 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, hdd_remain_on_chan_ctx_t *pRemainChanCtx; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); tANI_U16 extendedWait = 0; - tANI_U8 type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); - tANI_U8 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); + tANI_U8 type; + tANI_U8 subType; tActionFrmType actionFrmType; bool noack = 0; int status; @@ -1945,9 +1948,18 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, hdd_adapter_t *goAdapter; uint8_t home_ch = 0; bool enb_random_mac = false; + uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr); ENTER(); + if (len < mgmt_hdr_len + 1) { + hddLog(LOGE, FL("Invalid Length")); + return -EINVAL; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); + hddLog(LOG1, FL("wait: %d, offchan: %d"), wait, offchan); MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_ACTION, pAdapter->sessionId, @@ -1965,16 +1977,20 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, hdd_device_mode_to_string(pAdapter->device_mode), pAdapter->device_mode, type); - hddLog(LOG1, FL("category: %d, actionID: %d"), - buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET + + if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_ACTION && + len > IEEE80211_MIN_ACTION_SIZE) + hddLog(LOG1, FL("category: %d, actionID: %d"), + buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET + WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET], - buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET + + buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET + WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET]); #ifdef WLAN_FEATURE_P2P_DEBUG if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && - wlan_hdd_is_type_p2p_action(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET])) + wlan_hdd_is_type_p2p_action( + &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], + len - mgmt_hdr_len)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE) @@ -2128,7 +2144,9 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, pRemainChanCtx = cfgState->remain_on_chan_ctx; if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && - hdd_p2p_is_action_type_rsp(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET]) && + hdd_p2p_is_action_type_rsp( + &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], + len - mgmt_hdr_len) && cfgState->remain_on_chan_ctx && cfgState->current_freq == chan->center_freq ) { @@ -2283,7 +2301,9 @@ int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && - (buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME)) + wlan_hdd_is_type_p2p_action( + &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], + len - mgmt_hdr_len)) { actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; hddLog(LOG1, "Tx Action Frame %u", actionFrmType); |
