Commit 1cec775
mptcp: fix 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
If multiple connection requests attempt to create an implicit mptcp
endpoint in parallel, more than one caller may end up in
mptcp_pm_nl_append_new_local_addr because none found the address in
local_addr_list during their call to mptcp_pm_nl_get_local_id. In this
case, the concurrent new_local_addr calls may delete the address entry
created by the previous caller. These deletes use synchronize_rcu, but
this is not permitted in some of the contexts where this function may be
called. During packet recv, the caller may be in a rcu read critical
section and have preemption disabled.
An example stack:
BUG: scheduling while atomic: swapper/2/0/0x00000302
Call Trace:
<IRQ>
dump_stack_lvl+0x76/0xa0
dump_stack+0x10/0x20
__schedule_bug+0x64/0x80
schedule_debug.constprop.0+0xdb/0x130
__schedule+0x69/0x6a0
schedule+0x33/0x110
schedule_timeout+0x157/0x170
wait_for_completion+0x88/0x150
__wait_rcu_gp+0x150/0x160
synchronize_rcu+0x12d/0x140
mptcp_pm_nl_append_new_local_addr+0x1bd/0x280
mptcp_pm_nl_get_local_id+0x121/0x160
mptcp_pm_get_local_id+0x9d/0xe0
subflow_check_req+0x1a8/0x460
subflow_v4_route_req+0xb5/0x110
tcp_conn_request+0x3a4/0xd00
subflow_v4_conn_request+0x42/0xa0
tcp_rcv_state_process+0x1e3/0x7e0
tcp_v4_do_rcv+0xd3/0x2a0
tcp_v4_rcv+0xbb8/0xbf0
ip_protocol_deliver_rcu+0x3c/0x210
ip_local_deliver_finish+0x77/0xa0
ip_local_deliver+0x6e/0x120
ip_sublist_rcv_finish+0x6f/0x80
ip_sublist_rcv+0x178/0x230
ip_list_rcv+0x102/0x140
__netif_receive_skb_list_core+0x22d/0x250
netif_receive_skb_list_internal+0x1a3/0x2d0
napi_complete_done+0x74/0x1c0
igb_poll+0x6c/0xe0 [igb]
__napi_poll+0x30/0x200
net_rx_action+0x181/0x2e0
handle_softirqs+0xd8/0x340
__irq_exit_rcu+0xd9/0x100
irq_exit_rcu+0xe/0x20
common_interrupt+0xa4/0xb0
</IRQ>
This problem seems particularly prevalent if the user advertises an
endpoint that has a different external vs internal address. In the case
where the external address is advertised and multiple connections
already exist, multiple subflow SYNs arrive in parallel which tends to
trigger the race during creation of the first local_addr_list entries
which have the internal address instead.
Fix by skipping the replacement of an existing implicit local address if
called via mptcp_pm_nl_get_local_id.
Cc: [email protected]
Fixes: d045b9e ("mptcp: introduce implicit endpoints")
Suggested-by: Paolo Abeni <[email protected]>
Signed-off-by: Krister Johansen <[email protected]>1 parent 384fa1d commit 1cec775
1 file changed
+15
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
977 | 977 | | |
978 | 978 | | |
979 | 979 | | |
980 | | - | |
| 980 | + | |
981 | 981 | | |
982 | 982 | | |
983 | 983 | | |
| |||
1017 | 1017 | | |
1018 | 1018 | | |
1019 | 1019 | | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
1020 | 1031 | | |
1021 | 1032 | | |
1022 | 1033 | | |
| |||
1165 | 1176 | | |
1166 | 1177 | | |
1167 | 1178 | | |
1168 | | - | |
| 1179 | + | |
1169 | 1180 | | |
1170 | 1181 | | |
1171 | 1182 | | |
| |||
1433 | 1444 | | |
1434 | 1445 | | |
1435 | 1446 | | |
1436 | | - | |
| 1447 | + | |
| 1448 | + | |
1437 | 1449 | | |
1438 | 1450 | | |
1439 | 1451 | | |
| |||
0 commit comments