iwm(4): fix ccmp decrypt edge cases

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

iwm(4): fix ccmp decrypt edge cases

Stefan Sperling-5
This should hopefully prevent a crash reported to me by Jesper Wallin,
where net80211 crashes when it attempts to decrypt a CCMP-encrypted
frame which iwm passed up without decrypting it first.

By code inspection I have determined that this problem could happen
in case a CCMP frame is received peer before the WPA handshake has
completed (e.g. during re-association). Note how the hardware decryption
code path depends on IEEE80211_NODE_RXPROT being set, which is set only
once the handshake has been completed.
We have to be careful here to avoid breaking non-CCMP ciphers (WEP, TKIP).

It also attempts to close a small race where we're handing the key to
firmware and eventually get an interrupt which confirms key installation,
in parallel to sending/receiving unicast data frames.
Until the key has been confirmed by firmware, don't transmit data frames
and drop received encrypted frames.
This part of the diff has poor error handling; if firmware never confirms
they key then iwm will get stuck and the user will have to recover.
But that should be better than the current situation where we'd be
sending unencrypted frames or perhaps crash in net80211.

These fixes could be separated but a combined diff is easier to test.

Once we've got this working for iwm(4), the iwn(4) driver will need
a similar fix.

diff refs/heads/master refs/heads/ccmp-crash
blob - 038e6a63dfff113b525bb1e9a30c935996535569
blob + 0571a3a042c0097002241e2accc026c55af205ed
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -3601,6 +3601,13 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
     !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
     (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
     ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
+ if ((sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
+ /* Firmware has not installed the key yet. */
+ ic->ic_stats.is_ccmp_dec_errs++;
+ ifp->if_ierrors++;
+ m_freem(m);
+ goto done;
+ }
  if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
     IWM_RX_MPDU_RES_STATUS_SEC_CCM_ENC) {
  ic->ic_stats.is_ccmp_dec_errs++;
@@ -3625,6 +3632,22 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
  goto done;
  }
  rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
+ } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
+    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+    (ic->ic_flags & IEEE80211_F_RSNON) &&
+    (ic->ic_rsnprotos & IEEE80211_PROTO_RSN) &&
+    (ic->ic_rsnciphers & IEEE80211_CIPHER_CCMP) &&
+    (ni->ni_rsnciphers & IEEE80211_CIPHER_CCMP) &&
+    (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0) {
+ /*
+ * We're doing CCMP and have received an encrypted unicast
+ * frame before 4-way handshake has completed. Don't pass it
+ * up the stack; net80211 would crash trying to decrypt it.
+ */
+ ic->ic_stats.is_ccmp_dec_errs++;
+ ifp->if_ierrors++;
+ m_freem(m);
+ goto done;
  }
 
 #if NBPFILTER > 0
@@ -6090,6 +6113,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
 {
  struct iwm_softc *sc = ic->ic_softc;
  struct iwm_add_sta_key_cmd cmd = { 0 };
+ int err;
 
  if ((k->k_flags & IEEE80211_KEY_GROUP) ||
     k->k_cipher != IEEE80211_CIPHER_CCMP)  {
@@ -6097,6 +6121,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
  return (ieee80211_set_key(ic, ni, k));
  }
 
+ sc->sc_flags &= ~IWM_FLAG_CCMP_READY;
+
  cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
     IWM_STA_KEY_FLG_WEP_KEY_MAP |
     ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
@@ -6108,8 +6134,11 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
  cmd.key_offset = 0;
  cmd.sta_id = IWM_STATION_ID;
 
- return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
+ err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
     sizeof(cmd), &cmd);
+ if (!err)
+ sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
+ return err;
 }
 
 void
@@ -6135,6 +6164,7 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee802
  cmd.sta_id = IWM_STATION_ID;
 
  iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
+ sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
 }
 
 void
@@ -6765,6 +6795,14 @@ iwm_start(struct ifnet *ifp)
     (ic->ic_xflags & IEEE80211_F_TX_MGMT_ONLY))
  break;
 
+ if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
+ /*
+ * Can't send data frames before firmware is
+ * ready to encrypt them.
+ */
+ break;
+ }
+
  IFQ_DEQUEUE(&ifp->if_snd, m);
  if (!m)
  break;
@@ -6846,6 +6884,7 @@ iwm_stop(struct ifnet *ifp)
  sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
  sc->sc_flags &= ~IWM_FLAG_HW_ERR;
  sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
+ sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
 
  sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
 
@@ -7331,6 +7370,12 @@ iwm_notif_intr(struct iwm_softc *sc)
  break;
 
  case IWM_ADD_STA_KEY:
+ if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
+ sc->sc_flags |= IWM_FLAG_CCMP_READY;
+ sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
+ }
+ break;
+
  case IWM_PHY_CONFIGURATION_CMD:
  case IWM_TX_ANT_CONFIGURATION_CMD:
  case IWM_ADD_STA:
