HS 2.0: Avoid undefined behavior in pointer arithmetic
Reorder terms in a way that no invalid pointers are generated with pos+len operations. end-pos is always defined (with a valid pos pointer) while pos+len could end up pointing beyond the end pointer which would be undefined behavior. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
904e977bc7
commit
619fdfacc4
1 changed files with 32 additions and 32 deletions
|
@ -617,7 +617,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
prov->osu_ssid_len = osu_ssid_len;
|
prov->osu_ssid_len = osu_ssid_len;
|
||||||
|
|
||||||
/* OSU Friendly Name Length */
|
/* OSU Friendly Name Length */
|
||||||
if (pos + 2 > end) {
|
if (end - pos < 2) {
|
||||||
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 Length");
|
"Friendly Name Length");
|
||||||
return;
|
return;
|
||||||
|
@ -633,9 +633,9 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
pos += len2;
|
pos += len2;
|
||||||
|
|
||||||
/* OSU Friendly Name Duples */
|
/* OSU Friendly Name Duples */
|
||||||
while (pos2 + 4 <= pos && prov->friendly_name_count < OSU_MAX_ITEMS) {
|
while (pos - pos2 >= 4 && prov->friendly_name_count < OSU_MAX_ITEMS) {
|
||||||
struct osu_lang_string *f;
|
struct osu_lang_string *f;
|
||||||
if (pos2 + 1 + pos2[0] > pos || pos2[0] < 3) {
|
if (1 + pos2[0] > pos - pos2 || pos2[0] < 3) {
|
||||||
wpa_printf(MSG_DEBUG, "Invalid OSU Friendly Name");
|
wpa_printf(MSG_DEBUG, "Invalid OSU Friendly Name");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -646,7 +646,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSU Server URI */
|
/* OSU Server URI */
|
||||||
if (pos + 1 > end) {
|
if (end - pos < 1) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"HS 2.0: Not enough room for OSU Server URI length");
|
"HS 2.0: Not enough room for OSU Server URI length");
|
||||||
return;
|
return;
|
||||||
|
@ -661,7 +661,7 @@ 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) {
|
if (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 length");
|
"list length");
|
||||||
return;
|
return;
|
||||||
|
@ -681,7 +681,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icons Available Length */
|
/* Icons Available Length */
|
||||||
if (pos + 2 > end) {
|
if (end - pos < 2) {
|
||||||
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 Length");
|
"Available Length");
|
||||||
return;
|
return;
|
||||||
|
@ -701,7 +701,7 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
struct osu_icon *icon = &prov->icon[prov->icon_count];
|
struct osu_icon *icon = &prov->icon[prov->icon_count];
|
||||||
u8 flen;
|
u8 flen;
|
||||||
|
|
||||||
if (pos2 + 2 + 2 + 3 + 1 + 1 > pos) {
|
if (2 + 2 + 3 + 1 + 1 > pos - pos2) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
|
wpa_printf(MSG_DEBUG, "HS 2.0: Invalid Icon Metadata");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -713,46 +713,46 @@ 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;
|
||||||
|
|
||||||
flen = pos2[0];
|
flen = *pos2++;
|
||||||
if (flen > pos - pos2 - 1) {
|
if (flen > pos - pos2) {
|
||||||
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, flen);
|
os_memcpy(icon->icon_type, pos2, flen);
|
||||||
pos2 += 1 + flen;
|
pos2 += flen;
|
||||||
|
|
||||||
if (pos2 + 1 > pos) {
|
if (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 length");
|
"Filename length");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flen = pos2[0];
|
flen = *pos2++;
|
||||||
if (flen > pos - pos2 - 1) {
|
if (flen > pos - pos2) {
|
||||||
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, flen);
|
os_memcpy(icon->filename, pos2, flen);
|
||||||
pos2 += 1 + flen;
|
pos2 += flen;
|
||||||
|
|
||||||
prov->icon_count++;
|
prov->icon_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSU_NAI */
|
/* OSU_NAI */
|
||||||
if (pos + 1 > end) {
|
if (end - pos < 1) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
osu_nai_len = pos[0];
|
osu_nai_len = *pos++;
|
||||||
if (osu_nai_len > end - pos - 1) {
|
if (osu_nai_len > end - pos) {
|
||||||
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, osu_nai_len);
|
os_memcpy(prov->osu_nai, pos, osu_nai_len);
|
||||||
pos += 1 + osu_nai_len;
|
pos += osu_nai_len;
|
||||||
|
|
||||||
/* OSU Service Description Length */
|
/* OSU Service Description Length */
|
||||||
if (pos + 2 > end) {
|
if (end - pos < 2) {
|
||||||
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 Length");
|
"Service Description Length");
|
||||||
return;
|
return;
|
||||||
|
@ -768,20 +768,20 @@ static void hs20_osu_add_prov(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
pos += len2;
|
pos += len2;
|
||||||
|
|
||||||
/* OSU Service Description Duples */
|
/* OSU Service Description Duples */
|
||||||
while (pos2 + 4 <= pos && prov->serv_desc_count < OSU_MAX_ITEMS) {
|
while (pos - pos2 >= 4 && prov->serv_desc_count < OSU_MAX_ITEMS) {
|
||||||
struct osu_lang_string *f;
|
struct osu_lang_string *f;
|
||||||
u8 descr_len;
|
u8 descr_len;
|
||||||
|
|
||||||
descr_len = pos2[0];
|
descr_len = *pos2++;
|
||||||
if (descr_len > pos - pos2 - 1 || descr_len < 3) {
|
if (descr_len > pos - pos2 || 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, 3);
|
||||||
os_memcpy(f->text, pos2 + 1 + 3, descr_len - 3);
|
os_memcpy(f->text, pos2 + 3, descr_len - 3);
|
||||||
pos2 += 1 + descr_len;
|
pos2 += 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,
|
||||||
|
@ -816,9 +816,9 @@ void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
|
||||||
end = pos + wpabuf_len(prov_anqp);
|
end = pos + wpabuf_len(prov_anqp);
|
||||||
|
|
||||||
/* OSU SSID */
|
/* OSU SSID */
|
||||||
if (pos + 1 > end)
|
if (end - pos < 1)
|
||||||
continue;
|
continue;
|
||||||
if (pos + 1 + pos[0] > end) {
|
if (1 + pos[0] > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
|
||||||
"OSU SSID");
|
"OSU SSID");
|
||||||
continue;
|
continue;
|
||||||
|
@ -832,7 +832,7 @@ void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
|
||||||
osu_ssid = pos;
|
osu_ssid = pos;
|
||||||
pos += osu_ssid_len;
|
pos += osu_ssid_len;
|
||||||
|
|
||||||
if (pos + 1 > end) {
|
if (end - pos < 1) {
|
||||||
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
|
wpa_printf(MSG_DEBUG, "HS 2.0: Not enough room for "
|
||||||
"Number of OSU Providers");
|
"Number of OSU Providers");
|
||||||
continue;
|
continue;
|
||||||
|
@ -842,7 +842,7 @@ void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
|
||||||
num_providers);
|
num_providers);
|
||||||
|
|
||||||
/* OSU Providers */
|
/* OSU Providers */
|
||||||
while (pos + 2 < end && num_providers > 0) {
|
while (end - pos > 2 && num_providers > 0) {
|
||||||
num_providers--;
|
num_providers--;
|
||||||
len = WPA_GET_LE16(pos);
|
len = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
Loading…
Reference in a new issue