net/mptcp/protocol.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
The self-tests in a loop triggered a UaF similar to:
https://github.com/multipath-tcp/mptcp_net-next/issues/250
The critical scenario is actually almost fixed by:
"mptcp: cleanup MPJ subflow list handling"
with a notable exception: if an MPJ handshake races with
mptcp_close(), the subflow enter the join_list and __mptcp_finish_join()
is processed at the msk socket lock release in mptcp_close(),
the subflow will preserver a danfling reference to the msk sk_socket.
Address the issue fragting the subflow only on successful
__mptcp_finish_join()
Note that issues/250 triggers even before
"mptcp: cleanup MPJ subflow list handling", as before such commit the join
list was not spliced by mptcp_close(). We could consider a net-only patch to
address that.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
net/mptcp/protocol.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e81fd46a43c4..e89d7741aa7f 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -810,9 +810,17 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
{
- if (((struct sock *)msk)->sk_state != TCP_ESTABLISHED)
+ struct sock *sk = (struct sock *)msk;
+
+ if (sk->sk_state != TCP_ESTABLISHED)
return false;
+ /* attach to msk socket only after we are sure we will deal with it
+ * at close time
+ */
+ if (sk->sk_socket && !ssk->sk_socket)
+ mptcp_sock_graft(ssk, sk->sk_socket);
+
mptcp_propagate_sndbuf((struct sock *)msk, ssk);
mptcp_sockopt_sync_locked(msk, ssk);
WRITE_ONCE(msk->allow_infinite_fallback, false);
@@ -3234,7 +3242,6 @@ bool mptcp_finish_join(struct sock *ssk)
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
struct mptcp_sock *msk = mptcp_sk(subflow->conn);
struct sock *parent = (void *)msk;
- struct socket *parent_sock;
bool ret = true;
pr_debug("msk=%p, subflow=%p", msk, subflow);
@@ -3278,13 +3285,6 @@ bool mptcp_finish_join(struct sock *ssk)
return false;
}
- /* attach to msk socket only after we are sure he will deal with us
- * at close time
- */
- parent_sock = READ_ONCE(parent->sk_socket);
- if (parent_sock && !ssk->sk_socket)
- mptcp_sock_graft(ssk, parent_sock);
-
subflow->map_seq = READ_ONCE(msk->ack_seq);
out:
--
2.33.1
On Thu, 16 Dec 2021, Paolo Abeni wrote:
> The self-tests in a loop triggered a UaF similar to:
>
> https://github.com/multipath-tcp/mptcp_net-next/issues/250
>
> The critical scenario is actually almost fixed by:
>
> "mptcp: cleanup MPJ subflow list handling"
>
> with a notable exception: if an MPJ handshake races with
> mptcp_close(), the subflow enter the join_list and __mptcp_finish_join()
> is processed at the msk socket lock release in mptcp_close(),
> the subflow will preserver a danfling reference to the msk sk_socket.
>
> Address the issue fragting the subflow only on successful
^^^^^^^^ grafting?
Change looks good to squash, and the tests (other than the one ipv6 issue)
are ok on my local system.
> __mptcp_finish_join()
>
> Note that issues/250 triggers even before
> "mptcp: cleanup MPJ subflow list handling", as before such commit the join
> list was not spliced by mptcp_close(). We could consider a net-only patch to
> address that.
Yes, definitely need something for #250 in net.
Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> net/mptcp/protocol.c | 18 +++++++++---------
> 1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index e81fd46a43c4..e89d7741aa7f 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -810,9 +810,17 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
>
> static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
> {
> - if (((struct sock *)msk)->sk_state != TCP_ESTABLISHED)
> + struct sock *sk = (struct sock *)msk;
> +
> + if (sk->sk_state != TCP_ESTABLISHED)
> return false;
>
> + /* attach to msk socket only after we are sure we will deal with it
> + * at close time
> + */
> + if (sk->sk_socket && !ssk->sk_socket)
> + mptcp_sock_graft(ssk, sk->sk_socket);
> +
> mptcp_propagate_sndbuf((struct sock *)msk, ssk);
> mptcp_sockopt_sync_locked(msk, ssk);
> WRITE_ONCE(msk->allow_infinite_fallback, false);
> @@ -3234,7 +3242,6 @@ bool mptcp_finish_join(struct sock *ssk)
> struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
> struct mptcp_sock *msk = mptcp_sk(subflow->conn);
> struct sock *parent = (void *)msk;
> - struct socket *parent_sock;
> bool ret = true;
>
> pr_debug("msk=%p, subflow=%p", msk, subflow);
> @@ -3278,13 +3285,6 @@ bool mptcp_finish_join(struct sock *ssk)
> return false;
> }
>
> - /* attach to msk socket only after we are sure he will deal with us
> - * at close time
> - */
> - parent_sock = READ_ONCE(parent->sk_socket);
> - if (parent_sock && !ssk->sk_socket)
> - mptcp_sock_graft(ssk, parent_sock);
> -
> subflow->map_seq = READ_ONCE(msk->ack_seq);
>
> out:
> --
> 2.33.1
>
>
>
--
Mat Martineau
Intel
Hi Paolo, Mat, On 16/12/2021 15:33, Paolo Abeni wrote: > The self-tests in a loop triggered a UaF similar to: > > https://github.com/multipath-tcp/mptcp_net-next/issues/250 > > The critical scenario is actually almost fixed by: > > "mptcp: cleanup MPJ subflow list handling" > > with a notable exception: if an MPJ handshake races with > mptcp_close(), the subflow enter the join_list and __mptcp_finish_join() > is processed at the msk socket lock release in mptcp_close(), > the subflow will preserver a danfling reference to the msk sk_socket. > > Address the issue fragting the subflow only on successful > __mptcp_finish_join() Thank you for the patch and the review! Now in our tree: - 494ff5ec1dd6: "squashed" in "mptcp: cleanup MPJ subflow list handling" - Results: cabf1e05f011..82c91858f45c Builds and tests are now in progress: https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export/20211217T113938 https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export > Note that issues/250 triggers even before > "mptcp: cleanup MPJ subflow list handling", as before such commit the join > list was not spliced by mptcp_close(). We could consider a net-only patch to > address that. Please note I didn't close issues/250 for this reason. Cheers, Matt -- Tessares | Belgium | Hybrid Access Solutions www.tessares.net
© 2016 - 2026 Red Hat, Inc.