blob - e6593fbc840833a36d5a792042faaa85e3ac9719
blob + 747616074f868d8679f9f01232dec4ce09474f93
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -289,6 +289,8 @@ struct iwm_rx_ring {
 #define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
 #define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
 #define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
+#define IWM_FLAG_CCMP_KEY_SENT 0x400 /* CCMP key sent to firmware */
+#define IWM_FLAG_CCMP_READY 0x800 /* CCMP key installed in firmware */
 
 struct iwm_ucode_status {
  uint32_t uc_error_event_table;

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Martin Pieuchot
On 13/08/19(Tue) 13:52, Stefan Sperling wrote:
> This should hopefully prevent a crash reported to me by Jesper Wallin,
> where net80211 crashes when it attempts to decrypt a CCMP-encrypted
> frame which iwm passed up without decrypting it first.

How does the stack crashes?  Shouldn't we drop this packet in the stack
as well?

> By code inspection I have determined that this problem could happen
> in case a CCMP frame is received peer before the WPA handshake has
> completed (e.g. during re-association). Note how the hardware decryption
> code path depends on IEEE80211_NODE_RXPROT being set, which is set only
> once the handshake has been completed.
> We have to be careful here to avoid breaking non-CCMP ciphers (WEP, TKIP).

So it's like working around the firwmare by defining two new state
related to the CCMP key and dropping packets that should not reach
us at this point?

> It also attempts to close a small race where we're handing the key to
> firmware and eventually get an interrupt which confirms key installation,
> in parallel to sending/receiving unicast data frames.
> Until the key has been confirmed by firmware, don't transmit data frames
> and drop received encrypted frames.

Makes sense.

The actual solution also has a race if you change the key before
acknowledging the firmware IWM_ADD_STA_KEY, but I suppose this is
acceptable.

> This part of the diff has poor error handling; if firmware never confirms
> they key then iwm will get stuck and the user will have to recover.

Well up/down should work, right?

> But that should be better than the current situation where we'd be
> sending unencrypted frames or perhaps crash in net80211.
>
> These fixes could be separated but a combined diff is easier to test.

What should we test?

> Once we've got this working for iwm(4), the iwn(4) driver will need
> a similar fix.
>
> diff refs/heads/master refs/heads/ccmp-crash
> blob - 038e6a63dfff113b525bb1e9a30c935996535569
> blob + 0571a3a042c0097002241e2accc026c55af205ed
> --- sys/dev/pci/if_iwm.c
> +++ sys/dev/pci/if_iwm.c
> @@ -3601,6 +3601,13 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
>      !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
>      (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
>      ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
> + if ((sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
> + /* Firmware has not installed the key yet. */
> + ic->ic_stats.is_ccmp_dec_errs++;
> + ifp->if_ierrors++;
> + m_freem(m);
> + goto done;
> + }
>   if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
>      IWM_RX_MPDU_RES_STATUS_SEC_CCM_ENC) {
>   ic->ic_stats.is_ccmp_dec_errs++;
> @@ -3625,6 +3632,22 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
>   goto done;
>   }
>   rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
> + } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
> +    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&

Bikesheding: these 5 hardware decryption checks are executed for
non-multicast and if the FC1_PROTECTED bit is set right?  Should
that be a single if statement?

> +    (ic->ic_flags & IEEE80211_F_RSNON) &&
> +    (ic->ic_rsnprotos & IEEE80211_PROTO_RSN) &&
> +    (ic->ic_rsnciphers & IEEE80211_CIPHER_CCMP) &&
> +    (ni->ni_rsnciphers & IEEE80211_CIPHER_CCMP) &&
> +    (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0) {
> + /*
> + * We're doing CCMP and have received an encrypted unicast
> + * frame before 4-way handshake has completed. Don't pass it
> + * up the stack; net80211 would crash trying to decrypt it.
> + */
> + ic->ic_stats.is_ccmp_dec_errs++;
> + ifp->if_ierrors++;
> + m_freem(m);
> + goto done;
>   }
>  
>  #if NBPFILTER > 0
> @@ -6090,6 +6113,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>  {
>   struct iwm_softc *sc = ic->ic_softc;
>   struct iwm_add_sta_key_cmd cmd = { 0 };
> + int err;
>  
>   if ((k->k_flags & IEEE80211_KEY_GROUP) ||
>      k->k_cipher != IEEE80211_CIPHER_CCMP)  {
> @@ -6097,6 +6121,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>   return (ieee80211_set_key(ic, ni, k));
>   }
>  
> + sc->sc_flags &= ~IWM_FLAG_CCMP_READY;
> +
>   cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
>      IWM_STA_KEY_FLG_WEP_KEY_MAP |
>      ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
> @@ -6108,8 +6134,11 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>   cmd.key_offset = 0;
>   cmd.sta_id = IWM_STATION_ID;
>  
> - return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> + err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
>      sizeof(cmd), &cmd);
> + if (!err)
> + sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
> + return err;
>  }
>  
>  void
> @@ -6135,6 +6164,7 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee802
>   cmd.sta_id = IWM_STATION_ID;
>  
>   iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
> + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
>  }
>  
>  void
> @@ -6765,6 +6795,14 @@ iwm_start(struct ifnet *ifp)
>      (ic->ic_xflags & IEEE80211_F_TX_MGMT_ONLY))
>   break;
>  
> + if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
> + /*
> + * Can't send data frames before firmware is
> + * ready to encrypt them.
> + */
> + break;
> + }
> +
>   IFQ_DEQUEUE(&ifp->if_snd, m);
>   if (!m)
>   break;
> @@ -6846,6 +6884,7 @@ iwm_stop(struct ifnet *ifp)
>   sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
>   sc->sc_flags &= ~IWM_FLAG_HW_ERR;
>   sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
> + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
>  
>   sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
>  
> @@ -7331,6 +7370,12 @@ iwm_notif_intr(struct iwm_softc *sc)
>   break;
>  
>   case IWM_ADD_STA_KEY:
> + if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
> + sc->sc_flags |= IWM_FLAG_CCMP_READY;
> + sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
> + }
> + break;
> +
>   case IWM_PHY_CONFIGURATION_CMD:
>   case IWM_TX_ANT_CONFIGURATION_CMD:
>   case IWM_ADD_STA:
> blob - e6593fbc840833a36d5a792042faaa85e3ac9719
> blob + 747616074f868d8679f9f01232dec4ce09474f93
> --- sys/dev/pci/if_iwmvar.h
> +++ sys/dev/pci/if_iwmvar.h
> @@ -289,6 +289,8 @@ struct iwm_rx_ring {
>  #define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
>  #define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
>  #define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
> +#define IWM_FLAG_CCMP_KEY_SENT 0x400 /* CCMP key sent to firmware */
> +#define IWM_FLAG_CCMP_READY 0x800 /* CCMP key installed in firmware */
>  
>  struct iwm_ucode_status {
>   uint32_t uc_error_event_table;
>

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Stefan Sperling-5
On Tue, Aug 13, 2019 at 09:40:22AM -0300, Martin Pieuchot wrote:
> On 13/08/19(Tue) 13:52, Stefan Sperling wrote:
> > This should hopefully prevent a crash reported to me by Jesper Wallin,
> > where net80211 crashes when it attempts to decrypt a CCMP-encrypted
> > frame which iwm passed up without decrypting it first.
>
> How does the stack crashes?

Jesper only sent me a screen shot and no public bug report :(

The trace looks roughly like this, where AES_Encrypt_ECB crashes because
ieee80211_ccmp_set_key() is never called since iwm_set_key overrides it.

AES_Encrypt_ECB()
ieee80211_ccmp_phase1()
ieee80211_ccmp_decrypt()
ieee80211_input()
ieee80211_ba_move_window()
ieee80211_input()
iwm_rx_rx_mpdu()
iwm_notif_intr()
iwm_intr()

What's a bit confusing here is that the interrupt was for an uencrypted
frame (a Block Ack Request) which moved the BA window forward. When
this happens we flush frames currently waiting in the Rx BA reordering
buffer. The encrypted frame which caused the crash was on that queue;
It must have passed through iwm_rx_rx_mpdu() earlier before the WPA
handshake was complete, and ended up waiting in the Rx BA queue because
its sequence number was off.

> Shouldn't we drop this packet in the stack as well?

net80211 will always see a 'protected' bit in the frame header
In ieee80211_input, if rxi has an HW_DEC flag set, the code assumes
this frame needs no further processing for crypto.
Otherwise it tries to decrypt.

So if the driver passes up a frame without decrypting it and without
setting HW_DEC, we crash. There's nothing that would allow net80211
to detect an incorrect absence of HW_DEC. The driver overrides the
set_key function and corresponding frames are expected to arrive with
the HW_DEC flag set in net80211. (Please don't ask me to change this
design right now for a better fix, it wasn't my idea...)

> > By code inspection I have determined that this problem could happen
> > in case a CCMP frame is received peer before the WPA handshake has
> > completed (e.g. during re-association). Note how the hardware decryption
> > code path depends on IEEE80211_NODE_RXPROT being set, which is set only
> > once the handshake has been completed.
> > We have to be careful here to avoid breaking non-CCMP ciphers (WEP, TKIP).
>
> So it's like working around the firwmare by defining two new state
> related to the CCMP key and dropping packets that should not reach
> us at this point?

Yes.

> > It also attempts to close a small race where we're handing the key to
> > firmware and eventually get an interrupt which confirms key installation,
> > in parallel to sending/receiving unicast data frames.
> > Until the key has been confirmed by firmware, don't transmit data frames
> > and drop received encrypted frames.
>
> Makes sense.
>
> The actual solution also has a race if you change the key before
> acknowledging the firmware IWM_ADD_STA_KEY, but I suppose this is
> acceptable.

The stack-side key has already been changed at that point. It is derived
from the WPA handshake. The firmware has to accept it or we can't proceed.

> > This part of the diff has poor error handling; if firmware never confirms
> > they key then iwm will get stuck and the user will have to recover.
>
> Well up/down should work, right?

Yes it should.

> > But that should be better than the current situation where we'd be
> > sending unencrypted frames or perhaps crash in net80211.
> >
> > These fixes could be separated but a combined diff is easier to test.
>
> What should we test?

Just check for regressions.

I have lightly tested it on one machine and it works there.
There's not a lot of testing needed, but if a few people could run the
diff to check if I've missed something, that would be nice.

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Martin Pieuchot
On 13/08/19(Tue) 14:58, Stefan Sperling wrote:

> On Tue, Aug 13, 2019 at 09:40:22AM -0300, Martin Pieuchot wrote:
> > On 13/08/19(Tue) 13:52, Stefan Sperling wrote:
> > > This should hopefully prevent a crash reported to me by Jesper Wallin,
> > > where net80211 crashes when it attempts to decrypt a CCMP-encrypted
> > > frame which iwm passed up without decrypting it first.
> >
> > How does the stack crashes?
>
> Jesper only sent me a screen shot and no public bug report :(
>
> The trace looks roughly like this, where AES_Encrypt_ECB crashes because
> ieee80211_ccmp_set_key() is never called since iwm_set_key overrides it.

Could we call ieee80211_ccmp_set_key() with a default value when
initializing the stack then?  Would that prevent all the possible family
of bugs?

What problems can occur when passing encrypted frames to the stack without
having configure a CCMP key?  Are they packets going to be dropped at some
point?

> AES_Encrypt_ECB()
> ieee80211_ccmp_phase1()
> ieee80211_ccmp_decrypt()
> ieee80211_input()
> ieee80211_ba_move_window()
> ieee80211_input()
> iwm_rx_rx_mpdu()
> iwm_notif_intr()
> iwm_intr()
>
> What's a bit confusing here is that the interrupt was for an uencrypted
> frame (a Block Ack Request) which moved the BA window forward. When
> this happens we flush frames currently waiting in the Rx BA reordering
> buffer. The encrypted frame which caused the crash was on that queue;
> It must have passed through iwm_rx_rx_mpdu() earlier before the WPA
> handshake was complete, and ended up waiting in the Rx BA queue because
> its sequence number was off.

> > Shouldn't we drop this packet in the stack as well?
>
> net80211 will always see a 'protected' bit in the frame header
> In ieee80211_input, if rxi has an HW_DEC flag set, the code assumes
> this frame needs no further processing for crypto.
> Otherwise it tries to decrypt.
>
> So if the driver passes up a frame without decrypting it and without
> setting HW_DEC, we crash. There's nothing that would allow net80211
> to detect an incorrect absence of HW_DEC. The driver overrides the
> set_key function and corresponding frames are expected to arrive with
> the HW_DEC flag set in net80211. (Please don't ask me to change this
> design right now for a better fix, it wasn't my idea...)

See above, if the crash is because of a missing key, put one :)

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Jesper Wallin
In reply to this post by Stefan Sperling-5
Hi, (cc'ed to bugs@ as well)

On Tue, Aug 13, 2019 at 02:58:05PM +0200, Stefan Sperling wrote:
> On Tue, Aug 13, 2019 at 09:40:22AM -0300, Martin Pieuchot wrote:
> >
> > How does the stack crashes?
>
> Jesper only sent me a screen shot and no public bug report :(
>

I've had a really busy week and you asked me to transcribe the
screenshot, which took a extra time since I couldn't use OCR.  I've also
tried to reproduce it and running solely on wireless the last couple of
days, but sadly no luck.  I ran chrome, rtorrent and was starting the
tor-browser when the crash happened, but I doubt that really matters.

I now noticed the trace was in /var/log/messages, *after* I copied it
manually. Oh well... :-)

I also apologize for the noise and the column length of this mail, I
just want to provide as much as possible and copied it as-is.  The stack
trace below is written by hand, so typos might occur. Doublecheck the
screenshot (see below).

--8<--
restore_fbdev_mode_atomic(ffff800000862e00,1) at restore_fbdev-mode_atomic+0x1ac
drm_fb_helper_restore_fbdev_mode_unlocked(ffff800000862e00) at drm_fb_helper_restore_fbdev_mode_unlocked+0x76
intel_fbdev_restore_mode(ffff800000147078) at intel_fbdev_restore_mode+0x33
db_ktrap(6,0,ffff80002227b4a0) at db_ktrap+0x2c
kerntrap(ffff80002227b4a0) at kerntrap+0xa2
alltraps_kern_meltdown(6,0,ffff80002226b760,0,0,1) at alltraps_kern_meltdown+0x7b
AES_Encrypt_ECB(0,ffff80002227b760,ffff80002227b760,1) at AES_Encrypt_ECB+0xd6
ieee80211_ccmp_phase1(0,fffffd800239700c,53,5e4,ffff80002227b760,ffff80002227b700) at ieee80211_ccmp_phase1+0x1fc
ieee80211_ccmp_decrypt(ffff800000183048,fffffd808ce4ee00,ffff800000dba1a0) at ieee80211_ccmp_decrypt+0x238
ieee80211_input(ffff800000183048,fffffd808ce4ee00,ffff800000dba000,ffff800001368038) at ieee80211_input+0xa1f
ieee80211_ba_move_window(ffff800000183048,ffff800000dba000,0,9d) at ieee80211_ba_move_window+0xb7
ieee80211_input(ffff800000183048,fffffd8095616800,ffff800000dba000,ffff80002227baa0) at ieee80211_input+0x71d
iwm_rx_rx_mpdu(ffff800000183000,fffffd800238f000,ffff8000001e3d00) at iwm_rx_rx_mpdu+0x421
iwm_notif_intr(ffff800000183000) at iwm_notif_intr+0x67b
iwm_intr(ffff800000183000) at iwm_intr+0x389
intr_handler(ffff80002227bc50,ffff800000143180) at intr_handler+0x6e
Xintr_ioapic_edge22_untramp(0,0,1388,0,0,ffffffff81d3c6f8) at Xintr_ioapic_edge22_untramp+0x19f
acpicpu_idle() at acpicpu_idle+0x1d2
sched_idle(ffffffff81d3bff0) at sched_idle+0x225
end trace frame: 0x0, count: 231
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd81f6054f20) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd81f6054f20) at pool_put+0x5a
futex_wait(3e157caf160,c8,3e168a70960,2) at futex_wait+0x1fe
sys_futex(ffff800044028628,ffff800044767590,ffff8000447675f0) at sys_futex+0x94
syscall(ffff800044767660) at syscall+0x389
Xsyscall(0,53,16,53,3,3e1b03d0400) at Xsyscall+0x128
end of kernel
end trace frame: 0x3e168a709d0, count: 251
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
preempt() at preempt+0x5c
ast(ffff800044767660) at ast+0xb3
Xsyscall(0,3c,16,53,3,3e1b03d0400) at Xsyscall+0x156
end of kernel
end trace frame: 0x3e168a709d0, count: 252
End of stack trace.
kernel: page fault trap, code=0
Stopped at      AES_Encrypt_ECB+0xd6:    movl    0x2d0(%rax),%edi
ddb{0}>
--8<--

The above mentioned screenshots can also be found at:
https://ifconfig.se/IMG_5204.jpg
https://ifconfig.se/IMG_5205.jpg
https://ifconfig.se/IMG_5206.jpg
https://ifconfig.se/IMG_5207.jpg
https://ifconfig.se/IMG_5208.jpg
https://ifconfig.se/IMG_5209.jpg
https://ifconfig.se/IMG_5210.jpg
https://ifconfig.se/IMG_5211.jpg
https://ifconfig.se/IMG_5212.jpg
https://ifconfig.se/IMG_5213.jpg
https://ifconfig.se/IMG_5214.jpg
https://ifconfig.se/IMG_5215.jpg
https://ifconfig.se/IMG_5216.jpg


I sadly don't have a dmesg from the day, but tried to extract as much as
I could from /var/log/messages:

--8<--
OpenBSD 6.5-current (GENERIC.MP) #186: Thu Aug  8 21:35:57 MDT 2019
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 8261529600 (7878MB)
avail mem = 8000983040 (7630MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xacbfd000 (65 entries)
bios0: vendor LENOVO version "N14ET50W (1.28 )" date 03/21/2019
bios0: LENOVO 20BS00A5MS
acpi0 at bios0: ACPI 5.0
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP SLIC ASF! HPET ECDT APIC MCFG SSDT SSDT SSDT SSDT SSDT SSDT SSDT SSDT SSDT PCCT SSDT UEFI MSDM BATB FPDT UEFI DMAR
acpi0: wakeup devices LID_(S4) SLPB(S3) IGBE(S4) EXP2(S4) XHCI(S3) EHC1(S3)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpihpet0 at acpi0: 14318179 Hz
acpiec0 at acpi0
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz, 2295.13 MHz, 06-3d-04
cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
tsc_timecounter_init: TSC skew=0 observed drift=0
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
cpu1 at mainbus0: apid 1 (application processor)
TSC skew=-24
cpu1: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz, 2294.69 MHz, 06-3d-04
cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
tsc_timecounter_init: TSC skew=-24 observed drift=0
cpu1: smt 1, core 0, package 0
cpu2 at mainbus0: apid 2 (application processor)
TSC skew=4
cpu2: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz, 2294.70 MHz, 06-3d-04
cpu2: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu2: 256KB 64b/line 8-way L2 cache
tsc_timecounter_init: TSC skew=4 observed drift=0
cpu2: smt 0, core 1, package 0
cpu3 at mainbus0: apid 3 (application processor)
TSC skew=0
cpu3: Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz, 2294.69 MHz, 06-3d-04
cpu3: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu3: 256KB 64b/line 8-way L2 cache
tsc_timecounter_init: TSC skew=0 observed drift=0
cpu3: smt 1, core 1, package 0
ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 40 pins
acpimcfg0 at acpi0
acpimcfg0: addr 0xf8000000, bus 0-63
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus -1 (PEG_)
acpiprt2 at acpi0: bus 3 (EXP1)
acpiprt3 at acpi0: bus 4 (EXP2)
acpiprt4 at acpi0: bus -1 (EXP3)
acpiprt5 at acpi0: bus 10 (EXP6)
acpicpu0 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33), C1(1000@1 mwait.1), PSS
acpicpu1 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33), C1(1000@1 mwait.1), PSS
acpicpu2 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33), C1(1000@1 mwait.1), PSS
acpicpu3 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33), C1(1000@1 mwait.1), PSS
acpipwrres0 at acpi0: PUBS, resource for XHCI, EHC1
acpipwrres1 at acpi0: NVP3, resource for PEG_
acpipwrres2 at acpi0: NVP2, resource for PEG_
acpitz0 at acpi0: critical temperature is 128 degC
acpibtn0 at acpi0: LID_
acpibtn1 at acpi0: SLPB
acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
acpicmos0 at acpi0
acpibat0 at acpi0: BAT0 model "00HW003" serial   650 type LiP oem "SMP"
acpiac0 at acpi0: AC unit online
acpithinkpad0 at acpi0
"PNP0C14" at acpi0 not configured
Aug  9 10:04:41 nostromo last message repeated 2 times
"INT340F" at acpi0 not configured
acpivideo0 at acpi0: VID_
acpivout at acpivideo0 not configured
acpivideo1 at acpi0: VID_
cpu0: using VERW MDS workaround (except on vmm entry)
cpu0: Enhanced SpeedStep 2295 MHz: speeds: 2401, 2400, 2300, 2100, 2000, 1900, 1700, 1600, 1400, 1300, 1200, 1000, 900, 800, 600, 500 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel Core 5G Host" rev 0x09
inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics 5500" rev 0x09
drm0 at inteldrm0
inteldrm0: msi
azalia0 at pci0 dev 3 function 0 "Intel Core 5G HD Audio" rev 0x09: msi
azalia0: No codecs found
xhci0 at pci0 dev 20 function 0 "Intel 9 Series xHCI" rev 0x03: msi, xHCI 1.0
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev 3.00/1.00 addr 1
"Intel 9 Series MEI" rev 0x03 at pci0 dev 22 function 0 not configured
em0 at pci0 dev 25 function 0 "Intel I218-V" rev 0x03: msi, address 54:ee:75:7c:cf:3f
azalia1 at pci0 dev 27 function 0 "Intel 9 Series HD Audio" rev 0x03: msi
azalia1: codecs: Realtek ALC292
audio0 at azalia1
ppb0 at pci0 dev 28 function 0 "Intel 9 Series PCIE" rev 0xe3: msi
pci1 at ppb0 bus 3
ppb1 at pci0 dev 28 function 1 "Intel 9 Series PCIE" rev 0xe3: msi
pci2 at ppb1 bus 4
iwm0 at pci2 dev 0 function 0 "Intel Dual Band Wireless AC 7265" rev 0x99, msi
ppb2 at pci0 dev 28 function 5 "Intel 9 Series PCIE" rev 0xe3: msi
pci3 at ppb2 bus 10
ahci0 at pci3 dev 0 function 0 "Samsung SM951 AHCI" rev 0x01: apic 2 int 16, AHCI 1.3
ahci0: port 0: 6.0Gb/s
scsibus1 at ahci0: 32 targets
sd0 at scsibus1 targ 0 lun 0: <ATA, SAMSUNG MZHPV512, BXW2> SCSI3 0/direct fixed naa.5002538900000000
sd0: 488386MB, 512 bytes/sector, 1000215216 sectors, thin
pcib0 at pci0 dev 31 function 0 "Intel 9 Series LPC" rev 0x03
ichiic0 at pci0 dev 31 function 3 "Intel 9 Series SMBus" rev 0x03: apic 2 int 18
iic0 at ichiic0
pchtemp0 at pci0 dev 31 function 6 "Intel 9 Series Thermal" rev 0x03
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
wsmouse1 at pms0 mux 0
pms0: Synaptics clickpad, firmware 8.1, 0x1e2b1 0x943300
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
vmm0 at mainbus0: VMX/EPT
uhub1 at uhub0 port 1 configuration 1 interface 0 "Microchip Tech USB2734" rev 2.10/1.29 addr 2
uhidev0 at uhub1 port 1 configuration 1 interface 0 "Microsoft Microsoft\M-. Comfort Mouse 4500" rev 2.00/0.83 addr 3
uhidev0: iclass 3/1, 28 report ids
ums0 at uhidev0 reportid 16: 5 buttons, Z and W dir
wsmouse2 at ums0 mux 0
uhid0 at uhidev0 reportid 18: input=0, output=0, feature=1
uhid1 at uhidev0 reportid 19: input=1, output=0, feature=0
uhid2 at uhidev0 reportid 22: input=4, output=0, feature=0
uhid3 at uhidev0 reportid 23: input=0, output=0, feature=1
uhid4 at uhidev0 reportid 24: input=0, output=0, feature=1
uhid5 at uhidev0 reportid 28: input=1, output=0, feature=0
uhidev1 at uhub1 port 5 configuration 1 interface 1 "Microchip Tech Hub Controller" rev 2.01/2.00 addr 4
uhidev1: iclass 3/0
uhid6 at uhidev1: input=64, output=64, feature=0
ugen0 at uhub1 port 5 configuration 1 "Microchip Tech Hub Controller" rev 2.01/2.00 addr 4
uhidev2 at uhub0 port 5 configuration 1 interface 0 "ELAN Touchscreen" rev 2.00/0.13 addr 5
uhidev2: iclass 3/0, 68 report ids
ums1 at uhidev2 reportid 1: 1 button, tip
wsmouse3 at ums1 mux 0
uhid7 at uhidev2 reportid 2: input=64, output=0, feature=0
uhid8 at uhidev2 reportid 3: input=0, output=31, feature=0
uhid9 at uhidev2 reportid 4: input=19, output=0, feature=0
uhid10 at uhidev2 reportid 10: input=0, output=0, feature=1
ums2 at uhidev2 reportid 68
ums2: mouse has no X report
uhub2 at uhub0 port 12 configuration 1 interface 0 "Microchip Tech USB5734" rev 3.10/1.29 addr 6
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006> SCSI2 0/direct fixed
sd1: 460801MB, 512 bytes/sector, 943721768 sectors
root on sd1a (4e90ba8d3a52efc4.a) swap on sd1b dump on sd1b
inteldrm0: 2560x1440, 32bpp
wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
wsdisplay0: screen 1-5 added (std, vt100 emulation)
iwm0: hw rev 0x210, fw ver 16.242414.0, address 18:5e:0f:74:6e:04
--8<--

I also noticed the stack trace (and even more information I think) was
saved in /var/log/messages too:

--8<--
) at iwmt: bufcache_take: want 6 have 7
Starting stack trace...
bufcacheintr+0x67b
iwm_intr(ffff800000183000) at iwm_intr+0x389
intr_han09e18,3,4000,0,ffffffffffffffff) at getblk+0x113
bread(fffffd820fe09e18,3,4000,ffff800043c47de8) at bread+0x23
ffs1_balloc(fffffd820ff9f790,d4a8,4f,fffffd824d7c4a80,1,ffff800043c47de8) at ffs1_balloc+0x5ed
ffs_write(ffff800043c47e70) at ffs_write+0x262
VOP_WRITE(fffffd820fe09e18,ffff800043c48050,3,fffffd824d7c4a80) at VOP_WRITE+0x4f
vn_write(fffffd820fa28710,ffff800043c48050,0) at vn_write+0x11b
dofilewritev(ffff800022353160,f,ffff800043c48050,0,ffff800043c48150) at dofilewritev+0xf9
sys_writev(ffff800022353160,ffff800043c480f0,ffff800043c48150) at sys_writev+0xe2
syscall(ffff800043c481c0) at syscall+0x389
Xsyscall(0,79,35,79,7,4c264294100) at Xsyscall+0x128
end of kernel
end trace frame: 0x7f7ffffc0b00, count: 246
End of stack trace.
splassert: buf_acquire: want 6 have 7
Starting stack trace...
buf_acquire(fffffd820df0a76,2) at msleep+0xcc
intel_dp_aux_xfer() at intel_dp_aux_xfer+0xffffffffff) at getblk+0x11b
bread(fffffd820fe09e18,3,4000,ffff800043c47de8) at bread+0x23
ffs1_balloc(fffffd820ff9f790,d4a8,4f,fffffd824d7c4a80,1,ffff800043c47de8) at ffs1_balloc+0x5ed
ffs_write(ffff800043c47e70) at ffs_write+0x262
VOP_WRITE(fffffd820fe09eintel_ddi_pre_enable(ffff80000085f000,ffff800001800000,ffff800001470e80) at intel_ddi_pre_enable+0x3c7
haswell_crtc_enable(ffff800001800000,ffff8000011f2000) at haswell_crtc_enable+0x13f
intel_update_crtc(ffff800000855800,ffff8000011f2000,ffff8000010e4000,ffff800001800000) at intel_update_crtc+0xc8
intel_update_crtcs(ffff8000011f2000) at intel_update_crtcs+0x65
intel_atomic_commit_0x128
end of kernel
end trace frame: 0x7f7ffffc0b00, count: 246
tomic_commit(ffff800000147078,ffff8000011f2000,0) at intel_atomic_commit+0x323
restore_fbdev_mode_atomic(ffff800000862e00,1) at restore_fbdev_mode_atomic+0x1ac
drm_fb_helper_restore_fbdev_mode_unlocked(ffff800000862e00) at drm_fb_helper_restore_fbdev_mode_unlocked+0x76
intel_fbdev_restore_mode(ffff800000147078) at intel_fbdev_restore_mode+0x33
db_ktrap(6,0,ffff80002227b4a0) at db_ktrap+0x2c
kerntrap(ffff80002227b4a0) at kerntrap+0xa2
alltraps_kern_meltdown(6,0,ffff80002227b760,0,0,1) at alltraps_kern_meltdown+0x7b
AES_Encrypt_ECB(0,ffff80002227b760,ffff80002227b760,1) a043c48050,0,ffff800043c48150) at dofilewritev+0xf9
sys_writev(ffff800022353160,ffff800043c480f0,ffff800043c48150) at sys_writev+0xe2
syscall(ffff800043c481c0) at syscall+0x389
Xsyscall(0,79,35,79,7,4c264294100) at Xsyscall+0x128
end of kernel
end trace fraput(ffff800000183048,fffffd808ce4ee00,ffff800000dba000,ffff80000f_release: want 6 have 7
Starting stack trace...
buf_release(fffffd820df0a200) at buf_release+0x3d
brelse(fffffd820df0a200) at bxb7
ieee80211_input(ffff800000183048,fffffd8095616800,ffff800000ITE(fffffd820fe09e18,ffff800043c48050,3,fffffd824d7c4a80) at VOP(ffff800000183000,fffffd800238f000,ffff8000001e3d00) at iwm_rx_rx_mpdu+0x421
iwm_notif_intr(ffff800000183000) at iwm_notif_intr+0x67b
iwm_intr(ffff800000183000) at iwm_intr+0x389
intr_handler(ffff80002227bc50,ffff800000143180) at intr_handler+0x6e
Xintr_ioapic_edge22_untramp(0,0,1388,0,0,ffffffff81d3c6f8) at Xintr_ioapic_edge22_untramp+0x19f
acpicpu_idle() at acpicpu_idle+0x1d2
schc0b00, count: 248
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
preempt() at preempt+0x5c
ast(ffff800043c481c0) at ast+0xb3
Xsyscall(0,4f,35,79,7,4c264294100) at Xsyscall+0x156
end of kernel
end trace frame: 0x7f7ffffc0b00, count: 252
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff8000222811a0,1) at sleep_finish+0x84
softclock_thread(ffff80002226c4f0) at softclock_thread+0xb3
end trace frame: 0x0, count: 253
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd81f60543c0) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd81f60543c0) at pool_put+0x5a
futex_requeue(af5a71cb9b0,7fffffff,0,0,2) at futex_ri_switch() at mi_switch+0x40
sleep_finish(ffff80002227a9b8,1) at043dede50) at sys_futex+0xec
syscall(ffff800043dedec0) at syscalffffff81ab5376,2) at msleep+0xcc
intel_dp_aux_xfer() at intel_dp_aux_xfer+0x565
intel_dp_aux_transfer(ffff80000085f1b8,ffff80002unt: 251
End of stack trace.
splassert: assertwaitok: want 0 hav00085f1b8,202,ffff80002227ac96,6) at drm_dp_dpcd_read+0x9d
intel_dp_get_link_status(ffff80000085f108,ffff80002227ac96) at intel_800043dedec0) at ast+0xb3
Xsyscall(0,1,af5ac474070,53,af51df55af08) at intel_dp_start_link_train+0x394
intel_ddi_pre_enable(ffff80000085f000,ffff800001800000,ffff800001470e80) at intel_ddi_pre_enable+0x3c7
haswell_crtc_enable(ffff800001800000,ffff8000011f281db9e00,2,ffff800022292ad4) at pool_do_get+0x52
pool_get(ffffff5800,ffff8000011f2000,ffff8000010e4000,ffff800001800000) at intel_update_crtc+0xc8
intel_update_crtcs(ffff8000011f2000) at intel_update_crtcs+0x65
intel_atomic_commit_tail(ffff8000011f2000) at2a68
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ffff8000222dev_mode_atomic(ffff800000862e00,1) at restore_fbdev_mode_atomic+0x1ac
drm_fb_helper_restore_fbdev_mode_unlocked(ffff800000862e00) at drm_fb_helper_restore_fbdev_mode_unlocked+0x76
intel_fbdevffff800000de2800,fffffd809898f200,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd809898f200) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd809898f200,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 243
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81db9e00,2,ffff800022292ad4) at pool_do_get+0x52
pool_get(ffffffff81db9e00,2) at pool_get+0x8f
tcp_reass(ffff800001724668,fffffd80877ee424,fffffd800fff1a00,ffff800022292cbc) at tcp_reass+0x40
tcp_input(ffff800022292eb8,ffff800022292ec4,6,2) at tcp_input+0x2a68
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ffff800022292e18,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd800fff1a00) at ipv4_input+0x39
eth00143180) at intr_handler+0x6e
Xintr_ioapic_edge22_untramp(0,0,1388,0,0,ffffffff81d3c6f8) at Xintr_ioapic_edge22_untramp+0x19f
acpicpu_idle() at acpicpu_idle+0x1d2
sched_idle(ffffffff81d3bff0)) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_twitch+0x40
sleep_finish(ffff80002228d2f8,1) at sleep_finish+0x84
msleep(ffffffff81d0b2d0,ffffffff81d0b2f0,20,ffffffff81ac91f7,0)ol_do_get(ffffffff81db9e00,2,ffff800022292ad4) at pool_do_get+0x52
pool_get(ffffffff81db9e00,2) at pool_get+0x8f
tcp_reass(ffff80000158c680,fffffd80777993a4,fffffd8098227000,ffff800022292cbc) ce.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ffff800022292e18,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd8098227000) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd8098227000,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd8098227000) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd8098227000,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 243
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81dea550,a,ffff800022292a64) at pool_do_get+0x52
pool_get(ffffffff81dea550,a) at pool_get+0x8f
sonewconn(fffffd81e1852690,2) at sonewconn+0xd6
syn_cache_get(ffff800022292bf8,ffff800022292bb8,fffffd809e1253a4,6aa,30,fffffd81e18526) at intel_atomic_commit+0x323
restore_fbdev_mode_atomic(ffff800292ec4,6,2) at tcp_input+0x989
ip_deliver(ffff800022292eb8,ffff8store_fbdev_mode_unlocked(ffff800000862e00) at drm_fb_helper_resff800022292ec4,ed0,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd800ffed300) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800ffed300,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800ffed300) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800ffed300,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 242
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81ddc9b8,a,ffff800022292984) at pool_do_get+0x52
pool_get(ffffffff81ddc9b8,a) at pool_get+0x8f
in_pcballoc(fffffd81add197d8,ffffffff81dcbc58) at in_pcballoc+0x6e
tcp_attach(fffffd81add197d8,0) at tcp_attach+0xd6
sonewconn(fffffd81e1852690,2) at sonewconn+0x21f
syn_cache_get(ffff800022292bf8,ffff800022292bb8,fffffd809e1253a4,6aa,30,fffffd81e1852690) at syn_cache_get+0x1b6
tcp_input(ffff800022292eb8,ffff800022292ec4,6,2) at tcp_input+0x989
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ed0,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd800ffed300) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800ffed300,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800ffed300) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800ffed300,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
, count: 250
End of stack trace.
splassert: vwakeup: want 6 havepool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81db9c50,a,ffff8000222929d4) at pool_do_get+0x52
pool_get(ffffffff81db9c50,a) at pool_get+0x8f
tcp_newtcpcb(fffffd81ddff2e50) at tcp_newtcpcb+0x2c
tcp_attach(fffffd81add197d8,0) at tcp_attach+0x10c
sonewconn(fffffd81e1852690,2) at sonewconn+0x21f
syn_cache_get(ffff800022292bf8,ffff800022292bb8,fffffd809e1253a4,6aa,30,fffffd81e1852690) at syn_cache_get+0x1b6
tcp_input(ffff800022292eb8,ffff800022292ec4,6,2) at tcp_input+0x989
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ed0,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd800ffed300) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800ffed300,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800ffed300) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800ffed300,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 240
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81dbfd20,2,ffff800022292954) at pool_do_get+0x52
pool_get(ffffffff81dbfd20,2) at pool_get+0x8f
pf_match_rule(ffff800022292b30,ffffffff81dbf738) at pf_match_rule+0xe2b
pf_test_rule(ffff800022292c98,ffff800022292d88,ffff800022292da0,ffff800022292d70,ffff800022292d60,ffff800022292dae) at pf_test_rule+0x17e
pf_test(2,1,ffff800000de2800,ffff800022292eb8) at pf_test+0x794
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x3d6
ipv4_input(fne(fffffd81ceda4c60) at scsi_done+0x24
sr_scsi_done(ffff8000004cd000,fffffd81ceda4c60) at sr_scsi_done+0x2e
sr_crypto_done(ffff8nput(ffff800000de2800,fffffd800ffeeb00) at if_vinput+0xe5
trunk_004c9700) at sr_wu_done_callback+0x158
taskq_thread(ffff8000004d4080) at taskq_thread+0x4d
end trace frame: 0x0, count: 250
End ) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0xfd81d616be00) at biodone+0x8d
sd_buf_done(fffffd81ceda4c60) at st: pool_do_put: want 5 have 7
Starting stack trace...
pool_do_put(ffffffff81dbfd20,fffffd819410df50) at pool_do_put+0x40
pool_put(ffffffff81dbfd20,fffffd819410df50) at pool_put+0x5a
pf_test_rule(ffff800022292c98,ffff800022292d88,ffff800022292da0,ffff800022292d70,ffff800022292d60,ffff800022292dae) at pf_test_rule+0x1326
pf_test(2,1,ffff800000de2800,ffff800022292eb8) at pf_test+0x794
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x3d6
ipv4_input(ffff800000de2800,fffffd800ffeeb00) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800ffeeb00,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800ffeeb00) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800ffeeb00,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 245
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81db9e00,2,ffff800022292ad4) at pool_do_get+0x52
pool_get(ffffffff81db9e00,2) at pool_get+0x8f
tcp_reass(ffff80000158c680,fffffd801025b324,fffffd8095615600,ffff800022292cbc) at tcp_reass+0x40
tcp_input(ffff800022292eb8,ffff800022292ec4,6,2) at tcp_input+0x2a68
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ffff800022292e18,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd8095615600) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd8095615600,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd8095615600) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd8095615600,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 243
End of stack trace.
splassert: pool_do_put: want 5 have 7
Starting stack trace...
pool_do_put(ffffffff81db9e00,fffffd819d8cd5c8) at pool_do_put+0x40
pool_put(ffffffff81db9e00,fffffd819d8cd5c8) at pool_put+0x5a
tcp_flush_queue(ffff80000158c680) at tcp_flush_queue+0x137
tcp_input(ffff800022292eb8,ffff800022292ec4,6,2) at tcp_input+0x2a68
ip_deliver(ffff800022292eb8,ffff800022292ec4,6,2) at ip_deliver+0x223
ip_ours(ffff800022292eb8,ffff800022292ec4,ffff800022292e18,0) at ip_ours+0x329
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x47e
ipv4_input(ffff800000de2800,fffffd8095615600) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd8095615600,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd8095615600) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd8095615600,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 243
End of stack trace.
splassert: pool_do_get: want 5 have 7
Starting stack trace...
pool_do_get(ffffffff81dbfd20,2,ffff800022292954) at pool_do_get+0x52
pool_get(ffffffff81dbfd20,2) at pool_get+0x8f
pf_match_rule(ffff800022292b30,ffffffff81dbf738) at pf_match_rule+0xe2b
pf_test_rule(ffff800022292c98,ffff800022292d88,ffff800022292da0,ffff800022292d70,ffff800022292d60,ffff800022292dae) at pf_test_rule+0x17e
pf_test(2,1,ffff800000de2800,ffff800022292eb8) at pf_test+0x794
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x3d6
ipv4_input(ffff800000de2800,fffffd800fff6c00) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800fff6c00,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800fff6c00) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800fff6c00,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 244
End of stack trace.
splassert: pool_do_put: want 5 have 7
Starting stack trace...
pool_do_put(ffffffff81dbfd20,fffffd819410df50) at pool_do_put+0x40
pool_put(ffffffff81dbfd20,fffffd819410df50) at pool_put+0x5a
pf_test_rule(ffff800022292c98,ffff800022292d88,ffff800022292da0,ffff800022292d70,ffff800022292d60,ffff800022292dae) at pf_test_rule+0x1326
pf_test(2,1,ffff800000de2800,ffff800022292eb8) at pf_test+0x794
ip_input_if(ffff800022292eb8,ffff800022292ec4,4,0,ffff800000de2800) at ip_input_if+0x3d6
ipv4_input(ffff800000de2800,fffffd800fff6c00) at ipv4_input+0x39
ether_input(ffff800000de2800,fffffd800fff6c00,0) at ether_input+0x1d3
if_vinput(ffff800000de2800,fffffd800fff6c00) at if_vinput+0xe5
trunk_input(ffff800000166048,fffffd800fff6c00,ffff800000feee80) at trunk_input+0xcc
if_input_process(ffff800000166048,ffff800022293068) at if_input_process+0xb3
ifiq_process(ffff8000001663e8) at ifiq_process+0x71
taskq_thread(ffff800000027040) at taskq_thread+0x4d
end trace frame: 0x0, count: 245
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
yield() at yield+0x91
taskq_thread(ffff800000027040) at taskq_thread+0x64
end trace frame: 0x0, count: 253
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff8000222811a0,1) at sleep_finish+0x84
softclock_thread(ffff80002226c4f0) at softclock_thread+0xb3
end trace frame: 0x0, count: 253
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff80002228d2f8,1) at sleep_finish+0x84
msleep(ffffffff81d0b2d0,ffffffff81d0b2f0,20,ffffffff81ac91f7,0) at msleep+0xcc
taskq_next_work(ffffffff81d0b2d0,ffff80002228d3c0) at taskq_next_work+0x38
taskq_thread(ffffffff81d0b2d0) at taskq_thread+0x6f
end trace frame: 0x0, count: 251
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd823c04d738) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd823c04d738) at pool_put+0x5a
futex_wait(237e12230b0,0,237fb070b10,2) at futex_wait+0x1fe
sys_futex(ffff800043f0f978,ffff8000444f83a0,ffff8000444f8400) at sys_futex+0x94
syscall(ffff8000444f8470) at syscall+0x389
Xsyscall(0,53,16,53,3,23870b11a00) at Xsyscall+0x128
end of kernel
end trace frame: 0x237fb070b80, count: 251
End of stack trace.
splassert: pool_do_get: want 0 have 7
Starting stack trace...
pool_do_get(ffffffff81de50d0,1,ffff8000444f8204) at pool_do_get+0x52
pool_get(ffffffff81de50d0,1) at pool_get+0x8f
futex_get(23860f589c0,3) at futex_get+0xff
futex_wait(23860f589c0,0,0,2) at futex_wait+0x13f
sys_futex(ffff800043f0f978,ffff8000444f83a0,ffff8000444f8400) at sys_futex+0x94
syscall(ffff8000444f8470) at syscall+0x389
Xsyscall(0,53,0,53,3,23870b11a00) at Xsyscall+0x128
end of kernel
end trace frame: 0x237fb070c00, count: 250
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff8000444f8228,1) at sleep_finish+0x84
rwsleep(ffff800043f0f978,ffffffff81d3d4b0,120,ffffffff81aa4038,0) at rwsleep+0xb1
futex_wait(23860f589c0,0,0,2) at futex_wait+0x180
sys_futex(ffff800043f0f978,ffff8000444f83a0,ffff8000444f8400) at sys_futex+0x94
syscall(ffff8000444f8470) at syscall+0x389
Xsyscall(0,53,0,53,3,23870b11a00) at Xsyscall+0x128
end of kernel
end trace frame: 0x237fb070c00, count: 249
End of stack trace.
splassert: pool_do_get: want 0 have 7
Starting stack trace...
pool_do_get(ffffffff81de50d0,1,ffff800043f3bb84) at pool_do_get+0x52
pool_get(ffffffff81de50d0,1) at pool_get+0x8f
futex_get(99b04cb8e20,3) at futex_get+0xff
futex_wait(99b04cb8e20,0,99a7634f340,2) at futex_wait+0x13f
sys_futex(ffff800043e83190,ffff800043f3bd20,ffff800043f3bd80) at sys_futex+0x94
syscall(ffff800043f3bdf0) at syscall+0x389
Xsyscall(0,53,16,53,3,99add8f3600) at Xsyscall+0x128
end of kernel
end trace frame: 0x99a7634f3b0, count: 250
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff800043f3bba8,1) at sleep_finish+0x84
rwsleep(ffff800043e83190,ffffffff81d3d4b0,120,ffffffff81aa4038,2) at rwsleep+0xb1
futex_wait(99b04cb8e20,0,99a7634f340,2) at futex_wait+0x180
sys_futex(ffff800043e83190,ffff800043f3bd20,ffff800043f3bd80) at sys_futex+0x94
syscall(ffff800043f3bdf0) at syscall+0x389
Xsyscall(0,53,16,53,3,99add8f3600) at Xsyscall+0x128
end of kernel
end trace frame: 0x99a7634f3b0, count: 249
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd81f6054b30) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd81f6054b30) at pool_put+0x5a
futex_requeue(72678913020,1,0,0,2) at futex_requeue+0x150
sys_futex(ffff800043e5f450,ffff80004444ace0,ffff80004444ad40) at sys_futex+0xec
syscall(ffff80004444adb0) at syscall+0x389
Xsyscall(0,53,0,53,72678913020,0) at Xsyscall+0x128
end of kernel
end trace frame: 0x7261163f8f0, count: 251
End of stack trace.
splassert: pool_do_get: want 0 have 7
Starting stack trace...
pool_do_get(ffffffff81de50d0,1,ffff80004444ab44) at pool_do_get+0x52
pool_get(ffffffff81de50d0,1) at pool_get+0x8f
futex_get(725c204c860,3) at futex_get+0xff
futex_wait(725c204c860,2,0,2) at futex_wait+0x13f
sys_futex(ffff800043e5f450,ffff80004444ace0,ffff80004444ad40) at sys_futex+0x94
syscall(ffff80004444adb0) at syscall+0x389
Xsyscall(0,53,7261163f790,53,725c204c860,0) at Xsyscall+0x128
end of kernel
end trace frame: 0x7261163f7d0, count: 250
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff80004444ab68,1) at sleep_finish+0x84
rwsleep(ffff800043e5f450,ffffffff81d3d4b0,120,ffffffff81aa4038,0) at rwsleep+0xb1
futex_wait(725c204c860,2,0,2) at futex_wait+0x180
sys_futex(ffff800043e5f450,ffff80004444ace0,ffff80004444ad40) at sys_futex+0x94
syscall(ffff80004444adb0) at syscall+0x389
Xsyscall(0,53,7261163f790,53,725c204c860,0) at Xsyscall+0x128
end of kernel
end trace frame: 0x7261163f7d0, count: 249
End of stack trace.
splassert: assertwaitok: want 0 have 7
Starting stack trace...
assertwaitok() at assertwaitok+0x40
mi_switch() at mi_switch+0x40
sleep_finish(ffff8000222811a0,1) at sleep_finish+0x84
softclock_thread(ffff80002226c4f0) at softclock_thread+0xb3
end trace frame: 0x0, count: 253
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd81f6054f58) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd81f6054f58) at pool_put+0x5a
futex_wait(ed7d281d860,0,7f7ffffd7000,2) at futex_wait+0x1fe
sys_futex(ffff800043f0eaa8,ffff800044682370,ffff8000446823d0) at sys_futex+0x94
syscall(ffff800044682440) at syscall+0x389
Xsyscall(0,53,16,53,3,ed7c3646380) at Xsyscall+0x128
end of kernel
end trace frame: 0x7f7ffffd7070, count: 251
End of stack trace.
splassert: pool_do_put: want 0 have 7
Starting stack trace...
pool_do_put(ffffffff81de50d0,fffffd823c04d7e0) at pool_do_put+0x40
pool_put(ffffffff81de50d0,fffffd823c04d7e0) at pool_put+0x5a
futex_requeue(ed8068f5fd0,7fffffff,0,0,2) at futex_requeue+0x150
sys_futex(ffff800043f0eaa8,ffff800044682370,ffff8000446823d0) at sys_futex+0xec
syscall(ffff800044682440) at syscall+0x389
Xsyscall(0,53,7f7ffffd6b01,53,ed80c78e4d0,ed8068f5fd0) at Xsyscall+0x128
end of kernel
end trace frame: 0x7f7ffffd6a10, count: 251
--8<--


