* [PATCH net] dccp/tcp: fix ireq->opt races
@ 2017-10-17 19:45 Eric Dumazet
2017-10-17 19:50 ` Eric Dumazet
2017-10-19 12:31 ` David Miller
0 siblings, 2 replies; 12+ messages in thread
From: Eric Dumazet @ 2017-10-17 19:45 UTC (permalink / raw)
To: David Miller; +Cc: netdev, edumazet
From: Eric Dumazet <edumazet@google.com>
syzkaller found another bug in DCCP/TCP stacks [1]
For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix
ireq->pktopts race"), we need to make sure we do not access
ireq->opt unless we own the request sock.
[1]
BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295
CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:16 [inline]
dump_stack+0x194/0x257 lib/dump_stack.c:52
print_address_description+0x73/0x250 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351 [inline]
kasan_report+0x25b/0x340 mm/kasan/report.c:409
__asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427
ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474
tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135
tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587
tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557
__tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072
tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline]
tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071
tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816
tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x40c341
RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341
RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015
RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1
R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000
Allocated by task 3295:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
__do_kmalloc mm/slab.c:3725 [inline]
__kmalloc+0x162/0x760 mm/slab.c:3734
kmalloc include/linux/slab.h:498 [inline]
tcp_v4_save_options include/net/tcp.h:1962 [inline]
tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271
tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283
tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313
tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857
tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482
tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
Freed by task 3306:
save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
save_stack+0x43/0xd0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524
__cache_free mm/slab.c:3503 [inline]
kfree+0xca/0x250 mm/slab.c:3820
inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157
__sk_destruct+0xfd/0x910 net/core/sock.c:1560
sk_destruct+0x47/0x80 net/core/sock.c:1595
__sk_free+0x57/0x230 net/core/sock.c:1603
sk_free+0x2a/0x40 net/core/sock.c:1614
sock_put include/net/sock.h:1652 [inline]
inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959
tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765
tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675
ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257
dst_input include/net/dst.h:464 [inline]
ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397
NF_HOOK include/linux/netfilter.h:249 [inline]
ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493
__netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476
__netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514
netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587
netif_receive_skb+0xae/0x390 net/core/dev.c:4611
tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372
tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766
tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792
call_write_iter include/linux/fs.h:1770 [inline]
new_sync_write fs/read_write.c:468 [inline]
__vfs_write+0x68a/0x970 fs/read_write.c:481
vfs_write+0x18f/0x510 fs/read_write.c:543
SYSC_write fs/read_write.c:588 [inline]
SyS_write+0xef/0x220 fs/read_write.c:580
entry_SYSCALL_64_fastpath+0x1f/0xbe
The buggy address belongs to the object at ffff8801c9510380
which belongs to the cache kmalloc-64 of size 64
The buggy address is located 28 bytes inside of
64-byte region [ffff8801c9510380, ffff8801c95103c0)
The buggy address belongs to the page:
page:ffffea0007254400 count:1 mapcount:0 mapping:ffff8801c9510000 index:0x0
flags: 0x200000000000100(slab)
raw: 0200000000000100 ffff8801c9510000 0000000000000000 0000000100000020
raw: ffffea0007264f60 ffffea00072e2ae0 ffff8801dac00340 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801c9510280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ffff8801c9510300: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff8801c9510380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ffff8801c9510400: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
ffff8801c9510480: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
==================================================================
Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/inet_sock.h | 2 +-
net/dccp/ipv4.c | 13 ++++++++-----
net/ipv4/inet_connection_sock.c | 8 +++-----
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_input.c | 2 +-
net/ipv4/tcp_ipv4.c | 22 +++++++++++++---------
6 files changed, 27 insertions(+), 22 deletions(-)
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:45 [PATCH net] dccp/tcp: fix ireq->opt races Eric Dumazet @ 2017-10-17 19:50 ` Eric Dumazet 2017-10-17 19:53 ` Eric Dumazet ` (4 more replies) 2017-10-19 12:31 ` David Miller 1 sibling, 5 replies; 12+ messages in thread From: Eric Dumazet @ 2017-10-17 19:50 UTC (permalink / raw) To: David Miller; +Cc: netdev, edumazet From: Eric Dumazet <edumazet@google.com> syzkaller found another bug in DCCP/TCP stacks [1] For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix ireq->pktopts race"), we need to make sure we do not access ireq->opt unless we own the request sock. [1] BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295 CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x194/0x257 lib/dump_stack.c:52 print_address_description+0x73/0x250 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x25b/0x340 mm/kasan/report.c:409 __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427 ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135 tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587 tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557 __tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072 tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline] tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071 tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816 tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x40c341 RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341 RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015 RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1 R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000 Allocated by task 3295: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551 __do_kmalloc mm/slab.c:3725 [inline] __kmalloc+0x162/0x760 mm/slab.c:3734 kmalloc include/linux/slab.h:498 [inline] tcp_v4_save_options include/net/tcp.h:1962 [inline] tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271 tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283 tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313 tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857 tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482 tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe Freed by task 3306: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524 __cache_free mm/slab.c:3503 [inline] kfree+0xca/0x250 mm/slab.c:3820 inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157 __sk_destruct+0xfd/0x910 net/core/sock.c:1560 sk_destruct+0x47/0x80 net/core/sock.c:1595 __sk_free+0x57/0x230 net/core/sock.c:1603 sk_free+0x2a/0x40 net/core/sock.c:1614 sock_put include/net/sock.h:1652 [inline] inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959 tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765 tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe The buggy address belongs to the object at ffff8801c9510380 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 28 bytes inside of 64-byte region [ffff8801c9510380, ffff8801c95103c0) The buggy address belongs to the page: page:ffffea0007254400 count:1 mapcount:0 mapping:ffff8801c9510000 index:0x0 flags: 0x200000000000100(slab) raw: 0200000000000100 ffff8801c9510000 0000000000000000 0000000100000020 raw: ffffea0007264f60 ffffea00072e2ae0 ffff8801dac00340 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff8801c9510280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff8801c9510300: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff8801c9510380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff8801c9510400: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc ffff8801c9510480: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc ================================================================== Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table") Signed-off-by: Eric Dumazet <edumazet@google.com> --- include/net/inet_sock.h | 2 +- net/dccp/ipv4.c | 13 ++++++++----- net/ipv4/inet_connection_sock.c | 8 +++----- net/ipv4/syncookies.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_ipv4.c | 22 +++++++++++++--------- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index aa95053dfc78d35d04aef276e2a5dce7343f72a0..425752f768d2f1a0efb13964204e07f27609e9db 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -96,7 +96,7 @@ struct inet_request_sock { kmemcheck_bitfield_end(flags); u32 ir_mark; union { - struct ip_options_rcu *opt; + struct ip_options_rcu __rcu *ireq_opt; #if IS_ENABLED(CONFIG_IPV6) struct { struct ipv6_txoptions *ipv6_opt; diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 001c08696334bba0ceb896c116e595b814af0667..0490916864f93d5466e87f5b97dc524b3ee57a2e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newinet->inet_saddr = ireq->ir_loc_addr; - newinet->inet_opt = ireq->opt; - ireq->opt = NULL; + RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->inet_id = jiffies; @@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - + if (*own_req) + ireq->ireq_opt = NULL; + else + newinet->inet_opt = NULL; return newsk; exit_overflow: @@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); dccp_done(newsk); goto exit; @@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req ireq->ir_rmt_addr); err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb) static void dccp_v4_reqsk_destructor(struct request_sock *req) { dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } void dccp_syn_ack_timeout(const struct request_sock *req) diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 67aec7a106860b26c929fea1624d652c87972f04..5ec9136a7c36933cb36e5cd50058eb6cf189a7c3 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -540,9 +540,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk, { const struct inet_request_sock *ireq = inet_rsk(req); struct net *net = read_pnet(&ireq->ireq_net); - struct ip_options_rcu *opt = ireq->opt; + struct ip_options_rcu *opt; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -576,10 +577,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, struct flowi4 *fl4; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); fl4 = &newinet->cork.fl.u.ip4; - rcu_read_lock(); - opt = rcu_dereference(newinet->inet_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -592,13 +592,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, goto no_route; if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) goto route_err; - rcu_read_unlock(); return &rt->dst; route_err: ip_rt_put(rt); no_route: - rcu_read_unlock(); __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b1bb1b3a108232d56aa82383422d68b5ff9da3ed..77cf32a80952fcf3ceff4ada946cc2d0df2411d9 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) */ - ireq->opt = tcp_v4_save_options(sock_net(sk), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb)); if (security_inet_conn_request(sk, skb, req)) { reqsk_free(req); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c5d7656beeee29b3c92e1c8824dbf00d3fa32d28..7eec3383702bbab497a12095b55d255532ad5f60 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6196,7 +6196,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, struct inet_request_sock *ireq = inet_rsk(req); kmemcheck_annotate_bitfield(ireq, flags); - ireq->opt = NULL; + ireq->ireq_opt = NULL; #if IS_ENABLED(CONFIG_IPV6) ireq->pktopts = NULL; #endif diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 85164d4d3e537537c87d74c00172592c860d4dfb..4c43365c374c8bf868fc0b862333244ca26d5016 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, */ static void tcp_v4_reqsk_destructor(struct request_sock *req) { - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } #ifdef CONFIG_TCP_MD5SIG @@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req, struct sk_buff *skb) { struct inet_request_sock *ireq = inet_rsk(req); + struct net *net = sock_net(sk_listener); sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, @@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newsk->sk_bound_dev_if = ireq->ir_iif; - newinet->inet_saddr = ireq->ir_loc_addr; - inet_opt = ireq->opt; - rcu_assign_pointer(newinet->inet_opt, inet_opt); - ireq->opt = NULL; + newinet->inet_saddr = ireq->ir_loc_addr; + inet_opt = rcu_dereference(ireq->ireq_opt); + RCU_INIT_POINTER(newinet->inet_opt, inet_opt); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->rcv_tos = ip_hdr(skb)->tos; @@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - if (*own_req) + if (likely(*own_req)) { tcp_move_syn(newtp, req); - + ireq->ireq_opt = NULL; + } else { + newinet->inet_opt = NULL; + } return newsk; exit_overflow: @@ -1416,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, tcp_listendrop(sk); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); tcp_done(newsk); goto exit; ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:50 ` Eric Dumazet @ 2017-10-17 19:53 ` Eric Dumazet 2017-10-17 19:55 ` [PATCH v2 " Eric Dumazet ` (3 subsequent siblings) 4 siblings, 0 replies; 12+ messages in thread From: Eric Dumazet @ 2017-10-17 19:53 UTC (permalink / raw) To: David Miller; +Cc: netdev, edumazet On Tue, 2017-10-17 at 12:50 -0700, Eric Dumazet wrote: > From: Eric Dumazet <edumazet@google.com> > > syzkaller found another bug in DCCP/TCP stacks [1] > > For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix > ireq->pktopts race"), we need to make sure we do not access > ireq->opt unless we own the request sock. Arg, I will send a v2 without the silly lines that confuse patchwork. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 net] dccp/tcp: fix ireq->opt races 2017-10-17 19:50 ` Eric Dumazet 2017-10-17 19:53 ` Eric Dumazet @ 2017-10-17 19:55 ` Eric Dumazet 2017-10-20 16:53 ` [PATCH " kbuild test robot ` (2 subsequent siblings) 4 siblings, 0 replies; 12+ messages in thread From: Eric Dumazet @ 2017-10-17 19:55 UTC (permalink / raw) To: David Miller; +Cc: netdev, edumazet From: Eric Dumazet <edumazet@google.com> syzkaller found another bug in DCCP/TCP stacks [1] For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix ireq->pktopts race"), we need to make sure we do not access ireq->opt unless we own the request sock. [1] BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295 CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x194/0x257 lib/dump_stack.c:52 print_address_description+0x73/0x250 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x25b/0x340 mm/kasan/report.c:409 __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427 ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135 tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587 tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557 __tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072 tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline] tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071 tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816 tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x40c341 RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341 RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015 RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1 R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000 Allocated by task 3295: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551 __do_kmalloc mm/slab.c:3725 [inline] __kmalloc+0x162/0x760 mm/slab.c:3734 kmalloc include/linux/slab.h:498 [inline] tcp_v4_save_options include/net/tcp.h:1962 [inline] tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271 tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283 tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313 tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857 tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482 tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe Freed by task 3306: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524 __cache_free mm/slab.c:3503 [inline] kfree+0xca/0x250 mm/slab.c:3820 inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157 __sk_destruct+0xfd/0x910 net/core/sock.c:1560 sk_destruct+0x47/0x80 net/core/sock.c:1595 __sk_free+0x57/0x230 net/core/sock.c:1603 sk_free+0x2a/0x40 net/core/sock.c:1614 sock_put include/net/sock.h:1652 [inline] inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959 tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765 tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table") Signed-off-by: Eric Dumazet <edumazet@google.com> --- v2: removed some lines from KASAN report that confuse patchwork. include/net/inet_sock.h | 2 +- net/dccp/ipv4.c | 13 ++++++++----- net/ipv4/inet_connection_sock.c | 8 +++----- net/ipv4/syncookies.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_ipv4.c | 22 +++++++++++++--------- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index aa95053dfc78d35d04aef276e2a5dce7343f72a0..425752f768d2f1a0efb13964204e07f27609e9db 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -96,7 +96,7 @@ struct inet_request_sock { kmemcheck_bitfield_end(flags); u32 ir_mark; union { - struct ip_options_rcu *opt; + struct ip_options_rcu __rcu *ireq_opt; #if IS_ENABLED(CONFIG_IPV6) struct { struct ipv6_txoptions *ipv6_opt; diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 001c08696334bba0ceb896c116e595b814af0667..0490916864f93d5466e87f5b97dc524b3ee57a2e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newinet->inet_saddr = ireq->ir_loc_addr; - newinet->inet_opt = ireq->opt; - ireq->opt = NULL; + RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->inet_id = jiffies; @@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - + if (*own_req) + ireq->ireq_opt = NULL; + else + newinet->inet_opt = NULL; return newsk; exit_overflow: @@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); dccp_done(newsk); goto exit; @@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req ireq->ir_rmt_addr); err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb) static void dccp_v4_reqsk_destructor(struct request_sock *req) { dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } void dccp_syn_ack_timeout(const struct request_sock *req) diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 67aec7a106860b26c929fea1624d652c87972f04..5ec9136a7c36933cb36e5cd50058eb6cf189a7c3 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -540,9 +540,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk, { const struct inet_request_sock *ireq = inet_rsk(req); struct net *net = read_pnet(&ireq->ireq_net); - struct ip_options_rcu *opt = ireq->opt; + struct ip_options_rcu *opt; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -576,10 +577,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, struct flowi4 *fl4; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); fl4 = &newinet->cork.fl.u.ip4; - rcu_read_lock(); - opt = rcu_dereference(newinet->inet_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -592,13 +592,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, goto no_route; if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) goto route_err; - rcu_read_unlock(); return &rt->dst; route_err: ip_rt_put(rt); no_route: - rcu_read_unlock(); __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b1bb1b3a108232d56aa82383422d68b5ff9da3ed..77cf32a80952fcf3ceff4ada946cc2d0df2411d9 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) */ - ireq->opt = tcp_v4_save_options(sock_net(sk), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb)); if (security_inet_conn_request(sk, skb, req)) { reqsk_free(req); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c5d7656beeee29b3c92e1c8824dbf00d3fa32d28..7eec3383702bbab497a12095b55d255532ad5f60 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6196,7 +6196,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, struct inet_request_sock *ireq = inet_rsk(req); kmemcheck_annotate_bitfield(ireq, flags); - ireq->opt = NULL; + ireq->ireq_opt = NULL; #if IS_ENABLED(CONFIG_IPV6) ireq->pktopts = NULL; #endif diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 85164d4d3e537537c87d74c00172592c860d4dfb..4c43365c374c8bf868fc0b862333244ca26d5016 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, */ static void tcp_v4_reqsk_destructor(struct request_sock *req) { - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } #ifdef CONFIG_TCP_MD5SIG @@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req, struct sk_buff *skb) { struct inet_request_sock *ireq = inet_rsk(req); + struct net *net = sock_net(sk_listener); sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, @@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newsk->sk_bound_dev_if = ireq->ir_iif; - newinet->inet_saddr = ireq->ir_loc_addr; - inet_opt = ireq->opt; - rcu_assign_pointer(newinet->inet_opt, inet_opt); - ireq->opt = NULL; + newinet->inet_saddr = ireq->ir_loc_addr; + inet_opt = rcu_dereference(ireq->ireq_opt); + RCU_INIT_POINTER(newinet->inet_opt, inet_opt); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->rcv_tos = ip_hdr(skb)->tos; @@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - if (*own_req) + if (likely(*own_req)) { tcp_move_syn(newtp, req); - + ireq->ireq_opt = NULL; + } else { + newinet->inet_opt = NULL; + } return newsk; exit_overflow: @@ -1416,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, tcp_listendrop(sk); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); tcp_done(newsk); goto exit; ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:50 ` Eric Dumazet 2017-10-17 19:53 ` Eric Dumazet 2017-10-17 19:55 ` [PATCH v2 " Eric Dumazet @ 2017-10-20 16:53 ` kbuild test robot 2017-10-20 17:38 ` Eric Dumazet 2017-10-20 16:53 ` kbuild test robot 2017-10-20 18:34 ` kbuild test robot 4 siblings, 1 reply; 12+ messages in thread From: kbuild test robot @ 2017-10-20 16:53 UTC (permalink / raw) To: Eric Dumazet; +Cc: kbuild-all, David Miller, netdev, edumazet [-- Attachment #1: Type: text/plain, Size: 15070 bytes --] Hi Eric, [auto build test WARNING on net/master] url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-001234 config: ia64-allmodconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 6.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=ia64 All warnings (new ones prefixed by >>): In file included from arch/ia64/include/uapi/asm/intrinsics.h:21:0, from arch/ia64/include/asm/intrinsics.h:10, from arch/ia64/include/asm/atomic.h:17, from include/linux/atomic.h:4, from include/linux/rcupdate.h:38, from net/ipv4/cipso_ipv4.c:40: net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr': net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/cmpxchg.h:56:16: note: in definition of macro 'xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~ net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/cmpxchg.h:33:10: note: in definition of macro '__xchg' switch (size) { \ ^~~~ >> net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ In file included from arch/ia64/include/asm/gcc_intrin.h:9:0, from arch/ia64/include/uapi/asm/intrinsics.h:19, from arch/ia64/include/asm/intrinsics.h:10, from arch/ia64/include/asm/atomic.h:17, from include/linux/atomic.h:4, from include/linux/rcupdate.h:38, from net/ipv4/cipso_ipv4.c:40: net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:279:40: note: in definition of macro 'ia64_xchg1' : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ >> net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:287:16: note: in definition of macro 'ia64_xchg2' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ >> net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:295:16: note: in definition of macro 'ia64_xchg4' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ >> net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:303:16: note: in definition of macro 'ia64_xchg8' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ >> net/ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr': net/ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt' opt = req_inet->opt; ^~ net/ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt' cipso_v4_delopt(&req_inet->opt); ^~ -- In file included from arch/ia64/include/uapi/asm/intrinsics.h:21:0, from arch/ia64/include/asm/intrinsics.h:10, from arch/ia64/include/asm/atomic.h:17, from include/linux/atomic.h:4, from include/linux/rcupdate.h:38, from net//ipv4/cipso_ipv4.c:40: net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr': net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/cmpxchg.h:56:16: note: in definition of macro 'xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~ net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/cmpxchg.h:33:10: note: in definition of macro '__xchg' switch (size) { \ ^~~~ net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ In file included from arch/ia64/include/asm/gcc_intrin.h:9:0, from arch/ia64/include/uapi/asm/intrinsics.h:19, from arch/ia64/include/asm/intrinsics.h:10, from arch/ia64/include/asm/atomic.h:17, from include/linux/atomic.h:4, from include/linux/rcupdate.h:38, from net//ipv4/cipso_ipv4.c:40: net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:279:40: note: in definition of macro 'ia64_xchg1' : "=r" (ia64_intri_res) : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:287:16: note: in definition of macro 'ia64_xchg2' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:295:16: note: in definition of macro 'ia64_xchg4' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net//ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/ia64/include/uapi/asm/gcc_intrin.h:303:16: note: in definition of macro 'ia64_xchg8' : "r" (ptr), "r" (x) : "memory"); \ ^~~ >> arch/ia64/include/uapi/asm/cmpxchg.h:56:23: note: in expansion of macro '__xchg' ((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) ^~~~~~ net//ipv4/cipso_ipv4.c:1954:8: note: in expansion of macro 'xchg' opt = xchg(&req_inet->opt, opt); ^~~~ net//ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr': net//ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt' opt = req_inet->opt; ^~ net//ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt' cipso_v4_delopt(&req_inet->opt); ^~ vim +/xchg +1954 net/ipv4/cipso_ipv4.c 446fda4f2 Paul Moore 2006-08-03 1898 446fda4f2 Paul Moore 2006-08-03 1899 /** 389fb800a Paul Moore 2009-03-27 1900 * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket 389fb800a Paul Moore 2009-03-27 1901 * @req: the connection request socket 389fb800a Paul Moore 2009-03-27 1902 * @doi_def: the CIPSO DOI to use 389fb800a Paul Moore 2009-03-27 1903 * @secattr: the specific security attributes of the socket 014ab19a6 Paul Moore 2008-10-10 1904 * 014ab19a6 Paul Moore 2008-10-10 1905 * Description: 389fb800a Paul Moore 2009-03-27 1906 * Set the CIPSO option on the given socket using the DOI definition and 389fb800a Paul Moore 2009-03-27 1907 * security attributes passed to the function. Returns zero on success and 389fb800a Paul Moore 2009-03-27 1908 * negative values on failure. 014ab19a6 Paul Moore 2008-10-10 1909 * 014ab19a6 Paul Moore 2008-10-10 1910 */ 389fb800a Paul Moore 2009-03-27 1911 int cipso_v4_req_setattr(struct request_sock *req, 389fb800a Paul Moore 2009-03-27 1912 const struct cipso_v4_doi *doi_def, 389fb800a Paul Moore 2009-03-27 1913 const struct netlbl_lsm_secattr *secattr) 014ab19a6 Paul Moore 2008-10-10 1914 { 389fb800a Paul Moore 2009-03-27 1915 int ret_val = -EPERM; 389fb800a Paul Moore 2009-03-27 1916 unsigned char *buf = NULL; 389fb800a Paul Moore 2009-03-27 1917 u32 buf_len; 389fb800a Paul Moore 2009-03-27 1918 u32 opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1919 struct ip_options_rcu *opt = NULL; 389fb800a Paul Moore 2009-03-27 1920 struct inet_request_sock *req_inet; 014ab19a6 Paul Moore 2008-10-10 1921 389fb800a Paul Moore 2009-03-27 1922 /* We allocate the maximum CIPSO option size here so we are probably 389fb800a Paul Moore 2009-03-27 1923 * being a little wasteful, but it makes our life _much_ easier later 389fb800a Paul Moore 2009-03-27 1924 * on and after all we are only talking about 40 bytes. */ 389fb800a Paul Moore 2009-03-27 1925 buf_len = CIPSO_V4_OPT_LEN_MAX; 389fb800a Paul Moore 2009-03-27 1926 buf = kmalloc(buf_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1927 if (!buf) { 389fb800a Paul Moore 2009-03-27 1928 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1929 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1930 } 389fb800a Paul Moore 2009-03-27 1931 389fb800a Paul Moore 2009-03-27 1932 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 389fb800a Paul Moore 2009-03-27 1933 if (ret_val < 0) 389fb800a Paul Moore 2009-03-27 1934 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1935 buf_len = ret_val; 389fb800a Paul Moore 2009-03-27 1936 389fb800a Paul Moore 2009-03-27 1937 /* We can't use ip_options_get() directly because it makes a call to 389fb800a Paul Moore 2009-03-27 1938 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 389fb800a Paul Moore 2009-03-27 1939 * we won't always have CAP_NET_RAW even though we _always_ want to 389fb800a Paul Moore 2009-03-27 1940 * set the IPOPT_CIPSO option. */ 389fb800a Paul Moore 2009-03-27 1941 opt_len = (buf_len + 3) & ~3; 389fb800a Paul Moore 2009-03-27 1942 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1943 if (!opt) { 389fb800a Paul Moore 2009-03-27 1944 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1945 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1946 } f6d8bd051 Eric Dumazet 2011-04-21 1947 memcpy(opt->opt.__data, buf, buf_len); f6d8bd051 Eric Dumazet 2011-04-21 1948 opt->opt.optlen = opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1949 opt->opt.cipso = sizeof(struct iphdr); 389fb800a Paul Moore 2009-03-27 1950 kfree(buf); 389fb800a Paul Moore 2009-03-27 1951 buf = NULL; 389fb800a Paul Moore 2009-03-27 1952 389fb800a Paul Moore 2009-03-27 1953 req_inet = inet_rsk(req); 389fb800a Paul Moore 2009-03-27 @1954 opt = xchg(&req_inet->opt, opt); f6d8bd051 Eric Dumazet 2011-04-21 1955 if (opt) 4f9c8c1b0 Paul E. McKenney 2012-01-06 1956 kfree_rcu(opt, rcu); 389fb800a Paul Moore 2009-03-27 1957 389fb800a Paul Moore 2009-03-27 1958 return 0; 389fb800a Paul Moore 2009-03-27 1959 389fb800a Paul Moore 2009-03-27 1960 req_setattr_failure: 389fb800a Paul Moore 2009-03-27 1961 kfree(buf); 389fb800a Paul Moore 2009-03-27 1962 kfree(opt); 389fb800a Paul Moore 2009-03-27 1963 return ret_val; 389fb800a Paul Moore 2009-03-27 1964 } 389fb800a Paul Moore 2009-03-27 1965 :::::: The code at line 1954 was first introduced by commit :::::: 389fb800ac8be2832efedd19978a2b8ced37eb61 netlabel: Label incoming TCP connections correctly in SELinux :::::: TO: Paul Moore <paul.moore@hp.com> :::::: CC: James Morris <jmorris@namei.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 48800 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-20 16:53 ` [PATCH " kbuild test robot @ 2017-10-20 17:38 ` Eric Dumazet 0 siblings, 0 replies; 12+ messages in thread From: Eric Dumazet @ 2017-10-20 17:38 UTC (permalink / raw) To: kbuild test robot; +Cc: kbuild-all, David Miller, netdev, edumazet On Sat, 2017-10-21 at 00:53 +0800, kbuild test robot wrote: > Hi Eric, > > [auto build test WARNING on net/master] > > url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-001234 > config: ia64-allmodconfig (attached as .config) > compiler: ia64-linux-gcc (GCC) 6.2.0 > reproduce: > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=ia64 Thanks, v4 of the patch should fix this. https://patchwork.ozlabs.org/patch/828713/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:50 ` Eric Dumazet ` (2 preceding siblings ...) 2017-10-20 16:53 ` [PATCH " kbuild test robot @ 2017-10-20 16:53 ` kbuild test robot 2017-10-20 18:34 ` kbuild test robot 4 siblings, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-10-20 16:53 UTC (permalink / raw) To: Eric Dumazet; +Cc: kbuild-all, David Miller, netdev, edumazet [-- Attachment #1: Type: text/plain, Size: 7802 bytes --] Hi Eric, [auto build test ERROR on net/master] url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-001234 config: blackfin-allyesconfig (attached as .config) compiler: bfin-uclinux-gcc (GCC) 6.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=blackfin All errors (new ones prefixed by >>): In file included from arch/blackfin/include/asm/atomic.h:10:0, from include/linux/atomic.h:4, from include/linux/rcupdate.h:38, from net/ipv4/cipso_ipv4.c:40: net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_setattr': >> net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/blackfin/include/asm/cmpxchg.h:130:37: note: in definition of macro 'xchg' #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) ^~~ >> net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/blackfin/include/asm/cmpxchg.h:130:71: note: in definition of macro 'xchg' #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) ^~~ >> net/ipv4/cipso_ipv4.c:1954:22: error: 'struct inet_request_sock' has no member named 'opt' opt = xchg(&req_inet->opt, opt); ^ arch/blackfin/include/asm/cmpxchg.h:130:86: note: in definition of macro 'xchg' #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) ^~~ net/ipv4/cipso_ipv4.c: In function 'cipso_v4_req_delattr': net/ipv4/cipso_ipv4.c:2073:16: error: 'struct inet_request_sock' has no member named 'opt' opt = req_inet->opt; ^~ net/ipv4/cipso_ipv4.c:2077:27: error: 'struct inet_request_sock' has no member named 'opt' cipso_v4_delopt(&req_inet->opt); ^~ vim +1954 net/ipv4/cipso_ipv4.c 446fda4f2 Paul Moore 2006-08-03 1898 446fda4f2 Paul Moore 2006-08-03 1899 /** 389fb800a Paul Moore 2009-03-27 1900 * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket 389fb800a Paul Moore 2009-03-27 1901 * @req: the connection request socket 389fb800a Paul Moore 2009-03-27 1902 * @doi_def: the CIPSO DOI to use 389fb800a Paul Moore 2009-03-27 1903 * @secattr: the specific security attributes of the socket 014ab19a6 Paul Moore 2008-10-10 1904 * 014ab19a6 Paul Moore 2008-10-10 1905 * Description: 389fb800a Paul Moore 2009-03-27 1906 * Set the CIPSO option on the given socket using the DOI definition and 389fb800a Paul Moore 2009-03-27 1907 * security attributes passed to the function. Returns zero on success and 389fb800a Paul Moore 2009-03-27 1908 * negative values on failure. 014ab19a6 Paul Moore 2008-10-10 1909 * 014ab19a6 Paul Moore 2008-10-10 1910 */ 389fb800a Paul Moore 2009-03-27 1911 int cipso_v4_req_setattr(struct request_sock *req, 389fb800a Paul Moore 2009-03-27 1912 const struct cipso_v4_doi *doi_def, 389fb800a Paul Moore 2009-03-27 1913 const struct netlbl_lsm_secattr *secattr) 014ab19a6 Paul Moore 2008-10-10 1914 { 389fb800a Paul Moore 2009-03-27 1915 int ret_val = -EPERM; 389fb800a Paul Moore 2009-03-27 1916 unsigned char *buf = NULL; 389fb800a Paul Moore 2009-03-27 1917 u32 buf_len; 389fb800a Paul Moore 2009-03-27 1918 u32 opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1919 struct ip_options_rcu *opt = NULL; 389fb800a Paul Moore 2009-03-27 1920 struct inet_request_sock *req_inet; 014ab19a6 Paul Moore 2008-10-10 1921 389fb800a Paul Moore 2009-03-27 1922 /* We allocate the maximum CIPSO option size here so we are probably 389fb800a Paul Moore 2009-03-27 1923 * being a little wasteful, but it makes our life _much_ easier later 389fb800a Paul Moore 2009-03-27 1924 * on and after all we are only talking about 40 bytes. */ 389fb800a Paul Moore 2009-03-27 1925 buf_len = CIPSO_V4_OPT_LEN_MAX; 389fb800a Paul Moore 2009-03-27 1926 buf = kmalloc(buf_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1927 if (!buf) { 389fb800a Paul Moore 2009-03-27 1928 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1929 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1930 } 389fb800a Paul Moore 2009-03-27 1931 389fb800a Paul Moore 2009-03-27 1932 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 389fb800a Paul Moore 2009-03-27 1933 if (ret_val < 0) 389fb800a Paul Moore 2009-03-27 1934 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1935 buf_len = ret_val; 389fb800a Paul Moore 2009-03-27 1936 389fb800a Paul Moore 2009-03-27 1937 /* We can't use ip_options_get() directly because it makes a call to 389fb800a Paul Moore 2009-03-27 1938 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 389fb800a Paul Moore 2009-03-27 1939 * we won't always have CAP_NET_RAW even though we _always_ want to 389fb800a Paul Moore 2009-03-27 1940 * set the IPOPT_CIPSO option. */ 389fb800a Paul Moore 2009-03-27 1941 opt_len = (buf_len + 3) & ~3; 389fb800a Paul Moore 2009-03-27 1942 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1943 if (!opt) { 389fb800a Paul Moore 2009-03-27 1944 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1945 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1946 } f6d8bd051 Eric Dumazet 2011-04-21 1947 memcpy(opt->opt.__data, buf, buf_len); f6d8bd051 Eric Dumazet 2011-04-21 1948 opt->opt.optlen = opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1949 opt->opt.cipso = sizeof(struct iphdr); 389fb800a Paul Moore 2009-03-27 1950 kfree(buf); 389fb800a Paul Moore 2009-03-27 1951 buf = NULL; 389fb800a Paul Moore 2009-03-27 1952 389fb800a Paul Moore 2009-03-27 1953 req_inet = inet_rsk(req); 389fb800a Paul Moore 2009-03-27 @1954 opt = xchg(&req_inet->opt, opt); f6d8bd051 Eric Dumazet 2011-04-21 1955 if (opt) 4f9c8c1b0 Paul E. McKenney 2012-01-06 1956 kfree_rcu(opt, rcu); 389fb800a Paul Moore 2009-03-27 1957 389fb800a Paul Moore 2009-03-27 1958 return 0; 389fb800a Paul Moore 2009-03-27 1959 389fb800a Paul Moore 2009-03-27 1960 req_setattr_failure: 389fb800a Paul Moore 2009-03-27 1961 kfree(buf); 389fb800a Paul Moore 2009-03-27 1962 kfree(opt); 389fb800a Paul Moore 2009-03-27 1963 return ret_val; 389fb800a Paul Moore 2009-03-27 1964 } 389fb800a Paul Moore 2009-03-27 1965 :::::: The code at line 1954 was first introduced by commit :::::: 389fb800ac8be2832efedd19978a2b8ced37eb61 netlabel: Label incoming TCP connections correctly in SELinux :::::: TO: Paul Moore <paul.moore@hp.com> :::::: CC: James Morris <jmorris@namei.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 46054 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:50 ` Eric Dumazet ` (3 preceding siblings ...) 2017-10-20 16:53 ` kbuild test robot @ 2017-10-20 18:34 ` kbuild test robot 4 siblings, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-10-20 18:34 UTC (permalink / raw) To: Eric Dumazet; +Cc: kbuild-all, David Miller, netdev, edumazet Hi Eric, [auto build test WARNING on net/master] url: https://github.com/0day-ci/linux/commits/Eric-Dumazet/dccp-tcp-fix-ireq-opt-races/20171021-001234 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) vim +1954 net/ipv4/cipso_ipv4.c 446fda4f2 Paul Moore 2006-08-03 1898 446fda4f2 Paul Moore 2006-08-03 1899 /** 389fb800a Paul Moore 2009-03-27 1900 * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket 389fb800a Paul Moore 2009-03-27 1901 * @req: the connection request socket 389fb800a Paul Moore 2009-03-27 1902 * @doi_def: the CIPSO DOI to use 389fb800a Paul Moore 2009-03-27 1903 * @secattr: the specific security attributes of the socket 014ab19a6 Paul Moore 2008-10-10 1904 * 014ab19a6 Paul Moore 2008-10-10 1905 * Description: 389fb800a Paul Moore 2009-03-27 1906 * Set the CIPSO option on the given socket using the DOI definition and 389fb800a Paul Moore 2009-03-27 1907 * security attributes passed to the function. Returns zero on success and 389fb800a Paul Moore 2009-03-27 1908 * negative values on failure. 014ab19a6 Paul Moore 2008-10-10 1909 * 014ab19a6 Paul Moore 2008-10-10 1910 */ 389fb800a Paul Moore 2009-03-27 1911 int cipso_v4_req_setattr(struct request_sock *req, 389fb800a Paul Moore 2009-03-27 1912 const struct cipso_v4_doi *doi_def, 389fb800a Paul Moore 2009-03-27 1913 const struct netlbl_lsm_secattr *secattr) 014ab19a6 Paul Moore 2008-10-10 1914 { 389fb800a Paul Moore 2009-03-27 1915 int ret_val = -EPERM; 389fb800a Paul Moore 2009-03-27 1916 unsigned char *buf = NULL; 389fb800a Paul Moore 2009-03-27 1917 u32 buf_len; 389fb800a Paul Moore 2009-03-27 1918 u32 opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1919 struct ip_options_rcu *opt = NULL; 389fb800a Paul Moore 2009-03-27 1920 struct inet_request_sock *req_inet; 014ab19a6 Paul Moore 2008-10-10 1921 389fb800a Paul Moore 2009-03-27 1922 /* We allocate the maximum CIPSO option size here so we are probably 389fb800a Paul Moore 2009-03-27 1923 * being a little wasteful, but it makes our life _much_ easier later 389fb800a Paul Moore 2009-03-27 1924 * on and after all we are only talking about 40 bytes. */ 389fb800a Paul Moore 2009-03-27 1925 buf_len = CIPSO_V4_OPT_LEN_MAX; 389fb800a Paul Moore 2009-03-27 1926 buf = kmalloc(buf_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1927 if (!buf) { 389fb800a Paul Moore 2009-03-27 1928 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1929 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1930 } 389fb800a Paul Moore 2009-03-27 1931 389fb800a Paul Moore 2009-03-27 1932 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); 389fb800a Paul Moore 2009-03-27 1933 if (ret_val < 0) 389fb800a Paul Moore 2009-03-27 1934 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1935 buf_len = ret_val; 389fb800a Paul Moore 2009-03-27 1936 389fb800a Paul Moore 2009-03-27 1937 /* We can't use ip_options_get() directly because it makes a call to 389fb800a Paul Moore 2009-03-27 1938 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 389fb800a Paul Moore 2009-03-27 1939 * we won't always have CAP_NET_RAW even though we _always_ want to 389fb800a Paul Moore 2009-03-27 1940 * set the IPOPT_CIPSO option. */ 389fb800a Paul Moore 2009-03-27 1941 opt_len = (buf_len + 3) & ~3; 389fb800a Paul Moore 2009-03-27 1942 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 51456b291 Ian Morris 2015-04-03 1943 if (!opt) { 389fb800a Paul Moore 2009-03-27 1944 ret_val = -ENOMEM; 389fb800a Paul Moore 2009-03-27 1945 goto req_setattr_failure; 389fb800a Paul Moore 2009-03-27 1946 } f6d8bd051 Eric Dumazet 2011-04-21 1947 memcpy(opt->opt.__data, buf, buf_len); f6d8bd051 Eric Dumazet 2011-04-21 1948 opt->opt.optlen = opt_len; f6d8bd051 Eric Dumazet 2011-04-21 1949 opt->opt.cipso = sizeof(struct iphdr); 389fb800a Paul Moore 2009-03-27 1950 kfree(buf); 389fb800a Paul Moore 2009-03-27 1951 buf = NULL; 389fb800a Paul Moore 2009-03-27 1952 389fb800a Paul Moore 2009-03-27 1953 req_inet = inet_rsk(req); 389fb800a Paul Moore 2009-03-27 @1954 opt = xchg(&req_inet->opt, opt); f6d8bd051 Eric Dumazet 2011-04-21 1955 if (opt) 4f9c8c1b0 Paul E. McKenney 2012-01-06 1956 kfree_rcu(opt, rcu); 389fb800a Paul Moore 2009-03-27 1957 389fb800a Paul Moore 2009-03-27 1958 return 0; 389fb800a Paul Moore 2009-03-27 1959 389fb800a Paul Moore 2009-03-27 1960 req_setattr_failure: 389fb800a Paul Moore 2009-03-27 1961 kfree(buf); 389fb800a Paul Moore 2009-03-27 1962 kfree(opt); 389fb800a Paul Moore 2009-03-27 1963 return ret_val; 389fb800a Paul Moore 2009-03-27 1964 } 389fb800a Paul Moore 2009-03-27 1965 :::::: The code at line 1954 was first introduced by commit :::::: 389fb800ac8be2832efedd19978a2b8ced37eb61 netlabel: Label incoming TCP connections correctly in SELinux :::::: TO: Paul Moore <paul.moore@hp.com> :::::: CC: James Morris <jmorris@namei.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-17 19:45 [PATCH net] dccp/tcp: fix ireq->opt races Eric Dumazet 2017-10-17 19:50 ` Eric Dumazet @ 2017-10-19 12:31 ` David Miller 2017-10-19 14:45 ` Eric Dumazet 1 sibling, 1 reply; 12+ messages in thread From: David Miller @ 2017-10-19 12:31 UTC (permalink / raw) To: eric.dumazet; +Cc: netdev, edumazet From: Eric Dumazet <eric.dumazet@gmail.com> Date: Tue, 17 Oct 2017 12:45:26 -0700 > syzkaller found another bug in DCCP/TCP stacks [1] > > For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix > ireq->pktopts race"), we need to make sure we do not access > ireq->opt unless we own the request sock. This doesn't apply to 'net'. [davem@kkuri net]$ git am --signoff v2-net-dccp-tcp-fix-ireq--opt-races.patch Applying: dccp/tcp: fix ireq->opt races error: patch failed: include/net/inet_sock.h:96 error: include/net/inet_sock.h: patch does not apply error: patch failed: net/dccp/ipv4.c:414 error: net/dccp/ipv4.c: patch does not apply error: patch failed: net/ipv4/inet_connection_sock.c:540 error: net/ipv4/inet_connection_sock.c: patch does not apply error: patch failed: net/ipv4/syncookies.c:355 error: net/ipv4/syncookies.c: patch does not apply error: patch failed: net/ipv4/tcp_input.c:6196 error: net/ipv4/tcp_input.c: patch does not apply error: patch failed: net/ipv4/tcp_ipv4.c:877 error: net/ipv4/tcp_ipv4.c: patch does not apply ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-19 12:31 ` David Miller @ 2017-10-19 14:45 ` Eric Dumazet 2017-10-19 22:07 ` David Miller 0 siblings, 1 reply; 12+ messages in thread From: Eric Dumazet @ 2017-10-19 14:45 UTC (permalink / raw) To: David Miller; +Cc: Eric Dumazet, netdev On Thu, Oct 19, 2017 at 5:31 AM, David Miller <davem@davemloft.net> wrote: > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Tue, 17 Oct 2017 12:45:26 -0700 > >> syzkaller found another bug in DCCP/TCP stacks [1] >> >> For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix >> ireq->pktopts race"), we need to make sure we do not access >> ireq->opt unless we own the request sock. > > This doesn't apply to 'net'. > > [davem@kkuri net]$ git am --signoff v2-net-dccp-tcp-fix-ireq--opt-races.patch > Applying: dccp/tcp: fix ireq->opt races > error: patch failed: include/net/inet_sock.h:96 > error: include/net/inet_sock.h: patch does not apply > error: patch failed: net/dccp/ipv4.c:414 > error: net/dccp/ipv4.c: patch does not apply > error: patch failed: net/ipv4/inet_connection_sock.c:540 > error: net/ipv4/inet_connection_sock.c: patch does not apply > error: patch failed: net/ipv4/syncookies.c:355 > error: net/ipv4/syncookies.c: patch does not apply > error: patch failed: net/ipv4/tcp_input.c:6196 > error: net/ipv4/tcp_input.c: patch does not apply > error: patch failed: net/ipv4/tcp_ipv4.c:877 > error: net/ipv4/tcp_ipv4.c: patch does not apply Can you send me this v2-net-dccp-tcp-fix-ireq--opt-races.patch file ? Here the patch applies fine. Thanks ! ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-19 14:45 ` Eric Dumazet @ 2017-10-19 22:07 ` David Miller 2017-10-19 22:21 ` Eric Dumazet 0 siblings, 1 reply; 12+ messages in thread From: David Miller @ 2017-10-19 22:07 UTC (permalink / raw) To: edumazet; +Cc: eric.dumazet, netdev [-- Attachment #1: Type: Text/Plain, Size: 959 bytes --] From: Eric Dumazet <edumazet@google.com> Date: Thu, 19 Oct 2017 07:45:09 -0700 > Can you send me this v2-net-dccp-tcp-fix-ireq--opt-races.patch file ? > > Here the patch applies fine. Sure, attached. I even just tried it again, same result: [davem@kkuri net]$ git am --signoff v2-net-dccp-tcp-fix-ireq--opt-races.patch Applying: dccp/tcp: fix ireq->opt races error: patch failed: include/net/inet_sock.h:96 error: include/net/inet_sock.h: patch does not apply error: patch failed: net/dccp/ipv4.c:414 error: net/dccp/ipv4.c: patch does not apply error: patch failed: net/ipv4/inet_connection_sock.c:540 error: net/ipv4/inet_connection_sock.c: patch does not apply error: patch failed: net/ipv4/syncookies.c:355 error: net/ipv4/syncookies.c: patch does not apply error: patch failed: net/ipv4/tcp_input.c:6196 error: net/ipv4/tcp_input.c: patch does not apply error: patch failed: net/ipv4/tcp_ipv4.c:877 error: net/ipv4/tcp_ipv4.c: patch does not apply [-- Attachment #2: v2-net-dccp-tcp-fix-ireq--opt-races.patch --] [-- Type: Text/X-Patch, Size: 16549 bytes --] >From patchwork Tue Oct 17 19:55:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v2,net] dccp/tcp: fix ireq->opt races X-Patchwork-Submitter: Eric Dumazet <eric.dumazet@gmail.com> X-Patchwork-Id: 827264 X-Patchwork-Delegate: davem@davemloft.net Message-Id: <1508270101.31614.117.camel@edumazet-glaptop3.roam.corp.google.com> To: David Miller <davem@davemloft.net> Cc: netdev <netdev@vger.kernel.org>, edumazet@google.com Date: Tue, 17 Oct 2017 12:55:01 -0700 From: Eric Dumazet <eric.dumazet@gmail.com> List-Id: <netdev.vger.kernel.org> From: Eric Dumazet <edumazet@google.com> syzkaller found another bug in DCCP/TCP stacks [1] For the reasons explained in commit ce1050089c96 ("tcp/dccp: fix ireq->pktopts race"), we need to make sure we do not access ireq->opt unless we own the request sock. [1] BUG: KASAN: use-after-free in ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 Read of size 1 at addr ffff8801c951039c by task syz-executor5/3295 CPU: 1 PID: 3295 Comm: syz-executor5 Not tainted 4.14.0-rc4+ #80 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x194/0x257 lib/dump_stack.c:52 print_address_description+0x73/0x250 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x25b/0x340 mm/kasan/report.c:409 __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:427 ip_queue_xmit+0x1687/0x18e0 net/ipv4/ip_output.c:474 tcp_transmit_skb+0x1ab7/0x3840 net/ipv4/tcp_output.c:1135 tcp_send_ack.part.37+0x3bb/0x650 net/ipv4/tcp_output.c:3587 tcp_send_ack+0x49/0x60 net/ipv4/tcp_output.c:3557 __tcp_ack_snd_check+0x2c6/0x4b0 net/ipv4/tcp_input.c:5072 tcp_ack_snd_check net/ipv4/tcp_input.c:5085 [inline] tcp_rcv_state_process+0x2eff/0x4850 net/ipv4/tcp_input.c:6071 tcp_child_process+0x342/0x990 net/ipv4/tcp_minisocks.c:816 tcp_v4_rcv+0x1827/0x2f80 net/ipv4/tcp_ipv4.c:1682 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe RIP: 0033:0x40c341 RSP: 002b:00007f469523ec10 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000718000 RCX: 000000000040c341 RDX: 0000000000000037 RSI: 0000000020004000 RDI: 0000000000000015 RBP: 0000000000000086 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000000f4240 R11: 0000000000000293 R12: 00000000004b7fd1 R13: 00000000ffffffff R14: 0000000020000000 R15: 0000000000025000 Allocated by task 3295: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551 __do_kmalloc mm/slab.c:3725 [inline] __kmalloc+0x162/0x760 mm/slab.c:3734 kmalloc include/linux/slab.h:498 [inline] tcp_v4_save_options include/net/tcp.h:1962 [inline] tcp_v4_init_req+0x2d3/0x3e0 net/ipv4/tcp_ipv4.c:1271 tcp_conn_request+0xf6d/0x3410 net/ipv4/tcp_input.c:6283 tcp_v4_conn_request+0x157/0x210 net/ipv4/tcp_ipv4.c:1313 tcp_rcv_state_process+0x8ea/0x4850 net/ipv4/tcp_input.c:5857 tcp_v4_do_rcv+0x55c/0x7d0 net/ipv4/tcp_ipv4.c:1482 tcp_v4_rcv+0x2d10/0x2f80 net/ipv4/tcp_ipv4.c:1711 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe Freed by task 3306: save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524 __cache_free mm/slab.c:3503 [inline] kfree+0xca/0x250 mm/slab.c:3820 inet_sock_destruct+0x59d/0x950 net/ipv4/af_inet.c:157 __sk_destruct+0xfd/0x910 net/core/sock.c:1560 sk_destruct+0x47/0x80 net/core/sock.c:1595 __sk_free+0x57/0x230 net/core/sock.c:1603 sk_free+0x2a/0x40 net/core/sock.c:1614 sock_put include/net/sock.h:1652 [inline] inet_csk_complete_hashdance+0xd5/0xf0 net/ipv4/inet_connection_sock.c:959 tcp_check_req+0xf4d/0x1620 net/ipv4/tcp_minisocks.c:765 tcp_v4_rcv+0x17f6/0x2f80 net/ipv4/tcp_ipv4.c:1675 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216 NF_HOOK include/linux/netfilter.h:249 [inline] ip_local_deliver+0x1ce/0x6e0 net/ipv4/ip_input.c:257 dst_input include/net/dst.h:464 [inline] ip_rcv_finish+0x887/0x19a0 net/ipv4/ip_input.c:397 NF_HOOK include/linux/netfilter.h:249 [inline] ip_rcv+0xc3f/0x1820 net/ipv4/ip_input.c:493 __netif_receive_skb_core+0x1a3e/0x34b0 net/core/dev.c:4476 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4514 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4587 netif_receive_skb+0xae/0x390 net/core/dev.c:4611 tun_rx_batched.isra.50+0x5ed/0x860 drivers/net/tun.c:1372 tun_get_user+0x249c/0x36d0 drivers/net/tun.c:1766 tun_chr_write_iter+0xbf/0x160 drivers/net/tun.c:1792 call_write_iter include/linux/fs.h:1770 [inline] new_sync_write fs/read_write.c:468 [inline] __vfs_write+0x68a/0x970 fs/read_write.c:481 vfs_write+0x18f/0x510 fs/read_write.c:543 SYSC_write fs/read_write.c:588 [inline] SyS_write+0xef/0x220 fs/read_write.c:580 entry_SYSCALL_64_fastpath+0x1f/0xbe Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets") Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table") Signed-off-by: Eric Dumazet <edumazet@google.com> --- v2: removed some lines from KASAN report that confuse patchwork. include/net/inet_sock.h | 2 +- net/dccp/ipv4.c | 13 ++++++++----- net/ipv4/inet_connection_sock.c | 8 +++----- net/ipv4/syncookies.c | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_ipv4.c | 22 +++++++++++++--------- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index aa95053dfc78d35d04aef276e2a5dce7343f72a0..425752f768d2f1a0efb13964204e07f27609e9db 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -96,7 +96,7 @@ struct inet_request_sock { kmemcheck_bitfield_end(flags); u32 ir_mark; union { - struct ip_options_rcu *opt; + struct ip_options_rcu __rcu *ireq_opt; #if IS_ENABLED(CONFIG_IPV6) struct { struct ipv6_txoptions *ipv6_opt; diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 001c08696334bba0ceb896c116e595b814af0667..0490916864f93d5466e87f5b97dc524b3ee57a2e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -414,8 +414,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newinet->inet_saddr = ireq->ir_loc_addr; - newinet->inet_opt = ireq->opt; - ireq->opt = NULL; + RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->inet_id = jiffies; @@ -430,7 +429,10 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - + if (*own_req) + ireq->ireq_opt = NULL; + else + newinet->inet_opt = NULL; return newsk; exit_overflow: @@ -441,6 +443,7 @@ struct sock *dccp_v4_request_recv_sock(const struct sock *sk, __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); dccp_done(newsk); goto exit; @@ -492,7 +495,7 @@ static int dccp_v4_send_response(const struct sock *sk, struct request_sock *req ireq->ir_rmt_addr); err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -548,7 +551,7 @@ static void dccp_v4_ctl_send_reset(const struct sock *sk, struct sk_buff *rxskb) static void dccp_v4_reqsk_destructor(struct request_sock *req) { dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } void dccp_syn_ack_timeout(const struct request_sock *req) diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 67aec7a106860b26c929fea1624d652c87972f04..5ec9136a7c36933cb36e5cd50058eb6cf189a7c3 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -540,9 +540,10 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk, { const struct inet_request_sock *ireq = inet_rsk(req); struct net *net = read_pnet(&ireq->ireq_net); - struct ip_options_rcu *opt = ireq->opt; + struct ip_options_rcu *opt; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -576,10 +577,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, struct flowi4 *fl4; struct rtable *rt; + opt = rcu_dereference(ireq->ireq_opt); fl4 = &newinet->cork.fl.u.ip4; - rcu_read_lock(); - opt = rcu_dereference(newinet->inet_opt); flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -592,13 +592,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, goto no_route; if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) goto route_err; - rcu_read_unlock(); return &rt->dst; route_err: ip_rt_put(rt); no_route: - rcu_read_unlock(); __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b1bb1b3a108232d56aa82383422d68b5ff9da3ed..77cf32a80952fcf3ceff4ada946cc2d0df2411d9 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) */ - ireq->opt = tcp_v4_save_options(sock_net(sk), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb)); if (security_inet_conn_request(sk, skb, req)) { reqsk_free(req); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c5d7656beeee29b3c92e1c8824dbf00d3fa32d28..7eec3383702bbab497a12095b55d255532ad5f60 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6196,7 +6196,7 @@ struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, struct inet_request_sock *ireq = inet_rsk(req); kmemcheck_annotate_bitfield(ireq, flags); - ireq->opt = NULL; + ireq->ireq_opt = NULL; #if IS_ENABLED(CONFIG_IPV6) ireq->pktopts = NULL; #endif diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 85164d4d3e537537c87d74c00172592c860d4dfb..4c43365c374c8bf868fc0b862333244ca26d5016 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -877,7 +877,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, ireq->ir_rmt_addr, - ireq->opt); + rcu_dereference(ireq->ireq_opt)); err = net_xmit_eval(err); } @@ -889,7 +889,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, */ static void tcp_v4_reqsk_destructor(struct request_sock *req) { - kfree(inet_rsk(req)->opt); + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); } #ifdef CONFIG_TCP_MD5SIG @@ -1265,10 +1265,11 @@ static void tcp_v4_init_req(struct request_sock *req, struct sk_buff *skb) { struct inet_request_sock *ireq = inet_rsk(req); + struct net *net = sock_net(sk_listener); sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); } static struct dst_entry *tcp_v4_route_req(const struct sock *sk, @@ -1355,10 +1356,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, sk_daddr_set(newsk, ireq->ir_rmt_addr); sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); newsk->sk_bound_dev_if = ireq->ir_iif; - newinet->inet_saddr = ireq->ir_loc_addr; - inet_opt = ireq->opt; - rcu_assign_pointer(newinet->inet_opt, inet_opt); - ireq->opt = NULL; + newinet->inet_saddr = ireq->ir_loc_addr; + inet_opt = rcu_dereference(ireq->ireq_opt); + RCU_INIT_POINTER(newinet->inet_opt, inet_opt); newinet->mc_index = inet_iif(skb); newinet->mc_ttl = ip_hdr(skb)->ttl; newinet->rcv_tos = ip_hdr(skb)->tos; @@ -1403,9 +1403,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, if (__inet_inherit_port(sk, newsk) < 0) goto put_and_exit; *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); - if (*own_req) + if (likely(*own_req)) { tcp_move_syn(newtp, req); - + ireq->ireq_opt = NULL; + } else { + newinet->inet_opt = NULL; + } return newsk; exit_overflow: @@ -1416,6 +1419,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, tcp_listendrop(sk); return NULL; put_and_exit: + newinet->inet_opt = NULL; inet_csk_prepare_forced_close(newsk); tcp_done(newsk); goto exit; ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net] dccp/tcp: fix ireq->opt races 2017-10-19 22:07 ` David Miller @ 2017-10-19 22:21 ` Eric Dumazet 0 siblings, 0 replies; 12+ messages in thread From: Eric Dumazet @ 2017-10-19 22:21 UTC (permalink / raw) To: David Miller; +Cc: Eric Dumazet, netdev On Thu, Oct 19, 2017 at 3:07 PM, David Miller <davem@davemloft.net> wrote: > From: Eric Dumazet <edumazet@google.com> > Date: Thu, 19 Oct 2017 07:45:09 -0700 > >> Can you send me this v2-net-dccp-tcp-fix-ireq--opt-races.patch file ? >> >> Here the patch applies fine. > > Sure, attached. > > I even just tried it again, same result: > Thanks David. It is completely white space mangled (tabulations replaced by spaces.) I have no idea how it happened, but it definitely happened on my side. I will resend, sorry for this mess. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-10-20 18:34 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-10-17 19:45 [PATCH net] dccp/tcp: fix ireq->opt races Eric Dumazet 2017-10-17 19:50 ` Eric Dumazet 2017-10-17 19:53 ` Eric Dumazet 2017-10-17 19:55 ` [PATCH v2 " Eric Dumazet 2017-10-20 16:53 ` [PATCH " kbuild test robot 2017-10-20 17:38 ` Eric Dumazet 2017-10-20 16:53 ` kbuild test robot 2017-10-20 18:34 ` kbuild test robot 2017-10-19 12:31 ` David Miller 2017-10-19 14:45 ` Eric Dumazet 2017-10-19 22:07 ` David Miller 2017-10-19 22:21 ` Eric Dumazet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).