diff mbox series

netdev: fix crash in the RSSI polling fallback workaround

Message ID 20241003125817.75004-1-prestwoj@gmail.com (mailing list archive)
State Accepted, archived
Headers show
Series netdev: fix crash in the RSSI polling fallback workaround | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-alpine-ci-fetch success Fetch PR
prestwoj/iwd-ci-gitlint fail netdev: fix crash in the RSSI polling fallback workaround 16: B1 Line exceeds max length (87>80): "iwd: #2 0x49f82d in l_netlink_message_append() at ome/jprestwood/iwd/ell/netlink.c:825" 17: B1 Line exceeds max length (83>80): "iwd: #3 0x4a0c12 in l_genl_msg_append_attr() at ome/jprestwood/iwd/ell/genl.c:1522" 20: B1 Line exceeds max length (92>80): "iwd: #6 0x49c2ed in l_main_iterate() at ome/jprestwood/iwd/ell/main.c:455 (discriminator 2)" 22: B1 Line exceeds max length (82>80): "iwd: #8 0x49c5f0 in l_main_run_with_signal() at ome/jprestwood/iwd/ell/main.c:632"
prestwoj/iwd-alpine-ci-setupell success Prep - Setup ELL
prestwoj/iwd-ci-fetch success Fetch PR
prestwoj/iwd-ci-setupell success Prep - Setup ELL
prestwoj/iwd-ci-incremental_build success Incremental build not run PASS
prestwoj/iwd-ci-build success Build - Configure
prestwoj/iwd-alpine-ci-makedistcheck success Make Distcheck
prestwoj/iwd-alpine-ci-incremental_build success Incremental build not run PASS
prestwoj/iwd-alpine-ci-build success Build - Configure
prestwoj/iwd-alpine-ci-makecheckvalgrind success Make Check w/Valgrind
prestwoj/iwd-alpine-ci-makecheck success Make Check
prestwoj/iwd-ci-makecheckvalgrind success Make Check w/Valgrind
prestwoj/iwd-ci-clang success clang PASS
prestwoj/iwd-ci-makecheck success Make Check
prestwoj/iwd-ci-makedistcheck success Make Distcheck
prestwoj/iwd-ci-testrunner success test-runner PASS

Commit Message

James Prestwood Oct. 3, 2024, 12:58 p.m. UTC
Prior to adding the polling fallback this code path was only used for
signal level list notifications and netdev_rssi_polling_update() was
structured as such, where if the RSSI list feature existed there was
nothing to be done as the kernel handled the notifications.

For certain mediatek cards this is broken, hence why the fallback was
added. But netdev_rssi_polling_update() was never changed to take
this into account which bypassed the timer cleanup on disconnections
resulting in a crash when the timer fired after IWD was disconnected:

iwd: ++++++++ backtrace ++++++++
iwd: #0  0x7b5459642520 in /lib/x86_64-linux-gnu/libc.so.6
iwd: #1  0x7b54597aedf4 in /lib/x86_64-linux-gnu/libc.so.6
iwd: #2  0x49f82d in l_netlink_message_append() at ome/jprestwood/iwd/ell/netlink.c:825
iwd: #3  0x4a0c12 in l_genl_msg_append_attr() at ome/jprestwood/iwd/ell/genl.c:1522
iwd: #4  0x405c61 in netdev_rssi_poll() at ome/jprestwood/iwd/src/netdev.c:764
iwd: #5  0x49cce4 in timeout_callback() at ome/jprestwood/iwd/ell/timeout.c:70
iwd: #6  0x49c2ed in l_main_iterate() at ome/jprestwood/iwd/ell/main.c:455 (discriminator 2)
iwd: #7  0x49c3bc in l_main_run() at ome/jprestwood/iwd/ell/main.c:504
iwd: #8  0x49c5f0 in l_main_run_with_signal() at ome/jprestwood/iwd/ell/main.c:632
iwd: #9  0x4049ed in main() at ome/jprestwood/iwd/src/main.c:614
iwd: #10 0x7b5459629d90 in /lib/x86_64-linux-gnu/libc.so.6
iwd: #11 0x7b5459629e40 in /lib/x86_64-linux-gnu/libc.so.6
iwd: +++++++++++++++++++++++++++

To fix this we need to add checks for the cqm_poll_fallback flag in
netdev_rssi_polling_update().
---
 src/netdev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Denis Kenzior Oct. 4, 2024, 2:33 a.m. UTC | #1
Hi James,

On 10/3/24 7:58 AM, James Prestwood wrote:
> Prior to adding the polling fallback this code path was only used for
> signal level list notifications and netdev_rssi_polling_update() was
> structured as such, where if the RSSI list feature existed there was
> nothing to be done as the kernel handled the notifications.
> 
> For certain mediatek cards this is broken, hence why the fallback was
> added. But netdev_rssi_polling_update() was never changed to take
> this into account which bypassed the timer cleanup on disconnections
> resulting in a crash when the timer fired after IWD was disconnected:
> 
> iwd: ++++++++ backtrace ++++++++
> iwd: #0  0x7b5459642520 in /lib/x86_64-linux-gnu/libc.so.6
> iwd: #1  0x7b54597aedf4 in /lib/x86_64-linux-gnu/libc.so.6
> iwd: #2  0x49f82d in l_netlink_message_append() at ome/jprestwood/iwd/ell/netlink.c:825
> iwd: #3  0x4a0c12 in l_genl_msg_append_attr() at ome/jprestwood/iwd/ell/genl.c:1522
> iwd: #4  0x405c61 in netdev_rssi_poll() at ome/jprestwood/iwd/src/netdev.c:764
> iwd: #5  0x49cce4 in timeout_callback() at ome/jprestwood/iwd/ell/timeout.c:70
> iwd: #6  0x49c2ed in l_main_iterate() at ome/jprestwood/iwd/ell/main.c:455 (discriminator 2)
> iwd: #7  0x49c3bc in l_main_run() at ome/jprestwood/iwd/ell/main.c:504
> iwd: #8  0x49c5f0 in l_main_run_with_signal() at ome/jprestwood/iwd/ell/main.c:632
> iwd: #9  0x4049ed in main() at ome/jprestwood/iwd/src/main.c:614
> iwd: #10 0x7b5459629d90 in /lib/x86_64-linux-gnu/libc.so.6
> iwd: #11 0x7b5459629e40 in /lib/x86_64-linux-gnu/libc.so.6
> iwd: +++++++++++++++++++++++++++
> 
> To fix this we need to add checks for the cqm_poll_fallback flag in
> netdev_rssi_polling_update().
> ---
>   src/netdev.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 

Applied, thanks.

Regards,
-Denis
diff mbox series

Patch

diff --git a/src/netdev.c b/src/netdev.c
index d298977a..8379a598 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -769,11 +769,12 @@  static void netdev_rssi_poll(struct l_timeout *timeout, void *user_data)
 /* To be called whenever operational or rssi_levels_num are updated */
 static void netdev_rssi_polling_update(struct netdev *netdev)
 {
-	if (wiphy_has_ext_feature(netdev->wiphy,
+	if (!netdev->cqm_poll_fallback && wiphy_has_ext_feature(netdev->wiphy,
 					NL80211_EXT_FEATURE_CQM_RSSI_LIST))
 		return;
 
-	if (netdev->operational && netdev->rssi_levels_num > 0) {
+	if (netdev->operational && (netdev->rssi_levels_num > 0 ||
+					netdev->cqm_poll_fallback)) {
 		if (netdev->rssi_poll_timeout)
 			return;