Skip to content

Commit ed7f9c0

Browse files
committed
Merge branch 'mptcp-fixes'
Matthieu Baerts says: ==================== mptcp: fixes around listening sockets and the MPTCP worker Christoph Paasch reported a couple of issues found by syzkaller and linked to operations done by the MPTCP worker on (un)accepted sockets. Fixing these issues was not obvious and rather complex but Paolo Abeni nicely managed to propose these excellent patches that seem to satisfy syzkaller. Patch 1 partially reverts a recent fix but while still providing a solution for the previous issue, it also prevents the MPTCP worker from running concurrently with inet_csk_listen_stop(). A warning is then avoided. The partially reverted patch has been introduced in v6.3-rc3, backported up to v6.1 and fixing an issue visible from v5.18. Patch 2 prevents the MPTCP worker to race with mptcp_accept() causing a UaF when a fallback to TCP is done while in parallel, the socket is being accepted by the userspace. This is also a fix of a previous fix introduced in v6.3-rc3, backported up to v6.1 but here fixing an issue that is in theory there from v5.7. There is no need to backport it up to here as it looks like it is only visible later, around v5.18, see the previous cover-letter linked to this original fix. ==================== Signed-off-by: Matthieu Baerts <[email protected]>
2 parents 4e006c7 + 6374044 commit ed7f9c0

File tree

3 files changed

+129
-27
lines changed

3 files changed

+129
-27
lines changed

net/mptcp/protocol.c

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,7 +2315,26 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23152315
unsigned int flags)
23162316
{
23172317
struct mptcp_sock *msk = mptcp_sk(sk);
2318-
bool need_push, dispose_it;
2318+
bool dispose_it, need_push = false;
2319+
2320+
/* If the first subflow moved to a close state before accept, e.g. due
2321+
* to an incoming reset, mptcp either:
2322+
* - if either the subflow or the msk are dead, destroy the context
2323+
* (the subflow socket is deleted by inet_child_forget) and the msk
2324+
* - otherwise do nothing at the moment and take action at accept and/or
2325+
* listener shutdown - user-space must be able to accept() the closed
2326+
* socket.
2327+
*/
2328+
if (msk->in_accept_queue && msk->first == ssk) {
2329+
if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD))
2330+
return;
2331+
2332+
/* ensure later check in mptcp_worker() will dispose the msk */
2333+
sock_set_flag(sk, SOCK_DEAD);
2334+
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
2335+
mptcp_subflow_drop_ctx(ssk);
2336+
goto out_release;
2337+
}
23192338

23202339
dispose_it = !msk->subflow || ssk != msk->subflow->sk;
23212340
if (dispose_it)
@@ -2351,28 +2370,22 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23512370
if (!inet_csk(ssk)->icsk_ulp_ops) {
23522371
WARN_ON_ONCE(!sock_flag(ssk, SOCK_DEAD));
23532372
kfree_rcu(subflow, rcu);
2354-
} else if (msk->in_accept_queue && msk->first == ssk) {
2355-
/* if the first subflow moved to a close state, e.g. due to
2356-
* incoming reset and we reach here before inet_child_forget()
2357-
* the TCP stack could later try to close it via
2358-
* inet_csk_listen_stop(), or deliver it to the user space via
2359-
* accept().
2360-
* We can't delete the subflow - or risk a double free - nor let
2361-
* the msk survive - or will be leaked in the non accept scenario:
2362-
* fallback and let TCP cope with the subflow cleanup.
2363-
*/
2364-
WARN_ON_ONCE(sock_flag(ssk, SOCK_DEAD));
2365-
mptcp_subflow_drop_ctx(ssk);
23662373
} else {
23672374
/* otherwise tcp will dispose of the ssk and subflow ctx */
2368-
if (ssk->sk_state == TCP_LISTEN)
2375+
if (ssk->sk_state == TCP_LISTEN) {
2376+
tcp_set_state(ssk, TCP_CLOSE);
2377+
mptcp_subflow_queue_clean(sk, ssk);
2378+
inet_csk_listen_stop(ssk);
23692379
mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CLOSED);
2380+
}
23702381

