Hi,

On Mon, 2020-11-23 at 12:57 +0100, Eric Dumazet wrote:
> > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> > index 4ae2c4a30e44..748343f1a968 100644
> > --- a/net/mptcp/protocol.c
> > +++ b/net/mptcp/protocol.c
> > @@ -407,16 +407,42 @@ static void mptcp_set_timeout(const struct sock *sk, 
> > const struct sock *ssk)
> >     mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN;
> >  }
> >  
> > -static void mptcp_send_ack(struct mptcp_sock *msk)
> > +static bool mptcp_subflow_active(struct mptcp_subflow_context *subflow)
> > +{
> > +   struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> > +
> > +   /* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */
> > +   if (subflow->request_join && !subflow->fully_established)
> > +           return false;
> > +
> > +   /* only send if our side has not closed yet */
> > +   return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT));
> > +}
> > +
> > +static void mptcp_send_ack(struct mptcp_sock *msk, bool force)
> >  {
> >     struct mptcp_subflow_context *subflow;
> > +   struct sock *pick = NULL;
> >  
> >     mptcp_for_each_subflow(msk, subflow) {
> >             struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
> >  
> > -           lock_sock(ssk);
> > -           tcp_send_ack(ssk);
> > -           release_sock(ssk);
> > +           if (force) {
> > +                   lock_sock(ssk);
> > +                   tcp_send_ack(ssk);
> > +                   release_sock(ssk);
> > +                   continue;
> > +           }
> > +
> > +           /* if the hintes ssk is still active, use it */
> > +           pick = ssk;
> > +           if (ssk == msk->ack_hint)
> > +                   break;
> > +   }
> > +   if (!force && pick) {
> > +           lock_sock(pick);
> > +           tcp_cleanup_rbuf(pick, 1);
> 
> Calling tcp_cleanup_rbuf() on a socket that was never established is going to 
> fail
> with a divide by 0 (mss being 0)
> 
> AFAIK, mptcp_recvmsg() can be called right after a socket(AF_INET, 
> SOCK_STREAM, IPPROTO_MPTCP)
> call.
> 
> Probably, after a lock_sock(), you should double check socket state (same 
> above before calling tcp_send_ack())

Thank you for looking into this.

Indeed you are right! I'll try to cook a fix.

Cheers,

Paolo

Reply via email to