All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set
@ 2017-02-22 10:23 Alexey Kodanev
  2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Alexey Kodanev @ 2017-02-22 10:23 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Florian Westphal, Eric Dumazet, Alexey Kodanev

Found that when randomized tcp offsets are enabled (by default)
TCP client can still start new connections without them. Later,
if server does active close and re-uses sockets in TIME-WAIT
state, new SYN from client can be rejected on PAWS check inside
tcp_timewait_state_process(), because either tw_ts_recent or
rcv_tsval doesn't really have an offset set.

Here is how to reproduce it with LTP netstress tool:
    netstress -R 1 &
    netstress -H 127.0.0.1 -lr 1000000 -a1

    [...]
    < S  seq 1956977072 win 43690 TS val 295618 ecr 459956970
    > .  ack 1956911535 win 342 TS val 459967184 ecr 1547117608
    < R  seq 1956911535 win 0 length 0
+1. < S  seq 1956977072 win 43690 TS val 296640 ecr 459956970
    > S. seq 657450664 ack 1956977073 win 43690 TS val 459968205 ecr 296640

Fixes: 95a22caee396 ("tcp: randomize tcp timestamp offsets for each connection")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
v2: * remove 'else if' clause and add new variable 'seq' to store tmp result,
    * change slightly the subject and commit message.

 net/ipv4/tcp_ipv4.c |   16 ++++++++++------
 net/ipv6/tcp_ipv6.c |   16 ++++++++++------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fe9da4f..c5169b8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -145,6 +145,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 	struct flowi4 *fl4;
 	struct rtable *rt;
 	int err;
+	u32 seq;
 	struct ip_options_rcu *inet_opt;
 
 	if (addr_len < sizeof(struct sockaddr_in))
@@ -232,12 +233,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 	sk->sk_gso_type = SKB_GSO_TCPV4;
 	sk_setup_caps(sk, &rt->dst);
 
-	if (!tp->write_seq && likely(!tp->repair))
-		tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr,
-							   inet->inet_daddr,
-							   inet->inet_sport,
-							   usin->sin_port,
-							   &tp->tsoffset);
+	if (likely(!tp->repair)) {
+		seq = secure_tcp_sequence_number(inet->inet_saddr,
+						 inet->inet_daddr,
+						 inet->inet_sport,
+						 usin->sin_port,
+						 &tp->tsoffset);
+		if (!tp->write_seq)
+			tp->write_seq = seq;
+	}
 
 	inet->inet_id = tp->write_seq ^ jiffies;
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4c60c6f..e49a273 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -123,6 +123,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 	struct dst_entry *dst;
 	int addr_type;
 	int err;
+	u32 seq;
 
 	if (addr_len < SIN6_LEN_RFC2133)
 		return -EINVAL;
@@ -284,12 +285,15 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
 
 	sk_set_txhash(sk);
 
-	if (!tp->write_seq && likely(!tp->repair))
-		tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
-							     sk->sk_v6_daddr.s6_addr32,
-							     inet->inet_sport,
-							     inet->inet_dport,
-							     &tp->tsoffset);
+	if (likely(!tp->repair)) {
+		seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
+						   sk->sk_v6_daddr.s6_addr32,
+						   inet->inet_sport,
+						   inet->inet_dport,
+						   &tp->tsoffset);
+		if (!tp->write_seq)
+			tp->write_seq = seq;
+	}
 
 	err = tcp_connect(sk);
 	if (err)
-- 
1.7.1

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

