[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