23712382
__tcp_close(ssk, 0);
23722383

23732384
/* close acquired an extra ref */
23742385
__sock_put(ssk);
23752386
}
2387+
2388+
out_release:
23762389
release_sock(ssk);
23772390

23782391
sock_put(ssk);
@@ -2427,21 +2440,14 @@ static void __mptcp_close_subflow(struct sock *sk)
24272440
mptcp_close_ssk(sk, ssk, subflow);
24282441
}
24292442

2430-
/* if the MPC subflow has been closed before the msk is accepted,
2431-
* msk will never be accept-ed, close it now
2432-
*/
2433-
if (!msk->first && msk->in_accept_queue) {
2434-
sock_set_flag(sk, SOCK_DEAD);
2435-
inet_sk_state_store(sk, TCP_CLOSE);
2436-
}
24372443
}
24382444

2439-
static bool mptcp_check_close_timeout(const struct sock *sk)
2445+
static bool mptcp_should_close(const struct sock *sk)
24402446
{
24412447
s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp;
24422448
struct mptcp_subflow_context *subflow;
24432449

2444-
if (delta >= TCP_TIMEWAIT_LEN)
2450+
if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue)
24452451
return true;
24462452

24472453
/* if all subflows are in closed status don't bother with additional
@@ -2649,7 +2655,7 @@ static void mptcp_worker(struct work_struct *work)
26492655
* even if it is orphaned and in FIN_WAIT2 state
26502656
*/
26512657
if (sock_flag(sk, SOCK_DEAD)) {
2652-
if (mptcp_check_close_timeout(sk)) {
2658+
if (mptcp_should_close(sk)) {
26532659
inet_sk_state_store(sk, TCP_CLOSE);
26542660
mptcp_do_fastclose(sk);
26552661
}
@@ -2895,6 +2901,14 @@ static void __mptcp_destroy_sock(struct sock *sk)
28952901
sock_put(sk);
28962902
}
28972903

2904+
void __mptcp_unaccepted_force_close(struct sock *sk)
2905+
{
2906+
sock_set_flag(sk, SOCK_DEAD);
2907+
inet_sk_state_store(sk, TCP_CLOSE);
2908+
mptcp_do_fastclose(sk);
2909+
__mptcp_destroy_sock(sk);
2910+
}
2911+
28982912
static __poll_t mptcp_check_readable(struct mptcp_sock *msk)
28992913
{
29002914
/* Concurrent splices from sk_receive_queue into receive_queue will
@@ -3733,6 +3747,18 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
37333747
if (!ssk->sk_socket)
37343748
mptcp_sock_graft(ssk, newsock);
37353749
}
3750+
3751+
/* Do late cleanup for the first subflow as necessary. Also
3752+
* deal with bad peers not doing a complete shutdown.
3753+
*/
3754+
if (msk->first &&
3755+
unlikely(inet_sk_state_load(msk->first) == TCP_CLOSE)) {
3756+
__mptcp_close_ssk(newsk, msk->first,
3757+
mptcp_subflow_ctx(msk->first), 0);
3758+
if (unlikely(list_empty(&msk->conn_list)))
3759+
inet_sk_state_store(newsk, TCP_CLOSE);
3760+
}
3761+
37363762
release_sock(newsk);
37373763
}
37383764

net/mptcp/protocol.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,12 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
629629
struct mptcp_subflow_context *subflow);
630630
void __mptcp_subflow_send_ack(struct sock *ssk);
631631
void mptcp_subflow_reset(struct sock *ssk);
632+
void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
632633
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
633634
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
634635
bool __mptcp_close(struct sock *sk, long timeout);
635636
void mptcp_cancel_work(struct sock *sk);
637+
void __mptcp_unaccepted_force_close(struct sock *sk);
636638
void mptcp_set_owner_r(struct sk_buff *skb, struct sock *sk);
637639