Jesper Wallin

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Stefan Sperling-5
In reply to this post by Martin Pieuchot
On Tue, Aug 13, 2019 at 10:47:24AM -0300, Martin Pieuchot wrote:
> if the crash is because of a missing key, put one :)

Yes, you've convinced me. With this patch we install the CCMP key
to both firmware and net80211. Until firmware confirms that the
key has been installed, we do software encrypt/decrypt.

Should the firmware fail to install the key for some reason, we will
just keep using our software fallback until the interface is reset.

This also fixes the race with incoming frames during WPA handshake,
i.e. while (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0.
Such frames can be passed to net80211 and will be dropped there.

Lightly tested on a 7260 device.

Ok?

diff refs/heads/master refs/heads/ccmp-crash2
blob - 038e6a63dfff113b525bb1e9a30c935996535569
blob + 8afcce065eb0d85f4469a3f378cacba1513bc215
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -3595,10 +3595,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
  rxi.rxi_rssi = rssi;
  rxi.rxi_tstamp = device_timestamp;
 
- /* Handle hardware decryption. */
+ /*
+ * Handle hardware decryption.
+ *
+ * If the WPA handshake has completed but firmware is not yet ready
+ * to decrypt frames, fall back to software decryption in net80211.
+ * net80211 will drop encrypted frames until the handshake completes.
+ */
  if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL)
     && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
     !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+    (sc->sc_flags & IWM_FLAG_CCMP_READY) &&
     (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
     ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
  if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
@@ -4402,7 +4409,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
 
  if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
  k = ieee80211_get_txkey(ic, wh, ni);
- if  (k->k_cipher != IEEE80211_CIPHER_CCMP) {
+ if  (k->k_cipher != IEEE80211_CIPHER_CCMP ||
+    (sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
  if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
  return ENOBUFS;
 
@@ -4418,7 +4426,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
  /* Copy 802.11 header in TX command. */
  memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
 
- if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
+ if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP &&
+    (sc->sc_flags & IWM_FLAG_CCMP_READY)) {
  /* Trim 802.11 header and prepend CCMP IV. */
  m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
  ivp = mtod(m, u_int8_t *);
@@ -6090,6 +6099,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
 {
  struct iwm_softc *sc = ic->ic_softc;
  struct iwm_add_sta_key_cmd cmd = { 0 };
+ int err;
 
  if ((k->k_flags & IEEE80211_KEY_GROUP) ||
     k->k_cipher != IEEE80211_CIPHER_CCMP)  {
@@ -6097,6 +6107,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
  return (ieee80211_set_key(ic, ni, k));
  }
 
+ sc->sc_flags &= ~(IWM_FLAG_CCMP_READY | IWM_FLAG_CCMP_KEY_SENT);
+
  cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
     IWM_STA_KEY_FLG_WEP_KEY_MAP |
     ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
@@ -6108,8 +6120,15 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
  cmd.key_offset = 0;
  cmd.sta_id = IWM_STATION_ID;
 
- return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
-    sizeof(cmd), &cmd);
+ /* Allow for software CCMP encryption/decryption fallback. */
+ err = ieee80211_set_key(ic, ni, k);
+ if (!err) {
+ err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
+    sizeof(cmd), &cmd);
+ if (!err)
+ sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
+ }
+ return err;
 }
 
 void
@@ -6135,6 +6154,10 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee802
  cmd.sta_id = IWM_STATION_ID;
 
  iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
+ sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
+
+ /* Delete software fallback CCMP key. */
+        ieee80211_delete_key(ic, ni, k);
 }
 
 void
@@ -6846,6 +6869,7 @@ iwm_stop(struct ifnet *ifp)
  sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
  sc->sc_flags &= ~IWM_FLAG_HW_ERR;
  sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
+ sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
 
  sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
 
@@ -7331,6 +7355,12 @@ iwm_notif_intr(struct iwm_softc *sc)
  break;
 
  case IWM_ADD_STA_KEY:
+ if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
+ sc->sc_flags |= IWM_FLAG_CCMP_READY;
+ sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
+ }
+ break;
+
  case IWM_PHY_CONFIGURATION_CMD:
  case IWM_TX_ANT_CONFIGURATION_CMD:
  case IWM_ADD_STA:
