[PATCH AUTOSEL 6.19-5.10] wifi: iwlegacy: add missing mutex protection in il4965_store_tx_power()

Sasha Levin
2026-02-14T21:25:14Z

From: Ziyi Guo <n7l8m4@u.northwestern.edu>

[ Upstream commit e31fa691d0b1c07b6094a6cf0cce894192c462b3 ]

il4965_store_tx_power() calls il_set_tx_power() without holding il->mutex.
However, il_set_tx_power() has lockdep_assert_held(&il->mutex) indicating
that callers must hold this lock.

All other callers of il_set_tx_power() properly acquire the mutex:
- il_bg_scan_completed() acquires mutex at common.c:1683
- il_mac_config() acquires mutex at common.c:5006
- il3945_commit_rxon() and il4965_commit_rxon() are called via work
queues that hold the mutex (like il4965_bg_alive_start)

Add mutex_lock()/mutex_unlock() around the il_set_tx_power() call in
the sysfs store function to fix the missing lock protection.

Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
Link: https://patch.msgid.link/20260125194039.1196488-1-n7l8m4@u.northwestern.edu
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Analysis

### Commit Message Analysis

The commit message is clear and well-documented. It identifies a
specific bug: `il4965_store_tx_power()` calls `il_set_tx_power()`
without holding `il->mutex`, but `il_set_tx_power()` requires this lock
(enforced via `lockdep_assert_held`). The message also documents that
all other callers properly acquire the mutex, making this the only call
site that's missing the protection.

### Code Change Analysis

The fix is minimal and surgical — exactly 2 lines added:
```c
mutex_lock(&il->mutex);
ret = il_set_tx_power(il, val, false);
mutex_unlock(&il->mutex);
```

This is a sysfs store handler (`il4965_store_tx_power`), which can be
triggered from userspace by writing to the `tx_power` sysfs attribute.
Without the mutex:

1. **lockdep warning**: The `lockdep_assert_held(&il->mutex)` in
`il_set_tx_power()` will fire a warning/splat every time a user
writes to this sysfs file.
2. **Race condition**: `il_set_tx_power()` modifies driver state that is
also accessed by other code paths (scan completion, mac80211 config,
rxon commits) which all hold the mutex. Without the mutex, concurrent
access from sysfs and these other paths could corrupt driver state,
potentially leading to firmware errors, crashes, or undefined
behavior.

### Classification

This is a **synchronization bug fix** — missing mutex protection around
a function that requires it. It falls squarely into the "race condition"
and "missing locking" categories of stable-worthy fixes.

### Scope and Risk Assessment

- **Lines changed**: 2 (adding mutex_lock/unlock)
- **Files touched**: 1
- **Risk**: Extremely low. Adding mutex protection around a single
function call in a sysfs handler is about as safe as it gets. The
mutex is already used throughout the driver, and all other callers of
`il_set_tx_power()` already hold it. There's no risk of deadlock since
this is a sysfs store handler (not called from any context that
already holds the mutex).
- **Subsystem**: iwlegacy wireless driver — a mature, legacy Intel WiFi
driver

### User Impact

- Any user with iwlegacy hardware who writes to the `tx_power` sysfs
attribute will trigger a lockdep splat (if lockdep is enabled) and
potentially experience a race condition
- The race could lead to corrupted driver state, firmware errors, or
crashes
- The sysfs interface is a user-facing control, so this is a realistic
trigger path

### Stability Indicators

- **Acked-by**: Stanislaw Gruszka (iwlegacy maintainer) — strong signal
- **Committed by**: Johannes Berg (Intel wireless maintainer) — strong
signal
- The fix pattern (adding mutex around a call that requires it) is well-
understood and obviously correct

### Dependency Check

This commit is completely self-contained. It adds standard
mutex_lock/unlock calls around an existing function call. No other
patches are needed. The iwlegacy driver and this specific code path have
existed in stable kernels for a very long time.

### Conclusion

This is a textbook stable backport candidate:
- **Obviously correct**: The function requires the mutex (has lockdep
assertion), all other callers hold it, this one doesn't — the fix adds
the missing lock
- **Fixes a real bug**: Missing synchronization causing potential races
and lockdep warnings
- **Small and contained**: 2 lines added, 1 file changed
- **No new features**: Pure bug fix
- **Low risk**: Standard locking pattern, well-tested by maintainer
review
- **Acked by subsystem maintainer**: Confirms the fix is appropriate

**YES**

drivers/net/wireless/intel/iwlegacy/4965-mac.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 3588dec75ebdd..57fa866efd9f8 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -4606,7 +4606,9 @@ il4965_store_tx_power(struct device *d, struct device_attribute *attr,
if (ret)
IL_INFO("%s is not in decimal form.\n", buf);
else {
+ mutex_lock(&il->mutex);
ret = il_set_tx_power(il, val, false);
+ mutex_unlock(&il->mutex);
if (ret)
IL_ERR("failed setting tx power (0x%08x).\n", ret);
else
--
2.51.0