638640
bool mptcp_addresses_equal(const struct mptcp_addr_info *a,

net/mptcp/subflow.c

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,9 +723,12 @@ void mptcp_subflow_drop_ctx(struct sock *ssk)
723723
if (!ctx)
724724
return;
725725

726-
subflow_ulp_fallback(ssk, ctx);
727-
if (ctx->conn)
728-
sock_put(ctx->conn);
726+
list_del(&mptcp_subflow_ctx(ssk)->node);
727+
if (inet_csk(ssk)->icsk_ulp_ops) {
728+
subflow_ulp_fallback(ssk, ctx);
729+
if (ctx->conn)
730+
sock_put(ctx->conn);
731+
}
729732

730733
kfree_rcu(ctx, rcu);
731734
}
@@ -1819,6 +1822,77 @@ static void subflow_state_change(struct sock *sk)
18191822
}
18201823
}
18211824

1825+
void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk)
1826+
{
1827+
struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
1828+
struct mptcp_sock *msk, *next, *head = NULL;
1829+
struct request_sock *req;
1830+
struct sock *sk;
1831+
1832+
/* build a list of all unaccepted mptcp sockets */
1833+
spin_lock_bh(&queue->rskq_lock);
1834+
for (req = queue->rskq_accept_head; req; req = req->dl_next) {
1835+
struct mptcp_subflow_context *subflow;
1836+
struct sock *ssk = req->sk;
1837+
1838+
if (!sk_is_mptcp(ssk))
1839+
continue;
1840+
1841+
subflow = mptcp_subflow_ctx(ssk);
1842+
if (!subflow || !subflow->conn)
1843+
continue;
1844+
1845+
/* skip if already in list */
1846+
sk = subflow->conn;
1847+
msk = mptcp_sk(sk);
1848+
if (msk->dl_next || msk == head)
1849+
continue;
1850+
1851+
sock_hold(sk);
1852+
msk->dl_next = head;
1853+
head = msk;
1854+
}
1855+
spin_unlock_bh(&queue->rskq_lock);
1856+
if (!head)
1857+
return;
1858+
1859+
/* can't acquire the msk socket lock under the subflow one,
1860+
* or will cause ABBA deadlock
1861+
*/
1862+
release_sock(listener_ssk);
1863+
1864+
for (msk = head; msk; msk = next) {
1865+
sk = (struct sock *)msk;
1866+
1867+
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
1868+
next = msk->dl_next;
1869+
msk->dl_next = NULL;
1870+
1871+
__mptcp_unaccepted_force_close(sk);
1872+
release_sock(sk);
1873+
1874+
/* lockdep will report a false positive ABBA deadlock
1875+
* between cancel_work_sync and the listener socket.
1876+
* The involved locks belong to different sockets WRT
1877+
* the existing AB chain.
1878+
* Using a per socket key is problematic as key
1879+
* deregistration requires process context and must be
1880+
* performed at socket disposal time, in atomic
1881+
* context.
1882+
* Just tell lockdep to consider the listener socket
1883+
* released here.
1884+
*/
1885+
mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
1886+
mptcp_cancel_work(sk);
1887+
mutex_acquire(&listener_sk->sk_lock.dep_map, 0, 0, _RET_IP_);
1888+
1889+
sock_put(sk);
1890+
}
1891+
1892+
/* we are still under the listener msk socket lock */
1893+
lock_sock_nested(listener_ssk, SINGLE_DEPTH_NESTING);
1894+
}
1895+
18221896
static int subflow_ulp_init(struct sock *sk)
18231897
{
18241898
struct inet_connection_sock *icsk = inet_csk(sk);

0 commit comments

Comments
 (0)