Skip to content

Commit 5e35f54

Browse files
wifi: mwifiex: Fix OOB and integer underflow when rx packets
jira VULN-154525 cve CVE-2023-53226 commit-author Polaris Pi <[email protected]> commit 1195852 Make sure mwifiex_process_mgmt_packet, mwifiex_process_sta_rx_packet and mwifiex_process_uap_rx_packet, mwifiex_uap_queue_bridged_pkt and mwifiex_process_rx_packet not out-of-bounds access the skb->data buffer. Fixes: 2dbaf75 ("mwifiex: report received management frames to cfg80211") Signed-off-by: Polaris Pi <[email protected]> Reviewed-by: Matthew Wang <[email protected]> Reviewed-by: Brian Norris <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit 1195852) Signed-off-by: Shreeya Patel <[email protected]>
1 parent d8f9ea6 commit 5e35f54

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

drivers/net/wireless/marvell/mwifiex/sta_rx.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
8686
rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length);
8787
rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off;
8888

89+
if (sizeof(*rx_pkt_hdr) + rx_pkt_off > skb->len) {
90+
mwifiex_dbg(priv->adapter, ERROR,
91+
"wrong rx packet offset: len=%d, rx_pkt_off=%d\n",
92+
skb->len, rx_pkt_off);
93+
priv->stats.rx_dropped++;
94+
dev_kfree_skb_any(skb);
95+
}
96+
8997
if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
9098
sizeof(bridge_tunnel_header))) ||
9199
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
@@ -194,7 +202,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_private *priv,
194202

195203
rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset;
196204

197-
if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) {
205+
if ((rx_pkt_offset + rx_pkt_length) > skb->len ||
206+
sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) {
198207
mwifiex_dbg(adapter, ERROR,
199208
"wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n",
200209
skb->len, rx_pkt_offset, rx_pkt_length);

drivers/net/wireless/marvell/mwifiex/uap_txrx.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
103103
return;
104104
}
105105

106+
if (sizeof(*rx_pkt_hdr) +
107+
le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) {
108+
mwifiex_dbg(adapter, ERROR,
109+
"wrong rx packet offset: len=%d,rx_pkt_offset=%d\n",
110+
skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
111+
priv->stats.rx_dropped++;
112+
dev_kfree_skb_any(skb);
113+
}
114+
106115
if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header,
107116
sizeof(bridge_tunnel_header))) ||
108117
(!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header,
@@ -367,6 +376,16 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv,
367376
rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type);
368377
rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset);
369378

379+
if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) +
380+
sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) {
381+
mwifiex_dbg(adapter, ERROR,
382+
"wrong rx packet for struct ethhdr: len=%d, offset=%d\n",
383+
skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset));
384+
priv->stats.rx_dropped++;
385+
dev_kfree_skb_any(skb);
386+
return 0;
387+
}
388+
370389
ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source);
371390

372391
if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) +

drivers/net/wireless/marvell/mwifiex/util.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,15 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
393393
}
394394

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

397402
skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
398403
skb_pull(skb, sizeof(pkt_len));
399-
400-
pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
404+
pkt_len -= sizeof(pkt_len);
401405

402406
ieee_hdr = (void *)skb->data;
403407
if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
@@ -410,7 +414,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
410414
skb->data + sizeof(struct ieee80211_hdr),
411415
pkt_len - sizeof(struct ieee80211_hdr));
412416

413-
pkt_len -= ETH_ALEN + sizeof(pkt_len);
417+
pkt_len -= ETH_ALEN;
414418
rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
415419

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

0 commit comments

Comments
 (0)