[PATCH] wifi: mac80211: fix static key race condition in aql_enable_write()

From: Josh Poimboeuf

Date: Fri Mar 06 2026 - 15:05:27 EST


If multiple tasks are writing to the 'aql_enable' debugfs file, it may
incorrectly call static_branch_dec() for an already disabled static key,
resulting in the following warning:

val == 0
WARNING: kernel/jump_label.c:311 at __static_key_slow_dec_cpuslocked.part.0+0x107/0x120 kernel/jump_label.c:311, CPU#0: syz.1.3155/20288
...
Call Trace:
<TASK>
__static_key_slow_dec_cpuslocked kernel/jump_label.c:297 [inline]
__static_key_slow_dec kernel/jump_label.c:321 [inline]
static_key_slow_dec+0x7c/0xc0 kernel/jump_label.c:336
aql_enable_write+0x2b2/0x310 net/mac80211/debugfs.c:343
short_proxy_write+0x133/0x1a0 fs/debugfs/file.c:383
vfs_write+0x2aa/0x1070 fs/read_write.c:684
ksys_pwrite64 fs/read_write.c:793 [inline]
__do_sys_pwrite64 fs/read_write.c:801 [inline]
__se_sys_pwrite64 fs/read_write.c:798 [inline]
__x64_sys_pwrite64+0x1eb/0x250 fs/read_write.c:798
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xc9/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fix it by using the atomic static_branch_{enable,disable}() interfaces.

Fixes: e908435e402a ("mac80211: introduce aql_enable node in debugfs")
Reported-by: syzbot+feb9ce36a95341bb47a4@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
net/mac80211/debugfs.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index d02f07368c51..687a66cd4943 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -320,7 +320,6 @@ static ssize_t aql_enable_read(struct file *file, char __user *user_buf,
static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
- bool aql_disabled = static_key_false(&aql_disable.key);
char buf[3];
size_t len;

@@ -335,15 +334,12 @@ static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
if (len > 0 && buf[len - 1] == '\n')
buf[len - 1] = 0;

- if (buf[0] == '0' && buf[1] == '\0') {
- if (!aql_disabled)
- static_branch_inc(&aql_disable);
- } else if (buf[0] == '1' && buf[1] == '\0') {
- if (aql_disabled)
- static_branch_dec(&aql_disable);
- } else {
+ if (buf[0] == '0' && buf[1] == '\0')
+ static_branch_enable(&aql_disable);
+ else if (buf[0] == '1' && buf[1] == '\0')
+ static_branch_disable(&aql_disable);
+ else
return -EINVAL;
- }

return count;
}
--
2.53.0