From: Greg Kroah-Hartman Date: Mon, 12 Aug 2024 14:29:10 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v6.1.105~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a38ce81e495499a630447cf1638b3cdeefbe8926;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ipv6-fix-source-address-selection-with-route-leak.patch --- diff --git a/queue-5.10/ipv6-fix-source-address-selection-with-route-leak.patch b/queue-5.10/ipv6-fix-source-address-selection-with-route-leak.patch new file mode 100644 index 00000000000..67fd534ecaf --- /dev/null +++ b/queue-5.10/ipv6-fix-source-address-selection-with-route-leak.patch @@ -0,0 +1,85 @@ +From 252442f2ae317d109ef0b4b39ce0608c09563042 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Wed, 10 Jul 2024 10:14:28 +0200 +Subject: ipv6: fix source address selection with route leak + +From: Nicolas Dichtel + +commit 252442f2ae317d109ef0b4b39ce0608c09563042 upstream. + +By default, an address assigned to the output interface is selected when +the source address is not specified. This is problematic when a route, +configured in a vrf, uses an interface from another vrf (aka route leak). +The original vrf does not own the selected source address. + +Let's add a check against the output interface and call the appropriate +function to select the source address. + +CC: stable@vger.kernel.org +Fixes: 0d240e7811c4 ("net: vrf: Implement get_saddr for IPv6") +Signed-off-by: Nicolas Dichtel +Link: https://patch.msgid.link/20240710081521.3809742-3-nicolas.dichtel@6wind.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/net/ip6_route.h | 20 ++++++++++++++------ + net/ipv6/ip6_output.c | 1 + + net/ipv6/route.c | 2 +- + 3 files changed, 16 insertions(+), 7 deletions(-) + +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -132,18 +132,26 @@ void rt6_age_exceptions(struct fib6_info + + static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i, + const struct in6_addr *daddr, +- unsigned int prefs, ++ unsigned int prefs, int l3mdev_index, + struct in6_addr *saddr) + { ++ struct net_device *l3mdev; ++ struct net_device *dev; ++ bool same_vrf; + int err = 0; + +- if (f6i && f6i->fib6_prefsrc.plen) { ++ rcu_read_lock(); ++ ++ l3mdev = dev_get_by_index_rcu(net, l3mdev_index); ++ if (!f6i || !f6i->fib6_prefsrc.plen || l3mdev) ++ dev = f6i ? fib6_info_nh_dev(f6i) : NULL; ++ same_vrf = !l3mdev || l3mdev_master_dev_rcu(dev) == l3mdev; ++ if (f6i && f6i->fib6_prefsrc.plen && same_vrf) + *saddr = f6i->fib6_prefsrc.addr; +- } else { +- struct net_device *dev = f6i ? fib6_info_nh_dev(f6i) : NULL; ++ else ++ err = ipv6_dev_get_saddr(net, same_vrf ? dev : l3mdev, daddr, prefs, saddr); + +- err = ipv6_dev_get_saddr(net, dev, daddr, prefs, saddr); +- } ++ rcu_read_unlock(); + + return err; + } +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1108,6 +1108,7 @@ static int ip6_dst_lookup_tail(struct ne + from = rt ? rcu_dereference(rt->from) : NULL; + err = ip6_route_get_saddr(net, from, &fl6->daddr, + sk ? inet6_sk(sk)->srcprefs : 0, ++ fl6->flowi6_l3mdev, + &fl6->saddr); + rcu_read_unlock(); + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5569,7 +5569,7 @@ static int rt6_fill_node(struct net *net + goto nla_put_failure; + } else if (dest) { + struct in6_addr saddr_buf; +- if (ip6_route_get_saddr(net, rt, dest, 0, &saddr_buf) == 0 && ++ if (ip6_route_get_saddr(net, rt, dest, 0, 0, &saddr_buf) == 0 && + nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf)) + goto nla_put_failure; + } diff --git a/queue-5.10/series b/queue-5.10/series index d32d6ab4079..8ab18ac12e3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -342,3 +342,4 @@ mptcp-fix-nl-pm-announced-address-accounting.patch mptcp-mib-count-mpj-with-backup-flag.patch mptcp-export-local_address.patch mptcp-pm-fix-backup-support-in-signal-endpoints.patch +ipv6-fix-source-address-selection-with-route-leak.patch