git: 33e8fc370c18 - main - net80211: don't dereference a NULL HTINFO IE if it's presented

From: Adrian Chadd <adrian_at_FreeBSD.org>
Date: Wed, 16 Jul 2025 15:21:51 UTC
The branch main has been updated by adrian:

URL: https://cgit.FreeBSD.org/src/commit/?id=33e8fc370c186c693c32f909305520de7c75853a

commit 33e8fc370c186c693c32f909305520de7c75853a
Author:     Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2025-06-11 18:10:03 +0000
Commit:     Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2025-07-16 15:12:11 +0000

    net80211: don't dereference a NULL HTINFO IE if it's presented
    
    ieee80211_vht_get_vhtflags() is checking the htinfo IE for the
    20/40MHz flag as part of deciding valid channel widths.
    
    However, in the hostapd path, the ASSOC_REQ/REASSOC_REQ path
    will parse the IEs, do some HT/VHT setup, then call
    ieee80211_ht_updatehtcap_final().  In a HT ASSOC/REASSOC request
    there won't be a HTINFO IE, however ieee80211_vht_get_vhtflags()
    still checks for it, leading to a panic.
    
    Instead, treat it as if we don't yet know if it's HT40 or not.
    I'm not sure if we should do that or have it just do
    _RETURN_CHAN_BITS(0).
    
    Differential Revision:  https://reviews.freebsd.org/D50794
---
 sys/net80211/ieee80211_ht.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 5ec80e3646b8..c28f124648a1 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -1951,6 +1951,11 @@ do {									\
 	    (vap->iv_vht_flags & IEEE80211_FVHT_VHT) == 0)
 		_RETURN_CHAN_BITS(0);
 
+	/*
+	 * TODO: should we bail out if there's no htinfo?
+	 * Or just treat it as if we can't do the HT20/HT40 check?
+	 */
+
 	/*
 	 * The original code was based on
 	 * 802.11ac-2013, Table 8-183x-VHT Operation Information subfields.
@@ -1962,8 +1967,12 @@ do {									\
 	 */
 
 	htinfo = (const struct ieee80211_ie_htinfo *)ni->ni_ies.htinfo_ie;
-	ht40 = ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH) ==
-	    IEEE80211_HTINFO_TXWIDTH_2040);
+	if (htinfo != NULL)
+		ht40 = ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH) ==
+		    IEEE80211_HTINFO_TXWIDTH_2040);
+	else
+		ht40 = false;
+
 	can_vht160 = can_vht80p80 = can_vht80 = false;
 
 	/* 20 Mhz */