3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-29 13:59:24 +01:00

handshake: use _hs directly in handshake_event

Fixes the following crash:
 #0  0x000211c4 in netdev_connect_event (msg=<optimized out>, netdev=0x2016940) at src/netdev.c:2915
 #1  0x76f11220 in process_multicast (nlmsg=0x7e8acafc, group=<optimized out>, genl=<optimized out>) at ell/genl.c:1029
 #2  received_data (io=<optimized out>, user_data=<optimized out>) at ell/genl.c:1096
 #3  0x76f0da08 in io_callback (fd=<optimized out>, events=1, user_data=0x200a560) at ell/io.c:120
 #4  0x76f0ca78 in l_main_iterate (timeout=<optimized out>) at ell/main.c:478
 #5  0x76f0cb74 in l_main_run () at ell/main.c:525
 #6  l_main_run () at ell/main.c:507
 #7  0x76f0cdd4 in l_main_run_with_signal (callback=callback@entry=0x18c94 <signal_handler>, user_data=user_data@entry=0x0)
   at ell/main.c:647
 #8  0x00018178 in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:532

This crash was introduced in commit:
4d2176df29 ("handshake: Allow event handler to free handshake")

The culprit seems to be that 'hs' is being used both in the caller and
in the macro.  Since the macro defines a variable 'hs' in local block
scope, it overrides 'hs' from function scope.  Yet (_hs) still evaluates
to 'hs' leading the local variable to be initialized with itself.  Only
the 'handshake_event(hs, HANDSHAKE_EVENT_SETTING_KEYS))' is affected
since it is the only macro invocation that uses 'hs' from function
scope.  Thus, the crash would only happen on hardware supporting handshake
offload (brcmfmac).

Fix this by removing the local scope variable declaration and evaluate
(_hs) instead.

Fixes: 4d2176df29 ("handshake: Allow event handler to free handshake")
This commit is contained in:
James Prestwood 2022-01-26 09:41:00 -08:00 committed by Denis Kenzior
parent b2d0bb08a0
commit d22b174a73

View File

@ -166,19 +166,18 @@ struct handshake_state {
#define handshake_event(_hs, event, ...) \
(__extension__ ({ \
struct handshake_state *hs = (_hs); \
bool freed = false; \
\
if (hs->event_func && !hs->in_event) { \
hs->in_event = true; \
hs->event_func(hs, event, hs->user_data, \
if ((_hs)->event_func && !(_hs)->in_event) { \
(_hs)->in_event = true; \
(_hs)->event_func((_hs), event, (_hs)->user_data, \
##__VA_ARGS__); \
\
if (!hs->in_event) { \
handshake_state_free(hs); \
if (!(_hs)->in_event) { \
handshake_state_free((_hs)); \
freed = true; \
} else \
hs->in_event = false; \
(_hs)->in_event = false; \
} \
freed; \
}))