1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
diff -ur madwifi.old/net80211/ieee80211_input.c madwifi.dev/net80211/ieee80211_input.c
--- madwifi.old/net80211/ieee80211_input.c 2007-05-21 17:53:39.000000000 +0200
+++ madwifi.dev/net80211/ieee80211_input.c 2007-05-23 16:50:21.097957392 +0200
@@ -695,13 +695,31 @@
/* NB: assumes linear (i.e., non-fragmented) skb */
+ /* check length > header */
+ if (skb->len < sizeof(struct ether_header) + LLC_SNAPFRAMELEN
+ + roundup(sizeof(struct athl2p_tunnel_hdr) - 2, 4) + 2) {
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
+ ni->ni_macaddr, "data", "%s", "decap error");
+ vap->iv_stats.is_rx_decap++;
+ IEEE80211_NODE_STAT(ni, rx_decap);
+ goto err;
+ }
+
/* get to the tunneled headers */
ath_hdr = (struct athl2p_tunnel_hdr *)
skb_pull(skb, sizeof(struct ether_header) + LLC_SNAPFRAMELEN);
- /* ignore invalid frames */
- if(ath_hdr == NULL)
+ eh_tmp = (struct ether_header *)
+ skb_pull(skb, roundup(sizeof(struct athl2p_tunnel_hdr) - 2, 4) + 2);
+ /* sanity check for malformed 802.3 length */
+ frame_len = ntohs(eh_tmp->ether_type);
+ if (skb->len < roundup(sizeof(struct ether_header) + frame_len, 4)) {
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
+ ni->ni_macaddr, "data", "%s", "decap error");
+ vap->iv_stats.is_rx_decap++;
+ IEEE80211_NODE_STAT(ni, rx_decap);
goto err;
-
+ }
+
/* only implementing FF now. drop all others. */
if (ath_hdr->proto != ATH_L2TUNNEL_PROTO_FF) {
IEEE80211_DISCARD_MAC(vap,
@@ -714,10 +732,6 @@
}
vap->iv_stats.is_rx_ffcnt++;
- /* move past the tunneled header, with alignment */
- skb_pull(skb, roundup(sizeof(struct athl2p_tunnel_hdr) - 2, 4) + 2);
- eh_tmp = (struct ether_header *)skb->data;
-
/* ether_type must be length as FF frames are always LLC/SNAP encap'd */
frame_len = ntohs(eh_tmp->ether_type);
|