blob - e6593fbc840833a36d5a792042faaa85e3ac9719
blob + 747616074f868d8679f9f01232dec4ce09474f93
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -289,6 +289,8 @@ struct iwm_rx_ring {
 #define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
 #define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
 #define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
+#define IWM_FLAG_CCMP_KEY_SENT 0x400 /* CCMP key sent to firmware */
+#define IWM_FLAG_CCMP_READY 0x800 /* CCMP key installed in firmware */
 
 struct iwm_ucode_status {
  uint32_t uc_error_event_table;

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

richard.n.procter
Hi Stefan,

On Wed, 14 Aug 2019, Stefan Sperling wrote:

> On Tue, Aug 13, 2019 at 10:47:24AM -0300, Martin Pieuchot wrote:
> > if the crash is because of a missing key, put one :)
>
> Yes, you've convinced me. With this patch we install the CCMP key
> to both firmware and net80211. Until firmware confirms that the
> key has been installed, we do software encrypt/decrypt.

I agree we should handle a missing key but suggest an alternative approach
below.

I'm unconvinced the root cause is a race on loading the key: I tried to
induce an infinite race, by skipping the command to upload the key to
hardware, but couldn't reproduce the crash. I suspect the guard for
handling hardware decryption in iwm_rx_rx_mpdu() is too weak, and a frame
governed by the offloaded key is slipping through.

The immediate cause of the crash is that, unless the driver sets
IEEE80211_RXI_HWDEC on all frames governed by a key, the stack will
attempt software decryption without the necessary context and crash. i.e.
software decryption is the default and the stack assumes this is always
possible. But it isn't: the stack has delegated decryption to the driver.

So, evade this class of errors and check that software decrypt can handle
a key, i.e that ieee8021_set_key() has been called, and drop the frame if
not. (see below; compiled but untested.)

Thoughts?

best,
Richard.

iwm0 at pci1 dev 0 function 0 "Intel Dual Band Wireless AC 7265" rev 0x69, msi
iwm0: hw rev 0x210, fw ver 16.242414.0, address xx:xx:xx:xx:xx:xx

Index: net80211/ieee80211_crypto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
retrieving revision 1.74
diff -u -p -u -p -r1.74 ieee80211_crypto.c
--- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000 1.74
+++ net80211/ieee80211_crypto.c 15 Aug 2019 01:12:28 -0000
@@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
  /* should not get there */
  error = EINVAL;
  }
