From 0bbaa9b93f76025e81c3976bebcc00bf1660cfec Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 7 Jun 2014 16:33:28 +0300 Subject: [PATCH] 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 --- wpa_supplicant/sme.c | 5 +++-- wpa_supplicant/wpa_supplicant.c | 12 +++++++++--- wpa_supplicant/wpa_supplicant_i.h | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 9b6667a62..82aef0d80 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -151,7 +151,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, #endif /* CONFIG_IEEE80211R */ int i, bssid_changed; struct wpabuf *resp = NULL; - u8 ext_capab[10]; + u8 ext_capab[18]; int ext_capab_len; if (bss == NULL) { @@ -371,7 +371,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, } #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) { u8 *pos = wpa_s->sme.assoc_req_ie; if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 0b871d07b..ffba0f5e7 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -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 len = 6, i; if (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++ = len; @@ -1666,9 +1671,10 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) * interoperability issues. */ if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) { - u8 ext_capab[10]; + u8 ext_capab[18]; 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) { u8 *pos = wpa_ie; if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index a83c8cdf3..56434c464 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -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, size_t ssid_len); 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