Unverified Commit 3531f9ea authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11460 mptcp: pm: avoid possible UaF when selecting endp

parents 7ab021d4 528bf807
Loading
Loading
Loading
Loading
+34 −30
Original line number Diff line number Diff line
@@ -148,11 +148,13 @@ static bool lookup_subflow_by_daddr(const struct list_head *list,
	return false;
}

static struct mptcp_pm_addr_entry *
static bool
select_local_address(const struct pm_nl_pernet *pernet,
		     const struct mptcp_sock *msk)
		     const struct mptcp_sock *msk,
		     struct mptcp_pm_addr_entry *new_entry)
{
	struct mptcp_pm_addr_entry *entry, *ret = NULL;
	struct mptcp_pm_addr_entry *entry;
	bool found = false;

	msk_owned_by_me(msk);

@@ -164,17 +166,21 @@ select_local_address(const struct pm_nl_pernet *pernet,
		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
			continue;

		ret = entry;
		*new_entry = *entry;
		found = true;
		break;
	}
	rcu_read_unlock();
	return ret;

	return found;
}

static struct mptcp_pm_addr_entry *
select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
static bool
select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
		      struct mptcp_pm_addr_entry *new_entry)
{
	struct mptcp_pm_addr_entry *entry, *ret = NULL;
	struct mptcp_pm_addr_entry *entry;
	bool found = false;

	rcu_read_lock();
	/* do not keep any additional per socket state, just signal
@@ -189,11 +195,13 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk)
		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
			continue;

		ret = entry;
		*new_entry = *entry;
		found = true;
		break;
	}
	rcu_read_unlock();
	return ret;

	return found;
}

unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk)
@@ -520,9 +528,10 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info,

static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
{
	struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL;
	struct sock *sk = (struct sock *)msk;
	struct mptcp_pm_addr_entry local;
	unsigned int add_addr_signal_max;
	bool signal_and_subflow = false;
	unsigned int local_addr_max;
	struct pm_nl_pernet *pernet;
	unsigned int subflows_max;
@@ -573,23 +582,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
		if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
			return;

		local = select_signal_address(pernet, msk);
		if (!local)
		if (!select_signal_address(pernet, msk, &local))
			goto subflow;

		/* If the alloc fails, we are on memory pressure, not worth
		 * continuing, and trying to create subflows.
		 */
		if (!mptcp_pm_alloc_anno_list(msk, &local->addr))
		if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
			return;

		__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
		msk->pm.add_addr_signaled++;
		mptcp_pm_announce_addr(msk, &local->addr, false);
		mptcp_pm_announce_addr(msk, &local.addr, false);
		mptcp_pm_nl_addr_send_ack(msk);

		if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
			signal_and_subflow = local;
		if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
			signal_and_subflow = true;
	}

subflow:
@@ -600,26 +608,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
		bool fullmesh;
		int i, nr;

		if (signal_and_subflow) {
			local = signal_and_subflow;
			signal_and_subflow = NULL;
		} else {
			local = select_local_address(pernet, msk);
			if (!local)
		if (signal_and_subflow)
			signal_and_subflow = false;
		else if (!select_local_address(pernet, msk, &local))
			break;
		}

		fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
		fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);

		msk->pm.local_addr_used++;
		__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
		nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs);
		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
		nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
		if (nr == 0)
			continue;

		spin_unlock_bh(&msk->pm.lock);
		for (i = 0; i < nr; i++)
			__mptcp_subflow_connect(sk, &local->addr, &addrs[i]);
			__mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
		spin_lock_bh(&msk->pm.lock);
	}
	mptcp_pm_nl_check_work_pending(msk);