diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 315fa284c..d91a93627 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -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,