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.
This commit is contained in:
Denis Kenzior 2021-07-12 18:32:02 -05:00
parent cb5939f941
commit f67e5ea6d8
4 changed files with 30 additions and 48 deletions

View File

@ -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);

View File

@ -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 &

View File

@ -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))

View File

@ -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;