MPTCP Linux Development
 help / color / mirror / Atom feed
From: Mat Martineau <martineau@kernel.org>
To: Davide Caratti <dcaratti@redhat.com>
Cc: Matthieu Baerts <matttbe@kernel.org>, mptcp@lists.linux.dev
Subject: Re: [PATCH mptcp-net] mptcp: fix double-free on socket dismantle
Date: Wed, 21 Feb 2024 18:32:58 -0800 (PST)	[thread overview]
Message-ID: <dfe6b689-b36e-a38d-aed0-8894c99e382d@kernel.org> (raw)
In-Reply-To: <47b5459f6b9b07c5a669d5a5233b35cf6ec601ac.1708532911.git.dcaratti@redhat.com>

On Wed, 21 Feb 2024, Davide Caratti wrote:

> when MPTCP server accepts an incoming connection, it clones its listener
> socket. However, the pointer to 'inet_opt' for the new socket has the same
> value as the original one: as a consequence, on program exit it's possible
> to observe the following splat:
>
...
>
> Something similar (a refcount underflow) happens with CALIPSO/IPv6. Fix
> this by duplicating IP / IPv6 options after clone, so that
> ip{,6}_sock_destruct() doesn't end up freeing the same memory area twice.
>
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
> ---
> net/mptcp/protocol.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 49 insertions(+)

Thanks Davide. Looks good to me, and the appropriate "fixes" tag goes all 
the way back to the beginning:

Fixes: cf7da0d66cc1 ("mptcp: Create SUBFLOW socket for incoming connections")

Reviewed-by: Mat Martineau <martineau@kernel.org>


>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 50dcba41b6ef..352334bda0e3 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -3202,8 +3202,50 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk)
>
> 	return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
> }
> +
> +static void mptcp_copy_ip6_options(struct sock *newsk, const struct sock *sk)
> +{
> +	const struct ipv6_pinfo *np = inet6_sk(sk);
> +	struct ipv6_txoptions *opt;
> +	struct ipv6_pinfo *newnp;
> +
> +	newnp = inet6_sk(newsk);
> +
> +	rcu_read_lock();
> +	opt = rcu_dereference(np->opt);
> +	if (opt) {
> +		opt = ipv6_dup_options(newsk, opt);
> +		if (!opt)
> +			net_warn_ratelimited("%s: Failed to copy ip6 options\n", __func__);
> +	}
> +	RCU_INIT_POINTER(newnp->opt, opt);
> +	rcu_read_unlock();
> +}
> #endif
>
> +static void mptcp_copy_ip_options(struct sock *newsk, const struct sock *sk)
> +{
> +	struct ip_options_rcu *inet_opt, *newopt = NULL;
> +	const struct inet_sock *inet = inet_sk(sk);
> +	struct inet_sock *newinet;
> +
> +	newinet = inet_sk(newsk);
> +
> +	rcu_read_lock();
> +	inet_opt = rcu_dereference(inet->inet_opt);
> +	if (inet_opt) {
> +		newopt = sock_kmalloc(newsk, sizeof(*inet_opt) +
> +				      inet_opt->opt.optlen, GFP_ATOMIC);
> +		if (newopt)
> +			memcpy(newopt, inet_opt, sizeof(*inet_opt) +
> +			       inet_opt->opt.optlen);
> +		else
> +			net_warn_ratelimited("%s: Failed to copy ip options\n", __func__);
> +	}
> +	RCU_INIT_POINTER(newinet->inet_opt, newopt);
> +	rcu_read_unlock();
> +}
> +
> struct sock *mptcp_sk_clone_init(const struct sock *sk,
> 				 const struct mptcp_options_received *mp_opt,
> 				 struct sock *ssk,
> @@ -3224,6 +3266,13 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
>
> 	__mptcp_init_sock(nsk);
>
> +#if IS_ENABLED(CONFIG_MPTCP_IPV6)
> +	if (nsk->sk_family == AF_INET6)
> +		mptcp_copy_ip6_options(nsk, sk);
> +	else
> +#endif
> +		mptcp_copy_ip_options(nsk, sk);
> +
> 	msk = mptcp_sk(nsk);
> 	WRITE_ONCE(msk->local_key, subflow_req->local_key);
> 	WRITE_ONCE(msk->token, subflow_req->token);
> -- 
> 2.43.0
>
>
>

  parent reply	other threads:[~2024-02-22  2:32 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-21 16:30 [PATCH mptcp-net] mptcp: fix double-free on socket dismantle Davide Caratti
2024-02-21 17:25 ` mptcp: fix double-free on socket dismantle: Tests Results MPTCP CI
2024-02-22  2:32 ` Mat Martineau [this message]
2024-02-22  3:26 ` MPTCP CI
2024-02-22  9:21 ` [PATCH mptcp-net] mptcp: fix double-free on socket dismantle Matthieu Baerts

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dfe6b689-b36e-a38d-aed0-8894c99e382d@kernel.org \
    --to=martineau@kernel.org \
    --cc=dcaratti@redhat.com \
    --cc=matttbe@kernel.org \
    --cc=mptcp@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox