Hi Bernd and security team, On Thu, 24 May 2007 02:28:12 am Bernd Zeimetz wrote: > Package: madwifi > Version: 0.9.3 > Severity: critical > Tags: security > > Hi,
I was wondering how long it would take for someone to file a bug. 0.9.3-2 was uploaded to unstable[0] before the vulnerabilities were made public by the team at madwifi.org. It contained the pertinent patches. > > although I'm pretty sure you know about those issues, it won't be bad to > have them listed in the bugtracker. In case Etch is affected, too, > please get the fixes into r1. > > http://madwifi.org/ticket/1270 > http://madwifi.org/ticket/1335 > http://madwifi.org/ticket/1334 Last time madwifi vulnerabilities were discussed with the security team[1] there was a strong indication that non-free was not cared for[2]. I didn't know how much truth there was to that at the time as there was no further action required then. This time further action could be taken as there do exist security flaws in the madwifi package shipped with etch. The debian security FAQ states[3] that the security team generally don't care for contrib or non-free but they may be influenced into passing on required changes if handed to them on a silver platter by the maintainer or some other developer. A debdiff is attached that would fix the security concerns in madwifi stable version 1:0.9.2+r1842.20061207-2. Below is a brief description of the security concerns taken from the 0.9.3.1 madwifi release announcement, there are no known CVE id's at this time. 1. Remote DoS: insufficient input validation (beacon interval) The beacon interval information that is gathered while scanning for Access Points is not properly validated. This could be exploited from remote to cause a DoS due to a "division by zero" exception. See also: http://madwifi.org/ticket/1270 2. Remote DoS: insufficient input validation (Fast Frame parsing) The code which parses fast frames and 802.3 frames embedded therein does not properly validate the size parameters in such frames. This could be exploited from remote to cause a DoS due to a NULL-pointer dereference. See also: http://madwifi.org/ticket/1335 3. Local DoS: insufficient input validation (WMM parameters) A restricted local user could pass invalid data to two ioctl handlers, causing a DoS due to access being made to invalid addresses. Chances are that this issue also might allow read and/or write access to kernel memory; this has not yet been verified. See also: http://madwifi.org/ticket/1334 I've tested the resulting debian package and it does not change behaviour in ways that will make the end user unhappy as far as I can see. Hopefully it also conforms to guidelines set out in the debian reference for targetting security related fixes to the stable branch. Thanks, Kel. [0] http://packages.qa.debian.org/m/madwifi/news/20070522T134706Z.html [1] http://lists.alioth.debian.org/pipermail/pkg-madwifi-maintainers/2007-April/000626.html [2] http://lists.alioth.debian.org/pipermail/pkg-madwifi-maintainers/2007-April/000634.html [3] http://www.debian.org/security/faq#contrib [4] http://madwifi.org/wiki/Releases/0.9.3.1
diff -u madwifi-0.9.2+r1842.20061207/debian/patches/00list madwifi-0.9.2+r1842.20061207/debian/patches/00list --- 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 diff -u madwifi-0.9.2+r1842.20061207/debian/control madwifi-0.9.2+r1842.20061207/debian/control --- 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 diff -u madwifi-0.9.2+r1842.20061207/debian/changelog madwifi-0.9.2+r1842.20061207/debian/changelog --- 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-3) stable-security; urgency=high + + * Backport upstream security fixes: + - 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 diff -u madwifi-0.9.2+r1842.20061207/debian/control.modules.in madwifi-0.9.2+r1842.20061207/debian/control.modules.in --- 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 only in patch2: unchanged: --- 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 */ only in patch2: unchanged: --- 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); only in patch2: unchanged: --- 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