From: Sepherosa Ziehau Date: Tue, 21 Nov 2006 12:07:21 +0000 (+0000) Subject: - Tighten invariant on loops used to parse ie's; this ensures we never X-Git-Tag: v2.0.1~4074 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/8c56084fba69def7b2aae15bb2e5508fa3ac26c0 - Tighten invariant on loops used to parse ie's; this ensures we never touch data outside the packet (previously we might touch 1 byte); it also has the happy side effect of working around broken orinoco/agere firmware that sends malformed association response frames - Correct ie length check; need to include fixed part of ie Obtained-from: FreeBSD (sam@freebsd.org) --- diff --git a/sys/netproto/802_11/wlan/ieee80211_input.c b/sys/netproto/802_11/wlan/ieee80211_input.c index 12874f52f1..31d928875f 100644 --- a/sys/netproto/802_11/wlan/ieee80211_input.c +++ b/sys/netproto/802_11/wlan/ieee80211_input.c @@ -29,8 +29,8 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.62.2.12 2006/03/14 23:24:02 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_input.c,v 1.5 2006/10/21 05:21:30 sephe Exp $ + * $FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.62.2.13 2006/08/10 06:21:50 sam Exp $ + * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_input.c,v 1.6 2006/11/21 12:07:21 sephe Exp $ */ #include @@ -1821,8 +1821,8 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); scan.chan = scan.bchan; - while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]); + while (efrm - frm > 1) { + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); switch (*frm) { case IEEE80211_ELEMID_SSID: scan.ssid = frm; @@ -2067,8 +2067,8 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, * [tlv] extended supported rates */ ssid = rates = xrates = NULL; - while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]); + while (efrm - frm > 1) { + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); switch (*frm) { case IEEE80211_ELEMID_SSID: ssid = frm; @@ -2244,8 +2244,8 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, if (reassoc) frm += 6; /* ignore current AP info */ ssid = rates = xrates = wpa = wme = NULL; - while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]); + while (efrm - frm > 1) { + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); switch (*frm) { case IEEE80211_ELEMID_SSID: ssid = frm; @@ -2449,8 +2449,8 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, frm += 2; rates = xrates = wpa = wme = NULL; - while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]); + while (efrm - frm > 1) { + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); switch (*frm) { case IEEE80211_ELEMID_RATES: rates = frm;