Skip to content

Commit e154659

Browse files
Florian Westphaldavem330
authored andcommitted
mptcp: fix double-unlock in mptcp_poll
mptcp_connect/28740 is trying to release lock (sk_lock-AF_INET) at: [<ffffffff82c15869>] mptcp_poll+0xb9/0x550 but there are no more locks to release! Call Trace: lock_release+0x50f/0x750 release_sock+0x171/0x1b0 mptcp_poll+0xb9/0x550 sock_poll+0x157/0x470 ? get_net_ns+0xb0/0xb0 do_sys_poll+0x63c/0xdd0 Problem is that __mptcp_tcp_fallback() releases the mptcp socket lock, but after recent change it doesn't do this in all of its return paths. To fix this, remove the unlock from __mptcp_tcp_fallback() and always do the unlock in the caller. Also add a small comment as to why we have this __mptcp_needs_tcp_fallback(). Fixes: 0b4f33d ("mptcp: fix tcp fallback crash") Reported-by: [email protected] Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3fe260e commit e154659

File tree

1 file changed

+13
-12
lines changed

1 file changed

+13
-12
lines changed

net/mptcp/protocol.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,7 @@ static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
9797
if (likely(!__mptcp_needs_tcp_fallback(msk)))
9898
return NULL;
9999

100-
if (msk->subflow) {
101-
release_sock((struct sock *)msk);
102-
return msk->subflow;
103-
}
104-
105-
return NULL;
100+
return msk->subflow;
106101
}
107102

108103
static bool __mptcp_can_create_subflow(const struct mptcp_sock *msk)
@@ -734,9 +729,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
734729
goto out;
735730
}
736731

732+
fallback:
737733
ssock = __mptcp_tcp_fallback(msk);
738734
if (unlikely(ssock)) {
739-
fallback:
735+
release_sock(sk);
740736
pr_debug("fallback passthrough");
741737
ret = sock_sendmsg(ssock, msg);
742738
return ret >= 0 ? ret + copied : (copied ? copied : ret);
@@ -769,8 +765,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
769765
if (ret < 0)
770766
break;
771767
if (ret == 0 && unlikely(__mptcp_needs_tcp_fallback(msk))) {
768+
/* Can happen for passive sockets:
769+
* 3WHS negotiated MPTCP, but first packet after is
770+
* plain TCP (e.g. due to middlebox filtering unknown
771+
* options).
772+
*
773+
* Fall back to TCP.
774+
*/
772775
release_sock(ssk);
773-
ssock = __mptcp_tcp_fallback(msk);
774776
goto fallback;
775777
}
776778

@@ -883,6 +885,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
883885
ssock = __mptcp_tcp_fallback(msk);
884886
if (unlikely(ssock)) {
885887
fallback:
888+
release_sock(sk);
886889
pr_debug("fallback-read subflow=%p",
887890
mptcp_subflow_ctx(ssock->sk));
888891
copied = sock_recvmsg(ssock, msg, flags);
@@ -1467,12 +1470,11 @@ static int mptcp_setsockopt(struct sock *sk, int level, int optname,
14671470
*/
14681471
lock_sock(sk);
14691472
ssock = __mptcp_tcp_fallback(msk);
1473+
release_sock(sk);
14701474
if (ssock)
14711475
return tcp_setsockopt(ssock->sk, level, optname, optval,
14721476
optlen);
14731477

1474-
release_sock(sk);
1475-
14761478
return -EOPNOTSUPP;
14771479
}
14781480

@@ -1492,12 +1494,11 @@ static int mptcp_getsockopt(struct sock *sk, int level, int optname,
14921494
*/
14931495
lock_sock(sk);
14941496
ssock = __mptcp_tcp_fallback(msk);
1497+
release_sock(sk);
14951498
if (ssock)
14961499
return tcp_getsockopt(ssock->sk, level, optname, optval,
14971500
option);
14981501

1499-
release_sock(sk);
1500-
15011502
return -EOPNOTSUPP;
15021503
}
15031504

0 commit comments

Comments
 (0)