CVE-2026-74615: vxlan: do not arm the ageing timer on a device that is down
In the Linux kernel, the following vulnerability has been resolved:
vxlan: do not arm the ageing timer on a device that is down
vxlanchangelink() arms vxlan->agetimer whenever the requested ageing interval differs from the configured one:
if (conf.ageinterval != vxlan->cfg.ageinterval) modtimer(&vxlan->agetimer, jiffies);
There is no netifrunning() test, so the timer is armed even on a device that was never brought up. The only synchronous cancel in the driver is the timerdeletesync() in vxlanstop(), which is .ndostop. netifclosemany() drops devices without IFFUP before devclosemany() runs, so that cancel is skipped for such a device.
vxlansetup() sets dev->needsfreenetdev = true and agetimer is a member of struct vxlandev, so freenetdev() releases the allocation the timer lives in while it is still queued on a timerbase. expiretimers() unlinks the entry before it loads timer->function, so the timer core writes through the freed object's list pointers:
BUG: KASAN: slab-use-after-free in runtimers+0x208/0x654 Write of size 8 at addr ffff00001adace68 by task true/192 asanstore8+0x84/0xac runtimers+0x208/0x654 runtimersoftirq+0x154/0x18c Allocated by task 189: allocnetdevmqs+0x64/0x720 rtnlcreatelink+0x4ac/0x520 rtnlnewlink+0x758/0xd00 Freed by task 191: netdevrelease+0x40/0x58 netdevruntodo+0x4a4/0x8c0 rtnldellink+0x200/0x4e8
The rtnl operations involved are netns-scoped, so an unprivileged user can perform them in a new user and network namespace.
Arming the timer on a down device never had an effect: vxlancleanup() returns early on !netifrunning(), and vxlanopen() arms the timer for any non-zero interval once the device is brought up. Add the missing test.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Fixed in 6.6.152.1-1 - Configuration
Modify vxlan code to avoid arming the ageing timer for vxlan devices that are down (the timer should only be armed when the device is up/running), preventing use-after-free in __run_timers due to timer callbacks firing after free_netdev() skips cancel.
Linux kernel (vxlan ageing timer) vxlan: do not arm the ageing timer on a device that is down = Implement the change so vxlan does not call mod_timer(&vxlan->age_timer, ...) when the device is down / not netif_running()
Event History
Frequently Asked Questions
What conditions are required to trigger this issue?
A VXLAN device must be down, including a device that was never brought up. Its ageing interval must be changed so that vxlan_changelink() arms the ageing timer, and the device must then be removed before that queued timer expires.
Are VXLAN devices that have been brought up affected in the same way?
The described cleanup gap applies to devices that are not IFF_UP when they are closed, because the driver’s synchronous timer cancellation occurs in its stop callback and that callback is skipped for devices that were never up. Devices that are running follow the normal stop path described in the advisory.
What is the observable impact if the condition is reached?
The queued ageing timer can outlive the freed VXLAN device allocation. When the timer subsystem processes it, it can write through freed list pointers, producing a kernel slab use-after-free such as a KASAN report in __run_timers.