Do not deliver data frames to mac80211 unless the device is fully started. After carl9170_op_stop() the driver state drops to IDLE, but the USB RX path can still receive frames from the hardware. Without this gate, ieee80211_rx() may reference station data that sta_info_destroy_part2() is concurrently freeing during interface teardown, causing a use-after-free kernel panic. The race occurs when ieee80211_handle_reconfig_failure() clears IN_DRIVER flags without stopping the hardware: cfg80211 then tears down interfaces via ieee80211_do_stop() which calls sta_info_flush() while the driver's RX path still delivers frames. This was observed when carl9170 firmware deadlocks during a restart attempt and ieee80211_reconfig() fails at drv_add_interface(). The gate is placed in carl9170_rx_untie_data() just before the ieee80211_rx() call, not in the USB layer, because firmware command responses (including CARL9170_RSP_BOOT needed for firmware upload) must still flow through the shared RX path via carl9170_handle_command_response() which returns before reaching this point. Signed-off-by: Masi Osmani --- drivers/net/wireless/ath/carl9170/rx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -683,6 +683,14 @@ carl9170_ba_check(ar, buf, len); + /* + * Do not deliver data frames to mac80211 unless the device is + * fully started. After carl9170_op_stop() the state drops to + * IDLE, preventing a use-after-free when sta_info_destroy_part2() + * races with ieee80211_rx() during interface teardown. + */ + if (!IS_STARTED(ar)) + return 0; skb = carl9170_rx_copy_data(buf, len); if (!skb) return -ENOMEM;