Patch "netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     netfilter-nat-fix-ipv6-nat-redirect-with-mapped-and-.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0937c4da68b49a3a54537a46c6c15a145b91b6e3
Author: Florian Westphal <fw@xxxxxxxxx>
Date:   Wed Nov 8 13:18:53 2023 +0100

    netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses
    
    [ Upstream commit 80abbe8a8263106fe45a4f293b92b5c74cc9cc8a ]
    
    The ipv6 redirect target was derived from the ipv4 one, i.e. its
    identical to a 'dnat' with the first (primary) address assigned to the
    network interface.  The code has been moved around to make it usable
    from nf_tables too, but its still the same as it was back when this
    was added in 2012.
    
    IPv6, however, has different types of addresses, if the 'wrong' address
    comes first the redirection does not work.
    
    In Daniels case, the addresses are:
      inet6 ::ffff:192 ...
      inet6 2a01: ...
    
    ... so the function attempts to redirect to the mapped address.
    
    Add more checks before the address is deemed correct:
    1. If the packets' daddr is scoped, search for a scoped address too
    2. skip tentative addresses
    3. skip mapped addresses
    
    Use the first address that appears to match our needs.
    
    Reported-by: Daniel Huhardeaux <tech@xxxxxxxxxx>
    Closes: https://lore.kernel.org/netfilter/71be06b8-6aa0-4cf9-9e0b-e2839b01b22f@xxxxxxxxxx/
    Fixes: 115e23ac78f8 ("netfilter: ip6tables: add REDIRECT target")
    Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
    Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/netfilter/nf_nat_redirect.c b/net/netfilter/nf_nat_redirect.c
index 6616ba5d0b049..5b37487d9d11f 100644
--- a/net/netfilter/nf_nat_redirect.c
+++ b/net/netfilter/nf_nat_redirect.c
@@ -80,6 +80,26 @@ EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4);
 
 static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
 
+static bool nf_nat_redirect_ipv6_usable(const struct inet6_ifaddr *ifa, unsigned int scope)
+{
+	unsigned int ifa_addr_type = ipv6_addr_type(&ifa->addr);
+
+	if (ifa_addr_type & IPV6_ADDR_MAPPED)
+		return false;
+
+	if ((ifa->flags & IFA_F_TENTATIVE) && (!(ifa->flags & IFA_F_OPTIMISTIC)))
+		return false;
+
+	if (scope) {
+		unsigned int ifa_scope = ifa_addr_type & IPV6_ADDR_SCOPE_MASK;
+
+		if (!(scope & ifa_scope))
+			return false;
+	}
+
+	return true;
+}
+
 unsigned int
 nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 		     unsigned int hooknum)
@@ -89,14 +109,19 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 	if (hooknum == NF_INET_LOCAL_OUT) {
 		newdst.in6 = loopback_addr;
 	} else {
+		unsigned int scope = ipv6_addr_scope(&ipv6_hdr(skb)->daddr);
 		struct inet6_dev *idev;
-		struct inet6_ifaddr *ifa;
 		bool addr = false;
 
 		idev = __in6_dev_get(skb->dev);
 		if (idev != NULL) {
+			const struct inet6_ifaddr *ifa;
+
 			read_lock_bh(&idev->lock);
 			list_for_each_entry(ifa, &idev->addr_list, if_list) {
+				if (!nf_nat_redirect_ipv6_usable(ifa, scope))
+					continue;
+
 				newdst.in6 = ifa->addr;
 				addr = true;
 				break;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux