From 450ed03e2157f4b289a43140109e4fe2f425725f Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Fri, 18 May 2018 10:27:42 -0500 Subject: [PATCH] eap: Fix crash Some EAP servers might try to send us packets after the EAP connection has been established. When EAP succeeds we destroy the EAP object. If a new EAP request arrives we create a temporary EAP object to handle the request (most likely to NAK it). However, if the packet is not destined to a particular method (e.g. it is a notification) the current logic can result in a crash. src/netdev.c:netdev_set_gtk() 3 ==4300== Invalid read of size 8 ==4300== at 0x14204B: __eap_handle_request (eap.c:203) ==4300== by 0x142339: eap_rx_packet (eap.c:287) ==4300== by 0x12AEF9: eapol_rx_packet (eapol.c:1622) ==4300== by 0x12BBBC: __eapol_rx_packet (eapol.c:2018) ==4300== by 0x116D1E: netdev_pae_read (netdev.c:3121) ==4300== by 0x16672B: io_callback (io.c:123) ==4300== by 0x165239: l_main_iterate (main.c:376) ==4300== by 0x16537D: l_main_run (main.c:423) ==4300== by 0x10F95C: main (main.c:447) ==4300== Address 0x30 is not stack'd, malloc'd or (recently) free'd ==4300== --- src/eap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/eap.c b/src/eap.c index 6eeb201b..a26b0fdc 100644 --- a/src/eap.c +++ b/src/eap.c @@ -181,8 +181,7 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id, enum eap_type type; uint8_t buf[10]; int buf_len; - void (*op)(struct eap_state *eap, - const uint8_t *pkt, size_t len); + bool retransmit; if (len < 1) /* Invalid packets to be ignored */ @@ -196,15 +195,13 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id, goto unsupported_method; } - if (id == eap->last_id) - op = eap->method->handle_retransmit ? : - eap->method->handle_request; - else - op = eap->method->handle_request; - + retransmit = id == eap->last_id ? true : false; eap->last_id = id; if (type >= __EAP_TYPE_MIN_METHOD) { + void (*op)(struct eap_state *eap, + const uint8_t *pkt, size_t len); + if (type != eap->method->request_type) { l_warn("EAP server tried method %i while client was " "configured for method %i", @@ -213,6 +210,10 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id, goto unsupported_method; } + op = retransmit && eap->method->handle_retransmit ? + eap->method->handle_retransmit : + eap->method->handle_request; + if (type != EAP_TYPE_EXPANDED) { op(eap, pkt + 1, len - 1); return;