All of lore.kernel.org
 help / color / mirror / Atom feed
* [MPTCP] Re: [PATCH net] mptcp: fix NULL ptr dereference in MP_JOIN error path
@ 2020-05-28 15:42 Christoph Paasch
  0 siblings, 0 replies; 3+ messages in thread
From: Christoph Paasch @ 2020-05-28 15:42 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 3506 bytes --]

On 05/28/20 - 15:35, Paolo Abeni wrote:
> On Thu, 2020-05-28 at 15:27 +0200, Paolo Abeni wrote:
> > When token lookup on MP_JOIN 3rd ack fails, the server
> > socket closes with a reset the incoming child. Such socket
> > has the 'is_mptcp' flag set, but no msk socket associated
> > - due to the failed lookup.
> > 
> > While crafting the reset packet mptcp_established_options_mp()
> > will try to dereference the child's master socket, causing
> > a NULL ptr dereference.
> > 
> > This change addresses the issue with explicit fallback to
> > TCP in such error path.
> > 
> > Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
> > Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
> > ---
> >  net/mptcp/subflow.c | 17 +++++++++++++----
> >  net/mptcp/token.c   | 10 +++++++---
> >  2 files changed, 20 insertions(+), 7 deletions(-)
> > 
> > diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> > index ae7bcdb7f990..55fced4f136d 100644
> > --- a/net/mptcp/subflow.c
> > +++ b/net/mptcp/subflow.c
> > @@ -408,6 +408,17 @@ static void subflow_ulp_fallback(struct sock *sk,
> >  	tcp_sk(sk)->is_mptcp = 0;
> >  }
> >  
> > +static void subflow_drop_ctx(struct sock *ssk)
> > +{
> > +	struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(ssk);
> > +
> > +	if (!ctx)
> > +		return;
> > +
> > +	subflow_ulp_fallback(ssk, ctx);
> > +	kfree_rcu(ctx, rcu);
> > +}
> > +
> >  static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> >  					  struct sk_buff *skb,
> >  					  struct request_sock *req,
> > @@ -480,10 +491,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> >  			if (fallback_is_fatal)
> >  				goto dispose_child;
> >  
> > -			if (ctx) {
> > -				subflow_ulp_fallback(child, ctx);
> > -				kfree_rcu(ctx, rcu);
> > -			}
> > +			subflow_drop_ctx(child);
> >  			goto out;
> >  		}
> >  
> > @@ -532,6 +540,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
> >  	return child;
> >  
> >  dispose_child:
> > +	subflow_drop_ctx(child);
> >  	tcp_rsk(req)->drop_req = true;
> >  	tcp_send_active_reset(child, GFP_ATOMIC);
> >  	inet_csk_prepare_for_destroy_sock(child);
> > diff --git a/net/mptcp/token.c b/net/mptcp/token.c
> > index c0327ff5d1b7..d1068b51a45a 100644
> > --- a/net/mptcp/token.c
> > +++ b/net/mptcp/token.c
> > @@ -216,16 +216,20 @@ struct mptcp_sock *mptcp_token_get_sock(u32 token)
> >  		msk = mptcp_sk(sk);
> >  		if (READ_ONCE(msk->token) != token)
> >  			continue;
> > -		if (!refcount_inc_not_zero(&sk->sk_refcnt))
> > +		if (!refcount_inc_not_zero(&sk->sk_refcnt)) {
> > +			pr_warn("token match %x but 0 rfcnt\n", token);
> >  			goto not_found;
> > -		if (READ_ONCE(msk->token) != token) {
> > +		} if (READ_ONCE(msk->token) != token) {
> > +			pr_warn("token mis-match %x:%x after get\n", READ_ONCE(msk->token), token);
> >  			sock_put(sk);
> >  			goto again;
> >  		}
> >  		goto found;
> >  	}
> > -	if (get_nulls_value(pos) != (token & token_mask))
> > +	if (get_nulls_value(pos) != (token & token_mask)) {
> > +		pr_warn("moved nulls %ld id %d\n", get_nulls_value(pos), token & token_mask);
> >  		goto again;
> > +	}
> >  
> >  not_found:
> >  	msk = NULL;
> 
> whoops, I rushed too much and included also unneeded dbg. will send a
> v2 later.
> 
> Sorry for the noise,

