RSN auth: 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
a5a2f252cb
commit
1e72ba2e61
1 changed files with 5 additions and 5 deletions
|
@ -251,7 +251,7 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
if (pmkid) {
|
if (pmkid) {
|
||||||
if (pos + 2 + PMKID_LEN > buf + len)
|
if (2 + PMKID_LEN > buf + len - pos)
|
||||||
return -1;
|
return -1;
|
||||||
/* PMKID Count */
|
/* PMKID Count */
|
||||||
WPA_PUT_LE16(pos, 1);
|
WPA_PUT_LE16(pos, 1);
|
||||||
|
@ -263,7 +263,7 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||||
#ifdef CONFIG_IEEE80211W
|
#ifdef CONFIG_IEEE80211W
|
||||||
if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
|
if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
|
||||||
conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
|
conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
|
||||||
if (pos + 2 + 4 > buf + len)
|
if (2 + 4 > buf + len - pos)
|
||||||
return -1;
|
return -1;
|
||||||
if (pmkid == NULL) {
|
if (pmkid == NULL) {
|
||||||
/* PMKID Count */
|
/* PMKID Count */
|
||||||
|
@ -791,7 +791,7 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos + 1 + RSN_SELECTOR_LEN < end &&
|
if (1 + RSN_SELECTOR_LEN < end - pos &&
|
||||||
pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
|
pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
|
||||||
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
|
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_PMKID) {
|
||||||
ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
|
ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
|
||||||
|
@ -887,13 +887,13 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
os_memset(ie, 0, sizeof(*ie));
|
os_memset(ie, 0, sizeof(*ie));
|
||||||
for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
|
for (pos = buf, end = pos + len; end - pos > 1; pos += 2 + pos[1]) {
|
||||||
if (pos[0] == 0xdd &&
|
if (pos[0] == 0xdd &&
|
||||||
((pos == buf + len - 1) || pos[1] == 0)) {
|
((pos == buf + len - 1) || pos[1] == 0)) {
|
||||||
/* Ignore padding */
|
/* Ignore padding */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pos + 2 + pos[1] > end) {
|
if (2 + pos[1] > end - pos) {
|
||||||
wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
|
wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
|
||||||
"underflow (ie=%d len=%d pos=%d)",
|
"underflow (ie=%d len=%d pos=%d)",
|
||||||
pos[0], pos[1], (int) (pos - buf));
|
pos[0], pos[1], (int) (pos - buf));
|
||||||
|
|
Loading…
Reference in a new issue