[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

STABLE: Please review madwifi_0.9.2+r1842.20061207-2etch1



        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 <pkg-madwifi-maintainers@lists.alioth.debian.org>
-Uploaders: Loic Minier <lool@dooz.org>, Kel Modderman <kelmo@kanotixguide.org>, Matt Brown <mattb@debian.org>, Alex Wallis <awol@otaku42.de>
+Uploaders: Loic Minier <lool@dooz.org>, Kel Modderman <kel@otaku42.de>, Matt Brown <mattb@debian.org>, Alex Wallis <awol@otaku42.de>
 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 <kel@otaku42.de>  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 <pkg-madwifi-maintainers@lists.alioth.debian.org>
-Uploaders: Loic Minier <lool@dooz.org>, Kel Modderman <kelmo@kanotixguide.org>, Matt Brown <mattb@debian.org>, Alex Wallis <awol@otaku42.de>
+Uploaders: Loic Minier <lool@dooz.org>, Kel Modderman <kel@otaku42.de>, Matt Brown <mattb@debian.org>, Alex Wallis <awol@otaku42.de>
 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 <kel@otaku42.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fast Frame parsing remote kernel DoS fix
+
+@DPATCH@
+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 <kel@otaku42.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: ieee80211_ioctl_getwmmparams local kernel DoS
+
+@DPATCH@
+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 <kel@otaku42.de>
+##
+## 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
+
+@DPATCH@
+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

Reply to: