On 10/12/2018 05:45 PM, Daniel Borkmann wrote:
> Whenever the ULP data on the socket is mangled, enforce that the
> caller has the socket lock held as otherwise things may race with
> initialization and cleanup callbacks from ulp ops as both would
> mangle internal socket state.
>
> Joint work with John.
>
> Signed-off-by: Daniel Borkmann <dan...@iogearbox.net>
> Signed-off-by: John Fastabend <john.fastab...@gmail.com>
> ---
> net/ipv4/tcp_ulp.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
> index a5995bb..34e9635 100644
> --- a/net/ipv4/tcp_ulp.c
> +++ b/net/ipv4/tcp_ulp.c
> @@ -123,6 +123,8 @@ void tcp_cleanup_ulp(struct sock *sk)
> {
> struct inet_connection_sock *icsk = inet_csk(sk);
>
> + sock_owned_by_me(sk);
> +
> if (!icsk->icsk_ulp_ops)
> return;
Ahem... inet_csk_prepare_forced_close() releases the socket lock,
and tcp_done(newsk); is called after inet_csk_prepare_forced_close()
syzkaller got the following trace
TCP: request_sock_TCPv6: Possible SYN flooding on port 20002. Sending cookies.
Check SNMP counters.
tmpfs: Bad mount option
s\xA8\xFE\x9E\x92\xE9K\xD7:\x85\x87$z\x94\xFB3\xBF\xE4\x8E\x88\xE2\xF0%\x92\xF8\xE5\xC3lh
WARNING: CPU: 0 PID: 12625 at include/net/sock.h:1539 sock_owned_by_me
include/net/sock.h:1539 [inline]
WARNING: CPU: 0 PID: 12625 at include/net/sock.h:1539
tcp_cleanup_ulp+0x1ad/0x200 net/ipv4/tcp_ulp.c:102
Kernel panic - not syncing: panic_on_warn set ...
CPU: 0 PID: 12625 Comm: syz-executor3 Not tainted 4.19.0-rc8-next-20181016+ #95
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google
01/01/2011
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x244/0x39d lib/dump_stack.c:113
panic+0x2ad/0x55c kernel/panic.c:188
__warn.cold.8+0x20/0x45 kernel/panic.c:540
report_bug+0x254/0x2d0 lib/bug.c:186
fixup_bug arch/x86/kernel/traps.c:178 [inline]
do_error_trap+0x11b/0x200 arch/x86/kernel/traps.c:271
do_invalid_op+0x36/0x40 arch/x86/kernel/traps.c:290
invalid_op+0x14/0x20 arch/x86/entry/entry_64.S:969
RIP: 0010:sock_owned_by_me include/net/sock.h:1539 [inline]
RIP: 0010:tcp_cleanup_ulp+0x1ad/0x200 net/ipv4/tcp_ulp.c:102
Code: 83 c0 03 38 d0 7c 04 84 d2 75 61 44 8b 25 cb 4e df 02 31 ff 44 89 e6 e8
51 3d ed fa 45 85 e4 0f 84 91 fe ff ff e8 33 3c ed fa <0f> 0b e9 85 fe ff ff 4c
89 ef e8 34 84 30 fb e9 9f fe ff ff 4c 89
RSP: 0018:ffff8801dae06860 EFLAGS: 00010206
RAX: ffff8801bf202040 RBX: ffff8801918501c0 RCX: ffffffff8690e6ff
RDX: 0000000000000100 RSI: ffffffff8690e70d RDI: 0000000000000005
RBP: ffff8801dae06880 R08: ffff8801bf202040 R09: 0000000000000002
R10: 0000000000000000 R11: ffff8801bf202040 R12: 0000000000000001
R13: 0000000000000000 R14: 0000000000000003 R15: ffff8801dae069a0
tcp_v4_destroy_sock+0x15c/0x980 net/ipv4/tcp_ipv4.c:1980
tcp_v6_destroy_sock+0x15/0x20 net/ipv6/tcp_ipv6.c:1762
inet_csk_destroy_sock+0x19f/0x440 net/ipv4/inet_connection_sock.c:838
tcp_done+0x272/0x310 net/ipv4/tcp.c:3760
tcp_v6_syn_recv_sock+0x1f21/0x25f0 net/ipv6/tcp_ipv6.c:1236
tcp_get_cookie_sock+0x10e/0x580 net/ipv4/syncookies.c:213
cookie_v6_check+0x1830/0x27d0 net/ipv6/syncookies.c:257
tcp_v6_cookie_check net/ipv6/tcp_ipv6.c:1028 [inline]
tcp_v6_do_rcv+0x10ea/0x13c0 net/ipv6/tcp_ipv6.c:1336
tcp_v6_rcv+0x34e0/0x3ab0 net/ipv6/tcp_ipv6.c:1545
ip6_input_finish+0x3fc/0x1aa0 net/ipv6/ip6_input.c:384
NF_HOOK include/linux/netfilter.h:289 [inline]
ip6_input+0xe4/0x600 net/ipv6/ip6_input.c:427
dst_input include/net/dst.h:450 [inline]
ip6_rcv_finish+0x17a/0x330 net/ipv6/ip6_input.c:76
NF_HOOK include/linux/netfilter.h:289 [inline]
ipv6_rcv+0x110/0x630 net/ipv6/ip6_input.c:272
__netif_receive_skb_one_core+0x14d/0x200 net/core/dev.c:4930
__netif_receive_skb+0x27/0x1e0 net/core/dev.c:5040
process_backlog+0x24e/0x7a0 net/core/dev.c:5844
napi_poll net/core/dev.c:6264 [inline]
net_rx_action+0x7fa/0x19b0 net/core/dev.c:6330
__do_softirq+0x308/0xb7e kernel/softirq.c:292
do_softirq_own_stack+0x2a/0x40 arch/x86/entry/entry_64.S:1023
</IRQ>
do_softirq.part.14+0x126/0x160 kernel/softirq.c:337
do_softirq kernel/softirq.c:329 [inline]
__local_bh_enable_ip+0x21d/0x260 kernel/softirq.c:189
local_bh_enable include/linux/bottom_half.h:32 [inline]
rcu_read_unlock_bh include/linux/rcupdate.h:696 [inline]
ip6_finish_output2+0xce4/0x27a0 net/ipv6/ip6_output.c:121
ip6_finish_output+0x468/0xc60 net/ipv6/ip6_output.c:154
NF_HOOK_COND include/linux/netfilter.h:278 [inline]
ip6_output+0x232/0x9d0 net/ipv6/ip6_output.c:171
dst_output include/net/dst.h:444 [inline]
NF_HOOK include/linux/netfilter.h:289 [inline]
ip6_xmit+0xf64/0x2410 net/ipv6/ip6_output.c:275
inet6_csk_xmit+0x375/0x630 net/ipv6/inet6_connection_sock.c:139
__tcp_transmit_skb+0x1bc5/0x3b00 net/ipv4/tcp_output.c:1162
tcp_transmit_skb net/ipv4/tcp_output.c:1178 [inline]
tcp_write_xmit+0x1676/0x5710 net/ipv4/tcp_output.c:2364
tcp_push_one+0xdd/0x110 net/ipv4/tcp_output.c:2551
tcp_sendmsg_locked+0xbc3/0x3fa0 net/ipv4/tcp.c:1386
tcp_sendmsg+0x2f/0x50 net/ipv4/tcp.c:1443
inet_sendmsg+0x19c/0x690 net/ipv4/af_inet.c:798
sock_sendmsg_nosec net/socket.c:622 [inline]
sock_sendmsg+0xd5/0x120 net/socket.c:632
__sys_sendto+0x3d7/0x670 net/socket.c:1789
__do_sys_sendto net/socket.c:1801 [inline]
__se_sys_sendto net/socket.c:1797 [inline]
__x64_sys_sendto+0xe1/0x1a0 net/socket.c:1797
do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x457569
Code: fd b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48
89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83
cb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f438931cc78 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000000000000006 RCX: 0000000000457569
RDX: fffffffffffffedd RSI: 0000000020000280 RDI: 0000000000000005
RBP: 000000000072bf00 R08: 0000000020000080 R09: 000000000000001c
R10: 000000002000012c R11: 0000000000000246 R12: 00007f438931d6d4
R13: 00000000004c3921 R14: 00000000004d57d8 R15: 00000000ffffffff
Kernel Offset: disabled
Rebooting in 86400 seconds..