In the Linux kernel, the following vulnerability has been resolved:
net: ipv6: fix NOREF dst use in seg6 and rpl lwtunnels
seg6inputcore() and rplinput() call ip6routeinput() which sets a NOREF dst on the skb, then pass it to dstcachesetip6() invoking dsthold() unconditionally. On PREEMPTRT, ksoftirqd is preemptible and a higher-priority task can release the underlying pcpu_rt between the lookup and the caching through a concurrent FIB lookup on a shared nexthop. Simplified race sequence:
ksoftirqd/X higher-prio task (same CPU X) ----------- -------------------------------- seg6inputcore(,skb)/rplinput(skb) dstcacheget() -> miss ip6routeinput(skb) -> ip6polroute(,skb,flags) [RT6LOOKUPFDSTNOREF in flags] -> FIB lookup resolves fib6nh [nhid=N route] -> rt6makepcpuroute() [creates pcpurt, refcount=1] pcpurt->sernum = fib6sernum [fib6sernum=W] -> cmpxchg(fib6nh.rt6ipcpu, NULL, pcpurt) [slot was empty, store succeeds] -> skbdstsetnoref(skb, dst) [dst is pcpurt, refcount still 1]
rt_genid_bump_ipv6()
-> bumps fib6_sernum
[fib6_sernum from W to Z]
ip6_route_output()
-> ip6_pol_route()
-> FIB lookup resolves fib6_nh
[nhid=N]
-> rt6_get_pcpu_route()
pcpu_rt->sernum != fib6_sernum
[W <> Z, stale]
-> prev = xchg(rt6i_pcpu, NULL)
-> dst_release(prev)
[prev is pcpu_rt,
refcount 1->0, dead]
dst = skb_dst(skb)
[dst is the dead pcpu_rt]
dst_cache_set_ip6(dst)
-> dst_hold() on dead dst
-> WARN / use-after-free
For the race to occur, ksoftirqd must be preemptible (PREEMPTRT without PREEMPTRTNEEDSBHLOCK) and a concurrent task must be able to release the pcpurt. Shared nexthop objects provide such a path, as two routes pointing to the same nhid share the same fib6nh and its rt6ipcpu entry.
Fix seg6inputcore() and rplinput() by calling skbdstforce() after ip6routeinput() to force the NOREF dst into a refcounted one before caching. The output path is not affected as ip6route_output() already returns a refcounted dst.
{
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/46xxx/CVE-2026-46099.json",
"cna_assigner": "Linux"
}