Increase buffer size and prevent write beyond buffer end

wpa_config_write_key_mgmt has a buffer size of 50. This is not enough
to fit the longest case. I used a network with "WPA-PSK WPA-EAP
WPA-NONE" and CONFIG_IEEE80211R=y + CONFIG_IEEE80211W=y to produce
a string longer than 50 chars. Increase the buffer size to 100 to
prevent truncated output.

Truncated output is not the only problem. If the buffer end is
reached when adding certain key mgmt types the function does not
return immediately. This leaves pos > end. When a second os_sprintf
is called the calculation of end - pos yields a large positive
number for buffer size. End result is a write beyond the buffer end.
Fix this by bailing out if buffer end is reached.

Signed-hostap: Pontus Fuchs <pontus.fuchs@gmail.com>
This commit is contained in:
Pontus Fuchs 2013-10-14 20:49:26 +03:00 committed by Jouni Malinen
parent ded22b5390
commit 5079392954

View file

@ -546,10 +546,10 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
char *buf, *pos, *end;
int ret;
pos = buf = os_zalloc(50);
pos = buf = os_zalloc(100);
if (buf == NULL)
return NULL;
end = buf + 50;
end = buf + 100;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
ret = os_snprintf(pos, end - pos, "%sWPA-PSK",
@ -602,29 +602,59 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
}
#ifdef CONFIG_IEEE80211R
if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK)
pos += os_snprintf(pos, end - pos, "%sFT-PSK",
pos == buf ? "" : " ");
if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) {
ret = os_snprintf(pos, end - pos, "%sFT-PSK",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
pos += os_snprintf(pos, end - pos, "%sFT-EAP",
pos == buf ? "" : " ");
if (ssid->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
ret = os_snprintf(pos, end - pos, "%sFT-EAP",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
pos += os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
pos == buf ? "" : " ");
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
ret = os_snprintf(pos, end - pos, "%sWPA-PSK-SHA256",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
pos == buf ? "" : " ");
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPS
if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
pos += os_snprintf(pos, end - pos, "%sWPS",
pos == buf ? "" : " ");
if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
ret = os_snprintf(pos, end - pos, "%sWPS",
pos == buf ? "" : " ");
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
}
pos += ret;
}
#endif /* CONFIG_WPS */
return buf;