Skip to content

Commit e2a9eeb

Browse files
edumazetkuba-moo
authored andcommitted
mptcp: fix race in mptcp_pm_nl_flush_addrs_doit()
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. Fixes: 141694d ("mptcp: remove address when netlink flushes addrs") Signed-off-by: Eric Dumazet <[email protected]> Reported-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/T/ Reported-by: Eulgyu Kim <[email protected]> Closes: multipath-tcp/mptcp_net-next#611 Reviewed-by: Mat Martineau <[email protected]> Signed-off-by: Matthieu Baerts (NGI0) <[email protected]> Link: https://patch.msgid.link/20260124-net-mptcp-race_nl_flush_addrs-v3-1-b2dc1b613e9d@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8d7ba71 commit e2a9eeb

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

net/mptcp/pm_kernel.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,16 +1294,26 @@ static void __reset_counters(struct pm_nl_pernet *pernet)
12941294
int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
12951295
{
12961296
struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
1297-
LIST_HEAD(free_list);
1297+
struct list_head free_list;
12981298

12991299
spin_lock_bh(&pernet->lock);
1300-
list_splice_init(&pernet->endp_list, &free_list);
1300+
free_list = pernet->endp_list;
1301+
INIT_LIST_HEAD_RCU(&pernet->endp_list);
13011302
__reset_counters(pernet);
13021303
pernet->next_id = 1;
13031304
bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
13041305
spin_unlock_bh(&pernet->lock);
1305-
mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
1306+
1307+
if (free_list.next == &pernet->endp_list)
1308+
return 0;
1309+
13061310
synchronize_rcu();
1311+
1312+
/* Adjust the pointers to free_list instead of pernet->endp_list */
1313+
free_list.prev->next = &free_list;
1314+
free_list.next->prev = &free_list;
1315+
1316+
mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
13071317
__flush_addrs(&free_list);
13081318
return 0;
13091319
}

0 commit comments

Comments
 (0)