Skip to content

Commit 56a666c

Browse files
Paolo Abenikuba-moo
authored andcommitted
mptcp: fix possible list corruption on passive MPJ
At passive MPJ time, if the msk socket lock is held by the user, the new subflow is appended to the msk->join_list under the msk data lock. In mptcp_release_cb()/__mptcp_flush_join_list(), the subflows in that list are moved from the join_list into the conn_list under the msk socket lock. Append and removal could race, possibly corrupting such list. Address the issue splicing the join list into a temporary one while still under the msk data lock. Found by code inspection, the race itself should be almost impossible to trigger in practice. Fixes: 3e50149 ("mptcp: cleanup MPJ subflow list handling") Cc: [email protected] Signed-off-by: Paolo Abeni <[email protected]> Reviewed-by: Matthieu Baerts <[email protected]> Signed-off-by: Matthieu Baerts <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 0ad529d commit 56a666c

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

net/mptcp/protocol.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,12 @@ static bool __mptcp_finish_join(struct mptcp_sock *msk, struct sock *ssk)
850850
return true;
851851
}
852852

853-
static void __mptcp_flush_join_list(struct sock *sk)
853+
static void __mptcp_flush_join_list(struct sock *sk, struct list_head *join_list)
854854
{
855855
struct mptcp_subflow_context *tmp, *subflow;
856856
struct mptcp_sock *msk = mptcp_sk(sk);
857857

858-
list_for_each_entry_safe(subflow, tmp, &msk->join_list, node) {
858+
list_for_each_entry_safe(subflow, tmp, join_list, node) {
859859
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
860860
bool slow = lock_sock_fast(ssk);
861861

@@ -3342,9 +3342,14 @@ static void mptcp_release_cb(struct sock *sk)
33423342
for (;;) {
33433343
unsigned long flags = (msk->cb_flags & MPTCP_FLAGS_PROCESS_CTX_NEED) |
33443344
msk->push_pending;
3345+
struct list_head join_list;
3346+
33453347
if (!flags)
33463348
break;
33473349

3350+
INIT_LIST_HEAD(&join_list);
3351+
list_splice_init(&msk->join_list, &join_list);
3352+
33483353
/* the following actions acquire the subflow socket lock
33493354
*
33503355
* 1) can't be invoked in atomic scope
@@ -3355,8 +3360,9 @@ static void mptcp_release_cb(struct sock *sk)
33553360
msk->push_pending = 0;
33563361
msk->cb_flags &= ~flags;
33573362
spin_unlock_bh(&sk->sk_lock.slock);
3363+
33583364
if (flags & BIT(MPTCP_FLUSH_JOIN_LIST))
3359-
__mptcp_flush_join_list(sk);
3365+
__mptcp_flush_join_list(sk, &join_list);
33603366
if (flags & BIT(MPTCP_PUSH_PENDING))
33613367
__mptcp_push_pending(sk, 0);
33623368
if (flags & BIT(MPTCP_RETRANSMIT))

0 commit comments

Comments
 (0)