All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
@ 2026-03-12 14:30 Masi Osmani
  2026-03-13  7:08 ` Johannes Berg
  0 siblings, 1 reply; 6+ messages in thread
From: Masi Osmani @ 2026-03-12 14:30 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Christian Lamparter, Masi Osmani

When ieee80211_handle_reconfig_failure() is called after a failed HW
reconfiguration, it clears IEEE80211_SDATA_IN_DRIVER flags on all
interfaces but does not stop the hardware. This creates a race window:
cfg80211_shutdown_all_interfaces() subsequently calls ieee80211_do_stop()
which runs sta_info_flush() to destroy stations, while the driver's RX
path may still be delivering frames that reference station data being
freed.

This race was observed with the carl9170 driver: when firmware
deadlocks during a restart attempt, ieee80211_reconfig() fails
at drv_add_interface(). The subsequent interface teardown triggers
sta_info_destroy_part2() while the USB RX tasklet still calls
ieee80211_rx_napi(), causing a use-after-free kernel panic.

The fix stops the hardware in ieee80211_handle_reconfig_failure() before
clearing IN_DRIVER state, ensuring no driver can deliver RX frames once
the teardown begins. The drv_stop() call is guarded by local->started
since some call sites reach this function after drv_start() has already
failed (where the hardware was never started).

Signed-off-by: Masi Osmani <mas-i@hotmail.de>
---
 net/mac80211/util.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1614,6 +1614,18 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)

 	local->resuming = false;
 	local->suspended = false;
+
+	/*
+	 * Stop the hardware before clearing IN_DRIVER state. Without this,
+	 * cfg80211_shutdown_all_interfaces() tears down stations via
+	 * sta_info_flush() while the driver's RX path may still deliver
+	 * frames referencing station data being freed, causing use-after-free.
+	 * Guard with local->started since this function can be reached when
+	 * drv_start() itself failed (hardware never started).
+	 */
+	if (local->started)
+		drv_stop(local, false);
+
 	local->in_reconfig = false;
 	local->reconfig_failure = true;


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
  2026-03-12 14:30 Masi Osmani
@ 2026-03-13  7:08 ` Johannes Berg
  0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2026-03-13  7:08 UTC (permalink / raw)
  To: Masi Osmani; +Cc: linux-wireless, Christian Lamparter

On Thu, 2026-03-12 at 15:30 +0100, Masi Osmani wrote:
> When ieee80211_handle_reconfig_failure() is called after a failed HW
> reconfiguration, it clears IEEE80211_SDATA_IN_DRIVER flags on all
> interfaces but does not stop the hardware.

Yeah, but ieee80211_do_stop() via cfg80211_shutdown_all_interfaces()
should call it later? Now you're calling it twice, which seems odd?


> This creates a race window:
> cfg80211_shutdown_all_interfaces() subsequently calls ieee80211_do_stop()
> which runs sta_info_flush() to destroy stations, while the driver's RX
> path may still be delivering frames that reference station data being
> freed.

How is that possible?

> This race was observed with the carl9170 driver: when firmware
> deadlocks during a restart attempt, ieee80211_reconfig() fails
> at drv_add_interface(). The subsequent interface teardown triggers
> sta_info_destroy_part2() while the USB RX tasklet still calls
> ieee80211_rx_napi(), causing a use-after-free kernel panic.

That doesn't make sense, station lookups should be protected, either by
locking or by RCU; there's synchronize_net() in __sta_info_flush() for
that.

Can you please report the actual bug?

> The fix stops the hardware in ieee80211_handle_reconfig_failure() before
> clearing IN_DRIVER state, ensuring no driver can deliver RX frames once
> the teardown begins.

I don't think that really is a good fix, and if it that crash can happen
here then it can likely also happen during normal teardown, and we
should fix it differently.

