[PATCH net 04/14] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
From: Matthieu Baerts (NGI0)
Date: Mon Aug 24 2026 - 12:54:47 EST
From: Kalpan Jani <kalpan.jani@xxxxxxxxxxxxxxxxxx>
The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement
entry alive when removing the id 0 endpoint. This happens because the id 0
removal path does not tear down pending announcements, unlike the non-zero
id path.
When the PM later reselects id 0 after adding another signal endpoint, it
finds the stale anno_list entry and hits WARN_ON_ONCE(mptcp_pm_is_kernel())
in mptcp_pm_alloc_anno_list().
Root cause: asymmetry between removal paths.
- Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls
mptcp_pm_remove_anno_addr() to clean up.
- Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely.
Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove()
and decrement add_addr_signaled before queuing the RM_ADDR.
Subtle detail: signal endpoints are stored in anno_list with port 0, but
msk_local carries the connection's local port. mptcp_pm_announced_remove()
uses use_port=true for comparison, so clear the port before the lookup.
Fixes: 740d798e8767 ("mptcp: remove id 0 address")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: syzbot+55c2a5c871441261ed14@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/620
Suggested-by: Tao Cui <cuitao@xxxxxxxxxx>
Signed-off-by: Kalpan Jani <kalpan.jani@xxxxxxxxxxxxxxxxxx>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@xxxxxxxxxx>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@xxxxxxxxxx>
---
net/mptcp/pm_kernel.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
index 424f1a7f9248..1a7750813235 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -1137,6 +1137,8 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
struct sock *sk = (struct sock *)msk;
struct mptcp_addr_info msk_local;
+ struct mptcp_addr_info anno_addr;
+ bool announced;
if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
goto next;
@@ -1146,7 +1148,13 @@ static int mptcp_nl_remove_id_zero_address(struct net *net,
goto next;
lock_sock(sk);
+ /* Drop a possibly pending ADD_ADDR for this address. */
+ anno_addr = msk_local;
+ anno_addr.port = 0;
+ announced = mptcp_pm_announced_remove(msk, &anno_addr);
spin_lock_bh(&msk->pm.lock);
+ if (announced)
+ msk->pm.add_addr_signaled--;
mptcp_pm_remove_addr(msk, &list);
mptcp_pm_rm_subflow(msk, &list);
__mark_subflow_endp_available(msk, 0);
--
2.53.0