linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24  9:17 [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit Mao Wenan
@ 2019-07-24  9:15 ` maowenan
  2019-07-24  9:45 ` Eric Dumazet
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: maowenan @ 2019-07-24  9:15 UTC (permalink / raw)
  To: davem, gregkh, netdev, linux-kernel
  Cc: stable, Wangkefeng (Maro), weiyongjun (A)

Add stable@vger.kernel.org.

On 2019/7/24 17:17, Mao Wenan wrote:
> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> 
> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
> 
> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
> Call Trace:
>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
> 
> Allocated by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Freed by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Syzkaller reproducer():
> r0 = socket$packet(0x11, 0x3, 0x300)
> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
> r2 = fcntl$dupfd(r1, 0x0, r0)
> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
> 
> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
> 
> This is because when tcp_connect_init call tcp_write_queue_purge, it will
> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
> 
> Signed-off-by: Mao Wenan <maowenan@huawei.com>
> ---
>  include/net/tcp.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index bf8a0dae977a..8f8aace28cf8 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>  
>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>  		sk_wmem_free_skb(sk, skb);
> +	sk->sk_send_head = NULL;
>  	sk_mem_reclaim(sk);
>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>  	inet_csk(sk)->icsk_backoff = 0;
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
@ 2019-07-24  9:17 Mao Wenan
  2019-07-24  9:15 ` maowenan
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Mao Wenan @ 2019-07-24  9:17 UTC (permalink / raw)
  To: davem, gregkh, netdev, linux-kernel; +Cc: Mao Wenan

There is one report about tcp_write_xmit use-after-free with version 4.4.136:

BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195

CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
 0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
 ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
 dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
Call Trace:
 [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
 [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
 [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
 [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
 [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
 [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
 [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
 [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
 [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
 [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
 [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
 [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
 [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
 [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
 [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
 [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
 [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
 [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
 [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
 [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
 [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
 [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
 [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
 [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
 [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
 [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
 [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3

Allocated by task 4194:
 [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
 [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
 [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
 [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
 [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
 [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
 [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
 [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
 [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
 [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
 [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
 [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
 [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
 [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
 [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
 [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
 [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
 [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
 [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
 [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e

Freed by task 4194:
 [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
 [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
 [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
 [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
 [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
 [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
 [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
 [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
 [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
 [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
 [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
 [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
 [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
 [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
 [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
 [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
 [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
 [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
 [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
 [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e

Syzkaller reproducer():
r0 = socket$packet(0x11, 0x3, 0x300)
r1 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
r2 = fcntl$dupfd(r1, 0x0, r0)
connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)

C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000

This is because when tcp_connect_init call tcp_write_queue_purge, it will
kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.

Signed-off-by: Mao Wenan <maowenan@huawei.com>
---
 include/net/tcp.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index bf8a0dae977a..8f8aace28cf8 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
 
 	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
 		sk_wmem_free_skb(sk, skb);
+	sk->sk_send_head = NULL;
 	sk_mem_reclaim(sk);
 	tcp_clear_all_retrans_hints(tcp_sk(sk));
 	inet_csk(sk)->icsk_backoff = 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24  9:17 [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit Mao Wenan
  2019-07-24  9:15 ` maowenan
@ 2019-07-24  9:45 ` Eric Dumazet
  2019-07-24 10:46   ` maowenan
  2019-07-24 10:01 ` Eric Dumazet
  2019-07-24 11:05 ` Greg KH
  3 siblings, 1 reply; 21+ messages in thread
From: Eric Dumazet @ 2019-07-24  9:45 UTC (permalink / raw)
  To: Mao Wenan, davem, gregkh, netdev, linux-kernel



On 7/24/19 11:17 AM, Mao Wenan wrote:
> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> 
> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
> 
> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
> Call Trace:
>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
> 
> Allocated by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Freed by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Syzkaller reproducer():
> r0 = socket$packet(0x11, 0x3, 0x300)
> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
> r2 = fcntl$dupfd(r1, 0x0, r0)
> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
> 
> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
> 
> This is because when tcp_connect_init call tcp_write_queue_purge, it will
> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
> 
> Signed-off-by: Mao Wenan <maowenan@huawei.com>
> ---
>  include/net/tcp.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index bf8a0dae977a..8f8aace28cf8 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>  
>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>  		sk_wmem_free_skb(sk, skb);
> +	sk->sk_send_head = NULL;
>  	sk_mem_reclaim(sk);
>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>  	inet_csk(sk)->icsk_backoff = 0;
> 

This is strange, because tcp_init_send_head() is called from tcp_disconnect()
which is the syzkaller way to trigger this kind of bugs.


I suspect there is another root cause.



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24  9:17 [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit Mao Wenan
  2019-07-24  9:15 ` maowenan
  2019-07-24  9:45 ` Eric Dumazet
@ 2019-07-24 10:01 ` Eric Dumazet
  2019-07-24 10:13   ` Eric Dumazet
  2019-07-24 10:36   ` maowenan
  2019-07-24 11:05 ` Greg KH
  3 siblings, 2 replies; 21+ messages in thread
From: Eric Dumazet @ 2019-07-24 10:01 UTC (permalink / raw)
  To: Mao Wenan, davem, gregkh, netdev, linux-kernel



On 7/24/19 11:17 AM, Mao Wenan wrote:
> There is one report about tcp_write_xmit use-after-free with version 4.4.136:

Current stable 4.4 is 4.4.186

Can you check the bug is still there ?

List of patches between 4.4.136 and 4.4.186 (this list is not exhaustive)

46c7b5d6f2a51c355b29118814fbfbdb79c35656 tcp: refine memory limit test in tcp_fragment()
f938ae0ce5ef7b693125b918509b941281afc957 tcp: enforce tcp_min_snd_mss in tcp_mtu_probing()
e757d052f3b8ce739d068a1e890643376c16b7a9 tcp: add tcp_min_snd_mss sysctl
ad472d3a9483abc155e1644ad740cd8c039b5170 tcp: tcp_fragment() should apply sane memory limits
4657ee0fe05e15ab572b157f13a82e080d4b7d73 tcp: limit payload size of sacked skbs
b6d37bba0f7a7492427d7518d4be485dcdd9d5d1 tcp: tcp_grow_window() needs to respect tcp_space()
68337354043a3d5207cd4f055e5a8342ec4eec0f tcp: Ensure DCTCP reacts to losses
7ed7c0386ef2a5cbe58e15af5014c9302d3593eb tcp/dccp: drop SYN packets if accept queue is full
191aa19ab8c1459c11a5c541801f17e01dda17de tcp: handle inet_csk_reqsk_queue_add() failures
a466589807a13da2b7fbb2776e01634b38a4233b tcp: clear icsk_backoff in tcp_write_queue_purge()
122e4a30779336643614fe0f81e1f3fcbd0a371c tcp: tcp_v4_err() should be more careful
ed7748bcf290ad8f80020217d832f458ac9bae7f tcp: fix NULL ref in tail loss probe
eee1af4e268e10fecb76bce42a8d7343aeb2a5e6 tcp: add tcp_ooo_try_coalesce() helper
be288481479ca8c1beba02a7e779ffeaa11f1597 tcp: call tcp_drop() from tcp_data_queue_ofo()
352b66932a23fb11f0a7c316361220648bca3c79 tcp: free batches of packets in tcp_prune_ofo_queue()
e747775172a2d4dc4dae794f248f9687ba793f54 tcp: fix a stale ooo_last_skb after a replace
4666b6e2b27d91e05a5b8459e40e4a05dbc1c7b0 tcp: use an RB tree for ooo receive queue
ec7055c62714326c56dabcf7757069ac7f276bda tcp: increment sk_drops for dropped rx packets
86a0a00794c21b35c72d767a98fb917b5b76b513 tcp: do not restart timewait timer on rst reception
81970da69122fe4bf2af5bb1bb4c7f62d4744e79 tcp: identify cryptic messages as TCP seq # bugs
43707aa8c55fb165a1a56f590e0defb198ebdde9 tcp: remove DELAYED ACK events in DCTCP
42962538cd9fe281a6e8602f22c7b1e218ed812a tcp: Fix missing range_truesize enlargement in the backport
27a0762cb570834dc44155363c118cabdd024c3c tcp: add one more quick ack after after ECN events
cd760ab9f4e13aedccc80f19a0b7863d5c0b3c8c tcp: refactor tcp_ecn_check_ce to remove sk type cast
96b792d199d17545d6a53faf44b9c91d038f1ab3 tcp: do not aggressively quick ack after ECN events
2b30c04bc6f9e7be2d9a5e1b504faa904154c7da tcp: add max_quickacks param to tcp_incr_quickack and tcp_enter_quickack_mode
e2f337e2bd4efe32051a496a7fcdd94ea67c0cfa tcp: do not force quickack when receiving out-of-order packets
dc6ae4dffd656811dee7151b19545e4cd839d378 tcp: detect malicious patterns in tcp_collapse_ofo_queue()
5fbec4801264cb3279ef6ac9c70bcbe2aaef89d5 tcp: avoid collapses in tcp_prune_queue() if possible
255924ea891f647451af3acbc40a3730dcb3255e tcp: do not delay ACK in DCTCP upon CE status change
0b1d40e9e7738e3396ce414b1c62b911c285dfa3 tcp: do not cancel delay-AcK on DCTCP special ACK
17fea38e74ab24afb06970bbd9dc52db11a8034b tcp: helpers to send special DCTCP ack
500e03f463835e74c75890d56d9a7ab63755aa2d tcp: fix dctcp delayed ACK schedule
61c66cc52d42f78bbdd8f2e40b7c0bb9b936a12d tcp: prevent bogus FRTO undos with non-SACK flows
48ffbdea28808354b89447fac2d8524c29ce7ab4 tcp: verify the checksum of the first data segment in a new connection
4dff97920e13af3e92180eefa6b7712d4eac5e58 tcp: do not overshoot window_clamp in tcp_rcv_space_adjust()


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:01 ` Eric Dumazet
@ 2019-07-24 10:13   ` Eric Dumazet
  2019-07-24 10:38     ` maowenan
  2019-07-25  2:06     ` maowenan
  2019-07-24 10:36   ` maowenan
  1 sibling, 2 replies; 21+ messages in thread
From: Eric Dumazet @ 2019-07-24 10:13 UTC (permalink / raw)
  To: Mao Wenan, davem, gregkh, netdev, linux-kernel



On 7/24/19 12:01 PM, Eric Dumazet wrote:
> 
> 
> On 7/24/19 11:17 AM, Mao Wenan wrote:
>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> 
> Current stable 4.4 is 4.4.186
> 
> Can you check the bug is still there ?
> 

BTW, I tried the C repro and another bug showed up.

It looks like 4.4.186 misses other fixes :/

[  180.811610] skbuff: skb_under_panic: text:ffffffff825ec6ea len:156 put:84 head:ffff8837dd1f0990 data:ffff8837dd1f098c tail:0x98 end:0xc0 dev:ip6gre0
[  180.825037] ------------[ cut here ]------------
[  180.829688] kernel BUG at net/core/skbuff.c:104!
[  180.834316] invalid opcode: 0000 [#1] SMP KASAN
[  180.839305] gsmi: Log Shutdown Reason 0x03
[  180.843426] Modules linked in: ipip bonding bridge stp llc tun veth w1_therm wire i2c_mux_pca954x i2c_mux cdc_acm ehci_pci ehci_hcd ip_gre mlx4_en ib_uverbs mlx4_ib ib_sa ib_mad ib_core ib_addr mlx4_core
[  180.862052] CPU: 22 PID: 1619 Comm: kworker/22:1 Not tainted 4.4.186-smp-DEV #41
[  180.869475] Hardware name: Intel BIOS 2.56.0 10/19/2018
[  180.876463] Workqueue: ipv6_addrconf addrconf_dad_work
[  180.881658] task: ffff8837f1f59d80 ti: ffff8837eeeb8000 task.ti: ffff8837eeeb8000
[  180.889171] RIP: 0010:[<ffffffff821ef26f>]  [<ffffffff821ef26f>] skb_panic+0x14f/0x210
[  180.897162] RSP: 0018:ffff8837eeebf4b8  EFLAGS: 00010282
[  180.902504] RAX: 0000000000000088 RBX: ffff8837eeeeb600 RCX: 0000000000000000
[  180.909645] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff83508c00
[  180.916854] RBP: ffff8837eeebf520 R08: 0000000000000016 R09: 0000000000000000
[  180.924029] R10: ffff881fc8abf038 R11: 0000000000000007 R12: ffff881fc8abe720
[  180.931213] R13: ffffffff82aa9e80 R14: 00000000000000c0 R15: 0000000000000098
[  180.938390] FS:  0000000000000000(0000) GS:ffff8837ff280000(0000) knlGS:0000000000000000
[  180.946519] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  180.952290] CR2: 00007f519426f530 CR3: 00000037d37f2000 CR4: 0000000000160670
[  180.959447] Stack:
[  180.961458]  ffff8837dd1f098c 0000000000000098 00000000000000c0 ffff881fc8abe720
[  180.968909]  ffffea00df747c00 ffff881fff404b40 ffff8837ff2a1a20 ffff8837eeebf5b8
[  180.976371]  ffff8837eeeeb600 ffffffff825ec6ea 1ffff106fddd7eb6 ffff8837eeeeb600
[  180.983848] Call Trace:
[  180.986297]  [<ffffffff825ec6ea>] ? ip6gre_header+0xba/0xd50
[  180.991962]  [<ffffffff821f0e01>] skb_push+0xc1/0x100
[  180.997023]  [<ffffffff825ec6ea>] ip6gre_header+0xba/0xd50
[  181.002519]  [<ffffffff8158dc16>] ? memcpy+0x36/0x40
[  181.007509]  [<ffffffff825ec630>] ? ip6gre_changelink+0x6d0/0x6d0
[  181.013629]  [<ffffffff82550741>] ? ndisc_constructor+0x5b1/0x770
[  181.019728]  [<ffffffff82666861>] ? _raw_write_unlock_bh+0x41/0x50
[  181.025924]  [<ffffffff8226540b>] ? __neigh_create+0xe6b/0x1670
[  181.031851]  [<ffffffff8225817f>] neigh_connected_output+0x23f/0x480
[  181.038219]  [<ffffffff824f61ec>] ip6_finish_output2+0x74c/0x1a90
[  181.044324]  [<ffffffff810f1d33>] ? print_context_stack+0x73/0xf0
[  181.050429]  [<ffffffff824f5aa0>] ? ip6_xmit+0x1700/0x1700
[  181.055933]  [<ffffffff82304a28>] ? nf_hook_slow+0x118/0x1b0
[  181.061617]  [<ffffffff82502d7a>] ip6_finish_output+0x2ba/0x580
[  181.067546]  [<ffffffff82503179>] ip6_output+0x139/0x380
[  181.072884]  [<ffffffff82503040>] ? ip6_finish_output+0x580/0x580
[  181.079004]  [<ffffffff82502ac0>] ? ip6_fragment+0x31b0/0x31b0
[  181.084852]  [<ffffffff82251b51>] ? dst_init+0x4b1/0x820
[  181.090172]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
[  181.096437]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
[  181.102712]  [<ffffffff8254f3ca>] NF_HOOK_THRESH.constprop.22+0xca/0x180
[  181.109421]  [<ffffffff8254f300>] ? ndisc_alloc_skb+0x340/0x340
[  181.115338]  [<ffffffff8254d820>] ? compat_ipv6_setsockopt+0x180/0x180
[  181.121874]  [<ffffffff8254fbc2>] ndisc_send_skb+0x742/0xd10
[  181.127550]  [<ffffffff8254f480>] ? NF_HOOK_THRESH.constprop.22+0x180/0x180
[  181.134516]  [<ffffffff821f2440>] ? skb_complete_tx_timestamp+0x280/0x280
[  181.141311]  [<ffffffff8254e2b3>] ? ndisc_fill_addr_option+0x193/0x260
[  181.147844]  [<ffffffff82553bd9>] ndisc_send_rs+0x179/0x2d0
[  181.153426]  [<ffffffff8251e7df>] addrconf_dad_completed+0x41f/0x7c0
[  181.159795]  [<ffffffff81297f78>] ? pick_next_entity+0x198/0x470
[  181.165807]  [<ffffffff8251e3c0>] ? addrconf_rs_timer+0x4a0/0x4a0
[  181.171918]  [<ffffffff81aab928>] ? find_next_bit+0x18/0x20
[  181.177504]  [<ffffffff81a99ec9>] ? prandom_seed+0xd9/0x160
[  181.183095]  [<ffffffff8251eef5>] addrconf_dad_work+0x375/0x9e0
[  181.189024]  [<ffffffff8251eb80>] ? addrconf_dad_completed+0x7c0/0x7c0
[  181.195576]  [<ffffffff81249d8f>] process_one_work+0x52f/0xf60
[  181.201468]  [<ffffffff8124a89d>] worker_thread+0xdd/0xe80
[  181.206977]  [<ffffffff8265cf0a>] ? __schedule+0x73a/0x16d0
[  181.212550]  [<ffffffff8124a7c0>] ? process_one_work+0xf60/0xf60
[  181.218572]  [<ffffffff8125a115>] kthread+0x205/0x2b0
[  181.223633]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
[  181.229743]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
[  181.235834]  [<ffffffff8266726f>] ret_from_fork+0x3f/0x70
[  181.241232]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:01 ` Eric Dumazet
  2019-07-24 10:13   ` Eric Dumazet
@ 2019-07-24 10:36   ` maowenan
  2019-07-24 10:44     ` Eric Dumazet
  1 sibling, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-24 10:36 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel

Actually, I have tested 4.4.184, UAF still happen.

On 2019/7/24 18:01, Eric Dumazet wrote:
> 
> 
> On 7/24/19 11:17 AM, Mao Wenan wrote:
>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> 
> Current stable 4.4 is 4.4.186
> 
> Can you check the bug is still there ?
> 
> List of patches between 4.4.136 and 4.4.186 (this list is not exhaustive)
> 
> 46c7b5d6f2a51c355b29118814fbfbdb79c35656 tcp: refine memory limit test in tcp_fragment()
> f938ae0ce5ef7b693125b918509b941281afc957 tcp: enforce tcp_min_snd_mss in tcp_mtu_probing()
> e757d052f3b8ce739d068a1e890643376c16b7a9 tcp: add tcp_min_snd_mss sysctl
> ad472d3a9483abc155e1644ad740cd8c039b5170 tcp: tcp_fragment() should apply sane memory limits
> 4657ee0fe05e15ab572b157f13a82e080d4b7d73 tcp: limit payload size of sacked skbs
> b6d37bba0f7a7492427d7518d4be485dcdd9d5d1 tcp: tcp_grow_window() needs to respect tcp_space()
> 68337354043a3d5207cd4f055e5a8342ec4eec0f tcp: Ensure DCTCP reacts to losses
> 7ed7c0386ef2a5cbe58e15af5014c9302d3593eb tcp/dccp: drop SYN packets if accept queue is full
> 191aa19ab8c1459c11a5c541801f17e01dda17de tcp: handle inet_csk_reqsk_queue_add() failures
> a466589807a13da2b7fbb2776e01634b38a4233b tcp: clear icsk_backoff in tcp_write_queue_purge()
> 122e4a30779336643614fe0f81e1f3fcbd0a371c tcp: tcp_v4_err() should be more careful
> ed7748bcf290ad8f80020217d832f458ac9bae7f tcp: fix NULL ref in tail loss probe
> eee1af4e268e10fecb76bce42a8d7343aeb2a5e6 tcp: add tcp_ooo_try_coalesce() helper
> be288481479ca8c1beba02a7e779ffeaa11f1597 tcp: call tcp_drop() from tcp_data_queue_ofo()
> 352b66932a23fb11f0a7c316361220648bca3c79 tcp: free batches of packets in tcp_prune_ofo_queue()
> e747775172a2d4dc4dae794f248f9687ba793f54 tcp: fix a stale ooo_last_skb after a replace
> 4666b6e2b27d91e05a5b8459e40e4a05dbc1c7b0 tcp: use an RB tree for ooo receive queue
> ec7055c62714326c56dabcf7757069ac7f276bda tcp: increment sk_drops for dropped rx packets
> 86a0a00794c21b35c72d767a98fb917b5b76b513 tcp: do not restart timewait timer on rst reception
> 81970da69122fe4bf2af5bb1bb4c7f62d4744e79 tcp: identify cryptic messages as TCP seq # bugs
> 43707aa8c55fb165a1a56f590e0defb198ebdde9 tcp: remove DELAYED ACK events in DCTCP
> 42962538cd9fe281a6e8602f22c7b1e218ed812a tcp: Fix missing range_truesize enlargement in the backport
> 27a0762cb570834dc44155363c118cabdd024c3c tcp: add one more quick ack after after ECN events
> cd760ab9f4e13aedccc80f19a0b7863d5c0b3c8c tcp: refactor tcp_ecn_check_ce to remove sk type cast
> 96b792d199d17545d6a53faf44b9c91d038f1ab3 tcp: do not aggressively quick ack after ECN events
> 2b30c04bc6f9e7be2d9a5e1b504faa904154c7da tcp: add max_quickacks param to tcp_incr_quickack and tcp_enter_quickack_mode
> e2f337e2bd4efe32051a496a7fcdd94ea67c0cfa tcp: do not force quickack when receiving out-of-order packets
> dc6ae4dffd656811dee7151b19545e4cd839d378 tcp: detect malicious patterns in tcp_collapse_ofo_queue()
> 5fbec4801264cb3279ef6ac9c70bcbe2aaef89d5 tcp: avoid collapses in tcp_prune_queue() if possible
> 255924ea891f647451af3acbc40a3730dcb3255e tcp: do not delay ACK in DCTCP upon CE status change
> 0b1d40e9e7738e3396ce414b1c62b911c285dfa3 tcp: do not cancel delay-AcK on DCTCP special ACK
> 17fea38e74ab24afb06970bbd9dc52db11a8034b tcp: helpers to send special DCTCP ack
> 500e03f463835e74c75890d56d9a7ab63755aa2d tcp: fix dctcp delayed ACK schedule
> 61c66cc52d42f78bbdd8f2e40b7c0bb9b936a12d tcp: prevent bogus FRTO undos with non-SACK flows
> 48ffbdea28808354b89447fac2d8524c29ce7ab4 tcp: verify the checksum of the first data segment in a new connection
> 4dff97920e13af3e92180eefa6b7712d4eac5e58 tcp: do not overshoot window_clamp in tcp_rcv_space_adjust()
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:13   ` Eric Dumazet
@ 2019-07-24 10:38     ` maowenan
  2019-07-24 12:29       ` maowenan
  2019-07-25  2:06     ` maowenan
  1 sibling, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-24 10:38 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/24 18:13, Eric Dumazet wrote:
> 
> 
> On 7/24/19 12:01 PM, Eric Dumazet wrote:
>>
>>
>> On 7/24/19 11:17 AM, Mao Wenan wrote:
>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>
>> Current stable 4.4 is 4.4.186
>>
>> Can you check the bug is still there ?
>>
> 
> BTW, I tried the C repro and another bug showed up.
> 
> It looks like 4.4.186 misses other fixes :/

I will try 4.4.186.

> 
> [  180.811610] skbuff: skb_under_panic: text:ffffffff825ec6ea len:156 put:84 head:ffff8837dd1f0990 data:ffff8837dd1f098c tail:0x98 end:0xc0 dev:ip6gre0
> [  180.825037] ------------[ cut here ]------------
> [  180.829688] kernel BUG at net/core/skbuff.c:104!
> [  180.834316] invalid opcode: 0000 [#1] SMP KASAN
> [  180.839305] gsmi: Log Shutdown Reason 0x03
> [  180.843426] Modules linked in: ipip bonding bridge stp llc tun veth w1_therm wire i2c_mux_pca954x i2c_mux cdc_acm ehci_pci ehci_hcd ip_gre mlx4_en ib_uverbs mlx4_ib ib_sa ib_mad ib_core ib_addr mlx4_core
> [  180.862052] CPU: 22 PID: 1619 Comm: kworker/22:1 Not tainted 4.4.186-smp-DEV #41
> [  180.869475] Hardware name: Intel BIOS 2.56.0 10/19/2018
> [  180.876463] Workqueue: ipv6_addrconf addrconf_dad_work
> [  180.881658] task: ffff8837f1f59d80 ti: ffff8837eeeb8000 task.ti: ffff8837eeeb8000
> [  180.889171] RIP: 0010:[<ffffffff821ef26f>]  [<ffffffff821ef26f>] skb_panic+0x14f/0x210
> [  180.897162] RSP: 0018:ffff8837eeebf4b8  EFLAGS: 00010282
> [  180.902504] RAX: 0000000000000088 RBX: ffff8837eeeeb600 RCX: 0000000000000000
> [  180.909645] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff83508c00
> [  180.916854] RBP: ffff8837eeebf520 R08: 0000000000000016 R09: 0000000000000000
> [  180.924029] R10: ffff881fc8abf038 R11: 0000000000000007 R12: ffff881fc8abe720
> [  180.931213] R13: ffffffff82aa9e80 R14: 00000000000000c0 R15: 0000000000000098
> [  180.938390] FS:  0000000000000000(0000) GS:ffff8837ff280000(0000) knlGS:0000000000000000
> [  180.946519] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  180.952290] CR2: 00007f519426f530 CR3: 00000037d37f2000 CR4: 0000000000160670
> [  180.959447] Stack:
> [  180.961458]  ffff8837dd1f098c 0000000000000098 00000000000000c0 ffff881fc8abe720
> [  180.968909]  ffffea00df747c00 ffff881fff404b40 ffff8837ff2a1a20 ffff8837eeebf5b8
> [  180.976371]  ffff8837eeeeb600 ffffffff825ec6ea 1ffff106fddd7eb6 ffff8837eeeeb600
> [  180.983848] Call Trace:
> [  180.986297]  [<ffffffff825ec6ea>] ? ip6gre_header+0xba/0xd50
> [  180.991962]  [<ffffffff821f0e01>] skb_push+0xc1/0x100
> [  180.997023]  [<ffffffff825ec6ea>] ip6gre_header+0xba/0xd50
> [  181.002519]  [<ffffffff8158dc16>] ? memcpy+0x36/0x40
> [  181.007509]  [<ffffffff825ec630>] ? ip6gre_changelink+0x6d0/0x6d0
> [  181.013629]  [<ffffffff82550741>] ? ndisc_constructor+0x5b1/0x770
> [  181.019728]  [<ffffffff82666861>] ? _raw_write_unlock_bh+0x41/0x50
> [  181.025924]  [<ffffffff8226540b>] ? __neigh_create+0xe6b/0x1670
> [  181.031851]  [<ffffffff8225817f>] neigh_connected_output+0x23f/0x480
> [  181.038219]  [<ffffffff824f61ec>] ip6_finish_output2+0x74c/0x1a90
> [  181.044324]  [<ffffffff810f1d33>] ? print_context_stack+0x73/0xf0
> [  181.050429]  [<ffffffff824f5aa0>] ? ip6_xmit+0x1700/0x1700
> [  181.055933]  [<ffffffff82304a28>] ? nf_hook_slow+0x118/0x1b0
> [  181.061617]  [<ffffffff82502d7a>] ip6_finish_output+0x2ba/0x580
> [  181.067546]  [<ffffffff82503179>] ip6_output+0x139/0x380
> [  181.072884]  [<ffffffff82503040>] ? ip6_finish_output+0x580/0x580
> [  181.079004]  [<ffffffff82502ac0>] ? ip6_fragment+0x31b0/0x31b0
> [  181.084852]  [<ffffffff82251b51>] ? dst_init+0x4b1/0x820
> [  181.090172]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
> [  181.096437]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
> [  181.102712]  [<ffffffff8254f3ca>] NF_HOOK_THRESH.constprop.22+0xca/0x180
> [  181.109421]  [<ffffffff8254f300>] ? ndisc_alloc_skb+0x340/0x340
> [  181.115338]  [<ffffffff8254d820>] ? compat_ipv6_setsockopt+0x180/0x180
> [  181.121874]  [<ffffffff8254fbc2>] ndisc_send_skb+0x742/0xd10
> [  181.127550]  [<ffffffff8254f480>] ? NF_HOOK_THRESH.constprop.22+0x180/0x180
> [  181.134516]  [<ffffffff821f2440>] ? skb_complete_tx_timestamp+0x280/0x280
> [  181.141311]  [<ffffffff8254e2b3>] ? ndisc_fill_addr_option+0x193/0x260
> [  181.147844]  [<ffffffff82553bd9>] ndisc_send_rs+0x179/0x2d0
> [  181.153426]  [<ffffffff8251e7df>] addrconf_dad_completed+0x41f/0x7c0
> [  181.159795]  [<ffffffff81297f78>] ? pick_next_entity+0x198/0x470
> [  181.165807]  [<ffffffff8251e3c0>] ? addrconf_rs_timer+0x4a0/0x4a0
> [  181.171918]  [<ffffffff81aab928>] ? find_next_bit+0x18/0x20
> [  181.177504]  [<ffffffff81a99ec9>] ? prandom_seed+0xd9/0x160
> [  181.183095]  [<ffffffff8251eef5>] addrconf_dad_work+0x375/0x9e0
> [  181.189024]  [<ffffffff8251eb80>] ? addrconf_dad_completed+0x7c0/0x7c0
> [  181.195576]  [<ffffffff81249d8f>] process_one_work+0x52f/0xf60
> [  181.201468]  [<ffffffff8124a89d>] worker_thread+0xdd/0xe80
> [  181.206977]  [<ffffffff8265cf0a>] ? __schedule+0x73a/0x16d0
> [  181.212550]  [<ffffffff8124a7c0>] ? process_one_work+0xf60/0xf60
> [  181.218572]  [<ffffffff8125a115>] kthread+0x205/0x2b0
> [  181.223633]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> [  181.229743]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> [  181.235834]  [<ffffffff8266726f>] ret_from_fork+0x3f/0x70
> [  181.241232]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:36   ` maowenan
@ 2019-07-24 10:44     ` Eric Dumazet
  0 siblings, 0 replies; 21+ messages in thread
From: Eric Dumazet @ 2019-07-24 10:44 UTC (permalink / raw)
  To: maowenan, Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 7/24/19 12:36 PM, maowenan wrote:
> Actually, I have tested 4.4.184, UAF still happen.
> 
>

Thanks for testing.

Acked-by: Eric Dumazet <edumazet@google.com>



^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24  9:45 ` Eric Dumazet
@ 2019-07-24 10:46   ` maowenan
  2019-07-24 14:07     ` Eric Dumazet
  0 siblings, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-24 10:46 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/24 17:45, Eric Dumazet wrote:
> 
> 
> On 7/24/19 11:17 AM, Mao Wenan wrote:
>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>
>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>
>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>> Call Trace:
>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>
>> Allocated by task 4194:
>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>
>> Freed by task 4194:
>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>
>> Syzkaller reproducer():
>> r0 = socket$packet(0x11, 0x3, 0x300)
>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>> r2 = fcntl$dupfd(r1, 0x0, r0)
>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>
>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>
>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>
>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>> ---
>>  include/net/tcp.h | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index bf8a0dae977a..8f8aace28cf8 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>  
>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>  		sk_wmem_free_skb(sk, skb);
>> +	sk->sk_send_head = NULL;
>>  	sk_mem_reclaim(sk);
>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>  	inet_csk(sk)->icsk_backoff = 0;
>>
> 
> This is strange, because tcp_init_send_head() is called from tcp_disconnect()
> which is the syzkaller way to trigger this kind of bugs.
> 

syzkaller reproduce program duplicate one socket that have multiple skb in write queue,
and new socket have purged skb but original socket still try to send skb. In this program,
it does not call tcp_disconnect?

> 
> I suspect there is another root cause.
> 
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24  9:17 [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit Mao Wenan
                   ` (2 preceding siblings ...)
  2019-07-24 10:01 ` Eric Dumazet
@ 2019-07-24 11:05 ` Greg KH
  2019-07-24 12:13   ` maowenan
  3 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2019-07-24 11:05 UTC (permalink / raw)
  To: Mao Wenan; +Cc: stable, davem, netdev, linux-kernel

On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> 
> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
> 
> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
> Call Trace:
>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
> 
> Allocated by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Freed by task 4194:
>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> 
> Syzkaller reproducer():
> r0 = socket$packet(0x11, 0x3, 0x300)
> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
> r2 = fcntl$dupfd(r1, 0x0, r0)
> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
> 
> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
> 
> This is because when tcp_connect_init call tcp_write_queue_purge, it will
> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
> 
> Signed-off-by: Mao Wenan <maowenan@huawei.com>
> ---
>  include/net/tcp.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index bf8a0dae977a..8f8aace28cf8 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>  
>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>  		sk_wmem_free_skb(sk, skb);
> +	sk->sk_send_head = NULL;
>  	sk_mem_reclaim(sk);
>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>  	inet_csk(sk)->icsk_backoff = 0;

Does this corrispond with a specific commit that is already in Linus's
tree?  If not, why, did we change/mess something up when doing
backports, or is the code just that different?

Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
4.4.y?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 11:05 ` Greg KH
@ 2019-07-24 12:13   ` maowenan
  2019-07-27 10:44     ` maowenan
  0 siblings, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-24 12:13 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, davem, netdev, linux-kernel



On 2019/7/24 19:05, Greg KH wrote:
> On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>
>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>
>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>> Call Trace:
>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>
>> Allocated by task 4194:
>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>
>> Freed by task 4194:
>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>
>> Syzkaller reproducer():
>> r0 = socket$packet(0x11, 0x3, 0x300)
>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>> r2 = fcntl$dupfd(r1, 0x0, r0)
>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>
>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>
>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>
>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>> ---
>>  include/net/tcp.h | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>> index bf8a0dae977a..8f8aace28cf8 100644
>> --- a/include/net/tcp.h
>> +++ b/include/net/tcp.h
>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>  
>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>  		sk_wmem_free_skb(sk, skb);
>> +	sk->sk_send_head = NULL;
>>  	sk_mem_reclaim(sk);
>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>  	inet_csk(sk)->icsk_backoff = 0;
> 
> Does this corrispond with a specific commit that is already in Linus's
> tree?  If not, why, did we change/mess something up when doing
> backports, or is the code just that different?
> 
> Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
> 4.4.y?

Is it the commit 75c119afe14f? It does not use sk_send_head to indicate whether it has skb to be sent.

commit 75c119afe14f74b4dd967d75ed9f57ab6c0ef045
Author: Eric Dumazet <edumazet@google.com>
Date:   Thu Oct 5 22:21:27 2017 -0700

    tcp: implement rb-tree based retransmit queue


 static inline struct sk_buff *tcp_send_head(const struct sock *sk)
 {
-       return sk->sk_send_head;
+       return skb_peek(&sk->sk_write_queue);
 }



> 
> thanks,
> 
> greg k-h
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:38     ` maowenan
@ 2019-07-24 12:29       ` maowenan
  0 siblings, 0 replies; 21+ messages in thread
From: maowenan @ 2019-07-24 12:29 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/24 18:38, maowenan wrote:
> 
> 
> On 2019/7/24 18:13, Eric Dumazet wrote:
>>
>>
>> On 7/24/19 12:01 PM, Eric Dumazet wrote:
>>>
>>>
>>> On 7/24/19 11:17 AM, Mao Wenan wrote:
>>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>
>>> Current stable 4.4 is 4.4.186
>>>
>>> Can you check the bug is still there ?
>>>
>>
>> BTW, I tried the C repro and another bug showed up.
>>
>> It looks like 4.4.186 misses other fixes :/
> 
> I will try 4.4.186.

Hi Eric, bug exist in latest commit for 4.4 stable.
a3e421f Linux 4.4.186

> 
>>
>> [  180.811610] skbuff: skb_under_panic: text:ffffffff825ec6ea len:156 put:84 head:ffff8837dd1f0990 data:ffff8837dd1f098c tail:0x98 end:0xc0 dev:ip6gre0
>> [  180.825037] ------------[ cut here ]------------
>> [  180.829688] kernel BUG at net/core/skbuff.c:104!
>> [  180.834316] invalid opcode: 0000 [#1] SMP KASAN
>> [  180.839305] gsmi: Log Shutdown Reason 0x03
>> [  180.843426] Modules linked in: ipip bonding bridge stp llc tun veth w1_therm wire i2c_mux_pca954x i2c_mux cdc_acm ehci_pci ehci_hcd ip_gre mlx4_en ib_uverbs mlx4_ib ib_sa ib_mad ib_core ib_addr mlx4_core
>> [  180.862052] CPU: 22 PID: 1619 Comm: kworker/22:1 Not tainted 4.4.186-smp-DEV #41
>> [  180.869475] Hardware name: Intel BIOS 2.56.0 10/19/2018
>> [  180.876463] Workqueue: ipv6_addrconf addrconf_dad_work
>> [  180.881658] task: ffff8837f1f59d80 ti: ffff8837eeeb8000 task.ti: ffff8837eeeb8000
>> [  180.889171] RIP: 0010:[<ffffffff821ef26f>]  [<ffffffff821ef26f>] skb_panic+0x14f/0x210
>> [  180.897162] RSP: 0018:ffff8837eeebf4b8  EFLAGS: 00010282
>> [  180.902504] RAX: 0000000000000088 RBX: ffff8837eeeeb600 RCX: 0000000000000000
>> [  180.909645] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff83508c00
>> [  180.916854] RBP: ffff8837eeebf520 R08: 0000000000000016 R09: 0000000000000000
>> [  180.924029] R10: ffff881fc8abf038 R11: 0000000000000007 R12: ffff881fc8abe720
>> [  180.931213] R13: ffffffff82aa9e80 R14: 00000000000000c0 R15: 0000000000000098
>> [  180.938390] FS:  0000000000000000(0000) GS:ffff8837ff280000(0000) knlGS:0000000000000000
>> [  180.946519] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> [  180.952290] CR2: 00007f519426f530 CR3: 00000037d37f2000 CR4: 0000000000160670
>> [  180.959447] Stack:
>> [  180.961458]  ffff8837dd1f098c 0000000000000098 00000000000000c0 ffff881fc8abe720
>> [  180.968909]  ffffea00df747c00 ffff881fff404b40 ffff8837ff2a1a20 ffff8837eeebf5b8
>> [  180.976371]  ffff8837eeeeb600 ffffffff825ec6ea 1ffff106fddd7eb6 ffff8837eeeeb600
>> [  180.983848] Call Trace:
>> [  180.986297]  [<ffffffff825ec6ea>] ? ip6gre_header+0xba/0xd50
>> [  180.991962]  [<ffffffff821f0e01>] skb_push+0xc1/0x100
>> [  180.997023]  [<ffffffff825ec6ea>] ip6gre_header+0xba/0xd50
>> [  181.002519]  [<ffffffff8158dc16>] ? memcpy+0x36/0x40
>> [  181.007509]  [<ffffffff825ec630>] ? ip6gre_changelink+0x6d0/0x6d0
>> [  181.013629]  [<ffffffff82550741>] ? ndisc_constructor+0x5b1/0x770
>> [  181.019728]  [<ffffffff82666861>] ? _raw_write_unlock_bh+0x41/0x50
>> [  181.025924]  [<ffffffff8226540b>] ? __neigh_create+0xe6b/0x1670
>> [  181.031851]  [<ffffffff8225817f>] neigh_connected_output+0x23f/0x480
>> [  181.038219]  [<ffffffff824f61ec>] ip6_finish_output2+0x74c/0x1a90
>> [  181.044324]  [<ffffffff810f1d33>] ? print_context_stack+0x73/0xf0
>> [  181.050429]  [<ffffffff824f5aa0>] ? ip6_xmit+0x1700/0x1700
>> [  181.055933]  [<ffffffff82304a28>] ? nf_hook_slow+0x118/0x1b0
>> [  181.061617]  [<ffffffff82502d7a>] ip6_finish_output+0x2ba/0x580
>> [  181.067546]  [<ffffffff82503179>] ip6_output+0x139/0x380
>> [  181.072884]  [<ffffffff82503040>] ? ip6_finish_output+0x580/0x580
>> [  181.079004]  [<ffffffff82502ac0>] ? ip6_fragment+0x31b0/0x31b0
>> [  181.084852]  [<ffffffff82251b51>] ? dst_init+0x4b1/0x820
>> [  181.090172]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
>> [  181.096437]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
>> [  181.102712]  [<ffffffff8254f3ca>] NF_HOOK_THRESH.constprop.22+0xca/0x180
>> [  181.109421]  [<ffffffff8254f300>] ? ndisc_alloc_skb+0x340/0x340
>> [  181.115338]  [<ffffffff8254d820>] ? compat_ipv6_setsockopt+0x180/0x180
>> [  181.121874]  [<ffffffff8254fbc2>] ndisc_send_skb+0x742/0xd10
>> [  181.127550]  [<ffffffff8254f480>] ? NF_HOOK_THRESH.constprop.22+0x180/0x180
>> [  181.134516]  [<ffffffff821f2440>] ? skb_complete_tx_timestamp+0x280/0x280
>> [  181.141311]  [<ffffffff8254e2b3>] ? ndisc_fill_addr_option+0x193/0x260
>> [  181.147844]  [<ffffffff82553bd9>] ndisc_send_rs+0x179/0x2d0
>> [  181.153426]  [<ffffffff8251e7df>] addrconf_dad_completed+0x41f/0x7c0
>> [  181.159795]  [<ffffffff81297f78>] ? pick_next_entity+0x198/0x470
>> [  181.165807]  [<ffffffff8251e3c0>] ? addrconf_rs_timer+0x4a0/0x4a0
>> [  181.171918]  [<ffffffff81aab928>] ? find_next_bit+0x18/0x20
>> [  181.177504]  [<ffffffff81a99ec9>] ? prandom_seed+0xd9/0x160
>> [  181.183095]  [<ffffffff8251eef5>] addrconf_dad_work+0x375/0x9e0
>> [  181.189024]  [<ffffffff8251eb80>] ? addrconf_dad_completed+0x7c0/0x7c0
>> [  181.195576]  [<ffffffff81249d8f>] process_one_work+0x52f/0xf60
>> [  181.201468]  [<ffffffff8124a89d>] worker_thread+0xdd/0xe80
>> [  181.206977]  [<ffffffff8265cf0a>] ? __schedule+0x73a/0x16d0
>> [  181.212550]  [<ffffffff8124a7c0>] ? process_one_work+0xf60/0xf60
>> [  181.218572]  [<ffffffff8125a115>] kthread+0x205/0x2b0
>> [  181.223633]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
>> [  181.229743]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
>> [  181.235834]  [<ffffffff8266726f>] ret_from_fork+0x3f/0x70
>> [  181.241232]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
>>
>>
>> .
>>
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:46   ` maowenan
@ 2019-07-24 14:07     ` Eric Dumazet
  2019-07-25  4:29       ` maowenan
  0 siblings, 1 reply; 21+ messages in thread
From: Eric Dumazet @ 2019-07-24 14:07 UTC (permalink / raw)
  To: maowenan, davem, gregkh, netdev, linux-kernel



On 7/24/19 12:46 PM, maowenan wrote:
> 
> 
> On 2019/7/24 17:45, Eric Dumazet wrote:
>>
>>
>> On 7/24/19 11:17 AM, Mao Wenan wrote:
>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>
>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>>
>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>>> Call Trace:
>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>>
>>> Allocated by task 4194:
>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>
>>> Freed by task 4194:
>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>
>>> Syzkaller reproducer():
>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>
>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>>
>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>>
>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>> ---
>>>  include/net/tcp.h | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>> index bf8a0dae977a..8f8aace28cf8 100644
>>> --- a/include/net/tcp.h
>>> +++ b/include/net/tcp.h
>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>>  
>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>>  		sk_wmem_free_skb(sk, skb);
>>> +	sk->sk_send_head = NULL;
>>>  	sk_mem_reclaim(sk);
>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>>  	inet_csk(sk)->icsk_backoff = 0;
>>>
>>
>> This is strange, because tcp_init_send_head() is called from tcp_disconnect()
>> which is the syzkaller way to trigger this kind of bugs.
>>
> 
> syzkaller reproduce program duplicate one socket that have multiple skb in write queue,
> and new socket have purged skb but original socket still try to send skb. In this program,
> it does not call tcp_disconnect?


It does call tcp_disconnect(), by one of the connect() call.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 10:13   ` Eric Dumazet
  2019-07-24 10:38     ` maowenan
@ 2019-07-25  2:06     ` maowenan
  1 sibling, 0 replies; 21+ messages in thread
From: maowenan @ 2019-07-25  2:06 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/24 18:13, Eric Dumazet wrote:
> 
> 
> On 7/24/19 12:01 PM, Eric Dumazet wrote:
>>
>>
>> On 7/24/19 11:17 AM, Mao Wenan wrote:
>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>
>> Current stable 4.4 is 4.4.186
>>
>> Can you check the bug is still there ?
>>
> 
> BTW, I tried the C repro and another bug showed up.
> 
> It looks like 4.4.186 misses other fixes :/

Do you have logs about this?
Is it the bugs followed up this UAF?

> 
> [  180.811610] skbuff: skb_under_panic: text:ffffffff825ec6ea len:156 put:84 head:ffff8837dd1f0990 data:ffff8837dd1f098c tail:0x98 end:0xc0 dev:ip6gre0
> [  180.825037] ------------[ cut here ]------------
> [  180.829688] kernel BUG at net/core/skbuff.c:104!
> [  180.834316] invalid opcode: 0000 [#1] SMP KASAN
> [  180.839305] gsmi: Log Shutdown Reason 0x03
> [  180.843426] Modules linked in: ipip bonding bridge stp llc tun veth w1_therm wire i2c_mux_pca954x i2c_mux cdc_acm ehci_pci ehci_hcd ip_gre mlx4_en ib_uverbs mlx4_ib ib_sa ib_mad ib_core ib_addr mlx4_core
> [  180.862052] CPU: 22 PID: 1619 Comm: kworker/22:1 Not tainted 4.4.186-smp-DEV #41
> [  180.869475] Hardware name: Intel BIOS 2.56.0 10/19/2018
> [  180.876463] Workqueue: ipv6_addrconf addrconf_dad_work
> [  180.881658] task: ffff8837f1f59d80 ti: ffff8837eeeb8000 task.ti: ffff8837eeeb8000
> [  180.889171] RIP: 0010:[<ffffffff821ef26f>]  [<ffffffff821ef26f>] skb_panic+0x14f/0x210
> [  180.897162] RSP: 0018:ffff8837eeebf4b8  EFLAGS: 00010282
> [  180.902504] RAX: 0000000000000088 RBX: ffff8837eeeeb600 RCX: 0000000000000000
> [  180.909645] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffffffff83508c00
> [  180.916854] RBP: ffff8837eeebf520 R08: 0000000000000016 R09: 0000000000000000
> [  180.924029] R10: ffff881fc8abf038 R11: 0000000000000007 R12: ffff881fc8abe720
> [  180.931213] R13: ffffffff82aa9e80 R14: 00000000000000c0 R15: 0000000000000098
> [  180.938390] FS:  0000000000000000(0000) GS:ffff8837ff280000(0000) knlGS:0000000000000000
> [  180.946519] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [  180.952290] CR2: 00007f519426f530 CR3: 00000037d37f2000 CR4: 0000000000160670
> [  180.959447] Stack:
> [  180.961458]  ffff8837dd1f098c 0000000000000098 00000000000000c0 ffff881fc8abe720
> [  180.968909]  ffffea00df747c00 ffff881fff404b40 ffff8837ff2a1a20 ffff8837eeebf5b8
> [  180.976371]  ffff8837eeeeb600 ffffffff825ec6ea 1ffff106fddd7eb6 ffff8837eeeeb600
> [  180.983848] Call Trace:
> [  180.986297]  [<ffffffff825ec6ea>] ? ip6gre_header+0xba/0xd50
> [  180.991962]  [<ffffffff821f0e01>] skb_push+0xc1/0x100
> [  180.997023]  [<ffffffff825ec6ea>] ip6gre_header+0xba/0xd50
> [  181.002519]  [<ffffffff8158dc16>] ? memcpy+0x36/0x40
> [  181.007509]  [<ffffffff825ec630>] ? ip6gre_changelink+0x6d0/0x6d0
> [  181.013629]  [<ffffffff82550741>] ? ndisc_constructor+0x5b1/0x770
> [  181.019728]  [<ffffffff82666861>] ? _raw_write_unlock_bh+0x41/0x50
> [  181.025924]  [<ffffffff8226540b>] ? __neigh_create+0xe6b/0x1670
> [  181.031851]  [<ffffffff8225817f>] neigh_connected_output+0x23f/0x480
> [  181.038219]  [<ffffffff824f61ec>] ip6_finish_output2+0x74c/0x1a90
> [  181.044324]  [<ffffffff810f1d33>] ? print_context_stack+0x73/0xf0
> [  181.050429]  [<ffffffff824f5aa0>] ? ip6_xmit+0x1700/0x1700
> [  181.055933]  [<ffffffff82304a28>] ? nf_hook_slow+0x118/0x1b0
> [  181.061617]  [<ffffffff82502d7a>] ip6_finish_output+0x2ba/0x580
> [  181.067546]  [<ffffffff82503179>] ip6_output+0x139/0x380
> [  181.072884]  [<ffffffff82503040>] ? ip6_finish_output+0x580/0x580
> [  181.079004]  [<ffffffff82502ac0>] ? ip6_fragment+0x31b0/0x31b0
> [  181.084852]  [<ffffffff82251b51>] ? dst_init+0x4b1/0x820
> [  181.090172]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
> [  181.096437]  [<ffffffff8158da45>] ? kasan_unpoison_shadow+0x35/0x50
> [  181.102712]  [<ffffffff8254f3ca>] NF_HOOK_THRESH.constprop.22+0xca/0x180
> [  181.109421]  [<ffffffff8254f300>] ? ndisc_alloc_skb+0x340/0x340
> [  181.115338]  [<ffffffff8254d820>] ? compat_ipv6_setsockopt+0x180/0x180
> [  181.121874]  [<ffffffff8254fbc2>] ndisc_send_skb+0x742/0xd10
> [  181.127550]  [<ffffffff8254f480>] ? NF_HOOK_THRESH.constprop.22+0x180/0x180
> [  181.134516]  [<ffffffff821f2440>] ? skb_complete_tx_timestamp+0x280/0x280
> [  181.141311]  [<ffffffff8254e2b3>] ? ndisc_fill_addr_option+0x193/0x260
> [  181.147844]  [<ffffffff82553bd9>] ndisc_send_rs+0x179/0x2d0
> [  181.153426]  [<ffffffff8251e7df>] addrconf_dad_completed+0x41f/0x7c0
> [  181.159795]  [<ffffffff81297f78>] ? pick_next_entity+0x198/0x470
> [  181.165807]  [<ffffffff8251e3c0>] ? addrconf_rs_timer+0x4a0/0x4a0
> [  181.171918]  [<ffffffff81aab928>] ? find_next_bit+0x18/0x20
> [  181.177504]  [<ffffffff81a99ec9>] ? prandom_seed+0xd9/0x160
> [  181.183095]  [<ffffffff8251eef5>] addrconf_dad_work+0x375/0x9e0
> [  181.189024]  [<ffffffff8251eb80>] ? addrconf_dad_completed+0x7c0/0x7c0
> [  181.195576]  [<ffffffff81249d8f>] process_one_work+0x52f/0xf60
> [  181.201468]  [<ffffffff8124a89d>] worker_thread+0xdd/0xe80
> [  181.206977]  [<ffffffff8265cf0a>] ? __schedule+0x73a/0x16d0
> [  181.212550]  [<ffffffff8124a7c0>] ? process_one_work+0xf60/0xf60
> [  181.218572]  [<ffffffff8125a115>] kthread+0x205/0x2b0
> [  181.223633]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> [  181.229743]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> [  181.235834]  [<ffffffff8266726f>] ret_from_fork+0x3f/0x70
> [  181.241232]  [<ffffffff81259f10>] ? kthread_worker_fn+0x4e0/0x4e0
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 14:07     ` Eric Dumazet
@ 2019-07-25  4:29       ` maowenan
  2019-07-25  6:19         ` Eric Dumazet
  0 siblings, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-25  4:29 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/24 22:07, Eric Dumazet wrote:
> 
> 
> On 7/24/19 12:46 PM, maowenan wrote:
>>
>>
>> On 2019/7/24 17:45, Eric Dumazet wrote:
>>>
>>>
>>> On 7/24/19 11:17 AM, Mao Wenan wrote:
>>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>>
>>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>>>
>>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>>>> Call Trace:
>>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>>>
>>>> Allocated by task 4194:
>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>
>>>> Freed by task 4194:
>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>
>>>> Syzkaller reproducer():
>>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>>
>>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>>>
>>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>>>
>>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>>> ---
>>>>  include/net/tcp.h | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>>> index bf8a0dae977a..8f8aace28cf8 100644
>>>> --- a/include/net/tcp.h
>>>> +++ b/include/net/tcp.h
>>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>>>  
>>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>>>  		sk_wmem_free_skb(sk, skb);
>>>> +	sk->sk_send_head = NULL;
>>>>  	sk_mem_reclaim(sk);
>>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>>>  	inet_csk(sk)->icsk_backoff = 0;
>>>>
>>>
>>> This is strange, because tcp_init_send_head() is called from tcp_disconnect()
>>> which is the syzkaller way to trigger this kind of bugs.
>>>
>>
>> syzkaller reproduce program duplicate one socket that have multiple skb in write queue,
>> and new socket have purged skb but original socket still try to send skb. In this program,
>> it does not call tcp_disconnect?
> 
> 
> It does call tcp_disconnect(), by one of the connect() call.

yes, __inet_stream_connect will call tcp_disconnect when sa_family == AF_UNSPEC, in c repro if it
passes sa_family with AF_INET it won't call disconnect, and then sk_send_head won't be NULL when tcp_connect.

#define MSG_FASTOPEN	0x20000000	/* Send data in TCP SYN */

...
  case 2:
    *(uint16_t*)0x20e68000 = 2;
    *(uint16_t*)0x20e68002 = htobe16(0x4e23);
    *(uint8_t*)0x20e68004 = 0xac;
    *(uint8_t*)0x20e68005 = 0x14;
    *(uint8_t*)0x20e68006 = 0x14;
    *(uint8_t*)0x20e68007 = 0xaa;
    *(uint8_t*)0x20e68008 = 0;
    *(uint8_t*)0x20e68009 = 0;
    *(uint8_t*)0x20e6800a = 0;
    *(uint8_t*)0x20e6800b = 0;
    *(uint8_t*)0x20e6800c = 0;
    *(uint8_t*)0x20e6800d = 0;
    *(uint8_t*)0x20e6800e = 0;
    *(uint8_t*)0x20e6800f = 0;
    syscall(__NR_sendto, r[0], 0x20a88f88, 0xfffffffffffffe6e, 0x20000000,       //with fastopen, it will call __inet_stream_connect
            0x20e68000, 0x10);
    break;
  case 3:
    memcpy((void*)0x20000140, "\x7f", 1);
    syscall(__NR_write, r[0], 0x20000140, 1);
    break;
  case 4:
    *(uint16_t*)0x200012c0 = 0;   //sa_family
    *(uint16_t*)0x200012c2 = 0;
    *(uint32_t*)0x200012c4 = 0;
    *(uint32_t*)0x200012c8 = 0;
    syscall(__NR_connect, r[0], 0x200012c0, 0x80);
    break;
  case 5:
    *(uint16_t*)0x20000040 = 2;  //sa_family
    *(uint16_t*)0x20000042 = htobe16(0x4e23);
    *(uint8_t*)0x20000044 = 0xac;
    *(uint8_t*)0x20000045 = 0x14;
    *(uint8_t*)0x20000046 = 0x14;
    *(uint8_t*)0x20000047 = 0xaa;
    *(uint8_t*)0x20000048 = 0;
    *(uint8_t*)0x20000049 = 0;
    *(uint8_t*)0x2000004a = 0;
    *(uint8_t*)0x2000004b = 0;
    *(uint8_t*)0x2000004c = 0;
    *(uint8_t*)0x2000004d = 0;
    *(uint8_t*)0x2000004e = 0;
    *(uint8_t*)0x2000004f = 0;
    syscall(__NR_connect, r[0], 0x20000040, 0x10);
    break;
...

> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-25  4:29       ` maowenan
@ 2019-07-25  6:19         ` Eric Dumazet
  2019-07-26  9:10           ` maowenan
  0 siblings, 1 reply; 21+ messages in thread
From: Eric Dumazet @ 2019-07-25  6:19 UTC (permalink / raw)
  To: maowenan, Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 7/25/19 6:29 AM, maowenan wrote:
> 

>>>>> Syzkaller reproducer():
>>>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>>>
>>
>> It does call tcp_disconnect(), by one of the connect() call.
> 
> yes, __inet_stream_connect will call tcp_disconnect when sa_family == AF_UNSPEC, in c repro if it
> passes sa_family with AF_INET it won't call disconnect, and then sk_send_head won't be NULL when tcp_connect.
> 


Look again at the Syzkaller reproducer()

It definitely uses tcp_disconnect()

Do not be fooled by connect$unix(), this is a connect() call really, with AF_UNSPEC

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-25  6:19         ` Eric Dumazet
@ 2019-07-26  9:10           ` maowenan
  0 siblings, 0 replies; 21+ messages in thread
From: maowenan @ 2019-07-26  9:10 UTC (permalink / raw)
  To: Eric Dumazet, davem, gregkh, netdev, linux-kernel



On 2019/7/25 14:19, Eric Dumazet wrote:
> 
> 
> On 7/25/19 6:29 AM, maowenan wrote:
>>
> 
>>>>>> Syzkaller reproducer():
>>>>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>>>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>>>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>>>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>>>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>>>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>>>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>>>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>>>>
>>>
>>> It does call tcp_disconnect(), by one of the connect() call.
>>
>> yes, __inet_stream_connect will call tcp_disconnect when sa_family == AF_UNSPEC, in c repro if it
>> passes sa_family with AF_INET it won't call disconnect, and then sk_send_head won't be NULL when tcp_connect.
>>
> 
> 
> Look again at the Syzkaller reproducer()
> 
> It definitely uses tcp_disconnect()
> 
> Do not be fooled by connect$unix(), this is a connect() call really, with AF_UNSPEC

Right, in syzkaller reproducer, it calls connect() with AF_UNSPEC, actually I can reproduce the issue only with C repro(https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000).
syscall procedure in C:
__NR_socket
__NR_bind
__NR_sendto  (flag=0x20000000,MSG_FASTOPEN, it will call __inet_stream_connect with sa_family = AF_INET, sk->sk_send_head = NULL)
__NR_write
__NR_connect (call __inet_stream_connect with sa_family = AF_UNSPEC, it will call tcp_disconnect and set sk->sk_send_head = NULL)
__NR_connect (call __inet_stream_connect with sa_family = AF_INET, if sk->sk_send_head != NULL UAF happen)

I debug why tcp_disconnect has already set sk->sk_send_head = NULL, but it is NOT NULL after next __NR_connect.
I find that some packets send out before second __NR_connect(with AF_INET), so the sk_send_head is modified by: tcp_sendmsg->skb_entail->tcp_add_write_queue_tail
static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb)
{
	__tcp_add_write_queue_tail(sk, skb);

	/* Queue it, remembering where we must start sending. */
	if (sk->sk_send_head == NULL) {
		sk->sk_send_head = skb;  //here, sk->sk_send_head is changed.

		if (tcp_sk(sk)->highest_sack == NULL)
			tcp_sk(sk)->highest_sack = skb;
	}
}




> 
> 




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-24 12:13   ` maowenan
@ 2019-07-27 10:44     ` maowenan
  2019-07-27 11:22       ` maowenan
  0 siblings, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-27 10:44 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, davem, netdev, linux-kernel



On 2019/7/24 20:13, maowenan wrote:
> 
> 
> On 2019/7/24 19:05, Greg KH wrote:
>> On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>
>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>>
>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>>> Call Trace:
>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>>
>>> Allocated by task 4194:
>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>
>>> Freed by task 4194:
>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>
>>> Syzkaller reproducer():
>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>
>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>>
>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>>
>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>> ---
>>>  include/net/tcp.h | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>> index bf8a0dae977a..8f8aace28cf8 100644
>>> --- a/include/net/tcp.h
>>> +++ b/include/net/tcp.h
>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>>  
>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>>  		sk_wmem_free_skb(sk, skb);
>>> +	sk->sk_send_head = NULL;
>>>  	sk_mem_reclaim(sk);
>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>>  	inet_csk(sk)->icsk_backoff = 0;
>>
>> Does this corrispond with a specific commit that is already in Linus's
>> tree?  If not, why, did we change/mess something up when doing
>> backports, or is the code just that different?
>>
>> Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
>> 4.4.y?

Greg,

I have tested latest stable tree
4.4.186 oops
4.9.151 oops
4.14.106 NO oops

This patch can simple fix them.

> 
> Is it the commit 75c119afe14f? It does not use sk_send_head to indicate whether it has skb to be sent.
> 
> commit 75c119afe14f74b4dd967d75ed9f57ab6c0ef045
> Author: Eric Dumazet <edumazet@google.com>
> Date:   Thu Oct 5 22:21:27 2017 -0700
> 
>     tcp: implement rb-tree based retransmit queue
> 
> 
>  static inline struct sk_buff *tcp_send_head(const struct sock *sk)
>  {
> -       return sk->sk_send_head;
> +       return skb_peek(&sk->sk_write_queue);
>  }
> 
> 
> 
>>
>> thanks,
>>
>> greg k-h
>>
>> .
>>
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-27 10:44     ` maowenan
@ 2019-07-27 11:22       ` maowenan
  2019-07-27 11:40         ` Greg KH
  0 siblings, 1 reply; 21+ messages in thread
From: maowenan @ 2019-07-27 11:22 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, davem, netdev, linux-kernel



On 2019/7/27 18:44, maowenan wrote:
> 
> 
> On 2019/7/24 20:13, maowenan wrote:
>>
>>
>> On 2019/7/24 19:05, Greg KH wrote:
>>> On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
>>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>>
>>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>>>
>>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>>>> Call Trace:
>>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>>>
>>>> Allocated by task 4194:
>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>
>>>> Freed by task 4194:
>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>
>>>> Syzkaller reproducer():
>>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>>
>>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>>>
>>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>>>
>>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>>> ---
>>>>  include/net/tcp.h | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>>> index bf8a0dae977a..8f8aace28cf8 100644
>>>> --- a/include/net/tcp.h
>>>> +++ b/include/net/tcp.h
>>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>>>  
>>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>>>  		sk_wmem_free_skb(sk, skb);
>>>> +	sk->sk_send_head = NULL;
>>>>  	sk_mem_reclaim(sk);
>>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>>>  	inet_csk(sk)->icsk_backoff = 0;
>>>
>>> Does this corrispond with a specific commit that is already in Linus's
>>> tree?  If not, why, did we change/mess something up when doing
>>> backports, or is the code just that different?
>>>
>>> Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
>>> 4.4.y?
> 
> Greg,
> 
> I have tested latest stable tree
> 4.4.186 oops
> 4.9.151 oops
> 4.14.106 NO oops
> 
> This patch can simple fix them.

I have checked 4.14.y it has already existed the same fix as mine, this is the reason why 4.14.106 is NO oops.
commit dbbf2d1e4077bab0c65ece2765d3fc69cf7d610f
Author: Soheil Hassas Yeganeh <soheil@google.com>
Date:   Thu Mar 15 12:09:13 2018 -0400

    tcp: reset sk_send_head in tcp_write_queue_purge


> 
>>
>> Is it the commit 75c119afe14f? It does not use sk_send_head to indicate whether it has skb to be sent.
>>
>> commit 75c119afe14f74b4dd967d75ed9f57ab6c0ef045
>> Author: Eric Dumazet <edumazet@google.com>
>> Date:   Thu Oct 5 22:21:27 2017 -0700
>>
>>     tcp: implement rb-tree based retransmit queue
>>
>>
>>  static inline struct sk_buff *tcp_send_head(const struct sock *sk)
>>  {
>> -       return sk->sk_send_head;
>> +       return skb_peek(&sk->sk_write_queue);
>>  }
>>
>>
>>
>>>
>>> thanks,
>>>
>>> greg k-h
>>>
>>> .
>>>
>>
>>
>> .
>>
> 
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-27 11:22       ` maowenan
@ 2019-07-27 11:40         ` Greg KH
  2019-07-29  1:26           ` maowenan
  0 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2019-07-27 11:40 UTC (permalink / raw)
  To: maowenan; +Cc: stable, davem, netdev, linux-kernel

On Sat, Jul 27, 2019 at 07:22:30PM +0800, maowenan wrote:
> 
> 
> On 2019/7/27 18:44, maowenan wrote:
> > 
> > 
> > On 2019/7/24 20:13, maowenan wrote:
> >>
> >>
> >> On 2019/7/24 19:05, Greg KH wrote:
> >>> On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
> >>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
> >>>>
> >>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
> >>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
> >>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
> >>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
> >>>>
> >>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
> >>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> >>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
> >>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
> >>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
> >>>> Call Trace:
> >>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
> >>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
> >>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
> >>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
> >>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
> >>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
> >>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
> >>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
> >>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
> >>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
> >>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
> >>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
> >>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
> >>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
> >>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
> >>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
> >>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
> >>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
> >>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
> >>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
> >>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
> >>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
> >>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
> >>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
> >>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
> >>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
> >>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
> >>>>
> >>>> Allocated by task 4194:
> >>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
> >>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
> >>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
> >>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
> >>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
> >>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
> >>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
> >>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
> >>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
> >>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
> >>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
> >>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
> >>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
> >>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
> >>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
> >>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
> >>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
> >>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
> >>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
> >>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> >>>>
> >>>> Freed by task 4194:
> >>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
> >>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
> >>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
> >>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
> >>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
> >>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
> >>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
> >>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
> >>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
> >>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
> >>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
> >>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
> >>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
> >>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
> >>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
> >>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
> >>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
> >>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
> >>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
> >>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
> >>>>
> >>>> Syzkaller reproducer():
> >>>> r0 = socket$packet(0x11, 0x3, 0x300)
> >>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
> >>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
> >>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
> >>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
> >>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
> >>>> r2 = fcntl$dupfd(r1, 0x0, r0)
> >>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
> >>>>
> >>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
> >>>>
> >>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
> >>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
> >>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
> >>>>
> >>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
> >>>> ---
> >>>>  include/net/tcp.h | 1 +
> >>>>  1 file changed, 1 insertion(+)
> >>>>
> >>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
> >>>> index bf8a0dae977a..8f8aace28cf8 100644
> >>>> --- a/include/net/tcp.h
> >>>> +++ b/include/net/tcp.h
> >>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
> >>>>  
> >>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
> >>>>  		sk_wmem_free_skb(sk, skb);
> >>>> +	sk->sk_send_head = NULL;
> >>>>  	sk_mem_reclaim(sk);
> >>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
> >>>>  	inet_csk(sk)->icsk_backoff = 0;
> >>>
> >>> Does this corrispond with a specific commit that is already in Linus's
> >>> tree?  If not, why, did we change/mess something up when doing
> >>> backports, or is the code just that different?
> >>>
> >>> Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
> >>> 4.4.y?
> > 
> > Greg,
> > 
> > I have tested latest stable tree
> > 4.4.186 oops
> > 4.9.151 oops
> > 4.14.106 NO oops
> > 
> > This patch can simple fix them.
> 
> I have checked 4.14.y it has already existed the same fix as mine, this is the reason why 4.14.106 is NO oops.
> commit dbbf2d1e4077bab0c65ece2765d3fc69cf7d610f
> Author: Soheil Hassas Yeganeh <soheil@google.com>
> Date:   Thu Mar 15 12:09:13 2018 -0400
> 
>     tcp: reset sk_send_head in tcp_write_queue_purge
> 

So if this patch is backported to 4.4.y and 4.9.y all will be fine?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit
  2019-07-27 11:40         ` Greg KH
@ 2019-07-29  1:26           ` maowenan
  0 siblings, 0 replies; 21+ messages in thread
From: maowenan @ 2019-07-29  1:26 UTC (permalink / raw)
  To: Greg KH; +Cc: stable, davem, netdev, linux-kernel



On 2019/7/27 19:40, Greg KH wrote:
> On Sat, Jul 27, 2019 at 07:22:30PM +0800, maowenan wrote:
>>
>>
>> On 2019/7/27 18:44, maowenan wrote:
>>>
>>>
>>> On 2019/7/24 20:13, maowenan wrote:
>>>>
>>>>
>>>> On 2019/7/24 19:05, Greg KH wrote:
>>>>> On Wed, Jul 24, 2019 at 05:17:15PM +0800, Mao Wenan wrote:
>>>>>> There is one report about tcp_write_xmit use-after-free with version 4.4.136:
>>>>>>
>>>>>> BUG: KASAN: use-after-free in tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>>>> BUG: KASAN: use-after-free in tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>>>> BUG: KASAN: use-after-free in tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>>>> Read of size 2 at addr ffff8801d6fc87b0 by task syz-executor408/4195
>>>>>>
>>>>>> CPU: 0 PID: 4195 Comm: syz-executor408 Not tainted 4.4.136-gfb7e319 #59
>>>>>> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
>>>>>>  0000000000000000 7d8f38ecc03be946 ffff8801d73b7710 ffffffff81e0edad
>>>>>>  ffffea00075bf200 ffff8801d6fc87b0 0000000000000000 ffff8801d6fc87b0
>>>>>>  dffffc0000000000 ffff8801d73b7748 ffffffff815159b6 ffff8801d6fc87b0
>>>>>> Call Trace:
>>>>>>  [<ffffffff81e0edad>] __dump_stack lib/dump_stack.c:15 [inline]
>>>>>>  [<ffffffff81e0edad>] dump_stack+0xc1/0x124 lib/dump_stack.c:51
>>>>>>  [<ffffffff815159b6>] print_address_description+0x6c/0x216 mm/kasan/report.c:252
>>>>>>  [<ffffffff81515cd5>] kasan_report_error mm/kasan/report.c:351 [inline]
>>>>>>  [<ffffffff81515cd5>] kasan_report.cold.7+0x175/0x2f7 mm/kasan/report.c:408
>>>>>>  [<ffffffff814f9784>] __asan_report_load2_noabort+0x14/0x20 mm/kasan/report.c:427
>>>>>>  [<ffffffff83286582>] tcp_skb_pcount include/net/tcp.h:796 [inline]
>>>>>>  [<ffffffff83286582>] tcp_init_tso_segs net/ipv4/tcp_output.c:1619 [inline]
>>>>>>  [<ffffffff83286582>] tcp_write_xmit+0x3fc2/0x4cb0 net/ipv4/tcp_output.c:2056
>>>>>>  [<ffffffff83287a40>] __tcp_push_pending_frames+0xa0/0x290 net/ipv4/tcp_output.c:2307
>>>>>>  [<ffffffff8328e966>] tcp_send_fin+0x176/0xab0 net/ipv4/tcp_output.c:2883
>>>>>>  [<ffffffff8324c0d0>] tcp_close+0xca0/0xf70 net/ipv4/tcp.c:2112
>>>>>>  [<ffffffff832f8d0f>] inet_release+0xff/0x1d0 net/ipv4/af_inet.c:435
>>>>>>  [<ffffffff82f1a156>] sock_release+0x96/0x1c0 net/socket.c:586
>>>>>>  [<ffffffff82f1a296>] sock_close+0x16/0x20 net/socket.c:1037
>>>>>>  [<ffffffff81522da5>] __fput+0x235/0x6f0 fs/file_table.c:208
>>>>>>  [<ffffffff815232e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>>>>>  [<ffffffff8118bd7f>] task_work_run+0x10f/0x190 kernel/task_work.c:115
>>>>>>  [<ffffffff81135285>] exit_task_work include/linux/task_work.h:21 [inline]
>>>>>>  [<ffffffff81135285>] do_exit+0x9e5/0x26b0 kernel/exit.c:759
>>>>>>  [<ffffffff8113b1d1>] do_group_exit+0x111/0x330 kernel/exit.c:889
>>>>>>  [<ffffffff8115e5cc>] get_signal+0x4ec/0x14b0 kernel/signal.c:2321
>>>>>>  [<ffffffff8100e02b>] do_signal+0x8b/0x1d30 arch/x86/kernel/signal.c:712
>>>>>>  [<ffffffff8100360a>] exit_to_usermode_loop+0x11a/0x160 arch/x86/entry/common.c:248
>>>>>>  [<ffffffff81006535>] prepare_exit_to_usermode arch/x86/entry/common.c:283 [inline]
>>>>>>  [<ffffffff81006535>] syscall_return_slowpath+0x1b5/0x1f0 arch/x86/entry/common.c:348
>>>>>>  [<ffffffff838c29b5>] int_ret_from_sys_call+0x25/0xa3
>>>>>>
>>>>>> Allocated by task 4194:
>>>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>>>  [<ffffffff814f8b57>] set_track mm/kasan/kasan.c:524 [inline]
>>>>>>  [<ffffffff814f8b57>] kasan_kmalloc+0xc7/0xe0 mm/kasan/kasan.c:616
>>>>>>  [<ffffffff814f9122>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:554
>>>>>>  [<ffffffff814f4c1e>] slab_post_alloc_hook mm/slub.c:1349 [inline]
>>>>>>  [<ffffffff814f4c1e>] slab_alloc_node mm/slub.c:2615 [inline]
>>>>>>  [<ffffffff814f4c1e>] slab_alloc mm/slub.c:2623 [inline]
>>>>>>  [<ffffffff814f4c1e>] kmem_cache_alloc+0xbe/0x2a0 mm/slub.c:2628
>>>>>>  [<ffffffff82f380a6>] kmem_cache_alloc_node include/linux/slab.h:350 [inline]
>>>>>>  [<ffffffff82f380a6>] __alloc_skb+0xe6/0x600 net/core/skbuff.c:218
>>>>>>  [<ffffffff832466c3>] alloc_skb_fclone include/linux/skbuff.h:856 [inline]
>>>>>>  [<ffffffff832466c3>] sk_stream_alloc_skb+0xa3/0x5d0 net/ipv4/tcp.c:833
>>>>>>  [<ffffffff83249164>] tcp_sendmsg+0xd34/0x2b00 net/ipv4/tcp.c:1178
>>>>>>  [<ffffffff83300ef3>] inet_sendmsg+0x203/0x4d0 net/ipv4/af_inet.c:755
>>>>>>  [<ffffffff82f1e1fc>] sock_sendmsg_nosec net/socket.c:625 [inline]
>>>>>>  [<ffffffff82f1e1fc>] sock_sendmsg+0xcc/0x110 net/socket.c:635
>>>>>>  [<ffffffff82f1eedc>] SYSC_sendto+0x21c/0x370 net/socket.c:1665
>>>>>>  [<ffffffff82f21560>] SyS_sendto+0x40/0x50 net/socket.c:1633
>>>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>>>
>>>>>> Freed by task 4194:
>>>>>>  [<ffffffff810341d6>] save_stack_trace+0x26/0x50 arch/x86/kernel/stacktrace.c:63
>>>>>>  [<ffffffff814f8873>] save_stack+0x43/0xd0 mm/kasan/kasan.c:512
>>>>>>  [<ffffffff814f91a2>] set_track mm/kasan/kasan.c:524 [inline]
>>>>>>  [<ffffffff814f91a2>] kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:589
>>>>>>  [<ffffffff814f632e>] slab_free_hook mm/slub.c:1383 [inline]
>>>>>>  [<ffffffff814f632e>] slab_free_freelist_hook mm/slub.c:1405 [inline]
>>>>>>  [<ffffffff814f632e>] slab_free mm/slub.c:2859 [inline]
>>>>>>  [<ffffffff814f632e>] kmem_cache_free+0xbe/0x340 mm/slub.c:2881
>>>>>>  [<ffffffff82f3527f>] kfree_skbmem+0xcf/0x100 net/core/skbuff.c:635
>>>>>>  [<ffffffff82f372fd>] __kfree_skb+0x1d/0x20 net/core/skbuff.c:676
>>>>>>  [<ffffffff83288834>] sk_wmem_free_skb include/net/sock.h:1447 [inline]
>>>>>>  [<ffffffff83288834>] tcp_write_queue_purge include/net/tcp.h:1460 [inline]
>>>>>>  [<ffffffff83288834>] tcp_connect_init net/ipv4/tcp_output.c:3122 [inline]
>>>>>>  [<ffffffff83288834>] tcp_connect+0xb24/0x30c0 net/ipv4/tcp_output.c:3261
>>>>>>  [<ffffffff8329b991>] tcp_v4_connect+0xf31/0x1890 net/ipv4/tcp_ipv4.c:246
>>>>>>  [<ffffffff832f9ca9>] __inet_stream_connect+0x2a9/0xc30 net/ipv4/af_inet.c:615
>>>>>>  [<ffffffff832fa685>] inet_stream_connect+0x55/0xa0 net/ipv4/af_inet.c:676
>>>>>>  [<ffffffff82f1eb78>] SYSC_connect+0x1b8/0x300 net/socket.c:1557
>>>>>>  [<ffffffff82f214b4>] SyS_connect+0x24/0x30 net/socket.c:1538
>>>>>>  [<ffffffff838c2825>] entry_SYSCALL_64_fastpath+0x22/0x9e
>>>>>>
>>>>>> Syzkaller reproducer():
>>>>>> r0 = socket$packet(0x11, 0x3, 0x300)
>>>>>> r1 = socket$inet_tcp(0x2, 0x1, 0x0)
>>>>>> bind$inet(r1, &(0x7f0000000300)={0x2, 0x4e21, @multicast1}, 0x10)
>>>>>> connect$inet(r1, &(0x7f0000000140)={0x2, 0x1000004e21, @loopback}, 0x10)
>>>>>> recvmmsg(r1, &(0x7f0000001e40)=[{{0x0, 0x0, &(0x7f0000000100)=[{&(0x7f00000005c0)=""/88, 0x58}], 0x1}}], 0x1, 0x40000000, 0x0)
>>>>>> sendto$inet(r1, &(0x7f0000000000)="e2f7ad5b661c761edf", 0x9, 0x8080, 0x0, 0x0)
>>>>>> r2 = fcntl$dupfd(r1, 0x0, r0)
>>>>>> connect$unix(r2, &(0x7f00000001c0)=@file={0x0, './file0\x00'}, 0x6e)
>>>>>>
>>>>>> C repro link: https://syzkaller.appspot.com/text?tag=ReproC&x=14db474f800000
>>>>>>
>>>>>> This is because when tcp_connect_init call tcp_write_queue_purge, it will
>>>>>> kfree all the skb in the write_queue, but the sk->sk_send_head forget to set NULL,
>>>>>> then tcp_write_xmit try to send skb, which has freed in tcp_write_queue_purge, UAF happens.
>>>>>>
>>>>>> Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>>>>> ---
>>>>>>  include/net/tcp.h | 1 +
>>>>>>  1 file changed, 1 insertion(+)
>>>>>>
>>>>>> diff --git a/include/net/tcp.h b/include/net/tcp.h
>>>>>> index bf8a0dae977a..8f8aace28cf8 100644
>>>>>> --- a/include/net/tcp.h
>>>>>> +++ b/include/net/tcp.h
>>>>>> @@ -1457,6 +1457,7 @@ static inline void tcp_write_queue_purge(struct sock *sk)
>>>>>>  
>>>>>>  	while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
>>>>>>  		sk_wmem_free_skb(sk, skb);
>>>>>> +	sk->sk_send_head = NULL;
>>>>>>  	sk_mem_reclaim(sk);
>>>>>>  	tcp_clear_all_retrans_hints(tcp_sk(sk));
>>>>>>  	inet_csk(sk)->icsk_backoff = 0;
>>>>>
>>>>> Does this corrispond with a specific commit that is already in Linus's
>>>>> tree?  If not, why, did we change/mess something up when doing
>>>>> backports, or is the code just that different?
>>>>>
>>>>> Also, is this needed in 4.9.y, 4.14.y, 4.19.y, and/or 5.2.y?  Why just
>>>>> 4.4.y?
>>>
>>> Greg,
>>>
>>> I have tested latest stable tree
>>> 4.4.186 oops
>>> 4.9.151 oops
>>> 4.14.106 NO oops
>>>
>>> This patch can simple fix them.
>>
>> I have checked 4.14.y it has already existed the same fix as mine, this is the reason why 4.14.106 is NO oops.
>> commit dbbf2d1e4077bab0c65ece2765d3fc69cf7d610f
>> Author: Soheil Hassas Yeganeh <soheil@google.com>
>> Date:   Thu Mar 15 12:09:13 2018 -0400
>>
>>     tcp: reset sk_send_head in tcp_write_queue_purge
>>
> 
> So if this patch is backported to 4.4.y and 4.9.y all will be fine?
> 
yes, all are fine, but the scenarios are different, additional description should be added when backport.

4.4 and 4.9 don't have the commit abb4a8b870b5 ("tcp: purge write queue upon RST") which is referred in dbbf2d1e4077:
in tcp_connect_init calls tcp_write_queue_purge, and does not reset sk_send_head, then UAF.

4.14 have the commit abb4a8b870b5 ("tcp: purge write queue upon RST"),
in tcp_reset calls tcp_write_queue_purge(sk), and does not reset sk_send_head, then UAF.

> thanks,
> 
> greg k-h
> 
> .
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2019-07-29  1:26 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-24  9:17 [PATCH 4.4 stable net] net: tcp: Fix use-after-free in tcp_write_xmit Mao Wenan
2019-07-24  9:15 ` maowenan
2019-07-24  9:45 ` Eric Dumazet
2019-07-24 10:46   ` maowenan
2019-07-24 14:07     ` Eric Dumazet
2019-07-25  4:29       ` maowenan
2019-07-25  6:19         ` Eric Dumazet
2019-07-26  9:10           ` maowenan
2019-07-24 10:01 ` Eric Dumazet
2019-07-24 10:13   ` Eric Dumazet
2019-07-24 10:38     ` maowenan
2019-07-24 12:29       ` maowenan
2019-07-25  2:06     ` maowenan
2019-07-24 10:36   ` maowenan
2019-07-24 10:44     ` Eric Dumazet
2019-07-24 11:05 ` Greg KH
2019-07-24 12:13   ` maowenan
2019-07-27 10:44     ` maowenan
2019-07-27 11:22       ` maowenan
2019-07-27 11:40         ` Greg KH
2019-07-29  1:26           ` maowenan

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).