diff mbox series

[RFC,3/5] net/tcp-md5: Verify inbound segments on twsk

Message ID 20230509221608.2569333-4-dima@arista.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series net/tcp-md5: Verify segments on TIME_WAIT sockets | expand

Checks

Context Check Description
netdev/series_format warning Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 1017 this patch: 1017
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang fail Errors and warnings before: 131 this patch: 131
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 1024 this patch: 1024
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 70 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Dmitry Safonov May 9, 2023, 10:16 p.m. UTC
It seems rare for BGP to have twsk socket and quite unlikely on server
side, in addition I don't see any major concern of destroying twsk early
by unsigned segments.
But on the other hand, it seems better not to change TCP state by
unsigned inbound segments and fixing this seems not hard.
So, lets avoid replying or doing any TCP state changes as long as the
segments weren't verified.

Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 include/net/tcp.h   |  7 ++++---
 net/ipv4/tcp_ipv4.c |  9 +++++++--
 net/ipv6/tcp_ipv6.c | 10 ++++++++--
 3 files changed, 19 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/include/net/tcp.h b/include/net/tcp.h
index e127fc685ca6..db13dc7558f4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1705,12 +1705,16 @@  extern struct static_key_false_deferred tcp_md5_needed;
 struct tcp_md5sig_key *__tcp_md5_do_lookup(const struct sock *sk, int l3index,
 					   const union tcp_md5_addr *addr,
 					   int family);
+
+#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_key)
 static inline struct tcp_md5sig_key *
 tcp_md5_do_lookup(const struct sock *sk, int l3index,
 		  const union tcp_md5_addr *addr, int family)
 {
 	if (!static_branch_unlikely(&tcp_md5_needed.key))
 		return NULL;
+	if (unlikely(sk->sk_state == TCP_TIME_WAIT))
+		return tcp_twsk_md5_key(tcp_twsk(sk));
 	return __tcp_md5_do_lookup(sk, l3index, addr, family);
 }
 
@@ -1718,9 +1722,6 @@  enum skb_drop_reason
 tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb,
 		     const void *saddr, const void *daddr,
 		     int family, int dif, int sdif);
-
-
-#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_key)
 #else
 static inline struct tcp_md5sig_key *
 tcp_md5_do_lookup(const struct sock *sk, int l3index,
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index b1056a4af60f..f5b870943dcb 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -676,7 +676,7 @@  static bool tcp_v4_md5_sign_reset(struct net *net, const struct sock *sk,
 		return !!hash_location;
 
 	rcu_read_lock();
-	if (sk && sk_fullsock(sk)) {
+	if (sk && sk->sk_state != TCP_NEW_SYN_RECV) {
 		const union tcp_md5_addr *addr;
 		int l3index;
 
@@ -2195,8 +2195,13 @@  int tcp_v4_rcv(struct sk_buff *skb)
 	goto discard_it;
 
 do_time_wait:
-	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
+	else
+		drop_reason = tcp_inbound_md5_hash(sk, skb,
+						   &iph->saddr, &iph->daddr,
+						   AF_INET, dif, sdif);
+	if (drop_reason) {
 		inet_twsk_put(inet_twsk(sk));
 		goto discard_it;
 	}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 574398a89970..3756a43367a3 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -987,7 +987,7 @@  static int tcp_v6_md5_lookup_reset_key(struct net *net, const struct sock *sk,
 	if (!static_branch_unlikely(&tcp_md5_needed.key))
 		return !!hash_location;
 
-	if (sk && sk_fullsock(sk)) {
+	if (sk && sk->sk_state != TCP_NEW_SYN_RECV) {
 		/* sdif set, means packet ingressed via a device
 		 * in an L3 domain and inet_iif is set to it.
 		 */
@@ -1795,8 +1795,14 @@  INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb)
 	goto discard_it;
 
 do_time_wait:
-	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
 		drop_reason = SKB_DROP_REASON_XFRM_POLICY;
+	else
+		drop_reason = tcp_inbound_md5_hash(sk, skb,
+						   &hdr->saddr, &hdr->daddr,
+						   AF_INET6, dif, sdif);
+
+	if (drop_reason) {
 		inet_twsk_put(inet_twsk(sk));
 		goto discard_it;
 	}