From 40ac982c857d1d8c0444e937c8541428eab39c5f Mon Sep 17 00:00:00 2001 From: Ksawlii Date: Sun, 24 Nov 2024 00:23:45 +0100 Subject: [PATCH] Revert "mptcp: pm: avoid possible UaF when selecting endp" This reverts commit 7f092ac2f17cbb5c9e10d874801403025667996b. --- net/mptcp/pm_netlink.c | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index f115c92c4..25fab477f 100755 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -127,13 +127,11 @@ static bool lookup_subflow_by_saddr(const struct list_head *list, return false; } -static bool +static struct mptcp_pm_addr_entry * select_local_address(const struct pm_nl_pernet *pernet, - struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *new_entry) + struct mptcp_sock *msk) { - struct mptcp_pm_addr_entry *entry; - bool found = false; + struct mptcp_pm_addr_entry *entry, *ret = NULL; rcu_read_lock(); spin_lock_bh(&msk->join_list_lock); @@ -147,23 +145,19 @@ select_local_address(const struct pm_nl_pernet *pernet, if (entry->addr.family == ((struct sock *)msk)->sk_family && !lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) && !lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) { - *new_entry = *entry; - found = true; + ret = entry; break; } } spin_unlock_bh(&msk->join_list_lock); rcu_read_unlock(); - - return found; + return ret; } -static bool -select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos, - struct mptcp_pm_addr_entry *new_entry) +static struct mptcp_pm_addr_entry * +select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos) { - struct mptcp_pm_addr_entry *entry; - bool found = false; + struct mptcp_pm_addr_entry *entry, *ret = NULL; int i = 0; rcu_read_lock(); @@ -176,14 +170,12 @@ select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos, if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) continue; if (i++ == pos) { - *new_entry = *entry; - found = true; + ret = entry; break; } } rcu_read_unlock(); - - return found; + return ret; } static void check_work_pending(struct mptcp_sock *msk) @@ -313,7 +305,7 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) { struct mptcp_addr_info remote = { 0 }; struct sock *sk = (struct sock *)msk; - struct mptcp_pm_addr_entry local; + struct mptcp_pm_addr_entry *local; struct pm_nl_pernet *pernet; pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id); @@ -325,11 +317,13 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) /* check first for announce */ if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) { - if (select_signal_address(pernet, msk->pm.add_addr_signaled, - &local)) { - if (mptcp_pm_alloc_anno_list(msk, &local)) { + local = select_signal_address(pernet, + msk->pm.add_addr_signaled); + + if (local) { + if (mptcp_pm_alloc_anno_list(msk, local)) { msk->pm.add_addr_signaled++; - mptcp_pm_announce_addr(msk, &local.addr, false); + mptcp_pm_announce_addr(msk, &local->addr, false); } } else { /* pick failed, avoid fourther attempts later */ @@ -344,12 +338,13 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) msk->pm.subflows < msk->pm.subflows_max) { remote_address((struct sock_common *)sk, &remote); - if (select_local_address(pernet, msk, &local)) { + local = select_local_address(pernet, msk); + if (local) { msk->pm.local_addr_used++; msk->pm.subflows++; check_work_pending(msk); spin_unlock_bh(&msk->pm.lock); - __mptcp_subflow_connect(sk, &local.addr, &remote); + __mptcp_subflow_connect(sk, &local->addr, &remote); spin_lock_bh(&msk->pm.lock); return; }