syzbot
WARNING in rfkill_dev_uevent
Status:
upstream: reported C repro on 2026/10/31 08:52
Subsystems:
wireless
Labels:
prio:low
[Documentation on labels]
Reported-by: syzbot+56f5119a6b206041a6b7@syzkaller.appspotmail.com
First crash: 4d03h, last: 1d18h
⨠AI-generated root cause summary:
In mac80211_hwsim and cfg80211, the netlink attribute HWSIM_ATTR_RADIO_NAME is accepted without a length limit, and cfg80211 does not bound requested_name when setting the device and rfkill names. When a user creates a virtual radio with an excessively long name via netlink, rfkill registration triggers a uevent where RFKILL_NAME exceeds the fixed 2048-byte UEVENT_BUFFER_SIZE in add_uevent_var(), triggering a WARN. In production kernels, add_uevent_var() safely returns -ENOMEM and drops the uevent without memory corruption or system crashes.
▶
▼
⨠Full AI root cause analysis
Root Cause Analysis
1. Components and Files Involved
drivers/net/wireless/virtual/mac80211_hwsim_main.c: In hwsim_genl_policy, [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING } is defined without .len bounds. In hwsim_new_radio_nl(), the attribute is duplicated with kstrndup() without validating or capping its length before passing it to mac80211_hwsim_new_radio().
net/wireless/core.c: wiphy_new_nm() accepts requested_name without length restriction, assigns it as the device name via dev_set_name(&rdev->wiphy.dev, "%s", requested_name), and subsequently forwards dev_name(&rdev->wiphy.dev) to rfkill_alloc().
net/rfkill/core.c: rfkill_alloc() stores the wiphy name in rfkill->name. When rfkill_register() is invoked during wiphy_register(), device_add() triggers a kobject_uevent() with action KOBJ_ADD.
lib/kobject_uevent.c: During the KOBJ_ADD event dispatch, rfkill_dev_uevent() formats environment variables including "RFKILL_NAME=%s" into the fixed-size 2048-byte buffer (env->buf of struct kobj_uevent_env). add_uevent_var() checks if the formatted variable exceeds available buffer space.
2. Trigger Mechanism & Lifecycle Violation
- A userspace process sends a Generic Netlink command
HWSIM_CMD_NEW_RADIO with an oversized HWSIM_ATTR_RADIO_NAME attribute (several kilobytes long).
hwsim_new_radio_nl() accepts the name and calls mac80211_hwsim_new_radio(), which calls ieee80211_alloc_hw_nm() -> wiphy_new_nm().
- In
net/mac80211/main.c, ieee80211_register_hw() invokes alloc_ordered_workqueue("%s", 0, wiphy_name(local->hw.wiphy)) which emits:
workqueue: name exceeds WQ_NAME_LEN. Truncating to: ...
ieee80211_register_hw() then calls wiphy_register(), which calls rfkill_register(rdev->wiphy.rfkill) -> device_add(&rfkill->dev).
device_add() calls kobject_uevent(&dev->kobj, KOBJ_ADD) -> kobject_uevent_env() -> rfkill_dev_uevent().
rfkill_dev_uevent() calls add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name).
- Because
rfkill->name exceeds the remaining capacity of the 2048-byte UEVENT_BUFFER_SIZE, vsnprintf() returns a length greater than or equal to sizeof(env->buf) - env->buflen.
add_uevent_var() detects this buffer overflow condition, hits line 688 (WARN(1, KERN_ERR "add_uevent_var: buffer size too small\n");), and returns -ENOMEM.
3. Runtime Consequences in Production Kernels
- Memory Corruption (
false): add_uevent_var() bounds formatting using vsnprintf() against sizeof(env->buf) - env->buflen and checks for truncation before advancing env->buflen or updating pointers. There is no out-of-bounds write, use-after-free, or corrupted memory state.
- Information Leak (
"none"): No uninitialized or kernel memory is leaked to userspace.
- Denial of Service (
false): In a production kernel without CONFIG_PANIC_ON_WARN, the warning does not halt execution. add_uevent_var() returns -ENOMEM, which causes kobject_uevent_env() to discard the uevent buffer and cleanly return -ENOMEM. The return code of kobject_uevent() is ignored in device_add(), meaning registration finishes normally and no hang, panic, or unhandled leak occurs.
- Networking Candidate (
true): The bug is triggered via netlink into mac80211_hwsim, cfg80211, and rfkill.
- KVM Candidate (
false): Virtualization / KVM subsystems are not involved.
Sample crash report:
workqueue
workqueue: name exceeds WQ_NAME_LEN. Truncating to: ’„śeč45µ8) r1 += -8
15: .
------------[ cut here ]------------
add_uevent_var: buffer size too small
WARNING: lib/kobject_uevent.c:688 at add_uevent_var+0x2db/0x460 lib/kobject_uevent.c:688, CPU#0: syz-executor353/5646
Modules linked in:
CPU: 0 UID: 0 PID: 5646 Comm: syz-executor353 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/07/2026
RIP: 0010:add_uevent_var+0x2db/0x460 lib/kobject_uevent.c:688
Code: 48 8b 44 24 40 42 0f b6 04 38 84 c0 48 8b 5c 24 18 0f 85 73 01 00 00 44 01 33 31 c0 eb 20 e8 0c 1c dd f5 48 8d 3d 35 df a3 05 <67> 48 0f b9 3a b8 f4 ff ff ff 49 bf 00 00 00 00 00 fc ff df 66 43
RSP: 0018:ffffc90003996a00 EFLAGS: 00010293
RAX: ffffffff8beb4a14 RBX: 1ffff1100efa0443 RCX: ffff88807f68be80
RDX: 0000000000000000 RSI: 0000000000001770 RDI: ffffffff918f2950
RBP: ffffc90003996b38 R08: ffff88807f68be80 R09: 0000000000000008
R10: 0000000000000007 R11: 0000000000000000 R12: 0000000000001770
R13: 1ffff92000732d50 R14: 000000000000079e R15: 0000000000000062
FS: 000055556e425400(0000) GS:ffff888123a6b000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000000069e000 CR3: 00000000713cc000 CR4: 00000000003526f0
Call Trace:
<TASK>
rfkill_dev_uevent+0x2f/0x1f0 net/rfkill/core.c:875
dev_uevent+0x4ab/0x870 drivers/base/core.c:2774
kobject_uevent_env+0x475/0x9e0 lib/kobject_uevent.c:576
device_add+0x544/0xb80 drivers/base/core.c:3742
rfkill_register+0x170/0x9b0 net/rfkill/core.c:1100
wiphy_register+0x2a5f/0x3290 net/wireless/core.c:1310
ieee80211_register_hw+0x3d72/0x4b30 net/mac80211/main.c:1634
mac80211_hwsim_new_radio+0x32f1/0x5990 drivers/net/wireless/virtual/mac80211_hwsim_main.c:6186
hwsim_new_radio_nl+0xd8b/0xf90 drivers/net/wireless/virtual/mac80211_hwsim_main.c:7062
genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
genl_family_rcv_msg net/netlink/genetlink.c:1194 [inline]
genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2580
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline]
netlink_unicast+0x8ef/0xa80 net/netlink/af_netlink.c:1361
netlink_sendmsg+0x7f0/0xb20 net/netlink/af_netlink.c:1920
sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800
__sock_sendmsg net/socket.c:818 [inline]
____sys_sendmsg+0x54e/0x850 net/socket.c:2715
___sys_sendmsg+0x2a5/0x360 net/socket.c:2769
__sys_sendmsg net/socket.c:2801 [inline]
__do_sys_sendmsg net/socket.c:2806 [inline]
__se_sys_sendmsg net/socket.c:2804 [inline]
__x64_sys_sendmsg+0x1b1/0x290 net/socket.c:2804
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fbc181e2649
Code: c0 79 93 eb d5 48 8d 7c 1d 00 eb 99 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 d8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffc9f9d5c88 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fbc181e2649
RDX: 0000000000000084 RSI: 0000200000000a00 RDI: 0000000000000004
RBP: 0000000000000000 R08: 0000000000000006 R09: 0000000000000006
R10: 0000000000000006 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 00007fbc18275c40 R15: 0000000000000002
</TASK>
----------------
Code disassembly (best guess):
0: 48 8b 44 24 40 mov 0x40(%rsp),%rax
5: 42 0f b6 04 38 movzbl (%rax,%r15,1),%eax
a: 84 c0 test %al,%al
c: 48 8b 5c 24 18 mov 0x18(%rsp),%rbx
11: 0f 85 73 01 00 00 jne 0x18a
17: 44 01 33 add %r14d,(%rbx)
1a: 31 c0 xor %eax,%eax
1c: eb 20 jmp 0x3e
1e: e8 0c 1c dd f5 call 0xf5dd1c2f
23: 48 8d 3d 35 df a3 05 lea 0x5a3df35(%rip),%rdi # 0x5a3df5f
* 2a: 67 48 0f b9 3a ud1 (%edx),%rdi <-- trapping instruction
2f: b8 f4 ff ff ff mov $0xfffffff4,%eax
34: 49 bf 00 00 00 00 00 movabs $0xdffffc0000000000,%r15
3b: fc ff df
3e: 66 data16
3f: 43 rex.XB
* Struck through repros no longer work on HEAD.