In the Linux kernel, the following vulnerability has been resolved:
xfrm: always flush state and policy upon NETDEV_UNREGISTER event
syzbot is reporting that "struct xfrm_state" refcount is leaking.
unregisternetdevice: waiting for netdevsim0 to become free. Usage count = 2 reftracker: netdev@ffff888052f24618 has 1/1 users at __netdevtrackeralloc include/linux/netdevice.h:4400 [inline] netdev_trackeralloc include/linux/netdevice.h:4412 [inline] xfrmdevstateadd+0x3a5/0x1080 net/xfrm/xfrmdevice.c:316 xfrmstateconstruct net/xfrm/xfrmuser.c:986 [inline] xfrmaddsa+0x34ff/0x5fa0 net/xfrm/xfrmuser.c:1022 xfrmuserrcvmsg+0x58e/0xc00 net/xfrm/xfrmuser.c:3507 netlinkrcvskb+0x158/0x420 net/netlink/afnetlink.c:2550 xfrmnetlinkrcv+0x71/0x90 net/xfrm/xfrmuser.c:3529 netlinkunicastkernel net/netlink/afnetlink.c:1318 [inline] netlinkunicast+0x5aa/0x870 net/netlink/afnetlink.c:1344 netlinksendmsg+0x8c8/0xdd0 net/netlink/afnetlink.c:1894 socksendmsgnosec net/socket.c:727 [inline] __sock_sendmsg net/socket.c:742 [inline] ____sys_sendmsg+0xa5d/0xc30 net/socket.c:2592 ___sys_sendmsg+0x134/0x1d0 net/socket.c:2646 _syssendmsg+0x16d/0x220 net/socket.c:2678 dosyscallx64 arch/x86/entry/syscall64.c:63 [inline] dosyscall64+0xcd/0xf80 arch/x86/entry/syscall64.c:94 entrySYSCALL64afterhwframe+0x77/0x7f
This is because commit d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API") implemented xfrmdevunregister() as no-op despite xfrmdevstateadd() from xfrmstateconstruct() acquires a reference to "struct netdevice". I guess that that commit expected that NETDEVDOWN event is fired before NETDEVUNREGISTER event fires, and also assumed that xfrmdevstateadd() is called only if (dev->features & NETIFFHWESP) != 0.
Sabrina Dubroca identified steps to reproduce the same symptoms as below.
echo 0 > /sys/bus/netdevsim/newdevice dev=$(ls -1 /sys/bus/netdevsim/devices/netdevsim0/net/) ip xfrm state add src 192.168.13.1 dst 192.168.13.2 proto esp \ spi 0x1000 mode tunnel aead 'rfc4106(gcm(aes))' $key 128 \ offload crypto dev $dev dir out ethtool -K $dev esp-hw-offload off echo 0 > /sys/bus/netdevsim/deldevice
Like these steps indicate, the NETIFFHWESP bit can be cleared after xfrmdevstateadd() acquired a reference to "struct netdevice". Also, xfrmdevstateadd() does not check for the NETIFFHWESP bit when acquiring a reference to "struct netdevice".
Commit 03891f820c21 ("xfrm: handle NETDEVUNREGISTER for xfrm device") re-introduced the NETDEVUNREGISTER event to xfrmdevevent(), but that commit for unknown reason chose to share xfrmdevdown() between the NETDEVDOWN event and the NETDEVUNREGISTER event. I guess that that commit missed the behavior in the previous paragraph.
Therefore, we need to re-introduce xfrmdevunregister() in order to release the reference to "struct net_device" by unconditionally flushing state and policy.
{
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/43xxx/CVE-2026-43167.json",
"cna_assigner": "Linux"
}