The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3a427b8320840f1e69779efeccc5898eb2972030

commit 3a427b8320840f1e69779efeccc5898eb2972030
Author:     Bjoern A. Zeeb <b...@freebsd.org>
AuthorDate: 2025-06-08 18:05:54 +0000
Commit:     Bjoern A. Zeeb <b...@freebsd.org>
CommitDate: 2025-06-08 18:19:36 +0000

    rtw89: prevent a NULL pointer deref in rtw89_swap_chanctx()
    
    It is currently unclear if this is a result of the driver itself already
    or the way LinuxKPI drives channels and the driver simply accepting and
    acting on things it no longer should.
    For now put the bandaid into place to make the driver work and pass
    packets.  For better resilience the check does not hurt anyway.
    
    The moment we enter rtw89_chanctx_ops_add() the first time,
    entity_map 0x00000001 has the lowest bit set and find_next_zero_bit()
    will return 1. As a result the driver will try to swap chanctxs and
    trip over a NULL pointer in rtw89_swap_chanctx().  See comment there
    for how to (likely) trigger it.
    
    Sponsored by:   The FreeBSD Foundation
    Reported by:    Axel Rau (Axel.Rau Chaos1.DE) with 8852CE
    MFC after:      3 days
---
 sys/contrib/dev/rtw89/chan.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/sys/contrib/dev/rtw89/chan.c b/sys/contrib/dev/rtw89/chan.c
index 4df4e04c3e67..257331c2de2e 100644
--- a/sys/contrib/dev/rtw89/chan.c
+++ b/sys/contrib/dev/rtw89/chan.c
@@ -2612,6 +2612,27 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
        if (idx1 == idx2)
                return;
 
+#if defined(__FreeBSD__)
+       /*
+        * __rtw89_config_entity_chandef() might set RTW89_CHANCTX_0 but no
+        * cfg assigned.
+        * A mac80211 (*config)() with IEEE80211_CONF_CHANGE_CHANNEL could do
+        * that if rtw89_config_default_chandef() from rtw89_entity_init() does
+        * not already.
+        * A mac80211: (*assign_vif_chanctx)() following will find idx 0 filled
+        * and rtw89_chanctx_ops_add() will call here.  Trying to swap results
+        * in a NULL pointer deref as hal->chanctx[idx1].cfg is NULL.
+        * Catch this for now until fully understood or a proper solution is
+        * found.
+        */
+       if (hal->chanctx[idx1].cfg == NULL || hal->chanctx[idx2].cfg == NULL) {
+               rtw89_debug(rtwdev, RTW89_DBG_CHAN,
+                   "%s: !swapping idx1 %d cfg %p, idx2 %d cfg %p\n", __func__,
+                   idx1, hal->chanctx[idx1].cfg, idx2, hal->chanctx[idx2].cfg);
+               return;
+       }
+#endif
+
        hal->chanctx[idx1].cfg->idx = idx2;
        hal->chanctx[idx2].cfg->idx = idx1;
 

Reply via email to