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
1 changed files with 41 additions and 18 deletions
|
@ -562,7 +562,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
const u8 *end = pos + len;
|
||||
u16 len2;
|
||||
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);
|
||||
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);
|
||||
pos += 2;
|
||||
if (pos + len2 > end) {
|
||||
if (len2 > end - pos) {
|
||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
||||
"Friendly Name Duples");
|
||||
return;
|
||||
|
@ -623,13 +623,19 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
pos += uri_len;
|
||||
|
||||
/* 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 "
|
||||
"list");
|
||||
return;
|
||||
}
|
||||
pos2 = pos + 1;
|
||||
pos += 1 + pos[0];
|
||||
pos += 1 + osu_method_len;
|
||||
while (pos2 < pos) {
|
||||
if (*pos2 < 32)
|
||||
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);
|
||||
pos += 2;
|
||||
if (pos + len2 > end) {
|
||||
if (len2 > end - pos) {
|
||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for Icons "
|
||||
"Available");
|
||||
return;
|
||||
|
@ -655,6 +661,8 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
/* Icons Available */
|
||||
while (pos2 < pos) {
|
||||
struct osu_icon *icon = &prov->icon[prov->icon_count];
|
||||
u8 flen;
|
||||
|
||||
if (pos2 + 2 + 2 + 3 + 1 + 1 > pos) {
|
||||
wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
|
||||
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);
|
||||
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");
|
||||
break;
|
||||
}
|
||||
os_memcpy(icon->icon_type, pos2 + 1, pos2[0]);
|
||||
pos2 += 1 + pos2[0];
|
||||
os_memcpy(icon->icon_type, pos2 + 1, flen);
|
||||
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 "
|
||||
"Filename");
|
||||
break;
|
||||
}
|
||||
os_memcpy(icon->filename, pos2 + 1, pos2[0]);
|
||||
pos2 += 1 + pos2[0];
|
||||
os_memcpy(icon->filename, pos2 + 1, flen);
|
||||
pos2 += 1 + flen;
|
||||
|
||||
prov->icon_count++;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
return;
|
||||
}
|
||||
os_memcpy(prov->osu_nai, pos + 1, pos[0]);
|
||||
pos += 1 + pos[0];
|
||||
osu_nai_len = 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 */
|
||||
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);
|
||||
pos += 2;
|
||||
if (pos + len2 > end) {
|
||||
if (len2 > end - pos) {
|
||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for OSU "
|
||||
"Service Description Duples");
|
||||
return;
|
||||
|
@ -712,15 +732,18 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
|||
/* OSU Service Description Duples */
|
||||
while (pos2 + 4 <= pos && prov->serv_desc_count < OSU_MAX_ITEMS) {
|
||||
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 "
|
||||
"Description");
|
||||
break;
|
||||
}
|
||||
f = &prov->serv_desc[prov->serv_desc_count++];
|
||||
os_memcpy(f->lang, pos2 + 1, 3);
|
||||
os_memcpy(f->text, pos2 + 1 + 3, pos2[0] - 3);
|
||||
pos2 += 1 + pos2[0];
|
||||
os_memcpy(f->text, pos2 + 1 + 3, descr_len - 3);
|
||||
pos2 += 1 + descr_len;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "HS 2.0: Added OSU Provider through " MACSTR,
|
||||
|
|
Loading…
Reference in a new issue