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;
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_max_rate_ht (guint16 ht_cap_info, const guint8 *supported_mcs_set)
|
||||
static gboolean
|
||||
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 */
|
||||
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 */
|
||||
if (ht_cap_info & (1 << 1))
|
||||
return get_max_rate_ht_40 (mcs);
|
||||
m = get_max_rate_ht_40 (mcs);
|
||||
else
|
||||
return get_max_rate_ht_20 (mcs);
|
||||
m = get_max_rate_ht_20 (mcs);
|
||||
|
||||
*out_maxrate = m;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_max_rate_vht (guint32 vht_cap, guint16 tx_map)
|
||||
static gboolean
|
||||
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 */
|
||||
if (tx_map & 0x2a)
|
||||
mcs = 9;
|
||||
else if (tx_map & 0x15)
|
||||
mcs = 8;
|
||||
else
|
||||
mcs = 7;
|
||||
|
||||
/* Check for 160Mhz wide channel support and
|
||||
* spatial stream support */
|
||||
if (vht_cap & (1 << 2)) {
|
||||
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)
|
||||
return get_max_rate_vht_160_ss2 (mcs);
|
||||
m = get_max_rate_vht_160_ss2 (mcs);
|
||||
else
|
||||
return get_max_rate_vht_160_ss1 (mcs);
|
||||
m = get_max_rate_vht_160_ss1 (mcs);
|
||||
} else {
|
||||
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)
|
||||
return get_max_rate_vht_80_ss2 (mcs);
|
||||
m = get_max_rate_vht_80_ss2 (mcs);
|
||||
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 */
|
||||
@@ -691,6 +717,8 @@ get_max_rate (const guint8 *bytes, gsize len)
|
||||
guint32 max_rate = 0;
|
||||
|
||||
while (len) {
|
||||
guint32 m;
|
||||
|
||||
if (len < 2)
|
||||
return 0;
|
||||
|
||||
@@ -703,10 +731,14 @@ get_max_rate (const guint8 *bytes, gsize len)
|
||||
|
||||
switch (id) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user