Module Name: src
Committed By: maxv
Date: Tue Jan 16 14:37:24 UTC 2018
Modified Files:
src/sys/net80211: ieee80211_input.c
Log Message:
Fix overflow.
To generate a diff of this commit:
cvs rdiff -u -r1.95 -r1.96 src/sys/net80211/ieee80211_input.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/net80211/ieee80211_input.c
diff -u src/sys/net80211/ieee80211_input.c:1.95 src/sys/net80211/ieee80211_input.c:1.96
--- src/sys/net80211/ieee80211_input.c:1.95 Tue Jan 16 14:01:13 2018
+++ src/sys/net80211/ieee80211_input.c Tue Jan 16 14:37:24 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_input.c,v 1.95 2018/01/16 14:01:13 maxv Exp $ */
+/* $NetBSD: ieee80211_input.c,v 1.96 2018/01/16 14:37:24 maxv Exp $ */
/*
* Copyright (c) 2001 Atsushi Onoe
@@ -37,7 +37,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $");
#endif
#ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.95 2018/01/16 14:01:13 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.96 2018/01/16 14:37:24 maxv Exp $");
#endif
#ifdef _KERNEL_OPT
@@ -2003,8 +2003,7 @@ ieee80211_update_adhoc_node(struct ieee8
void
ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
- struct ieee80211_node *ni,
- int subtype, int rssi, u_int32_t rstamp)
+ struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
{
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
@@ -2016,8 +2015,9 @@ ieee80211_recv_mgmt(struct ieee80211com
IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]);
wh = mtod(m0, struct ieee80211_frame *);
- frm = (u_int8_t *)&wh[1];
+ frm = (u_int8_t *)(wh + 1);
efrm = mtod(m0, u_int8_t *) + m0->m_len;
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
@@ -2037,6 +2037,7 @@ ieee80211_recv_mgmt(struct ieee80211com
ic->ic_stats.is_rx_mgtdiscard++;
return;
}
+
/*
* beacon/probe response frame format
* [8] time stamp
@@ -2059,7 +2060,9 @@ ieee80211_recv_mgmt(struct ieee80211com
scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
scan.chan = scan.bchan;
- while (frm < efrm) {
+ while (frm + 1 < efrm) {
+ IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2);
+
switch (*frm) {
case IEEE80211_ELEMID_SSID:
scan.ssid = frm;
@@ -2122,10 +2125,13 @@ ieee80211_recv_mgmt(struct ieee80211com
ic->ic_stats.is_rx_elem_unknown++;
break;
}
+
frm += frm[1] + 2;
}
+
IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE);
IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN);
+
if (
#if IEEE80211_CHAN_MAX < 255
scan.chan > IEEE80211_CHAN_MAX ||
@@ -2172,7 +2178,7 @@ ieee80211_recv_mgmt(struct ieee80211com
if (ni != ic->ic_bss) {
ni = ieee80211_refine_node_for_beacon(ic, ni,
- &ic->ic_channels[scan.chan], scan.ssid);
+ &ic->ic_channels[scan.chan], scan.ssid);
}
/*
* Count frame now that we know it's to be processed.