linux-uconsole/net/ipv4
Eric Dumazet 9bbde08258 tcp: do not leave dangling pointers in tp->highest_sack
[ Upstream commit 2bec445f9b ]

Latest commit 853697504d ("tcp: Fix highest_sack and highest_sack_seq")
apparently allowed syzbot to trigger various crashes in TCP stack [1]

I believe this commit only made things easier for syzbot to find
its way into triggering use-after-frees. But really the bugs
could lead to bad TCP behavior or even plain crashes even for
non malicious peers.

I have audited all calls to tcp_rtx_queue_unlink() and
tcp_rtx_queue_unlink_and_free() and made sure tp->highest_sack would be updated
if we are removing from rtx queue the skb that tp->highest_sack points to.

These updates were missing in three locations :

1) tcp_clean_rtx_queue() [This one seems quite serious,
                          I have no idea why this was not caught earlier]

2) tcp_rtx_queue_purge() [Probably not a big deal for normal operations]

3) tcp_send_synack()     [Probably not a big deal for normal operations]

[1]
BUG: KASAN: use-after-free in tcp_highest_sack_seq include/net/tcp.h:1864 [inline]
BUG: KASAN: use-after-free in tcp_highest_sack_seq include/net/tcp.h:1856 [inline]
BUG: KASAN: use-after-free in tcp_check_sack_reordering+0x33c/0x3a0 net/ipv4/tcp_input.c:891
Read of size 4 at addr ffff8880a488d068 by task ksoftirqd/1/16

CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 5.5.0-rc5-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x197/0x210 lib/dump_stack.c:118
 print_address_description.constprop.0.cold+0xd4/0x30b mm/kasan/report.c:374
 __kasan_report.cold+0x1b/0x41 mm/kasan/report.c:506
 kasan_report+0x12/0x20 mm/kasan/common.c:639
 __asan_report_load4_noabort+0x14/0x20 mm/kasan/generic_report.c:134
 tcp_highest_sack_seq include/net/tcp.h:1864 [inline]
 tcp_highest_sack_seq include/net/tcp.h:1856 [inline]
 tcp_check_sack_reordering+0x33c/0x3a0 net/ipv4/tcp_input.c:891
 tcp_try_undo_partial net/ipv4/tcp_input.c:2730 [inline]
 tcp_fastretrans_alert+0xf74/0x23f0 net/ipv4/tcp_input.c:2847
 tcp_ack+0x2577/0x5bf0 net/ipv4/tcp_input.c:3710
 tcp_rcv_established+0x6dd/0x1e90 net/ipv4/tcp_input.c:5706
 tcp_v4_do_rcv+0x619/0x8d0 net/ipv4/tcp_ipv4.c:1619
 tcp_v4_rcv+0x307f/0x3b40 net/ipv4/tcp_ipv4.c:2001
 ip_protocol_deliver_rcu+0x5a/0x880 net/ipv4/ip_input.c:204
 ip_local_deliver_finish+0x23b/0x380 net/ipv4/ip_input.c:231
 NF_HOOK include/linux/netfilter.h:307 [inline]
 NF_HOOK include/linux/netfilter.h:301 [inline]
 ip_local_deliver+0x1e9/0x520 net/ipv4/ip_input.c:252
 dst_input include/net/dst.h:442 [inline]
 ip_rcv_finish+0x1db/0x2f0 net/ipv4/ip_input.c:428
 NF_HOOK include/linux/netfilter.h:307 [inline]
 NF_HOOK include/linux/netfilter.h:301 [inline]
 ip_rcv+0xe8/0x3f0 net/ipv4/ip_input.c:538
 __netif_receive_skb_one_core+0x113/0x1a0 net/core/dev.c:5148
 __netif_receive_skb+0x2c/0x1d0 net/core/dev.c:5262
 process_backlog+0x206/0x750 net/core/dev.c:6093
 napi_poll net/core/dev.c:6530 [inline]
 net_rx_action+0x508/0x1120 net/core/dev.c:6598
 __do_softirq+0x262/0x98c kernel/softirq.c:292
 run_ksoftirqd kernel/softirq.c:603 [inline]
 run_ksoftirqd+0x8e/0x110 kernel/softirq.c:595
 smpboot_thread_fn+0x6a3/0xa40 kernel/smpboot.c:165
 kthread+0x361/0x430 kernel/kthread.c:255
 ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

