Jiri Slaby 6b3564
From: Eric Dumazet <edumazet@google.com>
Jiri Slaby 6b3564
Date: Wed, 16 Aug 2017 07:03:15 -0700
Jiri Slaby 6b3564
Subject: [PATCH] dccp: defer ccid_hc_tx_delete() at dismantle time
Jiri Slaby 6b3564
References: bnc#1060662
Thomas Zimmermann 1d81d2
Patch-mainline: v4.12.10
Jiri Slaby 6b3564
Git-commit: 120e9dabaf551c6dc03d3a10a1f026376cb1811c
Jiri Slaby 6b3564
Jiri Slaby 6b3564
[ Upstream commit 120e9dabaf551c6dc03d3a10a1f026376cb1811c ]
Jiri Slaby 6b3564
Jiri Slaby 6b3564
syszkaller team reported another problem in DCCP [1]
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Problem here is that the structure holding RTO timer
Jiri Slaby 6b3564
(ccid2_hc_tx_rto_expire() handler) is freed too soon.
Jiri Slaby 6b3564
Jiri Slaby 6b3564
We can not use del_timer_sync() to cancel the timer
Jiri Slaby 6b3564
since this timer wants to grab socket lock (that would risk a dead lock)
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Solution is to defer the freeing of memory when all references to
Jiri Slaby 6b3564
the socket were released. Socket timers do own a reference, so this
Jiri Slaby 6b3564
should fix the issue.
Jiri Slaby 6b3564
Jiri Slaby 6b3564
[1]
Jiri Slaby 6b3564
Jiri Slaby 6b3564
==================================================================
Jiri Slaby 6b3564
BUG: KASAN: use-after-free in ccid2_hc_tx_rto_expire+0x51c/0x5c0 net/dccp/ccids/ccid2.c:144
Jiri Slaby 6b3564
Read of size 4 at addr ffff8801d2660540 by task kworker/u4:7/3365
Jiri Slaby 6b3564
Jiri Slaby 6b3564
CPU: 1 PID: 3365 Comm: kworker/u4:7 Not tainted 4.13.0-rc4+ #3
Jiri Slaby 6b3564
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Jiri Slaby 6b3564
Workqueue: events_unbound call_usermodehelper_exec_work
Jiri Slaby 6b3564
Call Trace:
Jiri Slaby 6b3564
 <IRQ>
Jiri Slaby 6b3564
 __dump_stack lib/dump_stack.c:16 [inline]
Jiri Slaby 6b3564
 dump_stack+0x194/0x257 lib/dump_stack.c:52
Jiri Slaby 6b3564
 print_address_description+0x73/0x250 mm/kasan/report.c:252
Jiri Slaby 6b3564
 kasan_report_error mm/kasan/report.c:351 [inline]
Jiri Slaby 6b3564
 kasan_report+0x24e/0x340 mm/kasan/report.c:409
Jiri Slaby 6b3564
 __asan_report_load4_noabort+0x14/0x20 mm/kasan/report.c:429
Jiri Slaby 6b3564
 ccid2_hc_tx_rto_expire+0x51c/0x5c0 net/dccp/ccids/ccid2.c:144
Jiri Slaby 6b3564
 call_timer_fn+0x233/0x830 kernel/time/timer.c:1268
Jiri Slaby 6b3564
 expire_timers kernel/time/timer.c:1307 [inline]
Jiri Slaby 6b3564
 __run_timers+0x7fd/0xb90 kernel/time/timer.c:1601
Jiri Slaby 6b3564
 run_timer_softirq+0x21/0x80 kernel/time/timer.c:1614
Jiri Slaby 6b3564
 __do_softirq+0x2f5/0xba3 kernel/softirq.c:284
Jiri Slaby 6b3564
 invoke_softirq kernel/softirq.c:364 [inline]
Jiri Slaby 6b3564
 irq_exit+0x1cc/0x200 kernel/softirq.c:405
Jiri Slaby 6b3564
 exiting_irq arch/x86/include/asm/apic.h:638 [inline]
Jiri Slaby 6b3564
 smp_apic_timer_interrupt+0x76/0xa0 arch/x86/kernel/apic/apic.c:1044
Jiri Slaby 6b3564
 apic_timer_interrupt+0x93/0xa0 arch/x86/entry/entry_64.S:702
