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);