+
+ if (error == 0)
+ k->k_flags |= IEEE80211_KEY_SWCRYPTO;
+
  return error;
 }
 
@@ -280,6 +284,11 @@ ieee80211_decrypt(struct ieee80211com *i
  }
  k = &ic->ic_nw_keys[kid];
  }
+
+ if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
+ goto err;
+ }
+
  switch (k->k_cipher) {
  case IEEE80211_CIPHER_WEP40:
  case IEEE80211_CIPHER_WEP104:
@@ -296,9 +305,15 @@ ieee80211_decrypt(struct ieee80211com *i
  break;
  default:
  /* key not defined */
- m_freem(m0);
- m0 = NULL;
+ goto err;
  }
+
+ return m0;
+
+err:
+ m0 = NULL;
+ m_freem(m0);
+
  return m0;
 }
 
Index: net80211/ieee80211_crypto.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 ieee80211_crypto.h
--- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000 1.25
+++ net80211/ieee80211_crypto.h 15 Aug 2019 01:12:28 -0000
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define IEEE80211_KEY_GROUP 0x00000001 /* group data key */
 #define IEEE80211_KEY_TX 0x00000002 /* Tx+Rx */
 #define IEEE80211_KEY_IGTK 0x00000004 /* integrity group key */
+#define IEEE80211_KEY_SWCRYPTO 0x00000080 /* loaded for software crypto */
 
  u_int k_len;
  u_int64_t k_rsc[IEEE80211_NUM_TID];

