{"id":"CVE-2026-46116","summary":"xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete","details":"In the Linux kernel, the following vulnerability has been resolved:\n\nxfrm: defensively unhash xfrm_state lists in __xfrm_state_delete\n\nKASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s\nhlist_del_rcu calls under syzkaller load on linux-6.12.y stable\n(reproduced on 6.12.47, also reachable via the same code path on\ntorvalds/master and on the ipsec tree). Nine unique signatures cluster\nin the xfrm_state lifecycle, the load-bearing one being:\n\n  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]\n  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]\n  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c\n  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435\n\n  Workqueue: netns cleanup_net\n  Call Trace:\n   __hlist_del / hlist_del_rcu\n   __xfrm_state_delete\n   xfrm_state_delete\n   xfrm_state_flush\n   xfrm_state_fini\n   ops_exit_list\n   cleanup_net\n\nThe other observed signatures hit the same slab object from\n__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB\nwrite variant of __xfrm_state_delete, all on the byseq/byspi\nhash chains.\n\n__xfrm_state_delete() guards its byseq and byspi unhashes with\nvalue-based predicates:\n\n\tif (x-\u003ekm.seq)\n\t\thlist_del_rcu(&x-\u003ebyseq);\n\tif (x-\u003eid.spi)\n\t\thlist_del_rcu(&x-\u003ebyspi);\n\nwhile everywhere else in the file (e.g. state_cache, state_cache_input)\nthe safer hlist_unhashed() check is used. xfrm_alloc_spi() sets\nx-\u003eid.spi = newspi inside xfrm_state_lock and then immediately inserts\ninto byspi, but a path that observes x-\u003eid.spi != 0 outside of\nxfrm_state_lock can still skip-or-hit the byspi unhash inconsistently\nwith whether x is actually on the list. The same holds for x-\u003ekm.seq\nversus byseq, and the bydst/bysrc unhashes have no predicate at all,\nso a second __xfrm_state_delete() on the same object writes through\nLIST_POISON pprev.\n\nThe defensive change here:\n\n  - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,\n    bysrc, byseq and byspi so a second deletion is a no-op rather\n    than a write through LIST_POISON pprev. The byseq/byspi nodes\n    are already initialised in xfrm_state_alloc().\n  - Test hlist_unhashed() rather than the value predicate for\n    byseq/byspi, so the unhash decision tracks list state rather than\n    mutable scalar fields.\n\nEmpirical verification: applied this patch on top of v6.12.47, rebuilt,\nand re-ran the same syzkaller harness for 1h16m on a previously-crashy\nconfiguration that produced ~100 hits each of slab-use-after-free\nRead in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in\n__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at\n~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo\nconfirms the xfrm_state slab is actively allocated and freed during\nthe run (~143 KiB resident), so the fuzzer is still exercising those\ncode paths -- they just no longer crash.\n\nReproduction:\n\n  - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV\n  - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db\n  - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal\n  - 9 unique signatures collected in ~9h, all within xfrm_state\n    lifecycle","modified":"2026-06-05T18:29:21.762132525Z","published":"2026-05-28T09:35:30.689Z","related":["openSUSE-SU-2026:10954-1"],"database_specific":{"cna_assigner":"Linux","osv_generated_from":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46116.json"},"references":[{"type":"WEB","url":"https://git.kernel.org/stable/c/14acf9652e5690de3c7486c6db5fb8dafd0a32a3"},{"type":"WEB","url":"https://git.kernel.org/stable/c/26edb0a3c99f9d958c212be68b21f1221614dcf0"},{"type":"WEB","url":"https://git.kernel.org/stable/c/4980162de555cb838f1a189ce7d2cbf5d2e7b050"},{"type":"WEB","url":"https://git.kernel.org/stable/c/a2e2d08fb070fab4947447171f1c4e3ca5a188e5"},{"type":"WEB","url":"https://git.kernel.org/stable/c/b4a53add2fa8f1b5aa17d4c5686c320785fab182"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46116.json"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-46116"},{"type":"PACKAGE","url":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"}],"affected":[{"ranges":[{"type":"GIT","repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","events":[{"introduced":"7b4dc3600e4877178ba94c7fbf7e520421378aa6"},{"fixed":"b4a53add2fa8f1b5aa17d4c5686c320785fab182"},{"fixed":"26edb0a3c99f9d958c212be68b21f1221614dcf0"},{"fixed":"4980162de555cb838f1a189ce7d2cbf5d2e7b050"},{"fixed":"a2e2d08fb070fab4947447171f1c4e3ca5a188e5"},{"fixed":"14acf9652e5690de3c7486c6db5fb8dafd0a32a3"}]}],"database_specific":{"source":"https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2026-46116.json"}},{"package":{"name":"Kernel","ecosystem":"Linux"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"2.6.19"},{"fixed":"6.6.140"}]},{"type":"ECOSYSTEM","events":[{"introduced":"6.7.0"},{"fixed":"6.12.88"}]},{"type":"ECOSYSTEM","events":[{"introduced":"6.13.0"},{"fixed":"6.18.30"}]},{"type":"ECOSYSTEM","events":[{"introduced":"6.19.0"},{"fixed":"7.0.7"}]}],"database_specific":{"source":"https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2026-46116.json"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"}]}