From: Florian Westphal Date: Thu, 10 Dec 2020 22:25:02 +0000 (-0800) Subject: mptcp: hold mptcp socket before calling tcp_done X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=ab82e996a1fa1b9ae514fa357d9ce8df62321157;p=linux.git mptcp: hold mptcp socket before calling tcp_done When processing options from tcp reset path its possible that tcp_done(ssk) drops the last reference on the mptcp socket which results in use-after-free. Reviewed-by: Matthieu Baerts Signed-off-by: Florian Westphal Signed-off-by: Mat Martineau Signed-off-by: Jakub Kicinski --- diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index bf808f1fabe5b..73e66a406d994 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -313,12 +313,17 @@ void mptcp_subflow_reset(struct sock *ssk) struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); struct sock *sk = subflow->conn; + /* must hold: tcp_done() could drop last reference on parent */ + sock_hold(sk); + tcp_set_state(ssk, TCP_CLOSE); tcp_send_active_reset(ssk, GFP_ATOMIC); tcp_done(ssk); if (!test_and_set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &mptcp_sk(sk)->flags) && schedule_work(&mptcp_sk(sk)->work)) - sock_hold(sk); + return; /* worker will put sk for us */ + + sock_put(sk); } static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)