From 3284ed4e8ee29d66ba4f90cba5d3508f1ca244f9 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 7 Apr 2021 16:47:40 -0500 Subject: [PATCH] eapol: Work around an apparent GCC 8.3 bug With GCC 8.3 on Rasberry Pi, iwd sends invalid EAPoL 1_of_4 packets: < PAE: len 99 8.785095 Interface Index: 27 EAPoL: len 99 Protocol Version: 2 (802.1X-2004) Type: 3 (Key) Length: 95 Checking mic len 16 Frame len 99 key data len 22 Checking mic len 24 Frame len 107 Bad MIC len, malformed packet? 02 03 00 5f 02 00 8a 00 10 00 00 00 00 00 00 00 ..._............ 02 94 40 a3 da c3 2b aa b7 a6 a5 5f 25 0a ae 74 ..@...+...._%..t b0 8d e2 62 9c 90 c9 e9 fd a5 33 1b e1 b4 9b 81 ...b......3..... 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B............... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 16 The trouble seems to be that eapol_key_data_append() correctly sets the key_data_length field (the last 2 bytes of the message), but the actual packet_length is not being set properly. Dropping to O0 optimization level results in GCC correctly computing the packet length. --- src/eapol.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/eapol.c b/src/eapol.c index 23aaf530..73b2aa61 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -1025,6 +1025,17 @@ static void eapol_set_key_timeout(struct eapol_sm *sm, } } +/* + * GCC version 8.3 seems to have trouble correctly calculating + * ek->header.packet_len when optimization is enabled. This results in iwd + * sending invalid 1_of_4 packets (with the KDE payload missing). Work + * around this by dropping to O0 for this function when old GCC versions + * are used + */ +#if __GNUC__ < 9 +#pragma GCC optimize ("O0") +#endif + /* 802.11-2016 Section 12.7.6.2 */ static void eapol_send_ptk_1_of_4(struct eapol_sm *sm) { @@ -1068,6 +1079,10 @@ static void eapol_send_ptk_1_of_4(struct eapol_sm *sm) eapol_sm_write(sm, (struct eapol_frame *) ek, false); } +#if __GNUC__ < 9 +#pragma GCC reset_options +#endif + static void eapol_ptk_1_of_4_retry(struct l_timeout *timeout, void *user_data) { struct eapol_sm *sm = user_data;