Validate driver extended capabilities length against buffer length

Prepare for new extended capabilities bits by checking that the local
buffer is large enough to contain all the bits the driver requests. The
existing buffers are large enough to include anything defined until now,
but it would be possible to add more definitions in the future, so
increase them a bit as well to make this more future proof.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-06-07 16:33:28 +03:00
parent 9c6c5589e0
commit 0bbaa9b93f
3 changed files with 13 additions and 6 deletions

View file

@ -151,7 +151,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
int i, bssid_changed; int i, bssid_changed;
struct wpabuf *resp = NULL; struct wpabuf *resp = NULL;
u8 ext_capab[10]; u8 ext_capab[18];
int ext_capab_len; int ext_capab_len;
if (bss == NULL) { if (bss == NULL) {
@ -371,7 +371,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
} }
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab); ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
sizeof(ext_capab));
if (ext_capab_len > 0) { if (ext_capab_len > 0) {
u8 *pos = wpa_s->sme.assoc_req_ie; u8 *pos = wpa_s->sme.assoc_req_ie;
if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)

View file

@ -1272,13 +1272,18 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
} }
int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf) int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
{ {
u8 *pos = buf; u8 *pos = buf;
u8 len = 6, i; u8 len = 6, i;
if (len < wpa_s->extended_capa_len) if (len < wpa_s->extended_capa_len)
len = wpa_s->extended_capa_len; len = wpa_s->extended_capa_len;
if (buflen < (size_t) len + 2) {
wpa_printf(MSG_INFO,
"Not enough room for building extended capabilities element");
return -1;
}
*pos++ = WLAN_EID_EXT_CAPAB; *pos++ = WLAN_EID_EXT_CAPAB;
*pos++ = len; *pos++ = len;
@ -1666,9 +1671,10 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
* interoperability issues. * interoperability issues.
*/ */
if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) { if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
u8 ext_capab[10]; u8 ext_capab[18];
int ext_capab_len; int ext_capab_len;
ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab); ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
sizeof(ext_capab));
if (ext_capab_len > 0) { if (ext_capab_len > 0) {
u8 *pos = wpa_ie; u8 *pos = wpa_ie;
if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN) if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)

View file

@ -941,7 +941,7 @@ int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid);
int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid, int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
size_t ssid_len); size_t ssid_len);
void wpas_request_connection(struct wpa_supplicant *wpa_s); void wpas_request_connection(struct wpa_supplicant *wpa_s);
int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf); int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
/** /**
* wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response