WARNING in devlink_free (2)

Status: moderation: reported on 2026/11/14 10:50
Subsystems: net
Labels: prio:low
[Documentation on labels]
Reported-by: syzbot+75f25d90d774273f7282@syzkaller.appspotmail.com
First crash: 2h15m, last: 2h15m
✨ AI-generated root cause summary:

In netdevsim, switchdev eswitch mode can be enabled with zero VFs configured, allowing userspace to create devlink rate nodes via netlink. However, during device teardown or reload in nsim_dev_reload_destroy(), the cleanup call to nsim_esw_legacy_enable()β€”which invokes devl_rate_nodes_destroy()β€”is conditionally guarded by if (nsim_dev_get_vfs(nsim_dev)). When VFs were never configured (num_vfs == 0), nsim_esw_legacy_enable() is bypassed, leaving devlink_rate nodes in devlink->rate_list and triggering the WARN_ON(devlink_rates_check(devlink, NULL, NULL)) sanity check in devlink_free().

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit aa40afa831eb:

Root Cause Analysis

Involved Functions, Structs, and Files


Bug Mechanism and Lifecycle Invariant Violation

  1. Switchdev Mode Allowed With Zero VFs: When userspace configures the netdevsim eswitch mode via Netlink (DEVLINK_CMD_ESWITCH_MODE_SET with DEVLINK_ESWITCH_MODE_SWITCHDEV), nsim_devlink_eswitch_mode_set() invokes nsim_esw_switchdev_enable(). In this function:

    for (i = 0; i < nsim_dev_get_vfs(nsim_dev); i++) {
        ...
    }
    nsim_dev->esw_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
    

    If no VFs have been instantiated (nsim_dev_get_vfs(nsim_dev) == 0), the loop does not run, but nsim_dev->esw_mode is successfully set to DEVLINK_ESWITCH_MODE_SWITCHDEV.

  2. Creation of Rate Nodes: Once in switchdev mode, userspace creates one or more devlink rate nodes using DEVLINK_CMD_RATE_NEW (devlink_nl_rate_new_doit()). The driver callback nsim_rate_node_new() checks:

    if (!nsim_esw_mode_is_switchdev(nsim_dev)) {
        NL_SET_ERR_MSG_MOD(extack, "Node creation allowed only in switchdev mode.");
        return -EOPNOTSUPP;
    }
    

    Because nsim_dev->esw_mode is DEVLINK_ESWITCH_MODE_SWITCHDEV, node creation succeeds regardless of the number of VFs. An allocated struct devlink_rate object of type DEVLINK_RATE_TYPE_NODE is added to devlink->rate_list.

  3. Incomplete Teardown in nsim_dev_reload_destroy(): When the netdevsim device is removed (nsim_drv_remove()) or reloaded (nsim_dev_reload_down()), nsim_dev_reload_destroy() is called to tear down sub-components. The destruction of rate nodes is handled within nsim_esw_legacy_enable(), which calls devl_rate_nodes_destroy(devlink). However, nsim_dev_reload_destroy() guards the eswitch transition with a VF existence check:

    if (nsim_dev_get_vfs(nsim_dev)) {
        nsim_bus_dev_set_vfs(nsim_dev->nsim_bus_dev, 0);
        if (nsim_esw_mode_is_switchdev(nsim_dev))
            nsim_esw_legacy_enable(nsim_dev, NULL);
    }
    

    Because nsim_dev_get_vfs(nsim_dev) is 0, the entire block is bypassed. nsim_esw_legacy_enable() is not executed, and devl_rate_nodes_destroy() is never called.

  4. Failure Trigger: Execution proceeds to devlink_free(devlink) in nsim_drv_remove(). Line 544 of net/devlink/core.c checks whether any rate elements remain registered on the devlink instance:

    WARN_ON(devlink_rates_check(devlink, NULL, NULL));
    

    Because the user-created devlink_rate node(s) were never destroyed and remain linked in devlink->rate_list, devlink_rates_check() returns -EBUSY, tripping the WARN_ON.

▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
3679af29 assessment-security DenialOfService: βœ… Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ WARNING in devlink_free (2) 2026/11/14 09:57 2026/11/14 09:58 2026/11/14 10:45 819ebe34
▶ ▼ Similar bugs (1)
Kernel Title Rank πŸ›ˆ Repro Cause bisect Fix bisect Count Last Reported Patched Status
upstream WARNING in devlink_free net -1 10 1390d 1403d 22/29 fixed on 2023/06/08 14:41

Sample crash report:
netdevsim netdevsim0 netdevsim0 (unregistering): unset [0, 0] type 1 family 0 port 8472 - 0
netdevsim netdevsim0 netdevsim0 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0
netdevsim netdevsim0 netdevsim0 (unregistering): unset [1, 1] type 2 family 0 port 20004 - 0
------------[ cut here ]------------
devlink_rates_check(devlink, NULL, NULL)
WARNING: net/devlink/core.c:544 at devlink_free+0x359/0x450 net/devlink/core.c:544, CPU#1: syz-executor/17425
Modules linked in:
CPU: 1 UID: 0 PID: 17425 Comm: syz-executor Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/06/2026
RIP: 0010:devlink_free+0x359/0x450 net/devlink/core.c:544
Code: 00 e8 fb 62 e8 f6 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc cc e8 e6 62 e8 f6 90 0f 0b 90 e9 02 fd ff ff e8 d8 62 e8 f6 90 <0f> 0b 90 e9 29 fd ff ff e8 ca 62 e8 f6 90 0f 0b 90 e9 59 fd ff ff
RSP: 0018:ffffc900038a78b8 EFLAGS: 00010293
RAX: ffffffff8ae0be08 RBX: ffff8880797aa000 RCX: ffff8880546a9f40
RDX: 0000000000000000 RSI: 00000000fffffff0 RDI: 0000000000000000
RBP: 00000000fffffff0 R08: ffffffff91be00bf R09: 1ffffffff237c017
R10: dffffc0000000000 R11: 0000000000000000 R12: dffffc0000000000
R13: 1ffff1100f2f5400 R14: ffff8880797aa1f8 R15: ffff8880797aa3e0
FS:  000055557a90f500(0000) GS:ffff888123508000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd61b5f0ce0 CR3: 000000002bf22000 CR4: 00000000003526f0
Call Trace:
 <TASK>
 nsim_drv_remove+0x146/0x170 drivers/net/netdevsim/dev.c:1736
 device_remove drivers/base/dd.c:617 [inline]
 __device_release_driver drivers/base/dd.c:1357 [inline]
 device_release_driver_internal+0x42b/0x7d0 drivers/base/dd.c:1380
 bus_remove_device+0x444/0x560 drivers/base/bus.c:678
 device_del+0x524/0x8f0 drivers/base/core.c:3967
 device_unregister+0x21/0xf0 drivers/base/core.c:4008
 nsim_bus_dev_del drivers/net/netdevsim/bus.c:488 [inline]
 del_device_store+0x2b5/0x370 drivers/net/netdevsim/bus.c:243
 kernfs_fop_write_iter+0x3a4/0x540 fs/kernfs/file.c:345
 new_sync_write fs/read_write.c:575 [inline]
 vfs_write+0x612/0xba0 fs/read_write.c:667
 ksys_write+0x150/0x270 fs/read_write.c:719
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x16a/0x530 arch/x86/entry/syscall_64.c:89
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7ffbf2169d0e
Code: 08 0f 85 a5 a8 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
RSP: 002b:00007ffef50b4238 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 000055557a90f500 RCX: 00007ffbf2169d0e
RDX: 0000000000000001 RSI: 00007ffef50b42c0 RDI: 0000000000000005
RBP: 00007ffbf223891c R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007ffef50b42c0 R14: 00007ffef50b4b00 R15: 0000000000000003
 </TASK>

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/14 09:57 net aa40afa831eb 819ebe34 .config console log report info [disk image] [vmlinux] [kernel image] ci-upstream-net-this-kasan-gce WARNING in devlink_free
* Struck through repros no longer work on HEAD.