EAP-FAST server: 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
b6f961ab25
commit
ed5e3a5888
1 changed files with 19 additions and 14 deletions
|
@ -180,42 +180,47 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
|
||||||
buf, end - buf);
|
buf, end - buf);
|
||||||
|
|
||||||
pos = buf;
|
pos = buf;
|
||||||
while (pos + 1 < end) {
|
while (end - pos > 1) {
|
||||||
if (pos + 2 + pos[1] > end)
|
u8 id, elen;
|
||||||
|
|
||||||
|
id = *pos++;
|
||||||
|
elen = *pos++;
|
||||||
|
if (elen > end - pos)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (*pos) {
|
switch (id) {
|
||||||
case PAC_OPAQUE_TYPE_PAD:
|
case PAC_OPAQUE_TYPE_PAD:
|
||||||
goto done;
|
goto done;
|
||||||
case PAC_OPAQUE_TYPE_KEY:
|
case PAC_OPAQUE_TYPE_KEY:
|
||||||
if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
|
if (elen != EAP_FAST_PAC_KEY_LEN) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
|
wpa_printf(MSG_DEBUG,
|
||||||
"PAC-Key length %d", pos[1]);
|
"EAP-FAST: Invalid PAC-Key length %d",
|
||||||
|
elen);
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pac_key = pos + 2;
|
pac_key = pos;
|
||||||
wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
|
wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
|
||||||
"decrypted PAC-Opaque",
|
"decrypted PAC-Opaque",
|
||||||
pac_key, EAP_FAST_PAC_KEY_LEN);
|
pac_key, EAP_FAST_PAC_KEY_LEN);
|
||||||
break;
|
break;
|
||||||
case PAC_OPAQUE_TYPE_LIFETIME:
|
case PAC_OPAQUE_TYPE_LIFETIME:
|
||||||
if (pos[1] != 4) {
|
if (elen != 4) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
|
wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
|
||||||
"PAC-Key lifetime length %d",
|
"PAC-Key lifetime length %d",
|
||||||
pos[1]);
|
elen);
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
lifetime = WPA_GET_BE32(pos + 2);
|
lifetime = WPA_GET_BE32(pos);
|
||||||
break;
|
break;
|
||||||
case PAC_OPAQUE_TYPE_IDENTITY:
|
case PAC_OPAQUE_TYPE_IDENTITY:
|
||||||
identity = pos + 2;
|
identity = pos;
|
||||||
identity_len = pos[1];
|
identity_len = elen;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += 2 + pos[1];
|
pos += elen;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
@ -1134,7 +1139,7 @@ static int eap_fast_parse_tlvs(struct wpabuf *data,
|
||||||
|
|
||||||
pos = wpabuf_mhead(data);
|
pos = wpabuf_mhead(data);
|
||||||
end = pos + wpabuf_len(data);
|
end = pos + wpabuf_len(data);
|
||||||
while (pos + 4 < end) {
|
while (end - pos > 4) {
|
||||||
mandatory = pos[0] & 0x80;
|
mandatory = pos[0] & 0x80;
|
||||||
tlv_type = WPA_GET_BE16(pos) & 0x3fff;
|
tlv_type = WPA_GET_BE16(pos) & 0x3fff;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
Loading…
Reference in a new issue