3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-01-03 19:02:34 +01:00

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==
This commit is contained in:
Denis Kenzior 2018-05-18 10:27:42 -05:00
parent 56eeaf7b7a
commit 450ed03e21

View File

@ -181,8 +181,7 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id,
enum eap_type type; enum eap_type type;
uint8_t buf[10]; uint8_t buf[10];
int buf_len; int buf_len;
void (*op)(struct eap_state *eap, bool retransmit;
const uint8_t *pkt, size_t len);
if (len < 1) if (len < 1)
/* Invalid packets to be ignored */ /* Invalid packets to be ignored */
@ -196,15 +195,13 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id,
goto unsupported_method; goto unsupported_method;
} }
if (id == eap->last_id) retransmit = id == eap->last_id ? true : false;
op = eap->method->handle_retransmit ? :
eap->method->handle_request;
else
op = eap->method->handle_request;
eap->last_id = id; eap->last_id = id;
if (type >= __EAP_TYPE_MIN_METHOD) { 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) { if (type != eap->method->request_type) {
l_warn("EAP server tried method %i while client was " l_warn("EAP server tried method %i while client was "
"configured for method %i", "configured for method %i",
@ -213,6 +210,10 @@ void __eap_handle_request(struct eap_state *eap, uint16_t id,
goto unsupported_method; goto unsupported_method;
} }
op = retransmit && eap->method->handle_retransmit ?
eap->method->handle_retransmit :
eap->method->handle_request;
if (type != EAP_TYPE_EXPANDED) { if (type != EAP_TYPE_EXPANDED) {
op(eap, pkt + 1, len - 1); op(eap, pkt + 1, len - 1);
return; return;