johannes

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
@ 2026-03-31 10:00 Masi Osmani
  2026-04-07 10:53 ` Johannes Berg
  0 siblings, 1 reply; 6+ messages in thread
From: Masi Osmani @ 2026-03-31 10:00 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Christian Lamparter

This patch fixes a hard system freeze (requires power cycle) observed
when unplugging an AR9170 USB WiFi adapter while under traffic, or when
any driver that uses ieee80211_reconfig() encounters a firmware deadlock.

The race: ieee80211_handle_reconfig_failure() tears down station tables
while USB RX tasklets can still deliver frames that reference them
(use-after-free). Calling drv_stop() before clearing IN_DRIVER state
closes the race at the root cause.

Tested-by: Masi Osmani <mas-i@hotmail.de>  [AR9170 USB, Linux 6.18]

---

When ieee80211_handle_reconfig_failure() is called after a failed HW
reconfiguration, it clears IEEE80211_SDATA_IN_DRIVER flags on all
interfaces but does not stop the hardware. This creates a race window:
cfg80211_shutdown_all_interfaces() subsequently calls ieee80211_do_stop()
which runs sta_info_flush() to destroy stations, while the driver's RX
path may still be delivering frames that reference station data being
freed.

This race was observed with the carl9170 driver: when firmware
deadlocks during a restart attempt, ieee80211_reconfig() fails
at drv_add_interface(). The subsequent interface teardown triggers
sta_info_destroy_part2() while the USB RX tasklet still calls
ieee80211_rx_napi(), causing a use-after-free kernel panic.

The fix stops the hardware in ieee80211_handle_reconfig_failure() before
clearing IN_DRIVER state, ensuring no driver can deliver RX frames once
the teardown begins. The drv_stop() call is guarded by local->started
since some call sites reach this function after drv_start() has already
failed (where the hardware was never started).

Signed-off-by: Masi Osmani <mas-i@hotmail.de>
---
 net/mac80211/util.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1614,6 +1614,18 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)

 	local->resuming = false;
 	local->suspended = false;
+
+	/*
+	 * Stop the hardware before clearing IN_DRIVER state. Without this,
+	 * cfg80211_shutdown_all_interfaces() tears down stations via
+	 * sta_info_flush() while the driver's RX path may still deliver
+	 * frames referencing station data being freed, causing use-after-free.
+	 * Guard with local->started since this function can be reached when
+	 * drv_start() itself failed (hardware never started).
+	 */
+	if (local->started)
+		drv_stop(local, false);
+
 	local->in_reconfig = false;
 	local->reconfig_failure = true;

--
Regards,
Masi Osmani

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
@ 2026-03-31 18:58 Masi Osmani
  0 siblings, 0 replies; 6+ messages in thread
From: Masi Osmani @ 2026-03-31 18:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Christian Lamparter

From: Masi Osmani <mas-i@hotmail.de>
Date: Thu, 12 Mar 2026 02:00:00 +0100

When ieee80211_handle_reconfig_failure() is called after a failed HW
reconfiguration, it clears IEEE80211_SDATA_IN_DRIVER flags on all
interfaces but does not stop the hardware. This creates a race window:
cfg80211_shutdown_all_interfaces() subsequently calls ieee80211_do_stop()
which runs sta_info_flush() to destroy stations, while the driver's RX
path may still be delivering frames that reference station data being
freed.

This race was observed with the carl9170 driver: when firmware
deadlocks during a restart attempt, ieee80211_reconfig() fails
at drv_add_interface(). The subsequent interface teardown triggers
sta_info_destroy_part2() while the USB RX tasklet still calls
ieee80211_rx_napi(), causing a use-after-free kernel panic (hard
system freeze, power cycle required — no oops saved to disk).

The race condition:
  1. carl9170 firmware deadlocks → ieee80211_reconfig() called
  2. carl9170_op_start() returns -ETIMEDOUT
  3. ieee80211_handle_reconfig_failure() clears IN_DRIVER flags
     but does NOT call drv_stop() → hardware still running
  4. cfg80211_shutdown_all_interfaces() → sta_info_flush() frees
     station data
  5. USB RX tasklet delivers frames via ieee80211_rx_napi() →
     use-after-free → hard freeze

The fix stops the hardware in ieee80211_handle_reconfig_failure() before
clearing IN_DRIVER state, ensuring no driver can deliver RX frames once
the teardown begins. The drv_stop() call is guarded by local->started
since some call sites reach this function after drv_start() has already
failed (where the hardware was never started).

Christian Lamparter (carl9170 original author) reviewed the carl9170-side
companion patches and confirmed: "If what you write is true for an
up-to-date kernel, this needs to be addressed in mac80211."

Signed-off-by: Masi Osmani <mas-i@hotmail.de>
---
 net/mac80211/util.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1614,6 +1614,18 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)

 	local->resuming = false;
 	local->suspended = false;
+
+	/*
+	 * Stop the hardware before clearing IN_DRIVER state. Without this,
+	 * cfg80211_shutdown_all_interfaces() tears down stations via
+	 * sta_info_flush() while the driver's RX path may still deliver
+	 * frames referencing station data being freed, causing use-after-free.
+	 * Guard with local->started since this function can be reached when
+	 * drv_start() itself failed (hardware never started).
+	 */
+	if (local->started)
+		drv_stop(local, false);
+
 	local->in_reconfig = false;
 	local->reconfig_failure = true;

-- 
2.51.0

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
@ 2026-04-01 16:51 kernel test robot
  0 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-04-01 16:51 UTC (permalink / raw)
  To: oe-kbuild

:::::: 
:::::: Manual check reason: "high confidence checkpatch report"
:::::: 

BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <GVYP280MB151883A5BB2910EE6439DE2F9453A@GVYP280MB1518.SWEP280.PROD.OUTLOOK.COM>
References: <GVYP280MB151883A5BB2910EE6439DE2F9453A@GVYP280MB1518.SWEP280.PROD.OUTLOOK.COM>
TO: Masi Osmani <mas-i@hotmail.de>
TO: Johannes Berg <johannes@sipsolutions.net>

Hi Masi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on wireless-next/main]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Masi-Osmani/mac80211-stop-hardware-before-clearing-driver-state-on-reconfig-failure/20260401-123427
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link:    https://lore.kernel.org/r/GVYP280MB151883A5BB2910EE6439DE2F9453A%40GVYP280MB1518.SWEP280.PROD.OUTLOOK.COM
patch subject: [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
:::::: branch date: 12 hours ago
:::::: commit date: 12 hours ago
reproduce: (https://download.01.org/0day-ci/archive/20260401/202604011809.Cn20eaf5-lkp@intel.com/reproduce)

# many are suggestions rather than must-fix

WARNING:BAD_SIGN_OFF: Unexpected content after email: 'Masi Osmani <mas-i@hotmail.de>  [AR9170 USB, Linux 6.18]', should be: 'Masi Osmani <mas-i@hotmail.de> (AR9170 USB, Linux 6.18)'
#16: 
Tested-by: Masi Osmani <mas-i@hotmail.de>  [AR9170 USB, Linux 6.18]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure
  2026-03-31 10:00 Masi Osmani
@ 2026-04-07 10:53 ` Johannes Berg
  0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2026-04-07 10:53 UTC (permalink / raw)
  To: Masi Osmani; +Cc: linux-wireless, Christian Lamparter

On Tue, 2026-03-31 at 12:00 +0200, Masi Osmani wrote:
> This patch fixes a hard system freeze (requires power cycle) observed
> when unplugging an AR9170 USB WiFi adapter while under traffic, or when
> any driver that uses ieee80211_reconfig() encounters a firmware deadlock.
> 
> The race: ieee80211_handle_reconfig_failure() tears down station tables
> while USB RX tasklets can still deliver frames that reference them
> (use-after-free). Calling drv_stop() before clearing IN_DRIVER state
> closes the race at the root cause.

You can really stop resending this patch, I'm not taking it.

https://lore.kernel.org/linux-wireless/e7f3ba3acca1308bc0871a3892da9e15525d5038.camel@sipsolutions.net/

johannes

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-07 10:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-01 16:51 [PATCH] mac80211: stop hardware before clearing driver state on reconfig failure kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2026-03-31 18:58 Masi Osmani
2026-03-31 10:00 Masi Osmani
2026-04-07 10:53 ` Johannes Berg
2026-03-12 14:30 Masi Osmani
2026-03-13  7:08 ` Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.