Skip to content

Commit 5564be7

Browse files
Paolo Abenigregkh
authored andcommitted
mptcp: fix UaF in listener shutdown
[ Upstream commit 0a3f4f1 ] Backports notes: one simple conflict in net/mptcp/protocol.c with: commit f8c9dfb ("mptcp: add pm listener events") Where one commit removes code in __mptcp_close_ssk() while the other one adds one line at the same place. We can simply remove the whole condition because this extra instruction is not present in v6.1. As reported by Christoph after having refactored the passive socket initialization, the mptcp listener shutdown path is prone to an UaF issue. BUG: KASAN: use-after-free in _raw_spin_lock_bh+0x73/0xe0 Write of size 4 at addr ffff88810cb23098 by task syz-executor731/1266 CPU: 1 PID: 1266 Comm: syz-executor731 Not tainted 6.2.0-rc59af4eaa31c1f6c00c8f1e448ed99a45c66340dd5 #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x6e/0x91 print_report+0x16a/0x46f kasan_report+0xad/0x130 kasan_check_range+0x14a/0x1a0 _raw_spin_lock_bh+0x73/0xe0 subflow_error_report+0x6d/0x110 sk_error_report+0x3b/0x190 tcp_disconnect+0x138c/0x1aa0 inet_child_forget+0x6f/0x2e0 inet_csk_listen_stop+0x209/0x1060 __mptcp_close_ssk+0x52d/0x610 mptcp_destroy_common+0x165/0x640 mptcp_destroy+0x13/0x80 __mptcp_destroy_sock+0xe7/0x270 __mptcp_close+0x70e/0x9b0 mptcp_close+0x2b/0x150 inet_release+0xe9/0x1f0 __sock_release+0xd2/0x280 sock_close+0x15/0x20 __fput+0x252/0xa20 task_work_run+0x169/0x250 exit_to_user_mode_prepare+0x113/0x120 syscall_exit_to_user_mode+0x1d/0x40 do_syscall_64+0x48/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc The msk grace period can legitly expire in between the last reference count dropped in mptcp_subflow_queue_clean() and the later eventual access in inet_csk_listen_stop() After the previous patch we don't need anymore special-casing msk listener socket cleanup: the mptcp worker will process each of the unaccepted msk sockets. Just drop the now unnecessary code. Please note this commit depends on the two parent ones: mptcp: refactor passive socket initialization mptcp: use the workqueue to destroy unaccepted sockets Fixes: 6aeed90 ("mptcp: fix race on unaccepted mptcp sockets") Cc: stable@vger.kernel.org Reported-and-tested-by: Christoph Paasch <cpaasch@apple.com> Closes: multipath-tcp/mptcp_net-next#346 Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 2827f09 commit 5564be7

3 files changed

Lines changed: 0 additions & 78 deletions

File tree

net/mptcp/protocol.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,11 +2380,6 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23802380
mptcp_subflow_drop_ctx(ssk);
23812381
} else {
23822382
/* otherwise tcp will dispose of the ssk and subflow ctx */
2383-
if (ssk->sk_state == TCP_LISTEN) {
2384-
tcp_set_state(ssk, TCP_CLOSE);
2385-
mptcp_subflow_queue_clean(sk, ssk);
2386-
inet_csk_listen_stop(ssk);
2387-
}
23882383
__tcp_close(ssk, 0);
23892384

23902385
/* close acquired an extra ref */

net/mptcp/protocol.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,6 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
615615
struct mptcp_subflow_context *subflow);
616616
void __mptcp_subflow_send_ack(struct sock *ssk);
617617
void mptcp_subflow_reset(struct sock *ssk);
618-
void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
619618
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
620619
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
621620
bool __mptcp_close(struct sock *sk, long timeout);

net/mptcp/subflow.c

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,78 +1764,6 @@ static void subflow_state_change(struct sock *sk)
17641764
}
17651765
}
17661766

1767-
void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk)
1768-
{
1769-
struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
1770-
struct mptcp_sock *msk, *next, *head = NULL;
1771-
struct request_sock *req;
1772-
1773-
/* build a list of all unaccepted mptcp sockets */
1774-
spin_lock_bh(&queue->rskq_lock);
1775-
for (req = queue->rskq_accept_head; req; req = req->dl_next) {
1776-
struct mptcp_subflow_context *subflow;
1777-
struct sock *ssk = req->sk;
1778-
struct mptcp_sock *msk;
1779-
1780-
if (!sk_is_mptcp(ssk))
1781-
continue;
1782-
1783-
subflow = mptcp_subflow_ctx(ssk);
1784-
if (!subflow || !subflow->conn)
1785-
continue;
1786-
1787-
/* skip if already in list */
1788-
msk = mptcp_sk(subflow->conn);
1789-
if (msk->dl_next || msk == head)
1790-
continue;
1791-
1792-
msk->dl_next = head;
1793-
head = msk;
1794-
}
1795-
spin_unlock_bh(&queue->rskq_lock);
1796-
if (!head)
1797-
return;
1798-
1799-
/* can't acquire the msk socket lock under the subflow one,
1800-
* or will cause ABBA deadlock
1801-
*/
1802-
release_sock(listener_ssk);
1803-
1804-
for (msk = head; msk; msk = next) {
1805-
struct sock *sk = (struct sock *)msk;
1806-
bool do_cancel_work;
1807-
1808-
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
1809-
next = msk->dl_next;
1810-
msk->first = NULL;
1811-
msk->dl_next = NULL;
1812-
1813-
do_cancel_work = __mptcp_close(sk, 0);
1814-
release_sock(sk);
1815-
if (do_cancel_work) {
1816-
/* lockdep will report a false positive ABBA deadlock
1817-
* between cancel_work_sync and the listener socket.
1818-
* The involved locks belong to different sockets WRT
1819-
* the existing AB chain.
1820-
* Using a per socket key is problematic as key
1821-
* deregistration requires process context and must be
1822-
* performed at socket disposal time, in atomic
1823-
* context.
1824-
* Just tell lockdep to consider the listener socket
1825-
* released here.
1826-
*/
1827-
mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
1828-
mptcp_cancel_work(sk);
1829-
mutex_acquire(&listener_sk->sk_lock.dep_map,
1830-
SINGLE_DEPTH_NESTING, 0, _RET_IP_);
1831-
}
1832-
sock_put(sk);
1833-
}
1834-
1835-
/* we are still under the listener msk socket lock */
1836-
lock_sock_nested(listener_ssk, SINGLE_DEPTH_NESTING);
1837-
}
1838-
18391767
static int subflow_ulp_init(struct sock *sk)
18401768
{
18411769
struct inet_connection_sock *icsk = inet_csk(sk);

0 commit comments

Comments
 (0)