Hey, I've uploaded madwifi_0.9.2+r1842.20061207-2etch1 prepared by Kel Modderman with the attached interdiff; it contains security fixes. Please review and accept.
Thanks, -- Loïc Minier
--- madwifi-0.9.2+r1842.20061207/debian/patches/00list +++ madwifi-0.9.2+r1842.20061207/debian/patches/00list @@ -1,0 +2,3 @@ +01_secfix-0.9.3-sizecheck-take3 +02_secfix-0.9.3-wmmparams-take2 +03_secfix-0.9.3-beacon_interval_range --- madwifi-0.9.2+r1842.20061207/debian/control +++ madwifi-0.9.2+r1842.20061207/debian/control @@ -2,7 +2,7 @@ Section: non-free/net Priority: optional Maintainer: Debian madwifi team <[EMAIL PROTECTED]> -Uploaders: Loic Minier <[EMAIL PROTECTED]>, Kel Modderman <[EMAIL PROTECTED]>, Matt Brown <[EMAIL PROTECTED]>, Alex Wallis <[EMAIL PROTECTED]> +Uploaders: Loic Minier <[EMAIL PROTECTED]>, Kel Modderman <[EMAIL PROTECTED]>, Matt Brown <[EMAIL PROTECTED]>, Alex Wallis <[EMAIL PROTECTED]> Build-Depends: cdbs, debhelper (>= 5.0.37), bzip2, dpatch Standards-Version: 3.7.2 --- madwifi-0.9.2+r1842.20061207/debian/changelog +++ madwifi-0.9.2+r1842.20061207/debian/changelog @@ -1,3 +1,19 @@ +madwifi (1:0.9.2+r1842.20061207-2etch1) stable; urgency=high + + * Backport upstream security fixes; closes: #425738. + - Remote DoS: insufficient input validation (beacon interval) + debian/patches/03_secfix-0.9.3-beacon_interval_range.dpatch + http://madwifi.org/ticket/1270 + - Remote DoS: insufficient input validation (Fast Frame parsing) + debian/patches/01_secfix-0.9.3-sizecheck-take3.dpatch + http://madwifi.org/ticket/1335 + - Local DoS: insufficient input validation (WMM parameters) + debian/patches/02_secfix-0.9.3-wmmparams-take2.dpatch + http://madwifi.org/ticket/1334 + * Update Uploaders email address. + + -- Kel Modderman <[EMAIL PROTECTED]> Thu, 24 May 2007 13:59:23 +1000 + madwifi (1:0.9.2+r1842.20061207-2) unstable; urgency=high * Add upstream revision 1847 as a new dpatch to completely fix --- madwifi-0.9.2+r1842.20061207/debian/control.modules.in +++ madwifi-0.9.2+r1842.20061207/debian/control.modules.in @@ -2,7 +2,7 @@ Section: non-free/net Priority: optional Maintainer: Debian madwifi team <[EMAIL PROTECTED]> -Uploaders: Loic Minier <[EMAIL PROTECTED]>, Kel Modderman <[EMAIL PROTECTED]>, Matt Brown <[EMAIL PROTECTED]>, Alex Wallis <[EMAIL PROTECTED]> +Uploaders: Loic Minier <[EMAIL PROTECTED]>, Kel Modderman <[EMAIL PROTECTED]>, Matt Brown <[EMAIL PROTECTED]>, Alex Wallis <[EMAIL PROTECTED]> Build-Depends: debhelper (>= 5.0.37), bzip2 Standards-Version: 3.7.2 --- madwifi-0.9.2+r1842.20061207.orig/debian/patches/01_secfix-0.9.3-sizecheck-take3.dpatch +++ madwifi-0.9.2+r1842.20061207/debian/patches/01_secfix-0.9.3-sizecheck-take3.dpatch @@ -0,0 +1,69 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## secfix-0.9.3-sizecheck-take3.patch by Kel Modderman <[EMAIL PROTECTED]> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Fast Frame parsing remote kernel DoS fix + [EMAIL PROTECTED]@ +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_input.c madwifi-0.9.3/net80211/ieee80211_input.c +--- madwifi-0.9.3.orig/net80211/ieee80211_input.c 2007-02-03 06:01:51.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_input.c 2007-05-22 21:10:55.000000000 +1000 +@@ -693,13 +693,31 @@ ieee80211_input(struct ieee80211_node *n + + /* 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, +@@ -712,14 +730,7 @@ ieee80211_input(struct ieee80211_node *n + } + 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); +- + skb1 = skb_clone(skb, GFP_ATOMIC); /* XXX: GFP_ATOMIC is overkill? */ +- eh_tmp = (struct ether_header *)skb->data; +- +- /* ether_type must be length*/ +- frame_len = ntohs(eh_tmp->ether_type); + + /* we now have 802.3 MAC hdr followed by 802.2 LLC/SNAP. convert to DIX */ + athff_decap(skb); +@@ -729,8 +740,6 @@ ieee80211_input(struct ieee80211_node *n + + /* prepare second tunneled frame */ + skb_pull(skb1, roundup(sizeof(struct ether_header) + frame_len, 4)); +- eh_tmp = (struct ether_header *)skb1->data; +- frame_len = ntohs(eh_tmp->ether_type); + athff_decap(skb1); + + /* deliver the frames */ --- madwifi-0.9.2+r1842.20061207.orig/debian/patches/02_secfix-0.9.3-wmmparams-take2.dpatch +++ madwifi-0.9.2+r1842.20061207/debian/patches/02_secfix-0.9.3-wmmparams-take2.dpatch @@ -0,0 +1,30 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## secfix-0.9.3-wmmparams-take2.patch by Kel Modderman <[EMAIL PROTECTED]> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: ieee80211_ioctl_getwmmparams local kernel DoS + [EMAIL PROTECTED]@ +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_wireless.c madwifi-0.9.3/net80211/ieee80211_wireless.c +--- madwifi-0.9.3.orig/net80211/ieee80211_wireless.c 2007-02-12 15:25:25.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_wireless.c 2007-05-22 21:12:07.000000000 +1000 +@@ -3621,7 +3621,8 @@ ieee80211_ioctl_setwmmparams(struct net_ + { + struct ieee80211vap *vap = dev->priv; + int *param = (int *) extra; +- int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE; ++ int ac = (param[1] >= 0 && param[1] < WME_NUM_AC) ? ++ param[1] : WME_AC_BE; + int bss = param[2]; + struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme; + +@@ -3709,7 +3710,8 @@ ieee80211_ioctl_getwmmparams(struct net_ + { + struct ieee80211vap *vap = dev->priv; + int *param = (int *) extra; +- int ac = (param[1] < WME_NUM_AC) ? param[1] : WME_AC_BE; ++ int ac = (param[1] >= 0 && param[1] < WME_NUM_AC) ? ++ param[1] : WME_AC_BE; + struct ieee80211_wme_state *wme = &vap->iv_ic->ic_wme; + struct chanAccParams *chanParams = (param[2] == 0) ? + &(wme->wme_chanParams) : &(wme->wme_bssChanParams); --- madwifi-0.9.2+r1842.20061207.orig/debian/patches/03_secfix-0.9.3-beacon_interval_range.dpatch +++ madwifi-0.9.2+r1842.20061207/debian/patches/03_secfix-0.9.3-beacon_interval_range.dpatch @@ -0,0 +1,181 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## beacon_interval_range_plus_iw_power_cleanup.patch by Kel Modderman <[EMAIL PROTECTED]> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: reject invalid local and remote beacons +## DP: http://madwifi.org/changeset/2348 +## DP: while there, clean up IW POWER handling +## DP: http://madwifi.org/changeset/2272 + [EMAIL PROTECTED]@ +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_input.c madwifi-0.9.3/net80211/ieee80211_input.c +--- madwifi-0.9.3.orig/net80211/ieee80211_input.c 2007-02-03 06:01:51.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_input.c 2007-05-22 21:30:35.000000000 +1000 +@@ -2733,7 +2733,20 @@ ieee80211_recv_mgmt(struct ieee80211_nod + vap->iv_stats.is_rx_chanmismatch++; + return; + } +- ++ ++ /* IEEE802.11 does not specify the allowed range for ++ * beacon interval. We discard any beacons with a ++ * beacon interval outside of an arbitrary range in ++ * order to protect against attack. ++ */ ++ if (!(IEEE80211_BINTVAL_MIN <= scan.bintval && ++ scan.bintval <= IEEE80211_BINTVAL_MAX)) { ++ IEEE80211_DISCARD(vap, IEEE80211_MSG_SCAN, ++ wh, "beacon", "invalid beacon interval (%u)", ++ scan.bintval); ++ return; ++ } ++ + /* + * Count frame now that we know it's to be processed. + */ +@@ -2861,7 +2874,7 @@ ieee80211_recv_mgmt(struct ieee80211_nod + IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); + memcpy(ni->ni_tstamp.data, scan.tstamp, + sizeof(ni->ni_tstamp)); +- ni->ni_intval = scan.bintval; ++ ni->ni_intval = IEEE80211_BINTVAL_SANITISE(scan.bintval); + ni->ni_capinfo = scan.capinfo; + ni->ni_chan = ic->ic_curchan; + ni->ni_fhdwell = scan.fhdwell; +@@ -3285,7 +3298,7 @@ ieee80211_recv_mgmt(struct ieee80211_nod + ni->ni_rssi = rssi; + ni->ni_rstamp = rstamp; + ni->ni_last_rx = jiffies; +- ni->ni_intval = bintval; ++ ni->ni_intval = IEEE80211_BINTVAL_SANITISE(bintval); + ni->ni_capinfo = capinfo; + ni->ni_chan = ic->ic_curchan; + ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_node.c madwifi-0.9.3/net80211/ieee80211_node.c +--- madwifi-0.9.3.orig/net80211/ieee80211_node.c 2007-02-07 01:33:38.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_node.c 2007-05-22 21:30:35.000000000 +1000 +@@ -664,7 +664,7 @@ ieee80211_sta_join(struct ieee80211vap * + memcpy(ni->ni_essid, se->se_ssid + 2, ni->ni_esslen); + ni->ni_rstamp = se->se_rstamp; + ni->ni_tstamp.tsf = se->se_tstamp.tsf; +- ni->ni_intval = se->se_intval; ++ ni->ni_intval = IEEE80211_BINTVAL_SANITISE(se->se_intval); + ni->ni_capinfo = se->se_capinfo; + ni->ni_chan = se->se_chan; + ni->ni_timoff = se->se_timoff; +@@ -1216,7 +1216,7 @@ ieee80211_add_neighbor(struct ieee80211v + memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]); + IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); + memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp)); +- ni->ni_intval = sp->bintval; ++ ni->ni_intval = IEEE80211_BINTVAL_SANITISE(sp->bintval); + ni->ni_capinfo = sp->capinfo; + ni->ni_chan = ic->ic_curchan; + ni->ni_fhdwell = sp->fhdwell; +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_scan.h madwifi-0.9.3/net80211/ieee80211_scan.h +--- madwifi-0.9.3.orig/net80211/ieee80211_scan.h 2007-01-30 14:57:52.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_scan.h 2007-05-22 21:30:35.000000000 +1000 +@@ -130,7 +130,7 @@ struct ieee80211_scanparams { + u_int8_t bchan; + u_int8_t fhindex; + u_int8_t erp; +- u_int8_t bintval; ++ u_int16_t bintval; + u_int8_t timoff; + u_int8_t *tim; + u_int8_t *tstamp; +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_var.h madwifi-0.9.3/net80211/ieee80211_var.h +--- madwifi-0.9.3.orig/net80211/ieee80211_var.h 2007-01-22 13:07:30.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_var.h 2007-05-22 21:30:35.000000000 +1000 +@@ -60,9 +60,15 @@ + #define IEEE80211_DTIM_MIN 1 /* min DTIM period */ + #define IEEE80211_DTIM_DEFAULT 1 /* default DTIM period */ + +-#define IEEE80211_BINTVAL_MAX 500 /* max beacon interval (TU's) */ ++#define IEEE80211_BINTVAL_MAX 1000 /* max beacon interval (TU's) */ + #define IEEE80211_BINTVAL_MIN 25 /* min beacon interval (TU's) */ + #define IEEE80211_BINTVAL_DEFAULT 100 /* default beacon interval (TU's) */ ++#define IEEE80211_BINTVAL_VALID(_bi) \ ++ ((IEEE80211_BINTVAL_MIN <= (_bi)) && \ ++ ((_bi) <= IEEE80211_BINTVAL_MAX)) ++#define IEEE80211_BINTVAL_SANITISE(_bi) \ ++ (IEEE80211_BINTVAL_VALID(_bi) ? \ ++ (_bi) : IEEE80211_BINTVAL_DEFAULT) + + #define IEEE80211_BGSCAN_INTVAL_MIN 15 /* min bg scan intvl (secs) */ + #define IEEE80211_BGSCAN_INTVAL_DEFAULT (5*60) /* default bg scan intvl */ +diff -Nrup madwifi-0.9.3.orig/net80211/ieee80211_wireless.c madwifi-0.9.3/net80211/ieee80211_wireless.c +--- madwifi-0.9.3.orig/net80211/ieee80211_wireless.c 2007-02-12 15:25:25.000000000 +1000 ++++ madwifi-0.9.3/net80211/ieee80211_wireless.c 2007-05-22 21:30:35.000000000 +1000 +@@ -1255,35 +1255,37 @@ ieee80211_ioctl_siwpower(struct net_devi + { + struct ieee80211vap *vap = dev->priv; + struct ieee80211com *ic = vap->iv_ic; ++ ++ /* XXX: These values, flags, and caps do not seem to be used elsewhere ++ * at all? */ + ++ if ((ic->ic_caps & IEEE80211_C_PMGT) == 0) ++ return -EOPNOTSUPP; ++ + if (wrq->disabled) { +- if (ic->ic_flags & IEEE80211_F_PMGTON) { ++ if (ic->ic_flags & IEEE80211_F_PMGTON) + ic->ic_flags &= ~IEEE80211_F_PMGTON; +- goto done; ++ } else { ++ switch (wrq->flags & IW_POWER_MODE) { ++ case IW_POWER_UNICAST_R: ++ case IW_POWER_ALL_R: ++ case IW_POWER_ON: ++ if (wrq->flags & IW_POWER_PERIOD) { ++ if (IEEE80211_BINTVAL_VALID(wrq->value)) ++ ic->ic_lintval = IEEE80211_MS_TO_TU(wrq->value); ++ else ++ return -EINVAL; ++ } ++ if (wrq->flags & IW_POWER_TIMEOUT) ++ ic->ic_holdover = IEEE80211_MS_TO_TU(wrq->value); ++ ++ ic->ic_flags |= IEEE80211_F_PMGTON; ++ break; ++ default: ++ return -EINVAL; + } +- return 0; +- } +- +- if ((ic->ic_caps & IEEE80211_C_PMGT) == 0) +- return -EOPNOTSUPP; +- switch (wrq->flags & IW_POWER_MODE) { +- case IW_POWER_UNICAST_R: +- case IW_POWER_ALL_R: +- case IW_POWER_ON: +- ic->ic_flags |= IEEE80211_F_PMGTON; +- break; +- default: +- return -EINVAL; + } +- if (wrq->flags & IW_POWER_TIMEOUT) { +- ic->ic_holdover = IEEE80211_MS_TO_TU(wrq->value); +- ic->ic_flags |= IEEE80211_F_PMGTON; +- } +- if (wrq->flags & IW_POWER_PERIOD) { +- ic->ic_lintval = IEEE80211_MS_TO_TU(wrq->value); +- ic->ic_flags |= IEEE80211_F_PMGTON; +- } +-done: ++ + return IS_UP(ic->ic_dev) ? ic->ic_reset(ic->ic_dev) : 0; + } + +@@ -2366,8 +2368,7 @@ ieee80211_ioctl_setparam(struct net_devi + if (vap->iv_opmode != IEEE80211_M_HOSTAP && + vap->iv_opmode != IEEE80211_M_IBSS) + return -EINVAL; +- if (IEEE80211_BINTVAL_MIN <= value && +- value <= IEEE80211_BINTVAL_MAX) { ++ if (IEEE80211_BINTVAL_VALID(value)) { + ic->ic_lintval = value; /* XXX multi-bss */ + retv = ENETRESET; /* requires restart */ + } else

