netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net v2] tcp: don't allow syn packets without timestamps to pass tcp_tw_recycle logic
@ 2014-08-14 20:06 Hannes Frederic Sowa
  2014-08-14 21:40 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Hannes Frederic Sowa @ 2014-08-14 20:06 UTC (permalink / raw)
  To: netdev; +Cc: Eric Dumazet, Florian Westphal

tcp_tw_recycle heavily relies on tcp timestamps to build a per-host
ordering of incoming connections and teardowns without the need to
hold state on a specific quadruple for TCP_TIMEWAIT_LEN, but only for
the last measured RTO. To do so, we keep the last seen timestamp in a
per-host indexed data structure and verify if the incoming timestamp
in a connection request is strictly greater than the saved one during
last connection teardown. Thus we can verify later on that no old data
packets will be accepted by the new connection.

During moving a socket to time-wait state we already verify if timestamps
where seen on a connection. Only if that was the case we let the
time-wait socket expire after the RTO, otherwise normal TCP_TIMEWAIT_LEN
will be used. But we don't verify this on incoming SYN packets. If a
connection teardown was less than TCP_PAWS_MSL seconds in the past we
cannot guarantee to not accept data packets from an old connection if
no timestamps are present. We should drop this SYN packet. This patch
closes this loophole.

Please note, this patch does not make tcp_tw_recycle in any way more
usable but only adds another safety check:
Sporadic drops of SYN packets because of reordering in the network or
in the socket backlog queues can happen. Users behing NAT trying to
connect to a tcp_tw_recycle enabled server can get caught in blackholes
and their connection requests may regullary get dropped because hosts
behind an address translator don't have synchronized tcp timestamp clocks.
tcp_tw_recycle cannot work if peers don't have tcp timestamps enabled.

In general, use of tcp_tw_recycle is disadvised.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Florian Westphal <fw@strlen.de>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2:
- updated changelog to disadvise people from ever using tcp_tw_recycle

 include/net/tcp.h      | 2 +-
 net/ipv4/tcp_input.c   | 9 ++++++---
 net/ipv4/tcp_metrics.c | 6 ++++--
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index dafa1cb..68425af 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -417,7 +417,7 @@ void tcp_update_metrics(struct sock *sk);
 void tcp_init_metrics(struct sock *sk);
 void tcp_metrics_init(void);
 bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst,
-			bool paws_check);
+			bool paws_check, bool timestamps);
 bool tcp_remember_stamp(struct sock *sk);
 bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw);
 void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a3d47af..a0eb435 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5979,12 +5979,14 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
 		 * timewait bucket, so that all the necessary checks
 		 * are made in the function processing timewait state.
 		 */
-		if (tmp_opt.saw_tstamp && tcp_death_row.sysctl_tw_recycle) {
+		if (tcp_death_row.sysctl_tw_recycle) {
 			bool strict;
 
 			dst = af_ops->route_req(sk, &fl, req, &strict);
+
 			if (dst && strict &&
-			    !tcp_peer_is_proven(req, dst, true)) {
+			    !tcp_peer_is_proven(req, dst, true,
+						tmp_opt.saw_tstamp)) {
 				NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
 				goto drop_and_release;
 			}
@@ -5993,7 +5995,8 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
 		else if (!sysctl_tcp_syncookies &&
 			 (sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) <
 			  (sysctl_max_syn_backlog >> 2)) &&
-			 !tcp_peer_is_proven(req, dst, false)) {
+			 !tcp_peer_is_proven(req, dst, false,
+					     tmp_opt.saw_tstamp)) {
 			/* Without syncookies last quarter of
 			 * backlog is filled with destinations,
 			 * proven to be alive.
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 0d54e59..ed9c9a9 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -576,7 +576,8 @@ reset:
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check)
+bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst,
+			bool paws_check, bool timestamps)
 {
 	struct tcp_metrics_block *tm;
 	bool ret;
@@ -589,7 +590,8 @@ bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool pa
 	if (paws_check) {
 		if (tm &&
 		    (u32)get_seconds() - tm->tcpm_ts_stamp < TCP_PAWS_MSL &&
-		    (s32)(tm->tcpm_ts - req->ts_recent) > TCP_PAWS_WINDOW)
+		    ((s32)(tm->tcpm_ts - req->ts_recent) > TCP_PAWS_WINDOW ||
+		     !timestamps))
 			ret = false;
 		else
 			ret = true;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net v2] tcp: don't allow syn packets without timestamps to pass tcp_tw_recycle logic
  2014-08-14 20:06 [PATCH net v2] tcp: don't allow syn packets without timestamps to pass tcp_tw_recycle logic Hannes Frederic Sowa
@ 2014-08-14 21:40 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2014-08-14 21:40 UTC (permalink / raw)
  To: hannes; +Cc: netdev, eric.dumazet, fw

From: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date: Thu, 14 Aug 2014 22:06:12 +0200

> tcp_tw_recycle heavily relies on tcp timestamps to build a per-host
> ordering of incoming connections and teardowns without the need to
> hold state on a specific quadruple for TCP_TIMEWAIT_LEN, but only for
> the last measured RTO. To do so, we keep the last seen timestamp in a
> per-host indexed data structure and verify if the incoming timestamp
> in a connection request is strictly greater than the saved one during
> last connection teardown. Thus we can verify later on that no old data
> packets will be accepted by the new connection.
> 
> During moving a socket to time-wait state we already verify if timestamps
> where seen on a connection. Only if that was the case we let the
> time-wait socket expire after the RTO, otherwise normal TCP_TIMEWAIT_LEN
> will be used. But we don't verify this on incoming SYN packets. If a
> connection teardown was less than TCP_PAWS_MSL seconds in the past we
> cannot guarantee to not accept data packets from an old connection if
> no timestamps are present. We should drop this SYN packet. This patch
> closes this loophole.
> 
> Please note, this patch does not make tcp_tw_recycle in any way more
> usable but only adds another safety check:
> Sporadic drops of SYN packets because of reordering in the network or
> in the socket backlog queues can happen. Users behing NAT trying to
> connect to a tcp_tw_recycle enabled server can get caught in blackholes
> and their connection requests may regullary get dropped because hosts
> behind an address translator don't have synchronized tcp timestamp clocks.
> tcp_tw_recycle cannot work if peers don't have tcp timestamps enabled.
> 
> In general, use of tcp_tw_recycle is disadvised.
> 
> Cc: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Florian Westphal <fw@strlen.de>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>

Applied.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-08-14 21:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-14 20:06 [PATCH net v2] tcp: don't allow syn packets without timestamps to pass tcp_tw_recycle logic Hannes Frederic Sowa
2014-08-14 21:40 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).