Allocated by task 10091:
 save_stack+0x23/0x90 mm/kasan/common.c:72
 set_track mm/kasan/common.c:80 [inline]
 __kasan_kmalloc mm/kasan/common.c:513 [inline]
 __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:486
 kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:521
 slab_post_alloc_hook mm/slab.h:584 [inline]
 slab_alloc_node mm/slab.c:3263 [inline]
 kmem_cache_alloc_node+0x138/0x740 mm/slab.c:3575
 __alloc_skb+0xd5/0x5e0 net/core/skbuff.c:198
 alloc_skb_fclone include/linux/skbuff.h:1099 [inline]
 sk_stream_alloc_skb net/ipv4/tcp.c:875 [inline]
 sk_stream_alloc_skb+0x113/0xc90 net/ipv4/tcp.c:852
 tcp_sendmsg_locked+0xcf9/0x3470 net/ipv4/tcp.c:1282
 tcp_sendmsg+0x30/0x50 net/ipv4/tcp.c:1432
 inet_sendmsg+0x9e/0xe0 net/ipv4/af_inet.c:807
 sock_sendmsg_nosec net/socket.c:652 [inline]
 sock_sendmsg+0xd7/0x130 net/socket.c:672
 __sys_sendto+0x262/0x380 net/socket.c:1998
 __do_sys_sendto net/socket.c:2010 [inline]
 __se_sys_sendto net/socket.c:2006 [inline]
 __x64_sys_sendto+0xe1/0x1a0 net/socket.c:2006
 do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Freed by task 10095:
 save_stack+0x23/0x90 mm/kasan/common.c:72
 set_track mm/kasan/common.c:80 [inline]
 kasan_set_free_info mm/kasan/common.c:335 [inline]
 __kasan_slab_free+0x102/0x150 mm/kasan/common.c:474
 kasan_slab_free+0xe/0x10 mm/kasan/common.c:483
 __cache_free mm/slab.c:3426 [inline]
 kmem_cache_free+0x86/0x320 mm/slab.c:3694
 kfree_skbmem+0x178/0x1c0 net/core/skbuff.c:645
 __kfree_skb+0x1e/0x30 net/core/skbuff.c:681
 sk_eat_skb include/net/sock.h:2453 [inline]
 tcp_recvmsg+0x1252/0x2930 net/ipv4/tcp.c:2166
 inet_recvmsg+0x136/0x610 net/ipv4/af_inet.c:838
 sock_recvmsg_nosec net/socket.c:886 [inline]
 sock_recvmsg net/socket.c:904 [inline]
 sock_recvmsg+0xce/0x110 net/socket.c:900
 __sys_recvfrom+0x1ff/0x350 net/socket.c:2055
 __do_sys_recvfrom net/socket.c:2073 [inline]
 __se_sys_recvfrom net/socket.c:2069 [inline]
 __x64_sys_recvfrom+0xe1/0x1a0 net/socket.c:2069
 do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

The buggy address belongs to the object at ffff8880a488d040
 which belongs to the cache skbuff_fclone_cache of size 456
The buggy address is located 40 bytes inside of
 456-byte region [ffff8880a488d040, ffff8880a488d208)
The buggy address belongs to the page:
page:ffffea0002922340 refcount:1 mapcount:0 mapping:ffff88821b057000 index:0x0
raw: 00fffe0000000200 ffffea00022a5788 ffffea0002624a48 ffff88821b057000
raw: 0000000000000000 ffff8880a488d040 0000000100000006 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff8880a488cf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff8880a488cf80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff8880a488d000: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
                                                          ^
 ffff8880a488d080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff8880a488d100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb

