Revert "mptcp: pm: avoid possible UaF when selecting endp"
This reverts commit 7f092ac2f1
.
This commit is contained in:
parent
4a63b68b74
commit
40ac982c85
1 changed files with 20 additions and 25 deletions
|
@ -127,13 +127,11 @@ static bool lookup_subflow_by_saddr(const struct list_head *list,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static struct mptcp_pm_addr_entry *
|
||||||
select_local_address(const struct pm_nl_pernet *pernet,
|
select_local_address(const struct pm_nl_pernet *pernet,
|
||||||
struct mptcp_sock *msk,
|
struct mptcp_sock *msk)
|
||||||
struct mptcp_pm_addr_entry *new_entry)
|
|
||||||
{
|
{
|
||||||
struct mptcp_pm_addr_entry *entry;
|
struct mptcp_pm_addr_entry *entry, *ret = NULL;
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
spin_lock_bh(&msk->join_list_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 &&
|
if (entry->addr.family == ((struct sock *)msk)->sk_family &&
|
||||||
!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
|
!lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) &&
|
||||||
!lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) {
|
!lookup_subflow_by_saddr(&msk->join_list, &entry->addr)) {
|
||||||
*new_entry = *entry;
|
ret = entry;
|
||||||
found = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&msk->join_list_lock);
|
spin_unlock_bh(&msk->join_list_lock);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static struct mptcp_pm_addr_entry *
|
||||||
select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos,
|
select_signal_address(struct pm_nl_pernet *pernet, unsigned int pos)
|
||||||
struct mptcp_pm_addr_entry *new_entry)
|
|
||||||
{
|
{
|
||||||
struct mptcp_pm_addr_entry *entry;
|
struct mptcp_pm_addr_entry *entry, *ret = NULL;
|
||||||
bool found = false;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
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))
|
if (!(entry->addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
|
||||||
continue;
|
continue;
|
||||||
if (i++ == pos) {
|
if (i++ == pos) {
|
||||||
*new_entry = *entry;
|
ret = entry;
|
||||||
found = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_work_pending(struct mptcp_sock *msk)
|
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 mptcp_addr_info remote = { 0 };
|
||||||
struct sock *sk = (struct sock *)msk;
|
struct sock *sk = (struct sock *)msk;
|
||||||
struct mptcp_pm_addr_entry local;
|
struct mptcp_pm_addr_entry *local;
|
||||||
struct pm_nl_pernet *pernet;
|
struct pm_nl_pernet *pernet;
|
||||||
|
|
||||||
pernet = net_generic(sock_net((struct sock *)msk), pm_nl_pernet_id);
|
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 */
|
/* check first for announce */
|
||||||
if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) {
|
if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) {
|
||||||
if (select_signal_address(pernet, msk->pm.add_addr_signaled,
|
local = select_signal_address(pernet,
|
||||||
&local)) {
|
msk->pm.add_addr_signaled);
|
||||||
if (mptcp_pm_alloc_anno_list(msk, &local)) {
|
|
||||||
|
if (local) {
|
||||||
|
if (mptcp_pm_alloc_anno_list(msk, local)) {
|
||||||
msk->pm.add_addr_signaled++;
|
msk->pm.add_addr_signaled++;
|
||||||
mptcp_pm_announce_addr(msk, &local.addr, false);
|
mptcp_pm_announce_addr(msk, &local->addr, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* pick failed, avoid fourther attempts later */
|
/* 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) {
|
msk->pm.subflows < msk->pm.subflows_max) {
|
||||||
remote_address((struct sock_common *)sk, &remote);
|
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.local_addr_used++;
|
||||||
msk->pm.subflows++;
|
msk->pm.subflows++;
|
||||||
check_work_pending(msk);
|
check_work_pending(msk);
|
||||||
spin_unlock_bh(&msk->pm.lock);
|
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);
|
spin_lock_bh(&msk->pm.lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue