Make iwm(4) not crash when aircrack-ng attempts to inject frames via
authorstsp <stsp@openbsd.org>
Sat, 2 Sep 2023 08:57:46 +0000 (08:57 +0000)
committerstsp <stsp@openbsd.org>
Sat, 2 Sep 2023 08:57:46 +0000 (08:57 +0000)
bpf in monitor mode.

Crash reported by brad and sthen.
I reproduced the issue to verify my fix but I did not check whether
aircrack-ng actually works with this.

sys/dev/pci/if_iwm.c

index 5f8042d..06a8a64 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwm.c,v 1.408 2023/07/05 15:07:28 stsp Exp $       */
+/*     $OpenBSD: if_iwm.c,v 1.409 2023/09/02 08:57:46 stsp Exp $       */
 
 /*
  * Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -6746,7 +6746,12 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
         * client mode; the firmware's station table contains only one entry
         * which represents our access point.
         */
-       if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+       if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+               if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
+                       qid = IWM_DQA_INJECT_MONITOR_QUEUE;
+               else
+                       qid = IWM_AUX_QUEUE;
+       } else if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_DQA_SUPPORT))
                qid = IWM_DQA_MIN_MGMT_QUEUE + ac;
        else
                qid = ac;
@@ -6818,7 +6823,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
 #endif
        totlen = m->m_pkthdr.len;
 
-       if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+       if (ic->ic_opmode != IEEE80211_M_MONITOR &&
+           (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
                k = ieee80211_get_txkey(ic, wh, ni);
                if ((k->k_flags & IEEE80211_KEY_GROUP) ||
                    (k->k_cipher != IEEE80211_CIPHER_CCMP)) {
@@ -6845,7 +6851,10 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
            (ic->ic_flags & IEEE80211_F_USEPROT)))
                flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;
 
-       tx->sta_id = IWM_STATION_ID;
+       if (ic->ic_opmode == IEEE80211_M_MONITOR)
+               tx->sta_id = IWM_MONITOR_STA_ID;
+       else
+               tx->sta_id = IWM_STATION_ID;
 
        if (type == IEEE80211_FC0_TYPE_MGT) {
                if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||