summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhd_flowring.h3
-rw-r--r--dhd_linux.c11
-rw-r--r--dhd_msgbuf.c6
-rw-r--r--wl_cfg80211.c14
4 files changed, 30 insertions, 4 deletions
diff --git a/dhd_flowring.h b/dhd_flowring.h
index 8f6222f..2fdb400 100644
--- a/dhd_flowring.h
+++ b/dhd_flowring.h
@@ -133,6 +133,9 @@
(DHD_IF_ROLE_AP(pub, idx) || DHD_IF_ROLE_P2PGO(pub, idx) ||\
DHD_IF_ROLE_NAN(pub, idx))
+#define DHD_FLOW_RING_INV_ID(dhdp, flowid) \
+ (flowid < FLOWID_RESERVED) || (flowid > (dhdp)->max_tx_flowid)
+
#define DHD_FLOW_RING(dhdp, flowid) \
(flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid])
diff --git a/dhd_linux.c b/dhd_linux.c
index 665eeb5..68007f6 100644
--- a/dhd_linux.c
+++ b/dhd_linux.c
@@ -6405,6 +6405,9 @@ dhd_stop(struct net_device *net)
#ifdef WL_STATIC_IF
struct bcm_cfg80211 *cfg = wl_get_cfg(net);
#endif /* WL_STATIC_IF */
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+ int ret = 0;
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
#endif /* WL_CFG80211 */
dhd_info_t *dhd = DHD_DEV_INFO(net);
int timeleft = 0;
@@ -6530,6 +6533,14 @@ dhd_stop(struct net_device *net)
#endif /* ARP_OFFLOAD_SUPPORT */
#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
if (dhd_inet6addr_notifier_registered) {
+ ret = dhd_ndo_remove_ip(&dhd->pub, ifidx);
+ if (ret < 0) {
+ DHD_ERROR(("%s: clear host ipv6 for NDO failed%d\n",
+ __FUNCTION__, ret));
+ } else {
+ DHD_PRINT(("%s: cleared host ipv6 table for NDO \n",
+ __FUNCTION__));
+ }
dhd_inet6addr_notifier_registered = FALSE;
unregister_inet6addr_notifier(&dhd_inet6addr_notifier);
}
diff --git a/dhd_msgbuf.c b/dhd_msgbuf.c
index 4bc1d1a..94666e6 100644
--- a/dhd_msgbuf.c
+++ b/dhd_msgbuf.c
@@ -7914,6 +7914,12 @@ BCMFASTPATH(dhd_prot_txstatus_process)(dhd_pub_t *dhd, void *msg)
txstatus = (host_txbuf_cmpl_t *)msg;
flowid = txstatus->compl_hdr.flow_ring_id;
+ if (DHD_FLOW_RING_INV_ID(dhd, flowid)) {
+ DHD_ERROR(("%s: invalid flowid:%d alloc_max:%d fid_max:%d\n",
+ __FUNCTION__, flowid, dhd->num_h2d_rings, dhd->max_tx_flowid));
+ return;
+ }
+
flow_ring_node = DHD_FLOW_RING(dhd, flowid);
#ifdef AGG_H2D_DB
flow_ring = DHD_RING_IN_FLOWRINGS_POOL(prot, flowid);
diff --git a/wl_cfg80211.c b/wl_cfg80211.c
index 3802ed0..53d79bd 100644
--- a/wl_cfg80211.c
+++ b/wl_cfg80211.c
@@ -15302,10 +15302,6 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
#if defined(BCMDONGLEHOST) && defined(TDLS_MSG_ONLY_WFD) && defined(WLTDLS)
dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
#endif /* BCMDONGLEHOST && TDLS_MSG_ONLY_WFD && WLTDLS */
- if (ntoh32(e->datalen) < sizeof(wl_event_rx_frame_data_t)) {
- WL_ERR(("wrong datalen:%d\n", ntoh32(e->datalen)));
- return -EINVAL;
- }
rxframe = (wl_event_rx_frame_data_t *)data;
if (!rxframe) {
@@ -15315,9 +15311,19 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
/* Handle different versions of Rx frame data */
if (ntoh16(rxframe->version) == BCM_RX_FRAME_DATA_VERSION_1) {
+ if (ntoh32(e->datalen) < sizeof(wl_event_rx_frame_data_v1_t)) {
+ WL_ERR(("wrong datalen:%d for rxframe v1:%lu\n",
+ ntoh32(e->datalen), sizeof(wl_event_rx_frame_data_v1_t)));
+ return -EINVAL;
+ }
mgmt_frame_len = ntoh32(e->datalen) - (uint32)sizeof(wl_event_rx_frame_data_v1_t);
rx_event_data = (u8 *) ((wl_event_rx_frame_data_v1_t *)rxframe + 1);
} else if (ntoh16(rxframe->version) == BCM_RX_FRAME_DATA_VERSION_2) {
+ if (ntoh32(e->datalen) < sizeof(wl_event_rx_frame_data_v2_t)) {
+ WL_ERR(("wrong datalen:%d for rxframe v2:%lu\n",
+ ntoh32(e->datalen), sizeof(wl_event_rx_frame_data_v2_t)));
+ return -EINVAL;
+ }
mgmt_frame_len = ntoh32(e->datalen) - (uint32)sizeof(wl_event_rx_frame_data_v2_t);
rx_event_data = (u8 *) ((wl_event_rx_frame_data_v2_t *)rxframe + 1);
} else {