mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 00:38:24 -05:00
HS 2.0: Clarify OSU Provider list length validation
The previous version was somewhat too complex for some static analyzers. Use local variables for the extracted length fields and explicitly compare these against the remaining buffer length. (CID 68121) Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
56b352ec58
commit
0570a3ea7d
@ -562,7 +562,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
const u8 *end = pos + len;
|
const u8 *end = pos + len;
|
||||||
u16 len2;
|
u16 len2;
|
||||||
const u8 *pos2;
|
const u8 *pos2;
|
||||||
u8 uri_len;
|
u8 uri_len, osu_method_len, osu_nai_len;
|
||||||
|
|
||||||
wpa_hexdump(MSG_DEBUG, "HS 2.0: Parsing OSU Provider", pos, len);
|
wpa_hexdump(MSG_DEBUG, "HS 2.0: Parsing OSU Provider", pos, len);
|
||||||
prov = os_realloc_array(wpa_s->osu_prov,
|
prov = os_realloc_array(wpa_s->osu_prov,
|
||||||
@ -586,7 +586,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
}
|
}
|
||||||
len2 = WPA_GET_LE16(pos);
|
len2 = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
if (pos + len2 > end) {
|
if (len2 > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
||||||
"Friendly Name Duples");
|
"Friendly Name Duples");
|
||||||
return;
|
return;
|
||||||
@ -623,13 +623,19 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
pos += uri_len;
|
pos += uri_len;
|
||||||
|
|
||||||
/* OSU Method list */
|
/* OSU Method list */
|
||||||
if (pos + 1 > end || pos + 1 + pos[0] > end) {
|
if (pos + 1 > end) {
|
||||||
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method "
|
||||||
|
"list length");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osu_method_len = pos[0];
|
||||||
|
if (osu_method_len > end - pos - 1) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU Method "
|
||||||
"list");
|
"list");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos2 = pos + 1;
|
pos2 = pos + 1;
|
||||||
pos += 1 + pos[0];
|
pos += 1 + osu_method_len;
|
||||||
while (pos2 < pos) {
|
while (pos2 < pos) {
|
||||||
if (*pos2 < 32)
|
if (*pos2 < 32)
|
||||||
prov->osu_methods |= BIT(*pos2);
|
prov->osu_methods |= BIT(*pos2);
|
||||||
@ -644,7 +650,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
}
|
}
|
||||||
len2 = WPA_GET_LE16(pos);
|
len2 = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
if (pos + len2 > end) {
|
if (len2 > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons "
|
||||||
"Available");
|
"Available");
|
||||||
return;
|
return;
|
||||||
@ -655,6 +661,8 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
/* Icons Available */
|
/* Icons Available */
|
||||||
while (pos2 < pos) {
|
while (pos2 < pos) {
|
||||||
struct osu_icon *icon = &prov->icon[prov->icon_count];
|
struct osu_icon *icon = &prov->icon[prov->icon_count];
|
||||||
|
u8 flen;
|
||||||
|
|
||||||
if (pos2 + 2 + 2 + 3 + 1 + 1 > pos) {
|
if (pos2 + 2 + 2 + 3 + 1 + 1 > pos) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
|
wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
|
||||||
break;
|
break;
|
||||||
@ -667,31 +675,43 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
os_memcpy(icon->lang, pos2, 3);
|
os_memcpy(icon->lang, pos2, 3);
|
||||||
pos2 += 3;
|
pos2 += 3;
|
||||||
|
|
||||||
if (pos2 + 1 + pos2[0] > pos) {
|
flen = pos2[0];
|
||||||
|
if (flen > pos - pos2 - 1) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon Type");
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon Type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os_memcpy(icon->icon_type, pos2 + 1, pos2[0]);
|
os_memcpy(icon->icon_type, pos2 + 1, flen);
|
||||||
pos2 += 1 + pos2[0];
|
pos2 += 1 + flen;
|
||||||
|
|
||||||
if (pos2 + 1 + pos2[0] > pos) {
|
if (pos2 + 1 > pos) {
|
||||||
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon "
|
||||||
|
"Filename length");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flen = pos2[0];
|
||||||
|
if (flen > pos - pos2 - 1) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not room for Icon "
|
||||||
"Filename");
|
"Filename");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os_memcpy(icon->filename, pos2 + 1, pos2[0]);
|
os_memcpy(icon->filename, pos2 + 1, flen);
|
||||||
pos2 += 1 + pos2[0];
|
pos2 += 1 + flen;
|
||||||
|
|
||||||
prov->icon_count++;
|
prov->icon_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSU_NAI */
|
/* OSU_NAI */
|
||||||
if (pos + 1 > end || pos + 1 + pos[0] > end) {
|
if (pos + 1 > end) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI");
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
os_memcpy(prov->osu_nai, pos + 1, pos[0]);
|
osu_nai_len = pos[0];
|
||||||
pos += 1 + pos[0];
|
if (osu_nai_len > end - pos - 1) {
|
||||||
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU_NAI");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
os_memcpy(prov->osu_nai, pos + 1, osu_nai_len);
|
||||||
|
pos += 1 + osu_nai_len;
|
||||||
|
|
||||||
/* OSU Service Description Length */
|
/* OSU Service Description Length */
|
||||||
if (pos + 2 > end) {
|
if (pos + 2 > end) {
|
||||||
@ -701,7 +721,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
}
|
}
|
||||||
len2 = WPA_GET_LE16(pos);
|
len2 = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
if (pos + len2 > end) {
|
if (len2 > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
||||||
"Service Description Duples");
|
"Service Description Duples");
|
||||||
return;
|
return;
|
||||||
@ -712,15 +732,18 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||||||
/* OSU Service Description Duples */
|
/* OSU Service Description Duples */
|
||||||
while (pos2 + 4 <= pos && prov->serv_desc_count < OSU_MAX_ITEMS) {
|
while (pos2 + 4 <= pos && prov->serv_desc_count < OSU_MAX_ITEMS) {
|
||||||
struct osu_lang_string *f;
|
struct osu_lang_string *f;
|
||||||
if (pos2 + 1 + pos2[0] > pos || pos2[0] < 3) {
|
u8 descr_len;
|
||||||
|
|
||||||
|
descr_len = pos2[0];
|
||||||
|
if (descr_len > pos - pos2 - 1 || descr_len < 3) {
|
||||||
wpa_printf(MSG_DEBUG, "Invalid OSU Service "
|
wpa_printf(MSG_DEBUG, "Invalid OSU Service "
|
||||||
"Description");
|
"Description");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f = &prov->serv_desc[prov->serv_desc_count++];
|
f = &prov->serv_desc[prov->serv_desc_count++];
|
||||||
os_memcpy(f->lang, pos2 + 1, 3);
|
os_memcpy(f->lang, pos2 + 1, 3);
|
||||||
os_memcpy(f->text, pos2 + 1 + 3, pos2[0] - 3);
|
os_memcpy(f->text, pos2 + 1 + 3, descr_len - 3);
|
||||||
pos2 += 1 + pos2[0];
|
pos2 += 1 + descr_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR,
|
wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR,
|
||||||
|
Loading…
Reference in New Issue
Block a user