Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions drivers/net/wireless/marvell/mwifiex/sta_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,23 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;

if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
sizeof(bridge_tunnel_header))) ||
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
sizeof(rfc1042_header)) &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) {
if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) +
rx_pkt_off > skb->len) {
mwifiex_dbg(priv->adapter, ERROR,
"wrong rx packet offset: len=%d, rx_pkt_off=%d\n",
skb->len, rx_pkt_off);
priv->stats.rx_dropped++;
dev_kfree_skb_any(skb);
return -1;
}

if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len &&
((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
sizeof(bridge_tunnel_header))) ||
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
sizeof(rfc1042_header)) &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP &&
ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) {
/*
* Replace the 803 header and rfc1042 header (llc/snap) with an
* EthernetII header, keep the src/dst and snap_type
Expand Down Expand Up @@ -206,7 +217,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,

rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset;

if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) {
if ((rx_pkt_offset + rx_pkt_length) > skb->len ||
sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) {
mwifiex_dbg(adapter, ERROR,
"wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
skb->len, rx_pkt_offset, rx_pkt_length);
Expand Down
20 changes: 20 additions & 0 deletions drivers/net/wireless/marvell/mwifiex/uap_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
return;
}

if (sizeof(*rx_pkt_hdr) +
le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) {
mwifiex_dbg(adapter, ERROR,
"wrong rx packet offset: len=%d,rx_pkt_offset=%d\n",
skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
priv->stats.rx_dropped++;
dev_kfree_skb_any(skb);
return;
}

if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
sizeof(bridge_tunnel_header))) ||
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
Expand Down Expand Up @@ -379,6 +389,16 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);

if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) {
mwifiex_dbg(adapter, ERROR,
"wrong rx packet for struct ethhdr: len=%d, offset=%d\n",
skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
priv->stats.rx_dropped++;
dev_kfree_skb_any(skb);
return 0;
}

ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);

if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/wireless/marvell/mwifiex/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,11 +405,15 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
}

rx_pd = (struct rxpd *)skb->data;
pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) {
mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length");
return -1;
}

skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
skb_pull(skb, sizeof(pkt_len));

pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
pkt_len -= sizeof(pkt_len);

ieee_hdr = (void *)skb->data;
if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
Expand All @@ -422,7 +426,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
skb->data + sizeof(struct ieee80211_hdr),
pkt_len - sizeof(struct ieee80211_hdr));

pkt_len -= ETH_ALEN + sizeof(pkt_len);
pkt_len -= ETH_ALEN;
rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);

cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
Expand Down