[PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
luoqing <[email protected]> Tue, 14 Jul 2026 16:03:56 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
From: luoqing <[email protected]> When all MPTCP address IDs (1-255) are exhausted, find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored in the u8 field e->addr.id, resulting in ID 0 being stored. ID 0 has special meaning in MPTCP (it's reserved for the initial connection), so this overflow can cause confusion and incorrect behavior, including unintentional ID 0 reuse or address conflicts. Signed-off-by: luoqing <[email protected]> --- net/mptcp/pm_kernel.c | 11 ++++++++--- net/mptcp/pm_userspace.c | 15 +++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index 424f1a7f9248..a0fc9cabd770 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -795,9 +795,14 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet, if (!entry->addr.id) { find_next: - entry->addr.id = find_next_zero_bit(pernet->id_bitmap, - MPTCP_PM_MAX_ADDR_ID + 1, - pernet->next_id); + unsigned int id = find_next_zero_bit(pernet->id_bitmap, + MPTCP_PM_MAX_ADDR_ID + 1, + pernet->next_id); + if (id > MPTCP_PM_MAX_ADDR_ID) { + ret = -ENOSPC; + goto out; + } + entry->addr.id = id; if (!entry->addr.id && pernet->next_id != 1) { pernet->next_id = 1; goto find_next; diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index d100867e9202..c48fd905f7a0 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -74,10 +74,17 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk, goto append_err; } - if (!e->addr.id && needs_id) - e->addr.id = find_next_zero_bit(id_bitmap, - MPTCP_PM_MAX_ADDR_ID + 1, - 1); + if (!e->addr.id && needs_id) { + unsigned int id = find_next_zero_bit(id_bitmap, + MPTCP_PM_MAX_ADDR_ID + 1, + 1); + if (id > MPTCP_PM_MAX_ADDR_ID) { + sock_kfree_s(sk, e, sizeof(*e)); + ret = -ENOSPC; + goto append_err; + } + e->addr.id = id; + } list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list); msk->pm.local_addr_used++; ret = e->addr.id; -- 2.25.1