-----------------------------------------------
illustration of disabling key upload below here
-----------------------------------------------


Index: dev/pci/if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.244
diff -u -p -u -p -r1.244 if_iwm.c
--- dev/pci/if_iwm.c 8 Aug 2019 13:56:56 -0000 1.244
+++ dev/pci/if_iwm.c 14 Aug 2019 20:32:47 -0000
@@ -6088,7 +6088,7 @@ int
 iwm_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
     struct ieee80211_key *k)
 {
- struct iwm_softc *sc = ic->ic_softc;
+ // struct iwm_softc *sc = ic->ic_softc;
  struct iwm_add_sta_key_cmd cmd = { 0 };
 
  if ((k->k_flags & IEEE80211_KEY_GROUP) ||
@@ -6108,8 +6108,10 @@ iwm_set_key(struct ieee80211com *ic, str
  cmd.key_offset = 0;
  cmd.sta_id = IWM_STATION_ID;
 
- return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
-    sizeof(cmd), &cmd);
+ // return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
+ //    sizeof(cmd), &cmd);
+
+ return 0;
 }
 
 void


>
> Should the firmware fail to install the key for some reason, we will
> just keep using our software fallback until the interface is reset.
>
> This also fixes the race with incoming frames during WPA handshake,
> i.e. while (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0.
> Such frames can be passed to net80211 and will be dropped there.
>
> Lightly tested on a 7260 device.
>
> Ok?
>
> diff refs/heads/master refs/heads/ccmp-crash2
> blob - 038e6a63dfff113b525bb1e9a30c935996535569
> blob + 8afcce065eb0d85f4469a3f378cacba1513bc215
> --- sys/dev/pci/if_iwm.c
> +++ sys/dev/pci/if_iwm.c
> @@ -3595,10 +3595,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
>   rxi.rxi_rssi = rssi;
>   rxi.rxi_tstamp = device_timestamp;
>  
> - /* Handle hardware decryption. */
> + /*
> + * Handle hardware decryption.
> + *
> + * If the WPA handshake has completed but firmware is not yet ready
> + * to decrypt frames, fall back to software decryption in net80211.
> + * net80211 will drop encrypted frames until the handshake completes.
> + */
>   if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL)
>      && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
>      !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> +    (sc->sc_flags & IWM_FLAG_CCMP_READY) &&
>      (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
>      ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
>   if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
> @@ -4402,7 +4409,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
>  
>   if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
>   k = ieee80211_get_txkey(ic, wh, ni);
> - if  (k->k_cipher != IEEE80211_CIPHER_CCMP) {
> + if  (k->k_cipher != IEEE80211_CIPHER_CCMP ||
> +    (sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
>   if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
>   return ENOBUFS;
>  
> @@ -4418,7 +4426,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
>   /* Copy 802.11 header in TX command. */
>   memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
>  
> - if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
> + if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP &&
> +    (sc->sc_flags & IWM_FLAG_CCMP_READY)) {
>   /* Trim 802.11 header and prepend CCMP IV. */
>   m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
>   ivp = mtod(m, u_int8_t *);
> @@ -6090,6 +6099,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>  {
>   struct iwm_softc *sc = ic->ic_softc;
>   struct iwm_add_sta_key_cmd cmd = { 0 };
> + int err;
>  
>   if ((k->k_flags & IEEE80211_KEY_GROUP) ||
>      k->k_cipher != IEEE80211_CIPHER_CCMP)  {
> @@ -6097,6 +6107,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>   return (ieee80211_set_key(ic, ni, k));
>   }
>  
> + sc->sc_flags &= ~(IWM_FLAG_CCMP_READY | IWM_FLAG_CCMP_KEY_SENT);
> +
>   cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
>      IWM_STA_KEY_FLG_WEP_KEY_MAP |
>      ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
> @@ -6108,8 +6120,15 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
>   cmd.key_offset = 0;
>   cmd.sta_id = IWM_STATION_ID;
>  
> - return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> -    sizeof(cmd), &cmd);
> + /* Allow for software CCMP encryption/decryption fallback. */
> + err = ieee80211_set_key(ic, ni, k);
> + if (!err) {
> + err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> +    sizeof(cmd), &cmd);
> + if (!err)
> + sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
> + }
> + return err;
>  }
>  
>  void
> @@ -6135,6 +6154,10 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee802
>   cmd.sta_id = IWM_STATION_ID;
>  
>   iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
> + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
> +
> + /* Delete software fallback CCMP key. */
> +        ieee80211_delete_key(ic, ni, k);
>  }
>  
>  void
> @@ -6846,6 +6869,7 @@ iwm_stop(struct ifnet *ifp)
>   sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
>   sc->sc_flags &= ~IWM_FLAG_HW_ERR;
>   sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
> + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
>  
>   sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
>  
> @@ -7331,6 +7355,12 @@ iwm_notif_intr(struct iwm_softc *sc)
>   break;
>  
>   case IWM_ADD_STA_KEY:
> + if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
> + sc->sc_flags |= IWM_FLAG_CCMP_READY;
> + sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
> + }
> + break;
> +
>   case IWM_PHY_CONFIGURATION_CMD:
>   case IWM_TX_ANT_CONFIGURATION_CMD:
>   case IWM_ADD_STA:
> blob - e6593fbc840833a36d5a792042faaa85e3ac9719
> blob + 747616074f868d8679f9f01232dec4ce09474f93
> --- sys/dev/pci/if_iwmvar.h
> +++ sys/dev/pci/if_iwmvar.h
> @@ -289,6 +289,8 @@ struct iwm_rx_ring {
>  #define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
>  #define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
>  #define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
> +#define IWM_FLAG_CCMP_KEY_SENT 0x400 /* CCMP key sent to firmware */
> +#define IWM_FLAG_CCMP_READY 0x800 /* CCMP key installed in firmware */
>  
>  struct iwm_ucode_status {
>   uint32_t uc_error_event_table;
>
>

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

richard.n.procter


On Thu, 15 Aug 2019, [hidden email] wrote:

> Hi Stefan,
>
> On Wed, 14 Aug 2019, Stefan Sperling wrote:
>
> > On Tue, Aug 13, 2019 at 10:47:24AM -0300, Martin Pieuchot wrote:
> > > if the crash is because of a missing key, put one :)
> >
> > Yes, you've convinced me. With this patch we install the CCMP key
> > to both firmware and net80211. Until firmware confirms that the
> > key has been installed, we do software encrypt/decrypt.
>
> I agree we should handle a missing key but suggest an alternative approach
> below.

so:

m0 = NULL;
m_free(m0);

isn't so useful; fixed patch follows.

best,
Richard.

Index: net80211/ieee80211_crypto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
retrieving revision 1.74
diff -u -p -u -p -r1.74 ieee80211_crypto.c
--- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000 1.74
+++ net80211/ieee80211_crypto.c 15 Aug 2019 03:44:12 -0000
@@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
  /* should not get there */
  error = EINVAL;
  }
+
+ if (error == 0)
+ k->k_flags |= IEEE80211_KEY_SWCRYPTO;
+
  return error;
 }
 
