From 5ecb45a41c116ba57ed6a4fafd703f2b670fa3f6 Mon Sep 17 00:00:00 2001 From: Veerendranath Jakkam Date: Thu, 3 Sep 2020 00:25:28 +0530 Subject: [PATCH] OCV: Use more granular error codes for OCI validation failures Enhance the return values of ocv_verify_tx_params with enum to indicate different OCI verification failures to caller. Signed-off-by: Veerendranath Jakkam --- src/ap/ieee802_11.c | 3 ++- src/ap/ieee802_11_shared.c | 3 ++- src/ap/wnm_ap.c | 2 +- src/ap/wpa_auth.c | 6 ++++-- src/ap/wpa_auth_ft.c | 3 ++- src/common/ocv.c | 23 ++++++++++++----------- src/common/ocv.h | 13 ++++++++++--- src/rsn_supp/wpa.c | 6 +++--- src/rsn_supp/wpa_ft.c | 2 +- wpa_supplicant/mesh_mpm.c | 2 +- wpa_supplicant/sme.c | 2 +- wpa_supplicant/wnm_sta.c | 2 +- 12 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index c98e77103..13431d567 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3563,7 +3563,8 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, return WLAN_STATUS_UNSPECIFIED_FAILURE; if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, - tx_chanwidth, tx_seg1_idx) != 0) { + tx_chanwidth, tx_seg1_idx) != + OCI_SUCCESS) { wpa_printf(MSG_WARNING, "FILS: OCV failed: %s", ocv_errorstr); wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index 79ed450e2..17003d506 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -275,7 +275,8 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd, return; if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, - tx_chanwidth, tx_seg1_idx) != 0) { + tx_chanwidth, tx_seg1_idx) != + OCI_SUCCESS) { wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=saquery%s error=%s", MAC2STR(sa), diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c index 248f5a1cf..be817978e 100644 --- a/src/ap/wnm_ap.c +++ b/src/ap/wnm_ap.c @@ -326,7 +326,7 @@ static void ieee802_11_rx_wnmsleep_req(struct hostapd_data *hapd, if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(hapd, MSG_WARNING, "WNM: OCV failed: %s", ocv_errorstr); return; diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 9e6c0cad3..a5b1953f6 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -3051,7 +3051,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) return; if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci, - tx_chanwidth, tx_seg1_idx) != 0) { + tx_chanwidth, tx_seg1_idx) != + OCI_SUCCESS) { wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, "OCV failed: %s", ocv_errorstr); if (wpa_auth->conf.msg_ctx) @@ -3913,7 +3914,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED) return; if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci, - tx_chanwidth, tx_seg1_idx) != 0) { + tx_chanwidth, tx_seg1_idx) != + OCI_SUCCESS) { wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, "OCV failed: %s", ocv_errorstr); if (wpa_auth->conf.msg_ctx) diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 9caac194e..5cd7037e9 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -3519,7 +3519,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, return WLAN_STATUS_UNSPECIFIED_FAILURE; if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci, - tx_chanwidth, tx_seg1_idx) != 0) { + tx_chanwidth, tx_seg1_idx) != + OCI_SUCCESS) { wpa_printf(MSG_WARNING, "OCV failed: %s", ocv_errorstr); if (sm->wpa_auth->conf.msg_ctx) wpa_msg(sm->wpa_auth->conf.msg_ctx, MSG_INFO, diff --git a/src/common/ocv.c b/src/common/ocv.c index 6c35117a7..4bc2749a7 100644 --- a/src/common/ocv.c +++ b/src/common/ocv.c @@ -95,23 +95,24 @@ int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos) } -int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, - struct wpa_channel_info *ci, int tx_chanwidth, - int tx_seg1_idx) +enum oci_verify_result +ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, + struct wpa_channel_info *ci, int tx_chanwidth, + int tx_seg1_idx) { struct oci_info oci; if (!oci_ie) { os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "did not receive mandatory OCI"); - return -1; + return OCI_NOT_FOUND; } if (oci_ie_len != 3) { os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "received OCI of unexpected length (%d)", (int) oci_ie_len); - return -1; + return OCI_INVALID_LENGTH; } os_memset(&oci, 0, sizeof(oci)); @@ -121,7 +122,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, if (ocv_derive_all_parameters(&oci) != 0) { os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "unable to interpret received OCI"); - return -1; + return OCI_PARSE_ERROR; } /* Primary frequency used to send frames to STA must match the STA's */ @@ -129,7 +130,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "primary channel mismatch in received OCI (we use %d but receiver is using %d)", ci->frequency, oci.freq); - return -1; + return OCI_PRIMARY_FREQ_MISMATCH; } /* We shouldn't transmit with a higher bandwidth than the STA supports @@ -138,7 +139,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "channel bandwidth mismatch in received OCI (we use %d but receiver only supports %d)", tx_chanwidth, oci.chanwidth); - return -1; + return OCI_CHANNEL_WIDTH_MISMATCH; } /* @@ -152,7 +153,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "secondary channel mismatch in received OCI (we use %d but receiver is using %d)", ci->sec_channel, oci.sec_channel); - return -1; + return OCI_SECONDARY_FREQ_MISMATCH; } /* @@ -165,8 +166,8 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, os_snprintf(ocv_errorstr, sizeof(ocv_errorstr), "frequency segment 1 mismatch in received OCI (we use %d but receiver is using %d)", tx_seg1_idx, oci.seg1_idx); - return -1; + return OCI_SEG_1_INDEX_MISMATCH; } - return 0; + return OCI_SUCCESS; } diff --git a/src/common/ocv.h b/src/common/ocv.h index 6379d9d06..7fa4522c1 100644 --- a/src/common/ocv.h +++ b/src/common/ocv.h @@ -27,14 +27,21 @@ struct oci_info { #define OCV_OCI_EXTENDED_LEN (3 + OCV_OCI_LEN) #define OCV_OCI_KDE_LEN (2 + RSN_SELECTOR_LEN + OCV_OCI_LEN) +enum oci_verify_result { + OCI_SUCCESS, OCI_NOT_FOUND, OCI_INVALID_LENGTH, OCI_PARSE_ERROR, + OCI_PRIMARY_FREQ_MISMATCH, OCI_CHANNEL_WIDTH_MISMATCH, + OCI_SECONDARY_FREQ_MISMATCH, OCI_SEG_1_INDEX_MISMATCH +}; + extern char ocv_errorstr[256]; int ocv_derive_all_parameters(struct oci_info *oci); int ocv_insert_oci(struct wpa_channel_info *ci, u8 **argpos); int ocv_insert_oci_kde(struct wpa_channel_info *ci, u8 **argpos); int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos); -int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, - struct wpa_channel_info *ci, int tx_chanwidth, - int tx_seg1_idx); +enum oci_verify_result +ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len, + struct wpa_channel_info *ci, int tx_chanwidth, + int tx_seg1_idx); #endif /* OCV_H */ diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index b41e6e427..f3d324a67 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -1717,7 +1717,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm, if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=eapol-key-m3 error=%s", MAC2STR(sm->bssid), ocv_errorstr); @@ -1865,7 +1865,7 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm, if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=eapol-key-g1 error=%s", MAC2STR(sm->bssid), ocv_errorstr); @@ -4799,7 +4799,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=fils-assoc error=%s", MAC2STR(sm->bssid), ocv_errorstr); diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index bcaf42fe6..bf73376b6 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -1167,7 +1167,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=ft-assoc error=%s", MAC2STR(sm->bssid), ocv_errorstr); diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c index 3abbe09d0..4547eea88 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -1292,7 +1292,7 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s, if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, tx_chanwidth, tx_seg1_idx) != - 0) { + OCI_SUCCESS) { wpa_printf(MSG_WARNING, "MPM: OCV failed: %s", ocv_errorstr); return; diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 2faaff930..7fec1cd8d 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -2915,7 +2915,7 @@ void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(wpa_s, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=saquery%s error=%s", MAC2STR(sa), data[0] == WLAN_SA_QUERY_REQUEST ? diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index d0c9f0f45..19f1eca8a 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -383,7 +383,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci, channel_width_to_int(ci.chanwidth), - ci.seg1_idx) != 0) { + ci.seg1_idx) != OCI_SUCCESS) { wpa_msg(wpa_s, MSG_WARNING, "WNM: OCV failed: %s", ocv_errorstr); return;