summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@kernel.org>2026-10-30 10:23:03 +0100
committerPaolo Abeni <pabeni@redhat.com>2026-11-03 22:30:55 +0100
commit787268686c64be60023743b527645a907e38ccca (patch)
treece307ad5d1d35014218ce1a50db26cb9e0884418 /include
parentf19f2b308beb158d0e6f6eb806ced636e4ebf6ce (diff)
ipmr, ip6mr: queue netlink route queries out of band
ipmr_get_route() and ip6mr_get_route() queue synthetic skbs on the unresolved MFC entry to answer RTM_GETROUTE requests once the route is resolved. These skbs carry a fake IP header with version 0, and ipmr_cache_resolve(), ipmr_destroy_unres(), ip6mr_cache_resolve() and ip6mr_destroy_unres() rely on this in-band tag to tell them apart from regular packets queued by the input and output paths. The IP version is only validated once, in ip_rcv_core() and ip6_rcv_core(). A netfilter hook running later, for instance an nftables payload statement in a PREROUTING chain owned by an unprivileged user namespace, can rewrite the first header byte to zero. The SRv6 End.DX6 action also passes the decapsulated packet to ip6_mr_input() without checking that the inner header version is 6. If no MFC entry exists, the packet is queued and later handled as a netlink request: its payload is treated as an nlmsghdr and written to, mr_fill_mroute() may call skb_put() on a nonlinear skb (hitting SKB_LINEAR_ASSERT()), and the skb is unicast to a netlink portid taken from stale IPCB/IP6CB bytes in skb->cb[]. ipmr_cache_report() also relies on the same tag since commit 94a6736bb5ab ("ipmr: only copy pktinfo to cache reports"). Stop trusting packet contents: queue route queries on a dedicated nl_queries list in the unresolved MFC entry, and pass an explicit nl_query flag from the callers. The per-entry limit of four queued skbs now applies to both lists combined, as before. The synthetic header keeps version 0, since it is copied into the NOCACHE report delivered to the mroute socket. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Fixes: 7bc570c8b4f7 ("[IPV6] MROUTE: Support multicast forwarding.") Reported-by: Katherine Leaver <kleaver@janestreet.com> Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20261030092303.2749386-1-edumazet@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/mroute_base.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h
index 4d55827e9705..2d506966357b 100644
--- a/include/linux/mroute_base.h
+++ b/include/linux/mroute_base.h
@@ -119,6 +119,7 @@ enum {
* @mfc_flags: entry flags
* @expires: unresolved entry expire time
* @unresolved: unresolved cached skbs
+ * @nl_queries: queued RTM_GETROUTE requests waiting for resolution
* @last_assert: time of last assert
* @minvif: minimum VIF id
* @maxvif: maximum VIF id
@@ -141,6 +142,7 @@ struct mr_mfc {
struct {
unsigned long expires;
struct sk_buff_head unresolved;
+ struct sk_buff_head nl_queries;
} unres;
struct {
unsigned long last_assert;