Revert "mptcp: pm: avoid possible UaF when selecting endp"

This reverts commit 7f092ac2f1.
This commit is contained in:
Ksawlii 2024-11-24 00:23:45 +01:00
parent 4a63b68b74
commit 40ac982c85

View file

@ -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;
}