{"id":"CVE-2026-90111","state":"PUBLISHED","title":"ip6mr: do not clone dst in ip6mr_cache_report()","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nip6mr: do not clone dst in ip6mr_cache_report()\n\nIPv6 input attaches a non-refcounted (NOREF) dst to skbs under RCU.\nWhen an ingress multicast packet misses MFC lookup,\nip6mr_cache_unresolved() places the skb onto the unresolved queue,\nescaping the receive-side RCU grace period.\n\nIf the underlying route is deleted and freed, and the MFC queue is later\nresolved with a wrong parent interface, ip6_mr_forward() invokes\nip6mr_cache_report(..., MRT6MSG_WRONGMIF), which executes\ndst_clone(skb_dst(pkt)) on the freed dst entry, triggering a slab\nuse-after-free.\n\nReport packets queued to mroute6_sk (a raw socket) and netlink\nnotifications do not require an attached dst entry.\n\nFix this by:\n1. Removing dst_clone() in ip6mr_cache_report() and ensuring report skbs\n   do not hold a dst.\n2. Dropping skb_dst before queuing unresolved skbs in\n   ip6mr_cache_unresolved(), matching the fact that multicast\n   forwarding resolves outgoing routes anew via ip6_route_output().","publishedAt":"2026-09-17T16:06:18.779Z","updatedAt":"2026-10-30T12:34:13.088Z","severity":{"score":7.8,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"b50d3cfb8513e895cee453dd0f834deee6ccc231","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"7f8287f606c8c028d4224e85d95dc448c6d6d623","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"42ef371466d5648f5c9e8bc219f0af0a2c2bbf8c","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"f57b0fd1c62e1be274ee154ab7fb8ac4481b7f89","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"4a674afaae4136c71943aa3e35d433676fd40e8f","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"235b42b5860189eb8c27c36435ad932cae65a734","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/ip6mr.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.3","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.3","versionType":"semver"},{"version":"6.1.191","status":"unaffected","lessThanOrEqual":"6.1.*","versionType":"semver"},{"version":"6.6.160","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.114","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.57","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.6","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/ip6mr.c"]}],"references":["https://git.kernel.org/stable/c/b50d3cfb8513e895cee453dd0f834deee6ccc231","https://git.kernel.org/stable/c/7f8287f606c8c028d4224e85d95dc448c6d6d623","https://git.kernel.org/stable/c/42ef371466d5648f5c9e8bc219f0af0a2c2bbf8c","https://git.kernel.org/stable/c/f57b0fd1c62e1be274ee154ab7fb8ac4481b7f89","https://git.kernel.org/stable/c/4a674afaae4136c71943aa3e35d433676fd40e8f","https://git.kernel.org/stable/c/235b42b5860189eb8c27c36435ad932cae65a734"],"weaknesses":[],"ingestedAt":"2026-10-30T12:52:04.348Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/90xxx/CVE-2026-90111.json","commit":"1f312381e38164a43607eebab851b151dd16861e","baselineCommit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-90111","state":"PUBLISHED","datePublished":"2026-09-17T16:06:18.779Z","dateUpdated":"2026-10-30T12:34:13.088Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-11T19:38:34.787Z"},"containers":{"cna":{"title":"ip6mr: do not clone dst in ip6mr_cache_report()","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nip6mr: do not clone dst in ip6mr_cache_report()\n\nIPv6 input attaches a non-refcounted (NOREF) dst to skbs under RCU.\nWhen an ingress multicast packet misses MFC lookup,\nip6mr_cache_unresolved() places the skb onto the unresolved queue,\nescaping the receive-side RCU grace period.\n\nIf the underlying route is deleted and freed, and the MFC queue is later\nresolved with a wrong parent interface, ip6_mr_forward() invokes\nip6mr_cache_report(..., MRT6MSG_WRONGMIF), which executes\ndst_clone(skb_dst(pkt)) on the freed dst entry, triggering a slab\nuse-after-free.\n\nReport packets queued to mroute6_sk (a raw socket) and netlink\nnotifications do not require an attached dst entry.\n\nFix this by:\n1. Removing dst_clone() in ip6mr_cache_report() and ensuring report skbs\n   do not hold a dst.\n2. Dropping skb_dst before queuing unresolved skbs in\n   ip6mr_cache_unresolved(), matching the fact that multicast\n   forwarding resolves outgoing routes anew via ip6_route_output()."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"b50d3cfb8513e895cee453dd0f834deee6ccc231","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"7f8287f606c8c028d4224e85d95dc448c6d6d623","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"42ef371466d5648f5c9e8bc219f0af0a2c2bbf8c","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"f57b0fd1c62e1be274ee154ab7fb8ac4481b7f89","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"4a674afaae4136c71943aa3e35d433676fd40e8f","versionType":"git"},{"version":"67f415dd29063a5906c560051c00e42dcf01a4dd","status":"affected","lessThan":"235b42b5860189eb8c27c36435ad932cae65a734","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/ip6mr.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"5.3","status":"affected"},{"version":"0","status":"unaffected","lessThan":"5.3","versionType":"semver"},{"version":"6.1.191","status":"unaffected","lessThanOrEqual":"6.1.*","versionType":"semver"},{"version":"6.6.160","status":"unaffected","lessThanOrEqual":"6.6.*","versionType":"semver"},{"version":"6.12.114","status":"unaffected","lessThanOrEqual":"6.12.*","versionType":"semver"},{"version":"6.18.57","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.6","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["net/ipv6/ip6mr.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/b50d3cfb8513e895cee453dd0f834deee6ccc231"},{"url":"https://git.kernel.org/stable/c/7f8287f606c8c028d4224e85d95dc448c6d6d623"},{"url":"https://git.kernel.org/stable/c/42ef371466d5648f5c9e8bc219f0af0a2c2bbf8c"},{"url":"https://git.kernel.org/stable/c/f57b0fd1c62e1be274ee154ab7fb8ac4481b7f89"},{"url":"https://git.kernel.org/stable/c/4a674afaae4136c71943aa3e35d433676fd40e8f"},{"url":"https://git.kernel.org/stable/c/235b42b5860189eb8c27c36435ad932cae65a734"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - The UAF is dst_clone(skb_dst(pkt)) in ip6mr_cache_report(MRT6MSG_WRONGMIF) on a NOREF dst that ip6_route_input() attached and ip6mr_cache_unresolved() queued past RCU. Completing it requires deleting that fib6 route and MRT6_ADD_MFC with mf6cc_parent != the arrival vif; those are local setsockopt/netlink from the same attacker, not a field in the IPv6 multicast datagram.\nAC:L - The attacker owns every step: MRT6_INIT/ADD_MIF/ASSERT, inject a non-link-local IPv6 multicast skb so ip6_mr_input() misses the MFC and ip6mr_cache_unresolved() queues it, delete the fib6 route and wait an RCU grace period, then MRT6_ADD_MFC with the wrong parent so ip6_mr_forward() takes the WRONGMIF path.\nPR:L - inet6_create() allows SOCK_RAW/IPPROTO_ICMPV6 only with ns_capable(CAP_NET_RAW); ip6_mroute_setsockopt() then lets that mroute socket (or ns_capable(CAP_NET_ADMIN)) run MRT6_ADD_MIF, MRT6_ASSERT, and MRT6_ADD_MFC. An unprivileged user obtains both capabilities in a user+net namespace via unshare -Urn.\nUI:N - The attacker opens the raw ICMPv6 mroute socket, adds MIFs, injects the multicast skb onto a veth, deletes the fib6 route, and installs the mismatched-parent MFC entirely with their own syscalls; no other user must mount a volume or otherwise interact.\nS:U - dst_clone()/dst_hold() touch the host kernel's struct dst_entry from the IPv6 fib looked up for the queued skb; the use-after-free stays in that networking authority and does not cross a VM, IOMMU, or other boundary.\nC:H - After the fib6 route is freed, ip6mr_cache_report() still does dst_clone(skb_dst(pkt)) and dst_hold() reads __rcuref on the dangling dst_entry; that slab UAF can be reclaimed with attacker-controlled objects and used as an arbitrary kernel read.\nI:H - dst_hold() calls rcuref_get(&dst->__rcuref) on the freed dst_entry, writing a reclaimable slab object that can be sprayed to forge a refcount/control-flow hijack when the WRONGMIF report clones the stale dst.\nA:H - ip6_mr_forward() invoking ip6mr_cache_report(MRT6MSG_WRONGMIF) oopses in dst_hold()/rcuref_get() on the already-freed dst_entry even without a full exploit, so the bug is a reliable kernel crash as well as a UAF."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-30T12:34:13.088Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"6.1.191"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"6.6.160"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"6.12.114"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"6.18.57"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"7.2.6"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"5.3","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}