Patch "tcp: md5: Fix overlap between vrf and non-vrf keys" has been added to the 5.10-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

    tcp: md5: Fix overlap between vrf and non-vrf keys

to the 5.10-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:
     tcp-md5-fix-overlap-between-vrf-and-non-vrf-keys.patch
and it can be found in the queue-5.10 subdirectory.

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



commit eaeb9a60ef06133e9355c5e6fd7c6e851c1ac433
Author: Leonard Crestez <cdleonard@xxxxxxxxx>
Date:   Fri Oct 15 10:26:04 2021 +0300

    tcp: md5: Fix overlap between vrf and non-vrf keys
    
    [ Upstream commit 86f1e3a8489f6a0232c1f3bc2bdb379f5ccdecec ]
    
    With net.ipv4.tcp_l3mdev_accept=1 it is possible for a listen socket to
    accept connection from the same client address in different VRFs. It is
    also possible to set different MD5 keys for these clients which differ
    only in the tcpm_l3index field.
    
    This appears to work when distinguishing between different VRFs but not
    between non-VRF and VRF connections. In particular:
    
     * tcp_md5_do_lookup_exact will match a non-vrf key against a vrf key.
    This means that adding a key with l3index != 0 after a key with l3index
    == 0 will cause the earlier key to be deleted. Both keys can be present
    if the non-vrf key is added later.
     * _tcp_md5_do_lookup can match a non-vrf key before a vrf key. This
    casues failures if the passwords differ.
    
    Fix this by making tcp_md5_do_lookup_exact perform an actual exact
    comparison on l3index and by making  __tcp_md5_do_lookup perfer
    vrf-bound keys above other considerations like prefixlen.
    
    Fixes: dea53bb80e07 ("tcp: Add l3index to tcp_md5sig_key and md5 functions")
    Signed-off-by: Leonard Crestez <cdleonard@xxxxxxxxx>
    Reviewed-by: David Ahern <dsahern@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 71395e745bc5..017cd666387f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1022,6 +1022,20 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req)
 DEFINE_STATIC_KEY_FALSE(tcp_md5_needed);
 EXPORT_SYMBOL(tcp_md5_needed);
 
+static bool better_md5_match(struct tcp_md5sig_key *old, struct tcp_md5sig_key *new)
+{
+	if (!old)
+		return true;
+
+	/* l3index always overrides non-l3index */
+	if (old->l3index && new->l3index == 0)
+		return false;
+	if (old->l3index == 0 && new->l3index)
+		return true;
+
+	return old->prefixlen < new->prefixlen;
+}
+
 /* Find the Key structure for an address.  */
 struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index,
 					   const union tcp_md5_addr *addr,
@@ -1059,8 +1073,7 @@ struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index,
 			match = false;
 		}
 
-		if (match && (!best_match ||
-			      key->prefixlen > best_match->prefixlen))
+		if (match && better_md5_match(best_match, key))
 			best_match = key;
 	}
 	return best_match;
@@ -1090,7 +1103,7 @@ static struct tcp_md5sig_key *tcp_md5_do_lookup_exact(const struct sock *sk,
 				 lockdep_sock_is_held(sk)) {
 		if (key->family != family)
 			continue;
-		if (key->l3index && key->l3index != l3index)
+		if (key->l3index != l3index)
 			continue;
 		if (!memcmp(&key->addr, addr, size) &&
 		    key->prefixlen == prefixlen)



[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