From: Greg Kroah-Hartman Date: Wed, 2 Apr 2025 19:50:02 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v6.1.133~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ce715e4adc8c1d6cddf6759c3ce59e5d8b5602cf;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: netfilter-socket-lookup-orig-tuple-for-ipv6-snat.patch --- diff --git a/queue-5.4/netfilter-socket-lookup-orig-tuple-for-ipv6-snat.patch b/queue-5.4/netfilter-socket-lookup-orig-tuple-for-ipv6-snat.patch new file mode 100644 index 0000000000..e6881d2134 --- /dev/null +++ b/queue-5.4/netfilter-socket-lookup-orig-tuple-for-ipv6-snat.patch @@ -0,0 +1,75 @@ +From 932b32ffd7604fb00b5c57e239a3cc4d901ccf6e Mon Sep 17 00:00:00 2001 +From: Maxim Mikityanskiy +Date: Tue, 18 Mar 2025 18:15:16 +0200 +Subject: netfilter: socket: Lookup orig tuple for IPv6 SNAT + +From: Maxim Mikityanskiy + +commit 932b32ffd7604fb00b5c57e239a3cc4d901ccf6e upstream. + +nf_sk_lookup_slow_v4 does the conntrack lookup for IPv4 packets to +restore the original 5-tuple in case of SNAT, to be able to find the +right socket (if any). Then socket_match() can correctly check whether +the socket was transparent. + +However, the IPv6 counterpart (nf_sk_lookup_slow_v6) lacks this +conntrack lookup, making xt_socket fail to match on the socket when the +packet was SNATed. Add the same logic to nf_sk_lookup_slow_v6. + +IPv6 SNAT is used in Kubernetes clusters for pod-to-world packets, as +pods' addresses are in the fd00::/8 ULA subnet and need to be replaced +with the node's external address. Cilium leverages Envoy to enforce L7 +policies, and Envoy uses transparent sockets. Cilium inserts an iptables +prerouting rule that matches on `-m socket --transparent` and redirects +the packets to localhost, but it fails to match SNATed IPv6 packets due +to that missing conntrack lookup. + +Closes: https://github.com/cilium/cilium/issues/37932 +Fixes: eb31628e37a0 ("netfilter: nf_tables: Add support for IPv6 NAT") +Signed-off-by: Maxim Mikityanskiy +Reviewed-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/netfilter/nf_socket_ipv6.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/net/ipv6/netfilter/nf_socket_ipv6.c ++++ b/net/ipv6/netfilter/nf_socket_ipv6.c +@@ -103,6 +103,10 @@ struct sock *nf_sk_lookup_slow_v6(struct + struct sk_buff *data_skb = NULL; + int doff = 0; + int thoff = 0, tproto; ++#if IS_ENABLED(CONFIG_NF_CONNTRACK) ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn const *ct; ++#endif + + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL); + if (tproto < 0) { +@@ -136,6 +140,25 @@ struct sock *nf_sk_lookup_slow_v6(struct + return NULL; + } + ++#if IS_ENABLED(CONFIG_NF_CONNTRACK) ++ /* Do the lookup with the original socket address in ++ * case this is a reply packet of an established ++ * SNAT-ted connection. ++ */ ++ ct = nf_ct_get(skb, &ctinfo); ++ if (ct && ++ ((tproto != IPPROTO_ICMPV6 && ++ ctinfo == IP_CT_ESTABLISHED_REPLY) || ++ (tproto == IPPROTO_ICMPV6 && ++ ctinfo == IP_CT_RELATED_REPLY)) && ++ (ct->status & IPS_SRC_NAT_DONE)) { ++ daddr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6; ++ dport = (tproto == IPPROTO_TCP) ? ++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port : ++ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port; ++ } ++#endif ++ + return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr, + sport, dport, indev); + } diff --git a/queue-5.4/series b/queue-5.4/series index fd458a5e43..da25de9e55 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -69,3 +69,4 @@ atm-fix-null-pointer-dereference.patch arm-9350-1-fault-implement-copy_from_kernel_nofault_allowed.patch arm-9351-1-fault-add-cut-here-line-for-prefetch-aborts.patch arm-remove-address-checking-for-mmuless-devices.patch +netfilter-socket-lookup-orig-tuple-for-ipv6-snat.patch