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;