On Wed, Nov 2, 2016 at 5:41 PM, Eric Dumazet <eric.duma...@gmail.com> wrote: > From: Eric Dumazet <eduma...@google.com> > > After my commit, tcp_sendmsg() might restart its loop after > processing socket backlog. > > If sk_err is set, we blindly return an error, even though we > copied data to user space before. > > We should instead return number of bytes that could be copied, > otherwise user space might resend data and corrupt the stream. > > This might happen if another thread is using recvmsg(MSG_ERRQUEUE) > to process timestamps. > > Issue was diagnosed by Soheil and Willem, big kudos to them ! > > Fixes: d41a69f1d390f ("tcp: make tcp_sendmsg() aware of socket backlog") > Signed-off-by: Eric Dumazet <eduma...@google.com> > Cc: Willem de Bruijn <will...@google.com> > Cc: Soheil Hassas Yeganeh <soh...@google.com> > Cc: Yuchung Cheng <ych...@google.com> > Cc: Neal Cardwell <ncardw...@google.com>
Tested-by: Soheil Hassas Yeganeh <soh...@google.com> > --- > net/ipv4/tcp.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index 3251fe71f39f..19e1468bf8ea 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -1164,7 +1164,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, > size_t size) > > err = -EPIPE; > if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) > - goto out_err; > + goto do_error; > > sg = !!(sk->sk_route_caps & NETIF_F_SG); > > > Nice fix. Thanks, Eric!