From f67e5ea6d8d900389e4e320ab8e0dfcb33f35406 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Mon, 12 Jul 2021 18:32:02 -0500 Subject: [PATCH] netdev: Centralize mmpdu validation Instead of requiring each auth_proto to perform validation of the frames received via rx_authenticate & rx_associate, have netdev itself perform the mpdu validation. This is unlikely to happen anyway since the kernel performs its own frame validation. Print a warning in case the validation fails. --- src/fils.c | 22 ++++------------------ src/netdev.c | 22 ++++++++++++++++++++-- src/owe.c | 12 ++---------- src/sae.c | 22 ++++------------------ 4 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/fils.c b/src/fils.c index 047ce66c..f12e8a28 100644 --- a/src/fils.c +++ b/src/fils.c @@ -338,8 +338,8 @@ static int fils_rx_authenticate(struct auth_proto *driver, const uint8_t *frame, size_t len) { struct fils_sm *fils = l_container_of(driver, struct fils_sm, ap); - const struct mmpdu_header *hdr = mpdu_validate(frame, len); - const struct mmpdu_authentication *auth; + const struct mmpdu_header *hdr = (const struct mmpdu_header *) frame; + const struct mmpdu_authentication *auth = mmpdu_body(hdr); uint16_t alg; struct ie_tlv_iter iter; const uint8_t *anonce = NULL; @@ -350,13 +350,6 @@ static int fils_rx_authenticate(struct auth_proto *driver, const uint8_t *frame, const uint8_t *mde = NULL; const uint8_t *fte = NULL; - if (!hdr) { - l_debug("Auth frame header did not validate"); - return -EBADMSG; - } - - auth = mmpdu_body(hdr); - if (auth->status != 0) { l_debug("invalid status %u", auth->status); return L_LE16_TO_CPU(auth->status); @@ -453,8 +446,8 @@ static int fils_rx_associate(struct auth_proto *driver, const uint8_t *frame, size_t len) { struct fils_sm *fils = l_container_of(driver, struct fils_sm, ap); - const struct mmpdu_header *hdr = mpdu_validate(frame, len); - const struct mmpdu_association_response *assoc; + const struct mmpdu_header *hdr = (const struct mmpdu_header *) frame; + const struct mmpdu_association_response *assoc = mmpdu_body(hdr); struct ie_tlv_iter iter; uint8_t key_rsc[8]; const uint8_t *gtk = NULL; @@ -470,13 +463,6 @@ static int fils_rx_associate(struct auth_proto *driver, const uint8_t *frame, uint8_t data[44]; uint8_t *ptr = data; - if (!hdr) { - l_debug("Assoc frame header did not validate"); - return -EBADMSG; - } - - assoc = mmpdu_body(hdr); - if (assoc->status_code != 0) return L_CPU_TO_LE16(assoc->status_code); diff --git a/src/netdev.c b/src/netdev.c index 1e8e39eb..9e5ed1da 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -2400,10 +2400,19 @@ static void netdev_authenticate_event(struct l_genl_msg *msg, } } - if (!frame) + if (L_WARN_ON(!frame)) goto auth_error; if (netdev->ap) { + const struct mmpdu_header *hdr; + const struct mmpdu_authentication *auth; + + if (L_WARN_ON(!(hdr = mpdu_validate(frame, frame_len)))) + goto auth_error; + + auth = mmpdu_body(hdr); + status_code = L_CPU_TO_LE16(auth->status); + ret = auth_proto_rx_authenticate(netdev->ap, frame, frame_len); if (ret == 0 || ret == -EAGAIN) return; @@ -2468,10 +2477,19 @@ static void netdev_associate_event(struct l_genl_msg *msg, } } - if (!frame) + if (L_WARN_ON(!frame)) goto assoc_failed; if (netdev->ap) { + const struct mmpdu_header *hdr; + const struct mmpdu_association_response *assoc; + + if (L_WARN_ON(!(hdr = mpdu_validate(frame, frame_len)))) + goto assoc_failed; + + assoc = mmpdu_body(hdr); + status_code = L_CPU_TO_LE16(assoc->status_code); + ret = auth_proto_rx_associate(netdev->ap, frame, frame_len); if (ret == 0) { bool fils = !!(netdev->handshake->akm_suite & diff --git a/src/owe.c b/src/owe.c index 3f95ff8a..b1eea025 100644 --- a/src/owe.c +++ b/src/owe.c @@ -240,8 +240,8 @@ static int owe_rx_associate(struct auth_proto *ap, const uint8_t *frame, { struct owe_sm *owe = l_container_of(ap, struct owe_sm, ap); - const struct mmpdu_header *mpdu = NULL; - const struct mmpdu_association_response *body; + const struct mmpdu_header *mpdu = (const struct mmpdu_header *) frame; + const struct mmpdu_association_response *body = mmpdu_body(mpdu); struct ie_tlv_iter iter; size_t owe_dh_len = 0; const uint8_t *owe_dh = NULL; @@ -249,14 +249,6 @@ static int owe_rx_associate(struct auth_proto *ap, const uint8_t *frame, bool akm_found = false; const void *data; - mpdu = mpdu_validate(frame, len); - if (!mpdu) { - l_error("could not process frame"); - return -EBADMSG; - } - - body = mmpdu_body(mpdu); - if (L_LE16_TO_CPU(body->status_code) == MMPDU_STATUS_CODE_UNSUPP_FINITE_CYCLIC_GROUP) { if (!owe_retry(owe)) diff --git a/src/sae.c b/src/sae.c index b61dfe31..413ebb27 100644 --- a/src/sae.c +++ b/src/sae.c @@ -1230,16 +1230,10 @@ static int sae_rx_authenticate(struct auth_proto *ap, const uint8_t *frame, size_t len) { struct sae_sm *sm = l_container_of(ap, struct sae_sm, ap); - const struct mmpdu_header *hdr = mpdu_validate(frame, len); - const struct mmpdu_authentication *auth; + const struct mmpdu_header *hdr = (const struct mmpdu_header *) frame; + const struct mmpdu_authentication *auth = mmpdu_body(hdr); int ret; - if (!hdr) { - l_debug("Auth frame header did not validate"); - return -EBADMSG; - } - - auth = mmpdu_body(hdr); len -= mmpdu_header_len(hdr); ret = sae_verify_packet(sm, L_LE16_TO_CPU(auth->transaction_sequence), @@ -1267,16 +1261,8 @@ static int sae_rx_authenticate(struct auth_proto *ap, static int sae_rx_associate(struct auth_proto *ap, const uint8_t *frame, size_t len) { - const struct mmpdu_header *mpdu = NULL; - const struct mmpdu_association_response *body; - - mpdu = mpdu_validate(frame, len); - if (!mpdu) { - l_error("could not process frame"); - return -EBADMSG; - } - - body = mmpdu_body(mpdu); + const struct mmpdu_header *mpdu = (const struct mmpdu_header *)frame; + const struct mmpdu_association_response *body = mmpdu_body(mpdu); if (body->status_code != 0) return -EPROTO;