mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()
Subsystems (3)
Matthieu Baerts (NGI0)
maintainerPATCH 1/1 mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()
From: Eric Dumazet <[email protected]>
commit e2a9eeb69f7d4ca4cf4c70463af77664fdb6ab1d upstream.
syzbot and Eulgyu Kim reported crashes in mptcp_pm_nl_get_local_id() and/or mptcp_pm_nl_is_backup()
Root cause is list_splice_init() in mptcp_pm_nl_flush_addrs_doit() which is not RCU ready.
list_splice_init_rcu() can not be called here while holding pernet->lock spinlock.
Many thanks to Eulgyu Kim for providing a repro and testing our patches.
[ Conflicts because the code has been moved from pm_netlink.c to
pm_kernel.c later on in commit 8617e85e04bd ("mptcp: pm: split in-kernel PM specific code"). The same modifications can be applied in pm_netlink.c with one exception, because 'pernet->local_addr_list' has been renamed to 'pernet->endp_list' in commit 35e71e43a56d ("mptcp: pm: in-kernel: rename 'local_addr_list' to 'endp_list'"). The previous name is then still being used in this version. Also, another conflict is caused by commit 7bcf4d8022f9 ("mptcp: pm:
rename helpers linked to 'flush'") which is not in this version:
mptcp_nl_remove_addrs_list() has been renamed to mptcp_nl_flush_addrs_list(). The previous name has then been kept. ]
--- net/mptcp/pm_netlink.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
net/mptcp/pm_netlink.c +13 -3
@@ -1855,16 +1855,26 @@ static void __reset_counters(struct pm_nl_pernet *pernet)static int mptcp_nl_cmd_flush_addrs (struct sk_buff *skb,struct genl_info *info) {struct pm_nl_pernet *pernet =genl_info_pm_nl (info); -LIST_HEAD (free_list); +struct list_head free_list;spin_lock_bh (&pernet->lock); -list_splice_init (&pernet->local_addr_list, &free_list); + free_list = pernet->local_addr_list; +INIT_LIST_HEAD_RCU (&pernet->local_addr_list);__reset_counters (pernet); pernet->next_id =1 ;bitmap_zero (pernet->id_bitmap,MPTCP_PM_MAX_ADDR_ID +1 );spin_unlock_bh (&pernet->lock); -mptcp_nl_remove_addrs_list (sock_net (skb->sk), &free_list); + +if (free_list.next == &pernet->local_addr_list) +return 0 ; +synchronize_rcu (); + +/* Adjust the pointers to free_list instead of pernet->local_addr_list */ + free_list.prev->next = &free_list; + free_list.next->prev = &free_list; + +mptcp_nl_remove_addrs_list (sock_net (skb->sk), &free_list);__flush_addrs (&free_list);return 0 ; }
Signature · 1 line
2.51.0
Patch "mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()" has been added to the 6.1-stable tree
This is a note to let you know that I've just added the patch titled
mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()
to the 6.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch
and it can be found in the queue-6.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
From [email protected] Thu Feb 12 18:41:08 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Thu, 12 Feb 2026 18:40:52 +0100
Subject: mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()
To: [email protected], [email protected]
Cc: MPTCP Upstream <[email protected]>, Eric Dumazet <[email protected]>, [email protected], Eulgyu Kim <[email protected]>, Mat Martineau <[email protected]>, "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>
From: Eric Dumazet <[email protected]>
commit e2a9eeb69f7d4ca4cf4c70463af77664fdb6ab1d upstream.
syzbot and Eulgyu Kim reported crashes in mptcp_pm_nl_get_local_id() and/or mptcp_pm_nl_is_backup()
Root cause is list_splice_init() in mptcp_pm_nl_flush_addrs_doit() which is not RCU ready.
list_splice_init_rcu() can not be called here while holding pernet->lock spinlock.
Many thanks to Eulgyu Kim for providing a repro and testing our patches.
[ Conflicts because the code has been moved from pm_netlink.c to
pm_kernel.c later on in commit 8617e85e04bd ("mptcp: pm: split in-kernel PM specific code"). The same modifications can be applied in pm_netlink.c with one exception, because 'pernet->local_addr_list' has been renamed to 'pernet->endp_list' in commit 35e71e43a56d ("mptcp: pm: in-kernel: rename 'local_addr_list' to 'endp_list'"). The previous name is then still being used in this version. Also, another conflict is caused by commit 7bcf4d8022f9 ("mptcp: pm:
rename helpers linked to 'flush'") which is not in this version:
mptcp_nl_remove_addrs_list() has been renamed to mptcp_nl_flush_addrs_list(). The previous name has then been kept. ]
--- net/mptcp/pm_netlink.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
net/mptcp/pm_netlink.c +13 -3
@@ -1855,16 +1855,26 @@ static void __reset_counters(struct pm_nstatic int mptcp_nl_cmd_flush_addrs (struct sk_buff *skb,struct genl_info *info) {struct pm_nl_pernet *pernet =genl_info_pm_nl (info); -LIST_HEAD (free_list); +struct list_head free_list;spin_lock_bh (&pernet->lock); -list_splice_init (&pernet->local_addr_list, &free_list); + free_list = pernet->local_addr_list; +INIT_LIST_HEAD_RCU (&pernet->local_addr_list);__reset_counters (pernet); pernet->next_id =1 ;bitmap_zero (pernet->id_bitmap,MPTCP_PM_MAX_ADDR_ID +1 );spin_unlock_bh (&pernet->lock); -mptcp_nl_remove_addrs_list (sock_net (skb->sk), &free_list); + +if (free_list.next == &pernet->local_addr_list) +return 0 ; +synchronize_rcu (); + +/* Adjust the pointers to free_list instead of pernet->local_addr_list */ + free_list.prev->next = &free_list; + free_list.next->prev = &free_list; + +mptcp_nl_remove_addrs_list (sock_net (skb->sk), &free_list);__flush_addrs (&free_list);return 0 ; }
Patches currently in stable-queue which might be from [email protected] are
queue-6.1/selftests-mptcp-join-fix-local-endp-not-being-tracked.patch queue-6.1/mptcp-fix-race-in-mptcp_pm_nl_flush_addrs_doit.patch queue-6.1/mptcp-schedule-rtx-timer-only-after-pushing-data.patch queue-6.1/mptcp-ensure-context-reset-on-disconnect.patch queue-6.1/selftests-mptcp-pm-ensure-unknown-flags-are-ignored.patch queue-6.1/selftests-mptcp-check-no-dup-close-events-after-error.patch queue-6.1/selftests-mptcp-check-subflow-errors-in-close-events.patch