Fixes: 853697504d ("tcp: Fix highest_sack and highest_sack_seq")
Fixes: 50895b9de1 ("tcp: highest_sack fix")
Fixes: 737ff31456 ("tcp: use sequence distance to detect reordering")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Cambda Zhu <cambda@linux.alibaba.com>
Cc: Yuchung Cheng <ycheng@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-01-29 16:43:17 +01:00
..
bpfilter bpfilter: remove trailing newline 2018-07-24 14:10:42 -07:00
netfilter netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct 2020-01-23 08:21:33 +01:00
af_inet.c net: don't clear sock->sk early to avoid trouble in strparser 2020-01-27 14:50:52 +01:00
ah4.c
arp.c proc: introduce proc_create_net{,_data} 2018-05-16 07:24:30 +02:00
cipso_ipv4.c net: avoid use IPCB in cipso_v4_error 2019-03-10 07:17:19 +01:00
datagram.c inet: stop leaking jiffies on the wire 2019-11-10 11:27:37 +01:00
devinet.c inet: protect against too small mtu values. 2019-12-21 10:57:08 +01:00
esp4.c esp4: add length check for UDP encapsulation 2019-05-25 18:23:41 +02:00
esp4_offload.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next 2018-07-27 09:33:37 -07:00
fib_frontend.c ipv4: fix route update on metric change. 2019-11-10 11:27:50 +01:00
fib_lookup.h
fib_notifier.c
fib_rules.c net: fib_rules: add extack support 2018-04-23 10:21:24 -04:00
fib_semantics.c ipv4: Fix table id reference in fib_sync_down_addr 2019-11-12 19:20:27 +01:00
fib_trie.c net: ipv4: Fix memory leak in network namespace dismantle 2019-01-31 08:14:32 +01:00
fou.c net: fou: do not use guehdr after iptunnel_pull_offloads in gue_udp_recv 2019-04-27 09:36:31 +02:00
gre_demux.c gre: refetch erspan header from skb->data after pskb_may_pull() 2019-12-17 20:35:51 +01:00
gre_offload.c Merge ra.kernel.org:/pub/scm/linux/kernel/git/davem/net 2018-07-03 10:29:26 +09:00
icmp.c net: icmp: fix data-race in cmp_global_allow() 2020-01-04 19:13:30 +01:00
igmp.c ipv4/igmp: fix v1/v2 switchback timeout based on rfc3376, 8.12 2019-12-01 09:17:05 +01:00
inet_connection_sock.c net: add {READ|WRITE}_ONCE() annotations on ->rskq_accept_head 2020-01-27 14:51:18 +01:00
inet_diag.c tcp/dccp: fix possible race __inet_lookup_established() 2020-01-04 19:13:41 +01:00
inet_fragment.c net: IP defrag: encapsulate rbtree defrag code into callable functions 2019-04-27 09:36:33 +02:00
inet_hashtables.c tcp/dccp: fix possible race __inet_lookup_established() 2020-01-04 19:13:41 +01:00
inet_timewait_sock.c soreuseport: initialise timewait reuseport field 2018-04-07 22:32:32 -04:00
inetpeer.c inetpeer: fix data-race in inet_putpeer / inet_putpeer 2020-01-04 19:13:29 +01:00
ip_forward.c net: clear skb->tstamp in forwarding paths 2019-01-09 17:38:31 +01:00
ip_fragment.c net: IP defrag: encapsulate rbtree defrag code into callable functions 2019-04-27 09:36:33 +02:00
ip_gre.c net: ip_gre: do not report erspan_ver for gre or gretap 2019-12-05 09:21:10 +01:00
ip_input.c vrf: check accept_source_route on the original netdevice 2019-04-17 08:38:42 +02:00
ip_options.c vrf: check accept_source_route on the original netdevice 2019-04-17 08:38:42 +02:00
ip_output.c net: always initialize pagedlen 2020-01-27 14:50:03 +01:00
ip_sockglue.c net: bpfilter: fix iptables failure if bpfilter_umh is disabled 2019-12-01 09:17:18 +01:00
ip_tunnel.c net, ip_tunnel: fix namespaces move 2020-01-29 16:43:15 +01:00
ip_tunnel_core.c ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL 2019-08-04 09:30:57 +02:00
ip_vti.c vti: do not confirm neighbor when do pmtu update 2020-01-04 19:13:39 +01:00
ipcomp.c
ipconfig.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2018-06-06 18:39:49 -07:00
ipip.c ipip: validate header length in ipip_tunnel_xmit 2019-08-09 17:52:30 +02:00
ipmr.c ipmr: Fix skb headroom in ipmr_get_route(). 2019-11-20 18:45:11 +01:00
ipmr_base.c net: ipmr: fix unresolved entry dumps 2018-10-17 22:35:42 -07:00
Kconfig net: remove blank lines at end of file 2018-07-24 14:10:43 -07:00
Makefile net: remove blank lines at end of file 2018-07-24 14:10:43 -07:00
metrics.c net: metrics: add proper netlink validation 2018-06-05 12:29:43 -04:00
netfilter.c netfilter: utils: move nf_ip_checksum* from ipv4 to utils 2018-07-16 17:51:48 +02:00
netlink.c ipv4: Add ICMPv6 support when parse route ipproto 2019-03-10 07:17:17 +01:00
ping.c net: add helpers checking if socket can be bound to nonlocal address 2018-08-01 09:50:04 -07:00
proc.c tcp: tcp_fragment() should apply sane memory limits 2019-06-17 19:51:56 +02:00
protocol.c
raw.c ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop 2019-07-03 13:14:46 +02:00
raw_diag.c net: don't warn in inet diag when IPV6 is disabled 2019-10-01 08:26:11 +02:00
route.c net: add bool confirm_neigh parameter for dst_ops.update_pmtu 2020-01-04 19:13:37 +01:00
syncookies.c tcp: handle inet_csk_reqsk_queue_add() failures 2019-03-19 13:12:39 +01:00
sysctl_net_ipv4.c tcp: add tcp_min_snd_mss sysctl 2019-06-17 19:51:56 +02:00
tcp.c tcp: do not leave dangling pointers in tp->highest_sack 2020-01-29 16:43:17 +01:00
tcp_bbr.c tcp_bbr: improve arithmetic division in bbr_update_bw() 2020-01-29 16:43:17 +01:00
tcp_bic.c
tcp_cdg.c
tcp_cong.c tcp: fix tcp_set_congestion_control() use from bpf hook 2019-07-28 08:29:26 +02:00
tcp_cubic.c
tcp_dctcp.c tcp: Ensure DCTCP reacts to losses 2019-04-17 08:38:41 +02:00
tcp_diag.c tcp: annotate tp->rcv_nxt lockless reads 2020-01-09 10:19:08 +01:00
tcp_fastopen.c
tcp_highspeed.c
tcp_htcp.c
tcp_hybla.c
tcp_illinois.c net/tcp/illinois: replace broken algorithm reference link 2018-02-28 12:03:47 -05:00
tcp_input.c tcp: do not leave dangling pointers in tp->highest_sack 2020-01-29 16:43:17 +01:00
tcp_ipv4.c tcp: annotate tp->rcv_nxt lockless reads 2020-01-09 10:19:08 +01:00
tcp_lp.c
tcp_metrics.c net: Drop pernet_operations::async 2018-03-27 13:18:09 -04:00
tcp_minisocks.c tcp: annotate tp->rcv_nxt lockless reads 2020-01-09 10:19:08 +01:00
tcp_nv.c
tcp_offload.c tcp: Don't coalesce decrypted and encrypted SKBs 2018-07-16 00:12:09 -07:00
tcp_output.c tcp: do not leave dangling pointers in tp->highest_sack 2020-01-29 16:43:17 +01:00
tcp_rate.c tcp: expose both send and receive intervals for rate sample 2018-07-11 23:01:56 -07:00
tcp_recovery.c tcp: add stat of data packet reordering events 2018-08-01 09:56:10 -07:00
tcp_scalable.c
tcp_timer.c tcp: fix SNMP TCP timeout under-estimation 2019-12-13 08:52:20 +01:00
tcp_ulp.c tcp, ulp: fix leftover icsk_ulp_ops preventing sock from reattach 2018-08-16 14:58:08 -07:00
tcp_vegas.c
tcp_vegas.h
tcp_veno.c
tcp_westwood.c
tcp_yeah.c
tunnel4.c inet: whitespace cleanup 2018-02-28 11:43:28 -05:00
udp.c Revert "udp: do rmem bulk free even if the rx sk queue is empty" 2020-01-29 16:43:17 +01:00
udp_diag.c udp: fix rx queue len reported by diag and proc interface 2018-06-08 19:55:15 -04:00
udp_impl.h
udp_offload.c net/udp_gso: Allow TX timestamp with UDP GSO 2020-01-27 14:50:56 +01:00
udp_tunnel.c
udplite.c proc: introduce proc_create_net{,_data} 2018-05-16 07:24:30 +02:00
xfrm4_input.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-09-04 10:26:30 +02:00
xfrm4_mode_beet.c
xfrm4_mode_transport.c xfrm: reset transport header back to network header after all input transforms ahave been applied 2018-09-04 10:26:30 +02:00
xfrm4_mode_tunnel.c xfrm: Verify MAC header exists before overwriting eth_hdr(skb)->h_proto 2018-03-07 10:54:29 +01:00
xfrm4_output.c net: xfrm: use skb_gso_validate_network_len() to check gso sizes 2018-03-04 17:49:17 -05:00
xfrm4_policy.c net: add bool confirm_neigh parameter for dst_ops.update_pmtu 2020-01-04 19:13:37 +01:00
xfrm4_protocol.c
xfrm4_state.c
xfrm4_tunnel.c