summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2021-08-12 16:01:26 +0300
committerMichael Bestas <mkbestas@lineageos.org>2021-08-12 16:01:40 +0300
commit48fe008ed6afcfa9ce3138b3558cd9c5764fc8c1 (patch)
treebbefcaa39ef097554988f6b64bfb6df78e33ba74
parentecedd447ac008fc249d779a7e57c11a17a4ca968 (diff)
parent1da16a753ff855f0635b2f6a32eb89231a877013 (diff)
Merge tag 'LA.UM.7.2.c26-02900-sdm660.0' of https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/wlan/qcacld-3.0 into lineage-18.1-caf-msm8998
"LA.UM.7.2.c26-02900-sdm660.0" # By Yeshwanth Sriram Guntuka (9) and others # Via Gerrit - the friendly Code Review server (9) and abhinav kumar (1) * tag 'LA.UM.7.2.c26-02900-sdm660.0' of https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/wlan/qcacld-3.0: qcacld-3.0: Possible buffer overflow issue in wma qcacld-3.0: Do not intrabss fwd frag EAPOL frames in HL qcacld-3.0: Drop EAPOL frame with DA different from SAP vdev mac addr qcacld-3.0: Do not intrabss fwd EAPOL frames in IPA exc path qcacld-3.0: Drop non-EAPOL/WAPI frames from unauthorized peer qcacld-3.0: Do not intrabss forward fragmented EAPOL frames qcacld-3.0: Fix MIC verification in helium family qcacld-3.0: Drop mcast and plaintext frags in protected network qcacld-3.0: Flush frags for peer on add key request qcacld-3.0: Add support to flush fragments for a particular peer qcacld-3.0: Modify check to ensure consecutive PN for frags qcacld-3.0: Fix integer underflow in assoc response frame qcacld-3.0: Send assoc reject upon failing to post ASSOC_IND qcacld-3.0: Fix integer overflow in rrm_fill_beacon_ies() qcacld-3.0: Possible integer overflow in hdd apf read memory cb qcacld-3.0: Validate assoc response IE len before copy qcacld-3.0: Validate assoc response IE len before copy qcacld-3.0: Add max index check for dscp_to_up_map array qcacld-3.0: Fix Integer overflow while sending beacon report qcacld-3.0: Possible OOB write in rrm_process_radio_measurement_request Conflicts: drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c drivers/staging/qcacld-3.0/core/mac/src/pe/rrm/rrm_api.c drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c Change-Id: I8296a9e88acde9824ac1973bf9cdb90150e0cafc
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c36
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c23
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c37
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h14
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c40
-rw-r--r--drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h4
-rw-r--r--drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c12
-rw-r--r--drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c95
-rw-r--r--drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c9
-rw-r--r--drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c5
-rw-r--r--drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c18
11 files changed, 263 insertions, 30 deletions
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c
index 84045eb8ad58..de94c0d676ab 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_defrag.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -445,6 +445,8 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev,
struct ol_rx_reorder_array_elem_t *rx_reorder_array_elem;
uint16_t frxseq, rxseq, seq;
htt_pdev_handle htt_pdev = pdev->htt_pdev;
+ void *rx_desc;
+ uint8_t index;
seq = seq_num & peer->tids_rx_reorder[tid].win_sz_mask;
qdf_assert(seq == 0);
@@ -458,6 +460,28 @@ ol_rx_reorder_store_frag(ol_txrx_pdev_handle pdev,
IEEE80211_SEQ_FRAG_MASK;
more_frag = mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
+ rx_desc = htt_rx_msdu_desc_retrieve(htt_pdev, frag);
+ qdf_assert(htt_rx_msdu_has_wlan_mcast_flag(htt_pdev, rx_desc));
+ index = htt_rx_msdu_is_wlan_mcast(htt_pdev, rx_desc) ?
+ txrx_sec_mcast : txrx_sec_ucast;
+
+ /*
+ * Multicast/Broadcast frames should not be fragmented so drop
+ * such frames.
+ */
+ if (index != txrx_sec_ucast) {
+ ol_rx_frames_free(htt_pdev, frag);
+ return;
+ }
+
+ if (peer->security[index].sec_type != htt_sec_type_none &&
+ !htt_rx_mpdu_is_encrypted(htt_pdev, rx_desc)) {
+ ol_txrx_err("Unencrypted fragment received in security mode %d",
+ peer->security[index].sec_type);
+ ol_rx_frames_free(htt_pdev, frag);
+ return;
+ }
+
if ((!more_frag) && (!fragno) && (!rx_reorder_array_elem->head)) {
ol_rx_fraglist_insert(htt_pdev, &rx_reorder_array_elem->head,
&rx_reorder_array_elem->tail, frag, &all_frag_present);
@@ -700,7 +724,13 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev,
while (cur) {
tmp_next = qdf_nbuf_next(cur);
qdf_nbuf_set_next(cur, NULL);
- if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) {
+ /*
+ * Strict PN check between the first fragment of the current
+ * frame and the last fragment of the previous frame is not
+ * necessary.
+ */
+ if (!ol_rx_pn_check_base(vdev, peer, tid, cur,
+ (cur == frag_list) ? false : true)) {
/* PN check failed,discard frags */
if (prev) {
qdf_nbuf_set_next(prev, NULL);
@@ -935,7 +965,7 @@ ol_rx_frag_tkip_demic(ol_txrx_pdev_handle pdev, const uint8_t *key,
ol_rx_defrag_copydata(msdu, pktlen - f_tkip.ic_miclen + rx_desc_len,
f_tkip.ic_miclen, (caddr_t) mic0);
- if (!qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen))
+ if (qdf_mem_cmp(mic, mic0, f_tkip.ic_miclen))
return OL_RX_DEFRAG_ERR;
qdf_nbuf_trim_tail(msdu, f_tkip.ic_miclen);
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c
index ebc15b7206d9..7059303b9f50 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_fwd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2018, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -150,6 +150,7 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev,
while (msdu) {
struct ol_txrx_vdev_t *tx_vdev;
void *rx_desc;
+ uint16_t off = 0;
/*
* Remember the next list elem, because our processing
* may cause the MSDU to get linked into a different list.
@@ -204,6 +205,26 @@ ol_rx_fwd_check(struct ol_txrx_vdev_t *vdev,
continue;
}
+ if (pdev->cfg.is_high_latency)
+ off = htt_rx_msdu_rx_desc_size_hl(
+ pdev->htt_pdev,
+ rx_desc);
+
+ if (vdev->opmode == wlan_op_mode_ap &&
+ __qdf_nbuf_data_is_ipv4_eapol_pkt(
+ qdf_nbuf_data(msdu) + off) &&
+ qdf_mem_cmp(qdf_nbuf_data(msdu) +
+ QDF_NBUF_DEST_MAC_OFFSET,
+ vdev->mac_addr.raw,
+ QDF_MAC_ADDR_SIZE)) {
+ TXRX_STATS_MSDU_LIST_INCR(
+ pdev, tx.dropped.host_reject, msdu);
+ qdf_nbuf_set_next(msdu, NULL);
+ qdf_nbuf_tx_free(msdu, QDF_NBUF_PKT_ERROR);
+ msdu = msdu_list;
+ continue;
+ }
+
/*
* This MSDU needs to be forwarded to the tx path.
* Check whether it also needs to be sent to the OS
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c
index dd09c3f50c71..0bd8e75e5191 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2013-2017, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -37,25 +37,36 @@
} while (0)
int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk)
{
- int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
- return rc;
+ if (strict_chk)
+ return ((new_pn->pn24 & 0xffffff) - (old_pn->pn24 & 0xffffff)
+ != 1);
+ else
+ return ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
}
int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk)
{
- int rc = ((new_pn->pn48 & 0xffffffffffffULL) <=
- (old_pn->pn48 & 0xffffffffffffULL));
- return rc;
+ if (strict_chk)
+ return ((new_pn->pn48 & 0xffffffffffffULL) -
+ (old_pn->pn48 & 0xffffffffffffULL) != 1);
+ else
+ return ((new_pn->pn48 & 0xffffffffffffULL) <=
+ (old_pn->pn48 & 0xffffffffffffULL));
}
int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk)
{
int pn_is_replay = 0;
+ /* TODO Strick check for WAPI is not implemented*/
+
if (new_pn->pn128[1] == old_pn->pn128[1])
pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]);
else
@@ -73,7 +84,7 @@ int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
qdf_nbuf_t
ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
struct ol_txrx_peer_t *peer,
- unsigned int tid, qdf_nbuf_t msdu_list)
+ unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk)
{
struct ol_txrx_pdev_t *pdev = vdev->pdev;
union htt_rx_pn_t *last_pn;
@@ -132,7 +143,7 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
pn_is_replay =
pdev->rx_pn[peer->security[index].sec_type].
cmp(&new_pn, last_pn, index == txrx_sec_ucast,
- vdev->opmode);
+ vdev->opmode, strict_chk);
} else {
last_pn_valid = peer->tids_last_pn_valid[tid] = 1;
}
@@ -253,7 +264,7 @@ ol_rx_pn_check(struct ol_txrx_vdev_t *vdev,
struct ol_txrx_peer_t *peer, unsigned int tid,
qdf_nbuf_t msdu_list)
{
- msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+ msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false);
ol_rx_fwd_check(vdev, peer, tid, msdu_list);
}
@@ -262,7 +273,7 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
struct ol_txrx_peer_t *peer,
unsigned int tid, qdf_nbuf_t msdu_list)
{
- msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+ msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false);
ol_rx_deliver(vdev, peer, tid, msdu_list);
}
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h
index 8e0c007b091d..fa64c3e5133c 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_rx_pn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2017, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -24,13 +24,16 @@
#include <ol_txrx_api.h> /* ol_txrx_peer_t, etc. */
int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk);
int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk);
int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
- union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+ union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+ bool strict_chk);
/**
* @brief If applicable, check the Packet Number to detect replays.
@@ -87,11 +90,12 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
* @param tid - which TID within the peer the rx frames belong to
* @param msdu_list - NULL-terminated list of MSDUs to perform PN check on
* (if PN check is applicable, i.e. PN length > 0)
+ * @param strick_chk - if PN consecutive stric check is needed or not
* @return list of netbufs that didn't fail the PN check
*/
qdf_nbuf_t
ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
struct ol_txrx_peer_t *peer,
- unsigned int tid, qdf_nbuf_t msdu_list);
+ unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk);
#endif /* _OL_RX_PN_H_ */
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c
index 7778d0a45dd6..89e627e04e20 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2020, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1951,14 +1951,32 @@ ol_txrx_pdev_post_attach(ol_txrx_pdev_handle pdev)
*/
qdf_mem_set(&pdev->rx_pn[0], sizeof(pdev->rx_pn), 0);
+ /* WEP: 24-bit PN */
+ pdev->rx_pn[htt_sec_type_wep40].len =
+ pdev->rx_pn[htt_sec_type_wep104].len =
+ pdev->rx_pn[htt_sec_type_wep128].len = 24;
+
+ pdev->rx_pn[htt_sec_type_wep40].cmp =
+ pdev->rx_pn[htt_sec_type_wep104].cmp =
+ pdev->rx_pn[htt_sec_type_wep128].cmp = ol_rx_pn_cmp24;
+
/* TKIP: 48-bit TSC, CCMP: 48-bit PN */
pdev->rx_pn[htt_sec_type_tkip].len =
pdev->rx_pn[htt_sec_type_tkip_nomic].len =
pdev->rx_pn[htt_sec_type_aes_ccmp].len = 48;
+
+ pdev->rx_pn[htt_sec_type_aes_ccmp_256].len =
+ pdev->rx_pn[htt_sec_type_aes_gcmp].len =
+ pdev->rx_pn[htt_sec_type_aes_gcmp_256].len = 48;
+
pdev->rx_pn[htt_sec_type_tkip].cmp =
pdev->rx_pn[htt_sec_type_tkip_nomic].cmp =
pdev->rx_pn[htt_sec_type_aes_ccmp].cmp = ol_rx_pn_cmp48;
+ pdev->rx_pn[htt_sec_type_aes_ccmp_256].cmp =
+ pdev->rx_pn[htt_sec_type_aes_gcmp].cmp =
+ pdev->rx_pn[htt_sec_type_aes_gcmp_256].cmp = ol_rx_pn_cmp48;
+
/* WAPI: 128-bit PN */
pdev->rx_pn[htt_sec_type_wapi].len = 128;
pdev->rx_pn[htt_sec_type_wapi].cmp = ol_rx_pn_wapi_cmp;
@@ -4008,6 +4026,26 @@ ol_txrx_peer_find_by_addr(struct ol_txrx_pdev_t *pdev, uint8_t *peer_mac_addr)
return peer;
}
+void
+ol_txrx_peer_flush_frags(ol_txrx_pdev_handle pdev, uint8_t vdev_id,
+ uint8_t *peer_mac)
+{
+ struct ol_txrx_peer_t *peer;
+ uint8_t peer_id;
+
+ if (!pdev)
+ return;
+
+ peer = ol_txrx_find_peer_by_addr_inc_ref(pdev, peer_mac, &peer_id);
+
+ if (!peer)
+ return;
+
+ ol_rx_reorder_peer_cleanup(peer->vdev, peer);
+
+ OL_TXRX_PEER_UNREF_DELETE(peer);
+}
+
/**
* ol_txrx_dump_tx_desc() - dump tx desc total and free count
* @txrx_pdev: Pointer to txrx pdev
diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h
index 3203a75ebeb0..e0210a6e8838 100644
--- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h
+++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -802,7 +802,7 @@ struct ol_txrx_pdev_t {
struct {
int (*cmp)(union htt_rx_pn_t *new,
union htt_rx_pn_t *old,
- int is_unicast, int opmode);
+ int is_unicast, int opmode, bool strict_chk);
int len;
} rx_pn[htt_num_sec_types];
diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
index d69b3c1f6f6f..473e26a724c3 100644
--- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -15473,6 +15473,12 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
QDF_STATUS qdf_ret_status;
hdd_context_t *pHddCtx;
hdd_ap_ctx_t *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
+ ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+
+ if (!pdev) {
+ hdd_err("DP pdev is NULL");
+ return -EINVAL;
+ }
ENTER();
@@ -15636,6 +15642,10 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
setKey.keyDirection = eSIR_TX_RX;
qdf_mem_copy(setKey.peerMac.bytes, mac_addr, QDF_MAC_ADDR_SIZE);
}
+
+ ol_txrx_peer_flush_frags(pdev, pAdapter->sessionId,
+ setKey.peerMac.bytes);
+
if ((QDF_IBSS_MODE == pAdapter->device_mode) && !pairwise) {
/* if a key is already installed, block all subsequent ones */
if (pAdapter->sessionCtx.station.ibss_enc_key_installed) {
diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c
index 6d1377ef0b02..7f0586ee47d5 100644
--- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c
+++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_ipa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -5779,6 +5779,40 @@ static enum hdd_ipa_forward_type hdd_ipa_intrabss_forward(
}
/**
+ * wlan_ipa_eapol_intrabss_fwd_check() - Check if eapol pkt intrabss fwd is
+ * allowed or not
+ * @nbuf: network buffer
+ * @vdev_id: vdev id
+ *
+ * Return: true if intrabss fwd is allowed for eapol else false
+ */
+static bool
+wlan_ipa_eapol_intrabss_fwd_check(qdf_nbuf_t nbuf, uint8_t vdev_id)
+{
+ ol_txrx_vdev_handle vdev;
+ uint8_t *vdev_mac_addr;
+
+ vdev = ol_txrx_get_vdev_from_vdev_id(vdev_id);
+
+ if (!vdev) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "txrx vdev is NULL for vdev_id = %d",
+ vdev_id);
+ return false;
+ }
+
+ vdev_mac_addr = ol_txrx_get_vdev_mac_addr( vdev);
+
+ if (!vdev_mac_addr)
+ return false;
+
+ if (qdf_mem_cmp(qdf_nbuf_data(nbuf) + QDF_NBUF_DEST_MAC_OFFSET,
+ vdev_mac_addr, QDF_MAC_ADDR_SIZE))
+ return false;
+
+ return true;
+}
+
+/**
* __hdd_ipa_w2i_cb() - WLAN to IPA callback handler
* @priv: pointer to private data registered with IPA (we register a
* pointer to the global IPA context)
@@ -5798,6 +5832,12 @@ static void __hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
struct hdd_ipa_iface_context *iface_context;
uint8_t fw_desc;
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ bool is_eapol_wapi = false;
+ struct qdf_mac_addr peer_mac_addr = QDF_MAC_ADDR_ZERO_INITIALIZER;
+ uint8_t sta_idx;
+ ol_txrx_peer_handle peer;
+ ol_txrx_pdev_handle pdev;
+ hdd_station_ctx_t *sta_ctx;
hdd_ipa = (struct hdd_ipa_priv *)priv;
@@ -5821,6 +5861,13 @@ static void __hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
return;
}
+ pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ if (NULL == pdev) {
+ WMA_LOGE("%s: DP pdev is NULL", __func__);
+ kfree_skb(skb);
+ return;
+ }
+
if (hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)) {
session_id = (uint8_t)skb->cb[0];
iface_id = hdd_ipa->vdev_to_iface[session_id];
@@ -5863,6 +5910,52 @@ static void __hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN);
}
+ if (iface_context->adapter->device_mode == QDF_STA_MODE) {
+ sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(
+ iface_context->adapter);
+ qdf_copy_macaddr(&peer_mac_addr,
+ &sta_ctx->conn_info.bssId);
+ } else if (iface_context->adapter->device_mode
+ == QDF_SAP_MODE) {
+ qdf_mem_copy(peer_mac_addr.bytes, qdf_nbuf_data(skb) +
+ QDF_NBUF_SRC_MAC_OFFSET,
+ QDF_MAC_ADDR_SIZE);
+ }
+
+ if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) {
+ is_eapol_wapi = true;
+ if (iface_context->adapter->device_mode ==
+ QDF_SAP_MODE &&
+ !wlan_ipa_eapol_intrabss_fwd_check(skb,
+ iface_context->adapter->sessionId)) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "EAPOL intrabss fwd drop DA: %pM",
+ qdf_nbuf_data(skb) +
+ QDF_NBUF_DEST_MAC_OFFSET);
+ hdd_ipa->ipa_rx_internal_drop_count++;
+ kfree_skb(skb);
+ return;
+ }
+ } else if (qdf_nbuf_is_ipv4_wapi_pkt(skb)) {
+ is_eapol_wapi = true;
+ }
+
+ peer = ol_txrx_find_peer_by_addr(pdev, peer_mac_addr.bytes,
+ &sta_idx);
+
+ /*
+ * Check for peer auth state before allowing non-EAPOL/WAPI
+ * frames to be intrabss forwarded or submitted to stack.
+ */
+ if (peer && ol_txrx_get_peer_state(peer) !=
+ OL_TXRX_PEER_STATE_AUTH && !is_eapol_wapi) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "non-EAPOL/WAPI frame received when peer is unauthorized");
+ hdd_ipa->ipa_rx_internal_drop_count++;
+ kfree_skb(skb);
+ return;
+ }
+
iface_context->stats.num_rx_ipa_excep++;
/* Disable to forward Intra-BSS Rx packets when
diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c
index c66a8ab5b65b..92fe1d522878 100644
--- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -910,6 +910,13 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
hdd_dhcp_indication(pAdapter, staid, skb, QDF_RX);
+ if (qdf_unlikely(qdf_nbuf_is_ipv4_eapol_pkt(skb) &&
+ qdf_mem_cmp(qdf_nbuf_data(skb) +
+ QDF_NBUF_DEST_MAC_OFFSET,
+ pAdapter->macAddressCurrent.bytes,
+ QDF_MAC_ADDR_SIZE)))
+ return QDF_STATUS_E_FAILURE;
+
hdd_event_eapol_log(skb, QDF_RX);
qdf_dp_trace_log_pkt(pAdapter->sessionId, skb, QDF_RX);
DPTRACE(qdf_dp_trace(skb,
diff --git a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c
index 4877816d63c0..c37ffd12ea9b 100644
--- a/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c
+++ b/drivers/staging/qcacld-3.0/core/mac/src/pe/lim/lim_process_fils.c
@@ -1819,6 +1819,11 @@ QDF_STATUS aead_decrypt_assoc_rsp(tpAniSirGlobal mac_ctx,
uint8_t *fils_ies;
struct pe_fils_session *fils_info = (session->fils_info);
+ if (*n_frame < FIXED_PARAM_OFFSET_ASSOC_RSP) {
+ pe_debug("payload len is less than ASSOC RES offset");
+ return QDF_STATUS_E_FAILURE;
+ }
+
status = find_ie_data_after_fils_session_ie(mac_ctx, p_frame +
FIXED_PARAM_OFFSET_ASSOC_RSP,
((*n_frame) -
diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c
index 60968b3a853e..ad1017e9bd7b 100644
--- a/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c
+++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -2371,8 +2371,22 @@ static QDF_STATUS wma_unified_bcn_tmpl_send(tp_wma_handle wma,
tmpl_len = *(uint32_t *) &bcn_info->beacon[0];
else
tmpl_len = bcn_info->beaconLength;
- if (p2p_ie_len)
+
+ if (tmpl_len > WMI_BEACON_TX_BUFFER_SIZE) {
+ WMA_LOGE("tmpl_len: %d > %d. Invalid tmpl len", tmpl_len,
+ WMI_BEACON_TX_BUFFER_SIZE);
+ return -EINVAL;
+ }
+
+ if (p2p_ie_len) {
+ if (tmpl_len <= p2p_ie_len) {
+ WMA_LOGE("tmpl_len %d <= p2p_ie_len %d, Invalid",
+ tmpl_len, p2p_ie_len);
+ return -EINVAL;
+ }
tmpl_len -= (uint32_t) p2p_ie_len;
+ }
+
frm = bcn_info->beacon + bytes_to_strip;
tmpl_len_aligned = roundup(tmpl_len, sizeof(A_UINT32));
/*