Fixed WEXT scan result parser to not crash on invalid IEs (zero len buffer)
If IWEVGENIE or custom event wpa_ie/rsn_ie is received in scan with empty buffer, the previous version ended up calling realloc(NULL, 0) which seems to return a non-NULL value in some cases. When this return value is passed again into realloc with realloc(ptr, 0), the returned value could be NULL. If the ptr is then freed (os_free(data.ie) in SIOCGIWAP handling), glibc may crash due to invalid pointer being freed (or double-freed?). The non-NULL realloc(NULL, 0) return value from glibc looks a bit odd behavior, but anyway, better avoid this case completely and just skip the IE events that have an empty buffer. This issue should not show up with drivers that produce proper scan results since the IEs will always include the two-octet header. However, it seems to be possible to see this when using 64-bit kernel and 32-bit userspace with incorrect compat-ioctl processing.
This commit is contained in:
parent
00ad53ef68
commit
fd630bc183
2 changed files with 10 additions and 4 deletions
|
@ -1618,6 +1618,9 @@ static void wext_get_scan_iwevgenie(struct iw_event *iwe,
|
||||||
char *genie, *gpos, *gend;
|
char *genie, *gpos, *gend;
|
||||||
u8 *tmp;
|
u8 *tmp;
|
||||||
|
|
||||||
|
if (iwe->u.data.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
gpos = genie = custom;
|
gpos = genie = custom;
|
||||||
gend = genie + iwe->u.data.length;
|
gend = genie + iwe->u.data.length;
|
||||||
if (gend > end) {
|
if (gend > end) {
|
||||||
|
@ -1650,7 +1653,7 @@ static void wext_get_scan_custom(struct iw_event *iwe,
|
||||||
int bytes;
|
int bytes;
|
||||||
spos = custom + 7;
|
spos = custom + 7;
|
||||||
bytes = custom + clen - spos;
|
bytes = custom + clen - spos;
|
||||||
if (bytes & 1)
|
if (bytes & 1 || bytes == 0)
|
||||||
return;
|
return;
|
||||||
bytes /= 2;
|
bytes /= 2;
|
||||||
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
||||||
|
@ -1664,7 +1667,7 @@ static void wext_get_scan_custom(struct iw_event *iwe,
|
||||||
int bytes;
|
int bytes;
|
||||||
spos = custom + 7;
|
spos = custom + 7;
|
||||||
bytes = custom + clen - spos;
|
bytes = custom + clen - spos;
|
||||||
if (bytes & 1)
|
if (bytes & 1 || bytes == 0)
|
||||||
return;
|
return;
|
||||||
bytes /= 2;
|
bytes /= 2;
|
||||||
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
||||||
|
|
|
@ -1447,6 +1447,9 @@ static void wext_get_scan_iwevgenie(struct iw_event *iwe,
|
||||||
char *genie, *gpos, *gend;
|
char *genie, *gpos, *gend;
|
||||||
u8 *tmp;
|
u8 *tmp;
|
||||||
|
|
||||||
|
if (iwe->u.data.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
gpos = genie = custom;
|
gpos = genie = custom;
|
||||||
gend = genie + iwe->u.data.length;
|
gend = genie + iwe->u.data.length;
|
||||||
if (gend > end) {
|
if (gend > end) {
|
||||||
|
@ -1479,7 +1482,7 @@ static void wext_get_scan_custom(struct iw_event *iwe,
|
||||||
int bytes;
|
int bytes;
|
||||||
spos = custom + 7;
|
spos = custom + 7;
|
||||||
bytes = custom + clen - spos;
|
bytes = custom + clen - spos;
|
||||||
if (bytes & 1)
|
if (bytes & 1 || bytes == 0)
|
||||||
return;
|
return;
|
||||||
bytes /= 2;
|
bytes /= 2;
|
||||||
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
||||||
|
@ -1493,7 +1496,7 @@ static void wext_get_scan_custom(struct iw_event *iwe,
|
||||||
int bytes;
|
int bytes;
|
||||||
spos = custom + 7;
|
spos = custom + 7;
|
||||||
bytes = custom + clen - spos;
|
bytes = custom + clen - spos;
|
||||||
if (bytes & 1)
|
if (bytes & 1 || bytes == 0)
|
||||||
return;
|
return;
|
||||||
bytes /= 2;
|
bytes /= 2;
|
||||||
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
tmp = os_realloc(res->ie, res->ie_len + bytes);
|
||||||
|
|
Loading…
Reference in a new issue