@@ -280,6 +284,11 @@ ieee80211_decrypt(struct ieee80211com *i
  }
  k = &ic->ic_nw_keys[kid];
  }
+
+ if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
+ goto err;
+ }
+
  switch (k->k_cipher) {
  case IEEE80211_CIPHER_WEP40:
  case IEEE80211_CIPHER_WEP104:
@@ -296,9 +305,15 @@ ieee80211_decrypt(struct ieee80211com *i
  break;
  default:
  /* key not defined */
- m_freem(m0);
- m0 = NULL;
+ goto err;
  }
+
+ return m0;
+
+err:
+ m_freem(m0);
+ m0 = NULL;
+
  return m0;
 }
 
Index: net80211/ieee80211_crypto.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 ieee80211_crypto.h
--- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000 1.25
+++ net80211/ieee80211_crypto.h 15 Aug 2019 03:44:12 -0000
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define IEEE80211_KEY_GROUP 0x00000001 /* group data key */
 #define IEEE80211_KEY_TX 0x00000002 /* Tx+Rx */
 #define IEEE80211_KEY_IGTK 0x00000004 /* integrity group key */
+#define IEEE80211_KEY_SWCRYPTO 0x00000080 /* loaded for software crypto */
 
  u_int k_len;
  u_int64_t k_rsc[IEEE80211_NUM_TID];