* [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero
  2017-02-22 10:23 [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Alexey Kodanev
@ 2017-02-22 10:23 ` Alexey Kodanev
  2017-02-22 13:32   ` Eric Dumazet
  2017-02-22 21:34   ` David Miller
  2017-02-22 13:17 ` [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Eric Dumazet
  2017-02-22 21:33 ` David Miller
  2 siblings, 2 replies; 7+ messages in thread
From: Alexey Kodanev @ 2017-02-22 10:23 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Florian Westphal, Eric Dumazet, Alexey Kodanev

We can get SYN with zero tsecr, don't apply offset in this case.

Fixes: ee684b6f2830 ("tcp: send packets with a socket timestamp")
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
v2: no changes from the previous version

 net/ipv4/tcp_minisocks.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 28ce5ee..baff824 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -106,7 +106,8 @@ enum tcp_tw_status
 		tcp_parse_options(skb, &tmp_opt, 0, NULL);
 
 		if (tmp_opt.saw_tstamp) {
-			tmp_opt.rcv_tsecr	-= tcptw->tw_ts_offset;
+			if (tmp_opt.rcv_tsecr)
+				tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset;
 			tmp_opt.ts_recent	= tcptw->tw_ts_recent;
 			tmp_opt.ts_recent_stamp	= tcptw->tw_ts_recent_stamp;
 			paws_reject = tcp_paws_reject(&tmp_opt, th->rst);
-- 
1.7.1

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

* Re: [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set
  2017-02-22 10:23 [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Alexey Kodanev
  2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
@ 2017-02-22 13:17 ` Eric Dumazet
  2017-02-22 14:31   ` Alexey Kodanev
  2017-02-22 21:33 ` David Miller
  2 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2017-02-22 13:17 UTC (permalink / raw)
  To: Alexey Kodanev; +Cc: David Miller, netdev, Florian Westphal, Eric Dumazet

On Wed, 2017-02-22 at 13:23 +0300, Alexey Kodanev wrote:
> Found that when randomized tcp offsets are enabled (by default)
> TCP client can still start new connections without them. Later,
> if server does active close and re-uses sockets in TIME-WAIT
> state, new SYN from client can be rejected on PAWS check inside
> tcp_timewait_state_process(), because either tw_ts_recent or
> rcv_tsval doesn't really have an offset set.
> 
> Here is how to reproduce it with LTP netstress tool:
>     netstress -R 1 &
>     netstress -H 127.0.0.1 -lr 1000000 -a1
> 
>     [...]
>     < S  seq 1956977072 win 43690 TS val 295618 ecr 459956970
>     > .  ack 1956911535 win 342 TS val 459967184 ecr 1547117608
>     < R  seq 1956911535 win 0 length 0
> +1. < S  seq 1956977072 win 43690 TS val 296640 ecr 459956970
>     > S. seq 657450664 ack 1956977073 win 43690 TS val 459968205 ecr 296640
> 
> Fixes: 95a22caee396 ("tcp: randomize tcp timestamp offsets for each connection")
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
> ---
> v2: * remove 'else if' clause and add new variable 'seq' to store tmp result,
>     * change slightly the subject and commit message.
> 
>  net/ipv4/tcp_ipv4.c |   16 ++++++++++------
>  net/ipv6/tcp_ipv6.c |   16 ++++++++++------
>  2 files changed, 20 insertions(+), 12 deletions(-)
> 
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index fe9da4f..c5169b8 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -145,6 +145,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>  	struct flowi4 *fl4;
>  	struct rtable *rt;
>  	int err;
> +	u32 seq;
>  	struct ip_options_rcu *inet_opt;
>  
>  	if (addr_len < sizeof(struct sockaddr_in))
> @@ -232,12 +233,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>  	sk->sk_gso_type = SKB_GSO_TCPV4;
>  	sk_setup_caps(sk, &rt->dst);
>  
> -	if (!tp->write_seq && likely(!tp->repair))
> -		tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr,
> -							   inet->inet_daddr,
> -							   inet->inet_sport,
> -							   usin->sin_port,
> -							   &tp->tsoffset);
> +	if (likely(!tp->repair)) {
> +		seq = secure_tcp_sequence_number(inet->inet_saddr,
> +						 inet->inet_daddr,
> +						 inet->inet_sport,
> +						 usin->sin_port,
> +						 &tp->tsoffset);
> +		if (!tp->write_seq)
> +			tp->write_seq = seq;
> +	}
>  

Nice catch !

secure_tcp_sequence_number() could be renamed, because it has two
purposes really.

Acked-by: Eric Dumazet <edumazet@google.com>

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

* Re: [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero
  2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
@ 2017-02-22 13:32   ` Eric Dumazet
  2017-02-22 21:34   ` David Miller
  1 sibling, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2017-02-22 13:32 UTC (permalink / raw)
  To: Alexey Kodanev; +Cc: David Miller, netdev, Florian Westphal, Eric Dumazet

On Wed, 2017-02-22 at 13:23 +0300, Alexey Kodanev wrote:
> We can get SYN with zero tsecr, don't apply offset in this case.
> 
> Fixes: ee684b6f2830 ("tcp: send packets with a socket timestamp")
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
> ---
> v2: no changes from the previous version

Acked-by: Eric Dumazet <edumazet@google.com>

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

* Re: [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set
  2017-02-22 13:17 ` [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Eric Dumazet
@ 2017-02-22 14:31   ` Alexey Kodanev
  0 siblings, 0 replies; 7+ messages in thread
From: Alexey Kodanev @ 2017-02-22 14:31 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Florian Westphal, Eric Dumazet

On 02/22/2017 04:17 PM, Eric Dumazet wrote:
> On Wed, 2017-02-22 at 13:23 +0300, Alexey Kodanev wrote:
>> ...
>>
>> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
>> index fe9da4f..c5169b8 100644
>> --- a/net/ipv4/tcp_ipv4.c
>> +++ b/net/ipv4/tcp_ipv4.c
>> @@ -145,6 +145,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>>  	struct flowi4 *fl4;
>>  	struct rtable *rt;
>>  	int err;
>> +	u32 seq;
>>  	struct ip_options_rcu *inet_opt;
>>  
>>  	if (addr_len < sizeof(struct sockaddr_in))
>> @@ -232,12 +233,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>>  	sk->sk_gso_type = SKB_GSO_TCPV4;
>>  	sk_setup_caps(sk, &rt->dst);
>>  
>> -	if (!tp->write_seq && likely(!tp->repair))
>> -		tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr,
>> -							   inet->inet_daddr,
>> -							   inet->inet_sport,
>> -							   usin->sin_port,
>> -							   &tp->tsoffset);
>> +	if (likely(!tp->repair)) {
>> +		seq = secure_tcp_sequence_number(inet->inet_saddr,
>> +						 inet->inet_daddr,
>> +						 inet->inet_sport,
>> +						 usin->sin_port,
>> +						 &tp->tsoffset);
>> +		if (!tp->write_seq)
>> +			tp->write_seq = seq;
>> +	}
>>  
> Nice catch !
>
> secure_tcp_sequence_number() could be renamed, because it has two
> purposes really.

What about "secure_tcp_seq_and_tsoff(...)" ?

Also,

tcp_v4_init_sequence(...) -> tcp_v4_init_seq_and_tsoff(...)
tcp_v6_init_sequence(...) -> tcp_v6_init_seq_and_tsoff(...)


Thanks,
Alexey

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

* Re: [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set
  2017-02-22 10:23 [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Alexey Kodanev
  2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
  2017-02-22 13:17 ` [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Eric Dumazet
@ 2017-02-22 21:33 ` David Miller
  2 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2017-02-22 21:33 UTC (permalink / raw)
  To: alexey.kodanev; +Cc: netdev, fw, edumazet

From: Alexey Kodanev <alexey.kodanev@oracle.com>
Date: Wed, 22 Feb 2017 13:23:55 +0300

> Found that when randomized tcp offsets are enabled (by default)
> TCP client can still start new connections without them. Later,
> if server does active close and re-uses sockets in TIME-WAIT
> state, new SYN from client can be rejected on PAWS check inside
> tcp_timewait_state_process(), because either tw_ts_recent or
> rcv_tsval doesn't really have an offset set.
> 
> Here is how to reproduce it with LTP netstress tool:
>     netstress -R 1 &
>     netstress -H 127.0.0.1 -lr 1000000 -a1
> 
>     [...]
>     < S  seq 1956977072 win 43690 TS val 295618 ecr 459956970
>     > .  ack 1956911535 win 342 TS val 459967184 ecr 1547117608
>     < R  seq 1956911535 win 0 length 0
> +1. < S  seq 1956977072 win 43690 TS val 296640 ecr 459956970
>     > S. seq 657450664 ack 1956977073 win 43690 TS val 459968205 ecr 296640
> 
> Fixes: 95a22caee396 ("tcp: randomize tcp timestamp offsets for each connection")
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>

Applied.

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

* Re: [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero
  2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
  2017-02-22 13:32   ` Eric Dumazet
@ 2017-02-22 21:34   ` David Miller
  1 sibling, 0 replies; 7+ messages in thread
From: David Miller @ 2017-02-22 21:34 UTC (permalink / raw)
  To: alexey.kodanev; +Cc: netdev, fw, edumazet

From: Alexey Kodanev <alexey.kodanev@oracle.com>
Date: Wed, 22 Feb 2017 13:23:56 +0300

> We can get SYN with zero tsecr, don't apply offset in this case.
> 
> Fixes: ee684b6f2830 ("tcp: send packets with a socket timestamp")
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>

Applied.

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

end of thread, other threads:[~2017-02-22 21:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-22 10:23 [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Alexey Kodanev
2017-02-22 10:23 ` [PATCH v2 2/2] tcp: account for ts offset only if tsecr not zero Alexey Kodanev
2017-02-22 13:32   ` Eric Dumazet
2017-02-22 21:34   ` David Miller
2017-02-22 13:17 ` [PATCH v2 1/2] tcp: setup timestamp offset when write_seq already set Eric Dumazet
2017-02-22 14:31   ` Alexey Kodanev
2017-02-22 21:33 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.