summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Kumar Sirasanagandla <rsirasan@codeaurora.org>2017-08-16 20:33:49 +0530
committersnandini <snandini@codeaurora.org>2017-08-29 06:53:45 -0700
commit2a178aa72dea489f809c913606cfbf24407e227c (patch)
treeefe6b24ce6d6239e5d3975d93036451324008974
parentdf538ea0fca8a7971fcbdf61d169a5ce0c7e41e0 (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.c42
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);