Jiri Slaby 6b3564
RIP: 0010:arch_local_irq_enable arch/x86/include/asm/paravirt.h:824 [inline]
Jiri Slaby 6b3564
RIP: 0010:__raw_write_unlock_irq include/linux/rwlock_api_smp.h:267 [inline]
Jiri Slaby 6b3564
RIP: 0010:_raw_write_unlock_irq+0x56/0x70 kernel/locking/spinlock.c:343
Jiri Slaby 6b3564
RSP: 0018:ffff8801cd50eaa8 EFLAGS: 00000286 ORIG_RAX: ffffffffffffff10
Jiri Slaby 6b3564
RAX: dffffc0000000000 RBX: ffffffff85a090c0 RCX: 0000000000000006
Jiri Slaby 6b3564
RDX: 1ffffffff0b595f3 RSI: 1ffff1003962f989 RDI: ffffffff85acaf98
Jiri Slaby 6b3564
RBP: ffff8801cd50eab0 R08: 0000000000000001 R09: 0000000000000000
Jiri Slaby 6b3564
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8801cc96ea60
Jiri Slaby 6b3564
R13: dffffc0000000000 R14: ffff8801cc96e4c0 R15: ffff8801cc96e4c0
Jiri Slaby 6b3564
 </IRQ>
Jiri Slaby 6b3564
 release_task+0xe9e/0x1a40 kernel/exit.c:220
Jiri Slaby 6b3564
 wait_task_zombie kernel/exit.c:1162 [inline]
Jiri Slaby 6b3564
 wait_consider_task+0x29b8/0x33c0 kernel/exit.c:1389
Jiri Slaby 6b3564
 do_wait_thread kernel/exit.c:1452 [inline]
Jiri Slaby 6b3564
 do_wait+0x441/0xa90 kernel/exit.c:1523
Jiri Slaby 6b3564
 kernel_wait4+0x1f5/0x370 kernel/exit.c:1665
Jiri Slaby 6b3564
 SYSC_wait4+0x134/0x140 kernel/exit.c:1677
Jiri Slaby 6b3564
 SyS_wait4+0x2c/0x40 kernel/exit.c:1673
Jiri Slaby 6b3564
 call_usermodehelper_exec_sync kernel/kmod.c:286 [inline]
Jiri Slaby 6b3564
 call_usermodehelper_exec_work+0x1a0/0x2c0 kernel/kmod.c:323
Jiri Slaby 6b3564
 process_one_work+0xbf3/0x1bc0 kernel/workqueue.c:2097
Jiri Slaby 6b3564
 worker_thread+0x223/0x1860 kernel/workqueue.c:2231
Jiri Slaby 6b3564
 kthread+0x35e/0x430 kernel/kthread.c:231
Jiri Slaby 6b3564
 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:425
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Allocated by task 21267:
Jiri Slaby 6b3564
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
Jiri Slaby 6b3564
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
Jiri Slaby 6b3564
 set_track mm/kasan/kasan.c:459 [inline]
Jiri Slaby 6b3564
 kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551
Jiri Slaby 6b3564
 kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:489
Jiri Slaby 6b3564
 kmem_cache_alloc+0x127/0x750 mm/slab.c:3561
Jiri Slaby 6b3564
 ccid_new+0x20e/0x390 net/dccp/ccid.c:151
Jiri Slaby 6b3564
 dccp_hdlr_ccid+0x27/0x140 net/dccp/feat.c:44
Jiri Slaby 6b3564
 __dccp_feat_activate+0x142/0x2a0 net/dccp/feat.c:344
Jiri Slaby 6b3564
 dccp_feat_activate_values+0x34e/0xa90 net/dccp/feat.c:1538
Jiri Slaby 6b3564
 dccp_rcv_request_sent_state_process net/dccp/input.c:472 [inline]
Jiri Slaby 6b3564
 dccp_rcv_state_process+0xed1/0x1620 net/dccp/input.c:677
Jiri Slaby 6b3564
 dccp_v4_do_rcv+0xeb/0x160 net/dccp/ipv4.c:679
Jiri Slaby 6b3564
 sk_backlog_rcv include/net/sock.h:911 [inline]
Jiri Slaby 6b3564
 __release_sock+0x124/0x360 net/core/sock.c:2269
Jiri Slaby 6b3564
 release_sock+0xa4/0x2a0 net/core/sock.c:2784
Jiri Slaby 6b3564
 inet_wait_for_connect net/ipv4/af_inet.c:557 [inline]
Jiri Slaby 6b3564
 __inet_stream_connect+0x671/0xf00 net/ipv4/af_inet.c:643
Jiri Slaby 6b3564
 inet_stream_connect+0x58/0xa0 net/ipv4/af_inet.c:682
Jiri Slaby 6b3564
 SYSC_connect+0x204/0x470 net/socket.c:1642
