wifi: avoid buffer overflow reading IEs
This commit is contained in:

committed by
Beniamino Galvani

parent
961d572472
commit
2b64961d05
@@ -625,10 +625,21 @@ get_max_rate_vht_160_ss3 (int mcs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static gboolean
|
||||||
get_max_rate_ht (guint16 ht_cap_info, const guint8 *supported_mcs_set)
|
get_max_rate_ht (const guint8 *bytes, guint len, guint32 *out_maxrate)
|
||||||
{
|
{
|
||||||
guint32 mcs, i, j;
|
guint32 mcs, i, j, m;
|
||||||
|
guint8 ht_cap_info;
|
||||||
|
const guint8 *supported_mcs_set;
|
||||||
|
|
||||||
|
/* https://mrncciew.com/2014/10/19/cwap-ht-capabilities-ie/
|
||||||
|
http://luci.subsignal.org/~jow/802.11n-2009.pdf */
|
||||||
|
|
||||||
|
if (len != 26)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ht_cap_info = bytes[0];
|
||||||
|
supported_mcs_set = &bytes[3];
|
||||||
|
|
||||||
/* Find the maximum supported mcs rate */
|
/* Find the maximum supported mcs rate */
|
||||||
mcs = -1;
|
mcs = -1;
|
||||||
@@ -642,42 +653,57 @@ get_max_rate_ht (guint16 ht_cap_info, const guint8 *supported_mcs_set)
|
|||||||
|
|
||||||
/* Check for 40Mhz wide channel support */
|
/* Check for 40Mhz wide channel support */
|
||||||
if (ht_cap_info & (1 << 1))
|
if (ht_cap_info & (1 << 1))
|
||||||
return get_max_rate_ht_40 (mcs);
|
m = get_max_rate_ht_40 (mcs);
|
||||||
else
|
else
|
||||||
return get_max_rate_ht_20 (mcs);
|
m = get_max_rate_ht_20 (mcs);
|
||||||
|
|
||||||
|
*out_maxrate = m;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static gboolean
|
||||||
get_max_rate_vht (guint32 vht_cap, guint16 tx_map)
|
get_max_rate_vht (const guint8 *bytes, guint len, guint32 *out_maxrate)
|
||||||
{
|
{
|
||||||
guint32 mcs = 7;
|
guint32 mcs, m;
|
||||||
|
guint8 vht_cap, tx_map;
|
||||||
|
|
||||||
|
/* https://tda802dot11.blogspot.it/2014/10/vht-capabilities-element-vht.html
|
||||||
|
* http://chimera.labs.oreilly.com/books/1234000001739/ch03.html#management_frames */
|
||||||
|
|
||||||
|
if (len != 12)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
vht_cap = bytes[0];
|
||||||
|
tx_map = bytes[8];
|
||||||
|
|
||||||
/* Check for mcs rates 8 and 9 support */
|
/* Check for mcs rates 8 and 9 support */
|
||||||
if (tx_map & 0x2a)
|
if (tx_map & 0x2a)
|
||||||
mcs = 9;
|
mcs = 9;
|
||||||
else if (tx_map & 0x15)
|
else if (tx_map & 0x15)
|
||||||
mcs = 8;
|
mcs = 8;
|
||||||
|
else
|
||||||
|
mcs = 7;
|
||||||
|
|
||||||
/* Check for 160Mhz wide channel support and
|
/* Check for 160Mhz wide channel support and
|
||||||
* spatial stream support */
|
* spatial stream support */
|
||||||
if (vht_cap & (1 << 2)) {
|
if (vht_cap & (1 << 2)) {
|
||||||
if (tx_map & 0x30)
|
if (tx_map & 0x30)
|
||||||
return get_max_rate_vht_160_ss3 (mcs);
|
m = get_max_rate_vht_160_ss3 (mcs);
|
||||||
else if (tx_map & 0x0C)
|
else if (tx_map & 0x0C)
|
||||||
return get_max_rate_vht_160_ss2 (mcs);
|
m = get_max_rate_vht_160_ss2 (mcs);
|
||||||
else
|
else
|
||||||
return get_max_rate_vht_160_ss1 (mcs);
|
m = get_max_rate_vht_160_ss1 (mcs);
|
||||||
} else {
|
} else {
|
||||||
if (tx_map & 0x30)
|
if (tx_map & 0x30)
|
||||||
return get_max_rate_vht_80_ss3 (mcs);
|
m = get_max_rate_vht_80_ss3 (mcs);
|
||||||
else if (tx_map & 0x0C)
|
else if (tx_map & 0x0C)
|
||||||
return get_max_rate_vht_80_ss2 (mcs);
|
m = get_max_rate_vht_80_ss2 (mcs);
|
||||||
else
|
else
|
||||||
return get_max_rate_vht_80_ss1 (mcs);
|
m = get_max_rate_vht_80_ss1 (mcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
*out_maxrate = m;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Management Frame Information Element IDs, ieee80211_eid */
|
/* Management Frame Information Element IDs, ieee80211_eid */
|
||||||
@@ -691,6 +717,8 @@ get_max_rate (const guint8 *bytes, gsize len)
|
|||||||
guint32 max_rate = 0;
|
guint32 max_rate = 0;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
|
guint32 m;
|
||||||
|
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -703,10 +731,14 @@ get_max_rate (const guint8 *bytes, gsize len)
|
|||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case WLAN_EID_HT_CAPABILITY:
|
case WLAN_EID_HT_CAPABILITY:
|
||||||
max_rate = NM_MAX (max_rate, get_max_rate_ht (*bytes, bytes+3));
|
if (!get_max_rate_ht (bytes, elem_len, &m))
|
||||||
|
return 0;
|
||||||
|
max_rate = NM_MAX (max_rate, m);
|
||||||
break;
|
break;
|
||||||
case WLAN_EID_VHT_CAPABILITY:
|
case WLAN_EID_VHT_CAPABILITY:
|
||||||
max_rate = NM_MAX (max_rate, get_max_rate_vht (*bytes, *(bytes+8)));
|
if (!get_max_rate_vht (bytes, elem_len, &m))
|
||||||
|
return 0;
|
||||||
|
max_rate = NM_MAX (max_rate, m);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user