And I didn't read this email here before reading your other one ;-)

Sorry for the noise as well!


Christoph

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

* [MPTCP] Re: [PATCH net] mptcp: fix NULL ptr dereference in MP_JOIN error path
@ 2020-05-28 15:41 Christoph Paasch
  0 siblings, 0 replies; 3+ messages in thread
From: Christoph Paasch @ 2020-05-28 15:41 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 3140 bytes --]

On 05/28/20 - 15:27, Paolo Abeni wrote:
> When token lookup on MP_JOIN 3rd ack fails, the server
> socket closes with a reset the incoming child. Such socket
> has the 'is_mptcp' flag set, but no msk socket associated
> - due to the failed lookup.
> 
> While crafting the reset packet mptcp_established_options_mp()
> will try to dereference the child's master socket, causing
> a NULL ptr dereference.
> 
> This change addresses the issue with explicit fallback to
> TCP in such error path.
> 
> Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
> Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
> ---
>  net/mptcp/subflow.c | 17 +++++++++++++----
>  net/mptcp/token.c   | 10 +++++++---
>  2 files changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index ae7bcdb7f990..55fced4f136d 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -408,6 +408,17 @@ static void subflow_ulp_fallback(struct sock *sk,
>  	tcp_sk(sk)->is_mptcp = 0;
>  }
>  
> +static void subflow_drop_ctx(struct sock *ssk)
> +{
> +	struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(ssk);
> +
> +	if (!ctx)
> +		return;
> +
> +	subflow_ulp_fallback(ssk, ctx);
> +	kfree_rcu(ctx, rcu);
> +}
> +
>  static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  					  struct sk_buff *skb,
>  					  struct request_sock *req,
> @@ -480,10 +491,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  			if (fallback_is_fatal)
>  				goto dispose_child;
>  
> -			if (ctx) {
> -				subflow_ulp_fallback(child, ctx);
> -				kfree_rcu(ctx, rcu);
> -			}
> +			subflow_drop_ctx(child);
>  			goto out;
>  		}
>  
> @@ -532,6 +540,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  	return child;
>  
>  dispose_child:
> +	subflow_drop_ctx(child);
>  	tcp_rsk(req)->drop_req = true;
>  	tcp_send_active_reset(child, GFP_ATOMIC);
>  	inet_csk_prepare_for_destroy_sock(child);
> diff --git a/net/mptcp/token.c b/net/mptcp/token.c
> index c0327ff5d1b7..d1068b51a45a 100644
> --- a/net/mptcp/token.c
> +++ b/net/mptcp/token.c
> @@ -216,16 +216,20 @@ struct mptcp_sock *mptcp_token_get_sock(u32 token)
>  		msk = mptcp_sk(sk);
>  		if (READ_ONCE(msk->token) != token)
>  			continue;
> -		if (!refcount_inc_not_zero(&sk->sk_refcnt))
> +		if (!refcount_inc_not_zero(&sk->sk_refcnt)) {
> +			pr_warn("token match %x but 0 rfcnt\n", token);
>  			goto not_found;
> -		if (READ_ONCE(msk->token) != token) {
> +		} if (READ_ONCE(msk->token) != token) {
> +			pr_warn("token mis-match %x:%x after get\n", READ_ONCE(msk->token), token);
>  			sock_put(sk);
>  			goto again;
>  		}
>  		goto found;
>  	}
> -	if (get_nulls_value(pos) != (token & token_mask))
> +	if (get_nulls_value(pos) != (token & token_mask)) {
> +		pr_warn("moved nulls %ld id %d\n", get_nulls_value(pos), token & token_mask);
>  		goto again;
> +	}

Just wondering if these warns are necessary, as they could trigger often on
a busy server. Maybe they should be pr_debug ?


Christoph

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

* [MPTCP] Re: [PATCH net] mptcp: fix NULL ptr dereference in MP_JOIN error path
@ 2020-05-28 13:35 Paolo Abeni
  0 siblings, 0 replies; 3+ messages in thread
