I believe I've just pinpointed a rare crash that I've been searching for, that seems to occur when using 802.11X authentication.
If I'm correct, this occurs in the mac80211 library in the rx.c file, ieee80211_rx_8023( ) -> ieee80211_deliver_skb_to_local_stack( )
The crash happens on the last line here, I believe where ehdr is dereferenced, as the other variables have already been dereferenced above this point without crashing. But the code comment is interesting in that it states it is overwriting the mac address with the bridge address when sending EAPOL frames.
My first theory is the ehdr pointer can be null if the STA disconnects at precisely the right moment immediately after connecting, while still in the state of 802.11X authentication.
I found that ehdr is almost always null unless skb->protocol == sdata->control_port_protocol, then it's not supposed to be null. Except when it is, perhaps due to a race condition?
I've added a sanity check to see where that leads.
struct ethhdr *ehdr = (void *)skb_mac_header(skb);
memset(skb->cb, 0, sizeof(skb->cb));
/*
* 802.1X over 802.11 requires that the authenticator address
* be used for EAPOL frames. However, 802.1X allows the use of
* the PAE group address instead. If the interface is part of
* a bridge and we pass the frame with the PAE group address,
* then the bridge will forward it to the network (even if the
* client was not associated yet), which isn't supposed to
* happen.
* To avoid that, rewrite the destination address to our own
* address, so that the authenticator (e.g. hostapd) will see
* the frame, but bridge won't forward it anywhere else. Note
* that due to earlier filtering, the only other address can
* be the PAE group address, unless the hardware allowed them
* through in 802.3 offloaded mode.
*/
if (unlikely(skb->protocol == sdata->control_port_protocol &&
ehdr && <-- I added this extra check
!ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
Here's the original stacktrace, which is misleading because it looks like the code crashes in eth_type_trans, but if you use gdb to dereference that address ends up in ieee80211_deliver_skb_to_local_stack
<1>[43203.019950] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
<7>[43203.159413] Hardware name: Linksys E8450 (UBI) (DT)
<7>[43203.171241] pc : eth_type_trans+0x44/0x190
<7>[43203.175342] lr : ieee80211_sta_ps_transition+0x12a0/0x3090 [mac80211]
<7>[43203.181833] sp : ffffffc008ce3bf0
<7>[43203.185139] x29: ffffffc008ce3bf0 x28: 0000000000000000 x27: 0000000000000000
<7>[43203.192273] x26: ffffff8002863820 x25: ffffffc008ce3d88 x24: ffffff80029a284a
<7>[43203.199406] x23: ffffffc008ce3d30 x22: ffffff80027b4aa8 x21: ffffff8006111980
<7>[43203.206539] x20: ffffffc008ce3c68 x19: ffffff8005a08000 x18: 0000000000000000
<7>[43203.213672] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
<7>[43203.220804] x14: 0000000000000001 x13: cbcccbcc0f000100 x12: 0000004040200e9a
<7>[43203.227937] x11: 143c08bc0004eb08 x10: ffffff80027b4735 x9 : ffffff8005a08050
<7>[43203.235070] x8 : ffffff80029a284a x7 : 000000000008beae x6 : ffffff8005a08028
<7>[43203.242204] x5 : 6c416a8400000000 x4 : 0000000000000000 x3 : b07cc422846a416c
<7>[43203.249336] x2 : ffffff80029a284a x1 : ffffff8006b88000 x0 : ffffff8005a08000
<7>[43203.256469] Call trace:
<7>[43203.258908] eth_type_trans+0x44/0x190
<7>[43203.262653] ieee80211_rx_list+0x260/0x28c [mac80211]
<7>[43203.267738] mt76_rx_complete+0xdc/0x158 [mt76]
<7>[43203.272274] mt76_rx_poll_complete+0x5c/0x134 [mt76]
<7>[43203.277242] mt76_dma_rx_poll+0x84/0xe4 [mt76]
<7>[43203.281690] __napi_poll.constprop.0+0x6c/0x154
<7>[43203.286217] napi_threaded_poll+0x7c/0xac
<7>[43203.290221] kthread+0xcc/0xdc
<7>[43203.293271] ret_from_fork+0x10/0x20
<0>[43203.296847] Code: 91003843 f9006403 f9419024 f9400043 (f9400084)