Jiri Slaby 6b3564
 SyS_connect+0x24/0x30 net/socket.c:1623
Jiri Slaby 6b3564
 entry_SYSCALL_64_fastpath+0x1f/0xbe
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Freed by task 3049:
Jiri Slaby 6b3564
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
Jiri Slaby 6b3564
 save_stack+0x43/0xd0 mm/kasan/kasan.c:447
Jiri Slaby 6b3564
 set_track mm/kasan/kasan.c:459 [inline]
Jiri Slaby 6b3564
 kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524
Jiri Slaby 6b3564
 __cache_free mm/slab.c:3503 [inline]
Jiri Slaby 6b3564
 kmem_cache_free+0x77/0x280 mm/slab.c:3763
Jiri Slaby 6b3564
 ccid_hc_tx_delete+0xc5/0x100 net/dccp/ccid.c:190
Jiri Slaby 6b3564
 dccp_destroy_sock+0x1d1/0x2b0 net/dccp/proto.c:225
Jiri Slaby 6b3564
 inet_csk_destroy_sock+0x166/0x3f0 net/ipv4/inet_connection_sock.c:833
Jiri Slaby 6b3564
 dccp_done+0xb7/0xd0 net/dccp/proto.c:145
Jiri Slaby 6b3564
 dccp_time_wait+0x13d/0x300 net/dccp/minisocks.c:72
Jiri Slaby 6b3564
 dccp_rcv_reset+0x1d1/0x5b0 net/dccp/input.c:160
Jiri Slaby 6b3564
 dccp_rcv_state_process+0x8fc/0x1620 net/dccp/input.c:663
Jiri Slaby 6b3564
 dccp_v4_do_rcv+0xeb/0x160 net/dccp/ipv4.c:679
Jiri Slaby 6b3564
 sk_backlog_rcv include/net/sock.h:911 [inline]
Jiri Slaby 6b3564
 __sk_receive_skb+0x33e/0xc00 net/core/sock.c:521
Jiri Slaby 6b3564
 dccp_v4_rcv+0xef1/0x1c00 net/dccp/ipv4.c:871
Jiri Slaby 6b3564
 ip_local_deliver_finish+0x2e2/0xba0 net/ipv4/ip_input.c:216
Jiri Slaby 6b3564
 NF_HOOK include/linux/netfilter.h:248 [inline]
Jiri Slaby 6b3564
 ip_local_deliver+0x1ce/0x6d0 net/ipv4/ip_input.c:257
Jiri Slaby 6b3564
 dst_input include/net/dst.h:477 [inline]
Jiri Slaby 6b3564
 ip_rcv_finish+0x8db/0x19c0 net/ipv4/ip_input.c:397
Jiri Slaby 6b3564
 NF_HOOK include/linux/netfilter.h:248 [inline]
Jiri Slaby 6b3564
 ip_rcv+0xc3f/0x17d0 net/ipv4/ip_input.c:488
Jiri Slaby 6b3564
 __netif_receive_skb_core+0x19af/0x33d0 net/core/dev.c:4417
Jiri Slaby 6b3564
 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4455
Jiri Slaby 6b3564
 process_backlog+0x203/0x740 net/core/dev.c:5130
Jiri Slaby 6b3564
 napi_poll net/core/dev.c:5527 [inline]
Jiri Slaby 6b3564
 net_rx_action+0x792/0x1910 net/core/dev.c:5593
Jiri Slaby 6b3564
 __do_softirq+0x2f5/0xba3 kernel/softirq.c:284
Jiri Slaby 6b3564
Jiri Slaby 6b3564
The buggy address belongs to the object at ffff8801d2660100
Jiri Slaby 6b3564
 which belongs to the cache ccid2_hc_tx_sock of size 1240
Jiri Slaby 6b3564
The buggy address is located 1088 bytes inside of
Jiri Slaby 6b3564
 1240-byte region [ffff8801d2660100, ffff8801d26605d8)
Jiri Slaby 6b3564
The buggy address belongs to the page:
Jiri Slaby 6b3564
page:ffffea0007499800 count:1 mapcount:0 mapping:ffff8801d2660100 index:0x0 compound_mapcount: 0
Jiri Slaby 6b3564
flags: 0x200000000008100(slab|head)
Jiri Slaby 6b3564
raw: 0200000000008100 ffff8801d2660100 0000000000000000 0000000100000005
Jiri Slaby 6b3564
raw: ffffea00075271a0 ffffea0007538820 ffff8801d3aef9c0 0000000000000000
Jiri Slaby 6b3564
page dumped because: kasan: bad access detected
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Memory state around the buggy address:
Jiri Slaby 6b3564
 ffff8801d2660400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Jiri Slaby 6b3564
 ffff8801d2660480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Jiri Slaby 6b3564