> >
> > Should the firmware fail to install the key for some reason, we will
> > just keep using our software fallback until the interface is reset.
> >
> > This also fixes the race with incoming frames during WPA handshake,
> > i.e. while (ni->ni_flags & IEEE80211_NODE_RXPROT) == 0.
> > Such frames can be passed to net80211 and will be dropped there.
> >
> > Lightly tested on a 7260 device.
> >
> > Ok?
> >
> > diff refs/heads/master refs/heads/ccmp-crash2
> > blob - 038e6a63dfff113b525bb1e9a30c935996535569
> > blob + 8afcce065eb0d85f4469a3f378cacba1513bc215
> > --- sys/dev/pci/if_iwm.c
> > +++ sys/dev/pci/if_iwm.c
> > @@ -3595,10 +3595,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_pac
> >   rxi.rxi_rssi = rssi;
> >   rxi.rxi_tstamp = device_timestamp;
> >  
> > - /* Handle hardware decryption. */
> > + /*
> > + * Handle hardware decryption.
> > + *
> > + * If the WPA handshake has completed but firmware is not yet ready
> > + * to decrypt frames, fall back to software decryption in net80211.
> > + * net80211 will drop encrypted frames until the handshake completes.
> > + */
> >   if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL)
> >      && (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
> >      !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> > +    (sc->sc_flags & IWM_FLAG_CCMP_READY) &&
> >      (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
> >      ni->ni_pairwise_key.k_cipher == IEEE80211_CIPHER_CCMP) {
> >   if ((rx_pkt_status & IWM_RX_MPDU_RES_STATUS_SEC_ENC_MSK) !=
> > @@ -4402,7 +4409,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
> >  
> >   if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
> >   k = ieee80211_get_txkey(ic, wh, ni);
> > - if  (k->k_cipher != IEEE80211_CIPHER_CCMP) {
> > + if  (k->k_cipher != IEEE80211_CIPHER_CCMP ||
> > +    (sc->sc_flags & IWM_FLAG_CCMP_READY) == 0) {
> >   if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
> >   return ENOBUFS;
> >  
> > @@ -4418,7 +4426,8 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ie
> >   /* Copy 802.11 header in TX command. */
> >   memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
> >  
> > - if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
> > + if  (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP &&
> > +    (sc->sc_flags & IWM_FLAG_CCMP_READY)) {
> >   /* Trim 802.11 header and prepend CCMP IV. */
> >   m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
> >   ivp = mtod(m, u_int8_t *);
> > @@ -6090,6 +6099,7 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
> >  {
> >   struct iwm_softc *sc = ic->ic_softc;
> >   struct iwm_add_sta_key_cmd cmd = { 0 };
> > + int err;
> >  
> >   if ((k->k_flags & IEEE80211_KEY_GROUP) ||
> >      k->k_cipher != IEEE80211_CIPHER_CCMP)  {
> > @@ -6097,6 +6107,8 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
> >   return (ieee80211_set_key(ic, ni, k));
> >   }
> >  
> > + sc->sc_flags &= ~(IWM_FLAG_CCMP_READY | IWM_FLAG_CCMP_KEY_SENT);
> > +
> >   cmd.key_flags = htole16(IWM_STA_KEY_FLG_CCM |
> >      IWM_STA_KEY_FLG_WEP_KEY_MAP |
> >      ((k->k_id << IWM_STA_KEY_FLG_KEYID_POS) &
> > @@ -6108,8 +6120,15 @@ iwm_set_key(struct ieee80211com *ic, struct ieee80211_
> >   cmd.key_offset = 0;
> >   cmd.sta_id = IWM_STATION_ID;
> >  
> > - return iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> > -    sizeof(cmd), &cmd);
> > + /* Allow for software CCMP encryption/decryption fallback. */
> > + err = ieee80211_set_key(ic, ni, k);
> > + if (!err) {
> > + err = iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC,
> > +    sizeof(cmd), &cmd);
> > + if (!err)
> > + sc->sc_flags |= IWM_FLAG_CCMP_KEY_SENT;
> > + }
> > + return err;
> >  }
> >  
> >  void
> > @@ -6135,6 +6154,10 @@ iwm_delete_key(struct ieee80211com *ic, struct ieee802
> >   cmd.sta_id = IWM_STATION_ID;
> >  
> >   iwm_send_cmd_pdu(sc, IWM_ADD_STA_KEY, IWM_CMD_ASYNC, sizeof(cmd), &cmd);
> > + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
> > +
> > + /* Delete software fallback CCMP key. */
> > +        ieee80211_delete_key(ic, ni, k);
> >  }
> >  
> >  void
> > @@ -6846,6 +6869,7 @@ iwm_stop(struct ifnet *ifp)
> >   sc->sc_flags &= ~IWM_FLAG_TE_ACTIVE;
> >   sc->sc_flags &= ~IWM_FLAG_HW_ERR;
> >   sc->sc_flags &= ~IWM_FLAG_SHUTDOWN;
> > + sc->sc_flags &= ~(IWM_FLAG_CCMP_KEY_SENT | IWM_FLAG_CCMP_READY);
> >  
> >   sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
> >  
> > @@ -7331,6 +7355,12 @@ iwm_notif_intr(struct iwm_softc *sc)
> >   break;
> >  
> >   case IWM_ADD_STA_KEY:
> > + if (sc->sc_flags & IWM_FLAG_CCMP_KEY_SENT) {
> > + sc->sc_flags |= IWM_FLAG_CCMP_READY;
> > + sc->sc_flags &= ~IWM_FLAG_CCMP_KEY_SENT;
> > + }
> > + break;
> > +
> >   case IWM_PHY_CONFIGURATION_CMD:
> >   case IWM_TX_ANT_CONFIGURATION_CMD:
> >   case IWM_ADD_STA:
> > blob - e6593fbc840833a36d5a792042faaa85e3ac9719
> > blob + 747616074f868d8679f9f01232dec4ce09474f93
> > --- sys/dev/pci/if_iwmvar.h
> > +++ sys/dev/pci/if_iwmvar.h
> > @@ -289,6 +289,8 @@ struct iwm_rx_ring {
> >  #define IWM_FLAG_HW_ERR 0x80 /* hardware error occurred */
> >  #define IWM_FLAG_SHUTDOWN 0x100 /* shutting down; new tasks forbidden */
> >  #define IWM_FLAG_BGSCAN 0x200 /* background scan in progress */
> > +#define IWM_FLAG_CCMP_KEY_SENT 0x400 /* CCMP key sent to firmware */
> > +#define IWM_FLAG_CCMP_READY 0x800 /* CCMP key installed in firmware */
> >  
> >  struct iwm_ucode_status {
> >   uint32_t uc_error_event_table;
> >
> >
>

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Stefan Sperling-5
On Thu, Aug 15, 2019 at 03:47:02PM +1200, [hidden email] wrote:

> On Thu, 15 Aug 2019, [hidden email] wrote:
> > > On Tue, Aug 13, 2019 at 10:47:24AM -0300, Martin Pieuchot wrote:
> > > > if the crash is because of a missing key, put one :)
> > >
> > > Yes, you've convinced me. With this patch we install the CCMP key
> > > to both firmware and net80211. Until firmware confirms that the
> > > key has been installed, we do software encrypt/decrypt.
> >
> > I agree we should handle a missing key but suggest an alternative approach
> > below.
>
> so:
>
> m0 = NULL;
> m_free(m0);
>
> isn't so useful; fixed patch follows.

Hmm... your patch is surprisingly simple. I like it :)

I am still a bit worried about iwm firmware failing to install the key,
which this patch would not handle. But that's a separate question.

Two comments inline:

> Index: net80211/ieee80211_crypto.c
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
> retrieving revision 1.74
> diff -u -p -u -p -r1.74 ieee80211_crypto.c
> --- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000 1.74
> +++ net80211/ieee80211_crypto.c 15 Aug 2019 03:44:12 -0000
> @@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
>   /* should not get there */
>   error = EINVAL;
>   }
> +
> + if (error == 0)
> + k->k_flags |= IEEE80211_KEY_SWCRYPTO;
> +
>   return error;
>  }
>  
> @@ -280,6 +284,11 @@ ieee80211_decrypt(struct ieee80211com *i
>   }
>   k = &ic->ic_nw_keys[kid];
>   }
> +
> + if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
> + goto err;
> + }

Can you also add a corresponding panic() to ieee80211_encrypt()?
This would catch drivers calling ieee80211_encrypt() on the wrong key.

> +
>   switch (k->k_cipher) {
>   case IEEE80211_CIPHER_WEP40:
>   case IEEE80211_CIPHER_WEP104:
> @@ -296,9 +305,15 @@ ieee80211_decrypt(struct ieee80211com *i
>   break;
>   default:
>   /* key not defined */
> - m_freem(m0);
> - m0 = NULL;
> + goto err;
>   }
> +
> + return m0;
> +
> +err:
> + m_freem(m0);
> + m0 = NULL;
> +
>   return m0;

The above could be simplified to:

+ return m0;
+
+err:
+ m_freem(m0);
+   return NULL;

> Index: net80211/ieee80211_crypto.h
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
> retrieving revision 1.25
> diff -u -p -u -p -r1.25 ieee80211_crypto.h
> --- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000 1.25
> +++ net80211/ieee80211_crypto.h 15 Aug 2019 03:44:12 -0000
> @@ -78,6 +78,7 @@ struct ieee80211_key {
>  #define IEEE80211_KEY_GROUP 0x00000001 /* group data key */
>  #define IEEE80211_KEY_TX 0x00000002 /* Tx+Rx */
>  #define IEEE80211_KEY_IGTK 0x00000004 /* integrity group key */
> +#define IEEE80211_KEY_SWCRYPTO 0x00000080 /* loaded for software crypto */
>  
>   u_int k_len;
>   u_int64_t k_rsc[IEEE80211_NUM_TID];

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

richard.n.procter

On Thu, 15 Aug 2019, Stefan Sperling wrote:
> On Thu, Aug 15, 2019 at 03:47:02PM +1200, [hidden email] wrote:
> > > I agree we should handle a missing key but suggest an alternative approach
> > > below.
>
> Hmm... your patch is surprisingly simple. I like it :)
>
> I am still a bit worried about iwm firmware failing to install the key,
> which this patch would not handle. But that's a separate question.

See below for updated diff. Nice idea to add a panic on encrypt.
Also I've followed the existing idiom of m_freem(m0); return NULL;

I've checked that all assignments to k_flags are to fresh keys; the new
flag is never clobbered.

The new check will be accounted against is_rx_wepfail ("input wep/wpa
packets failed").

Lightly tested with a download and ifconfig up/down.

ok?

best,
Richard.

Index: net80211/ieee80211_crypto.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
retrieving revision 1.74
diff -u -p -u -p -r1.74 ieee80211_crypto.c
--- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000 1.74
+++ net80211/ieee80211_crypto.c 16 Aug 2019 09:50:47 -0000
@@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
  /* should not get there */
  error = EINVAL;
  }
+
+ if (error == 0)
+ k->k_flags |= IEEE80211_KEY_SWCRYPTO;
+
  return error;
 }
 
@@ -209,6 +213,9 @@ struct mbuf *
 ieee80211_encrypt(struct ieee80211com *ic, struct mbuf *m0,
     struct ieee80211_key *k)
 {
+ if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0)
+ panic("%s: unset key %d", __func__, k->k_id);
+
  switch (k->k_cipher) {
  case IEEE80211_CIPHER_WEP40:
  case IEEE80211_CIPHER_WEP104:
@@ -280,6 +287,12 @@ ieee80211_decrypt(struct ieee80211com *i
  }
  k = &ic->ic_nw_keys[kid];
  }
+
+ if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
+ m_free(m0);
+ return NULL;
+ }
+
  switch (k->k_cipher) {
  case IEEE80211_CIPHER_WEP40:
  case IEEE80211_CIPHER_WEP104:
Index: net80211/ieee80211_crypto.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 ieee80211_crypto.h
--- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000 1.25
+++ net80211/ieee80211_crypto.h 16 Aug 2019 09:50:47 -0000
@@ -78,6 +78,7 @@ struct ieee80211_key {
 #define IEEE80211_KEY_GROUP 0x00000001 /* group data key */
 #define IEEE80211_KEY_TX 0x00000002 /* Tx+Rx */
 #define IEEE80211_KEY_IGTK 0x00000004 /* integrity group key */
+#define IEEE80211_KEY_SWCRYPTO 0x00000080 /* loaded for software crypto */
 
  u_int k_len;
  u_int64_t k_rsc[IEEE80211_NUM_TID];

Reply | Threaded
Open this post in threaded view
|

Re: iwm(4): fix ccmp decrypt edge cases

Stefan Sperling-5
On Fri, Aug 16, 2019 at 10:11:55PM +1200, [hidden email] wrote:

> See below for updated diff. Nice idea to add a panic on encrypt.
> Also I've followed the existing idiom of m_freem(m0); return NULL;
>
> I've checked that all assignments to k_flags are to fresh keys; the new
> flag is never clobbered.
>
> The new check will be accounted against is_rx_wepfail ("input wep/wpa
> packets failed").
>
> Lightly tested with a download and ifconfig up/down.
>
> ok?

Yes, ok.

I would suggest to change the panic message to say something like
"%s: key not loaded for software crypto", but it's no big deal.

Thanks!

>
> best,
> Richard.
>
> Index: net80211/ieee80211_crypto.c
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_crypto.c,v
> retrieving revision 1.74
> diff -u -p -u -p -r1.74 ieee80211_crypto.c
> --- net80211/ieee80211_crypto.c 24 Sep 2018 20:14:59 -0000 1.74
> +++ net80211/ieee80211_crypto.c 16 Aug 2019 09:50:47 -0000
> @@ -157,6 +157,10 @@ ieee80211_set_key(struct ieee80211com *i
>   /* should not get there */
>   error = EINVAL;
>   }
> +
> + if (error == 0)
> + k->k_flags |= IEEE80211_KEY_SWCRYPTO;
> +
>   return error;
>  }
>  
> @@ -209,6 +213,9 @@ struct mbuf *
>  ieee80211_encrypt(struct ieee80211com *ic, struct mbuf *m0,
>      struct ieee80211_key *k)
>  {
> + if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0)
> + panic("%s: unset key %d", __func__, k->k_id);
> +
>   switch (k->k_cipher) {
>   case IEEE80211_CIPHER_WEP40:
>   case IEEE80211_CIPHER_WEP104:
> @@ -280,6 +287,12 @@ ieee80211_decrypt(struct ieee80211com *i
>   }
>   k = &ic->ic_nw_keys[kid];
>   }
> +
> + if ((k->k_flags & IEEE80211_KEY_SWCRYPTO) == 0) {
> + m_free(m0);
> + return NULL;
> + }
> +
>   switch (k->k_cipher) {
>   case IEEE80211_CIPHER_WEP40:
>   case IEEE80211_CIPHER_WEP104:
> Index: net80211/ieee80211_crypto.h
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_crypto.h,v
> retrieving revision 1.25
> diff -u -p -u -p -r1.25 ieee80211_crypto.h
> --- net80211/ieee80211_crypto.h 18 Aug 2017 17:30:12 -0000 1.25
> +++ net80211/ieee80211_crypto.h 16 Aug 2019 09:50:47 -0000
> @@ -78,6 +78,7 @@ struct ieee80211_key {
>  #define IEEE80211_KEY_GROUP 0x00000001 /* group data key */
>  #define IEEE80211_KEY_TX 0x00000002 /* Tx+Rx */
>  #define IEEE80211_KEY_IGTK 0x00000004 /* integrity group key */
> +#define IEEE80211_KEY_SWCRYPTO 0x00000080 /* loaded for software crypto */
>  
>   u_int k_len;
>   u_int64_t k_rsc[IEEE80211_NUM_TID];
>