* [PATCH net] tcp: avoid fastopen API to be used on AF_UNSPEC
@ 2017-05-24 16:59 Wei Wang
2017-05-25 17:30 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Wei Wang @ 2017-05-24 16:59 UTC (permalink / raw)
To: David Miller, netdev; +Cc: Yuchung Cheng, Vegard Nossum, Eric Dumazet, Wei Wang
From: Wei Wang <weiwan@google.com>
Fastopen API should be used to perform fastopen operations on the TCP
socket. It does not make sense to use fastopen API to perform disconnect
by calling it with AF_UNSPEC. The fastopen data path is also prone to
race conditions and bugs when using with AF_UNSPEC.
One issue reported and analyzed by Vegard Nossum is as follows:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Thread A: Thread B:
------------------------------------------------------------------------
sendto()
- tcp_sendmsg()
- sk_stream_memory_free() = 0
- goto wait_for_sndbuf
- sk_stream_wait_memory()
- sk_wait_event() // sleep
| sendto(flags=MSG_FASTOPEN, dest_addr=AF_UNSPEC)
| - tcp_sendmsg()
| - tcp_sendmsg_fastopen()
| - __inet_stream_connect()
| - tcp_disconnect() //because of AF_UNSPEC
| - tcp_transmit_skb()// send RST
| - return 0; // no reconnect!
| - sk_stream_wait_connect()
| - sock_error()
| - xchg(&sk->sk_err, 0)
| - return -ECONNRESET
- ... // wake up, see sk->sk_err == 0
- skb_entail() on TCP_CLOSE socket
If the connection is reopened then we will send a brand new SYN packet
after thread A has already queued a buffer. At this point I think the
socket internal state (sequence numbers etc.) becomes messed up.
When the new connection is closed, the FIN-ACK is rejected because the
sequence number is outside the window. The other side tries to
retransmit,
but __tcp_retransmit_skb() calls tcp_trim_head() on an empty skb which
corrupts the skb data length and hits a BUG() in copy_and_csum_bits().
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hence, this patch adds a check for AF_UNSPEC in the fastopen data path
and return EOPNOTSUPP to user if such case happens.
Fixes: cf60af03ca4e7 ("tcp: Fast Open client - sendmsg(MSG_FASTOPEN)")
Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 60203f1c793e..fea7c4f2d36c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1161,9 +1161,12 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
{
struct tcp_sock *tp = tcp_sk(sk);
struct inet_sock *inet = inet_sk(sk);
+ struct sockaddr *uaddr = msg->msg_name;
int err, flags;
- if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE))
+ if (!(sysctl_tcp_fastopen & TFO_CLIENT_ENABLE) ||
+ (uaddr && msg->msg_namelen >= sizeof(uaddr->sa_family) &&
+ uaddr->sa_family == AF_UNSPEC))
return -EOPNOTSUPP;
if (tp->fastopen_req)
return -EALREADY; /* Another Fast Open is in progress */
@@ -1185,7 +1188,7 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
}
}
flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
- err = __inet_stream_connect(sk->sk_socket, msg->msg_name,
+ err = __inet_stream_connect(sk->sk_socket, uaddr,
msg->msg_namelen, flags, 1);
/* fastopen_req could already be freed in __inet_stream_connect
* if the connection times out or gets rst
--
2.13.0.219.gdb65acc882-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net] tcp: avoid fastopen API to be used on AF_UNSPEC
2017-05-24 16:59 [PATCH net] tcp: avoid fastopen API to be used on AF_UNSPEC Wei Wang
@ 2017-05-25 17:30 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2017-05-25 17:30 UTC (permalink / raw)
To: weiwan; +Cc: netdev, ycheng, vegard.nossum, edumazet
From: Wei Wang <weiwan@google.com>
Date: Wed, 24 May 2017 09:59:31 -0700
> Fastopen API should be used to perform fastopen operations on the TCP
> socket. It does not make sense to use fastopen API to perform disconnect
> by calling it with AF_UNSPEC. The fastopen data path is also prone to
> race conditions and bugs when using with AF_UNSPEC.
>
> One issue reported and analyzed by Vegard Nossum is as follows:
...
> If the connection is reopened then we will send a brand new SYN packet
> after thread A has already queued a buffer. At this point I think the
> socket internal state (sequence numbers etc.) becomes messed up.
>
> When the new connection is closed, the FIN-ACK is rejected because the
> sequence number is outside the window. The other side tries to
> retransmit,
> but __tcp_retransmit_skb() calls tcp_trim_head() on an empty skb which
> corrupts the skb data length and hits a BUG() in copy_and_csum_bits().
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Hence, this patch adds a check for AF_UNSPEC in the fastopen data path
> and return EOPNOTSUPP to user if such case happens.
>
> Fixes: cf60af03ca4e7 ("tcp: Fast Open client - sendmsg(MSG_FASTOPEN)")
> Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
> Signed-off-by: Wei Wang <weiwan@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queue up for -stable, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-05-25 17:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-24 16:59 [PATCH net] tcp: avoid fastopen API to be used on AF_UNSPEC Wei Wang
2017-05-25 17:30 ` 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).