>ffff8801d2660500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Jiri Slaby 6b3564
                                           ^
Jiri Slaby 6b3564
 ffff8801d2660580: fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc
Jiri Slaby 6b3564
 ffff8801d2660600: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
Jiri Slaby 6b3564
==================================================================
Jiri Slaby 6b3564
Jiri Slaby 6b3564
Signed-off-by: Eric Dumazet <edumazet@google.com>
Jiri Slaby 6b3564
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Jiri Slaby 6b3564
Cc: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Jiri Slaby 6b3564
Signed-off-by: David S. Miller <davem@davemloft.net>
Jiri Slaby 6b3564
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby 6b3564
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 6b3564
---
Jiri Slaby 6b3564
 net/dccp/proto.c | 14 ++++++++++++--
Jiri Slaby 6b3564
 1 file changed, 12 insertions(+), 2 deletions(-)
Jiri Slaby 6b3564
Jiri Slaby 6b3564
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
Jiri Slaby 6b3564
index 86bc40ba6ba5..b68168fcc06a 100644
Jiri Slaby 6b3564
--- a/net/dccp/proto.c
Jiri Slaby 6b3564
+++ b/net/dccp/proto.c
Jiri Slaby 6b3564
@@ -24,6 +24,7 @@
Jiri Slaby 6b3564
 #include <net/checksum.h>
Jiri Slaby 6b3564
 
Jiri Slaby 6b3564
 #include <net/inet_sock.h>
Jiri Slaby 6b3564
+#include <net/inet_common.h>
Jiri Slaby 6b3564
 #include <net/sock.h>
Jiri Slaby 6b3564
 #include <net/xfrm.h>
Jiri Slaby 6b3564
 
Jiri Slaby 6b3564
@@ -170,6 +171,15 @@ const char *dccp_packet_name(const int type)
Jiri Slaby 6b3564
 
Jiri Slaby 6b3564
 EXPORT_SYMBOL_GPL(dccp_packet_name);
Jiri Slaby 6b3564
 
Jiri Slaby 6b3564
+static void dccp_sk_destruct(struct sock *sk)
Jiri Slaby 6b3564
+{
Jiri Slaby 6b3564
+	struct dccp_sock *dp = dccp_sk(sk);
Jiri Slaby 6b3564
+
Jiri Slaby 6b3564
+	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
Jiri Slaby 6b3564
+	dp->dccps_hc_tx_ccid = NULL;
Jiri Slaby 6b3564
+	inet_sock_destruct(sk);
Jiri Slaby 6b3564
+}
Jiri Slaby 6b3564
+
Jiri Slaby 6b3564
 int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
Jiri Slaby 6b3564
 {
Jiri Slaby 6b3564
 	struct dccp_sock *dp = dccp_sk(sk);
Jiri Slaby 6b3564
@@ -179,6 +189,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
Jiri Slaby 6b3564
 	icsk->icsk_syn_retries	= sysctl_dccp_request_retries;
Jiri Slaby 6b3564
 	sk->sk_state		= DCCP_CLOSED;
Jiri Slaby 6b3564
 	sk->sk_write_space	= dccp_write_space;
Jiri Slaby 6b3564
+	sk->sk_destruct		= dccp_sk_destruct;
Jiri Slaby 6b3564
 	icsk->icsk_sync_mss	= dccp_sync_mss;
Jiri Slaby 6b3564
 	dp->dccps_mss_cache	= 536;
Jiri Slaby 6b3564
 	dp->dccps_rate_last	= jiffies;
Jiri Slaby 6b3564
@@ -219,8 +230,7 @@ void dccp_destroy_sock(struct sock *sk)
Jiri Slaby 6b3564
 		dp->dccps_hc_rx_ackvec = NULL;
Jiri Slaby 6b3564
 	}
Jiri Slaby 6b3564
 	ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
Jiri Slaby 6b3564
-	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
Jiri Slaby 6b3564
-	dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
Jiri Slaby 6b3564
+	dp->dccps_hc_rx_ccid = NULL;
Jiri Slaby 6b3564
 
Jiri Slaby 6b3564
 	/* clean up feature negotiation state */
Jiri Slaby 6b3564
 	dccp_feat_list_purge(&dp->dccps_featneg);
Jiri Slaby 6b3564
-- 
Jiri Slaby 6b3564
2.14.2
Jiri Slaby 6b3564