From: Paolo Abeni @ 2020-05-28 13:35 UTC (permalink / raw)
  To: mptcp

[-- Attachment #1: Type: text/plain, Size: 3166 bytes --]

On Thu, 2020-05-28 at 15:27 +0200, Paolo Abeni wrote:
> When token lookup on MP_JOIN 3rd ack fails, the server
> socket closes with a reset the incoming child. Such socket
> has the 'is_mptcp' flag set, but no msk socket associated
> - due to the failed lookup.
> 
> While crafting the reset packet mptcp_established_options_mp()
> will try to dereference the child's master socket, causing
> a NULL ptr dereference.
> 
> This change addresses the issue with explicit fallback to
> TCP in such error path.
> 
> Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
> Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
> ---
>  net/mptcp/subflow.c | 17 +++++++++++++----
>  net/mptcp/token.c   | 10 +++++++---
>  2 files changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
> index ae7bcdb7f990..55fced4f136d 100644
> --- a/net/mptcp/subflow.c
> +++ b/net/mptcp/subflow.c
> @@ -408,6 +408,17 @@ static void subflow_ulp_fallback(struct sock *sk,
>  	tcp_sk(sk)->is_mptcp = 0;
>  }
>  
> +static void subflow_drop_ctx(struct sock *ssk)
> +{
> +	struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(ssk);
> +
> +	if (!ctx)
> +		return;
> +
> +	subflow_ulp_fallback(ssk, ctx);
> +	kfree_rcu(ctx, rcu);
> +}
> +
>  static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  					  struct sk_buff *skb,
>  					  struct request_sock *req,
> @@ -480,10 +491,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  			if (fallback_is_fatal)
>  				goto dispose_child;
>  
> -			if (ctx) {
> -				subflow_ulp_fallback(child, ctx);
> -				kfree_rcu(ctx, rcu);
> -			}
> +			subflow_drop_ctx(child);
>  			goto out;
>  		}
>  
> @@ -532,6 +540,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
>  	return child;
>  
>  dispose_child:
> +	subflow_drop_ctx(child);
>  	tcp_rsk(req)->drop_req = true;
>  	tcp_send_active_reset(child, GFP_ATOMIC);
>  	inet_csk_prepare_for_destroy_sock(child);
> diff --git a/net/mptcp/token.c b/net/mptcp/token.c
> index c0327ff5d1b7..d1068b51a45a 100644
> --- a/net/mptcp/token.c
> +++ b/net/mptcp/token.c
> @@ -216,16 +216,20 @@ struct mptcp_sock *mptcp_token_get_sock(u32 token)
>  		msk = mptcp_sk(sk);
>  		if (READ_ONCE(msk->token) != token)
>  			continue;
> -		if (!refcount_inc_not_zero(&sk->sk_refcnt))
> +		if (!refcount_inc_not_zero(&sk->sk_refcnt)) {
> +			pr_warn("token match %x but 0 rfcnt\n", token);
>  			goto not_found;
> -		if (READ_ONCE(msk->token) != token) {
> +		} if (READ_ONCE(msk->token) != token) {
> +			pr_warn("token mis-match %x:%x after get\n", READ_ONCE(msk->token), token);
>  			sock_put(sk);
>  			goto again;
>  		}
>  		goto found;
>  	}
> -	if (get_nulls_value(pos) != (token & token_mask))
> +	if (get_nulls_value(pos) != (token & token_mask)) {
> +		pr_warn("moved nulls %ld id %d\n", get_nulls_value(pos), token & token_mask);
>  		goto again;
> +	}
>  
>  not_found:
>  	msk = NULL;

whoops, I rushed too much and included also unneeded dbg. will send a
v2 later.

Sorry for the noise,

Paolo

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

end of thread, other threads:[~2020-05-28 15:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-28 15:42 [MPTCP] Re: [PATCH net] mptcp: fix NULL ptr dereference in MP_JOIN error path Christoph Paasch
  -- strict thread matches above, loose matches on Subject: below --
2020-05-28 15:41 Christoph Paasch
2020-05-28 13:35 Paolo Abeni

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.