Skip to content

Commit ec7cb62

Browse files
aryabinindavem330
authored andcommitted
net/dccp: fix use after free in tw_timer_handler()
DCCP doesn't purge timewait sockets on network namespace shutdown. So, after net namespace destroyed we could still have an active timer which will trigger use after free in tw_timer_handler(): BUG: KASAN: use-after-free in tw_timer_handler+0x4a/0xa0 at addr ffff88010e0d1e10 Read of size 8 by task swapper/1/0 Call Trace: __asan_load8+0x54/0x90 tw_timer_handler+0x4a/0xa0 call_timer_fn+0x127/0x480 expire_timers+0x1db/0x2e0 run_timer_softirq+0x12f/0x2a0 __do_softirq+0x105/0x5b4 irq_exit+0xdd/0xf0 smp_apic_timer_interrupt+0x57/0x70 apic_timer_interrupt+0x90/0xa0 Object at ffff88010e0d1bc0, in cache net_namespace size: 6848 Allocated: save_stack_trace+0x1b/0x20 kasan_kmalloc+0xee/0x180 kasan_slab_alloc+0x12/0x20 kmem_cache_alloc+0x134/0x310 copy_net_ns+0x8d/0x280 create_new_namespaces+0x23f/0x340 unshare_nsproxy_namespaces+0x75/0xf0 SyS_unshare+0x299/0x4f0 entry_SYSCALL_64_fastpath+0x18/0xad Freed: save_stack_trace+0x1b/0x20 kasan_slab_free+0xae/0x180 kmem_cache_free+0xb4/0x350 net_drop_ns+0x3f/0x50 cleanup_net+0x3df/0x450 process_one_work+0x419/0xbb0 worker_thread+0x92/0x850 kthread+0x192/0x1e0 ret_from_fork+0x2e/0x40 Add .exit_batch hook to dccp_v4_ops()/dccp_v6_ops() which will purge timewait sockets on net namespace destruction and prevent above issue. Fixes: f2bf415 ("mib: add net to NET_ADD_STATS_BH") Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2618be7 commit ec7cb62

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

net/dccp/ipv4.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,9 +1017,15 @@ static void __net_exit dccp_v4_exit_net(struct net *net)
10171017
inet_ctl_sock_destroy(net->dccp.v4_ctl_sk);
10181018
}
10191019

1020+
static void __net_exit dccp_v4_exit_batch(struct list_head *net_exit_list)
1021+
{
1022+
inet_twsk_purge(&dccp_hashinfo, AF_INET);
1023+
}
1024+
10201025
static struct pernet_operations dccp_v4_ops = {
10211026
.init = dccp_v4_init_net,
10221027
.exit = dccp_v4_exit_net,
1028+
.exit_batch = dccp_v4_exit_batch,
10231029
};
10241030

10251031
static int __init dccp_v4_init(void)

net/dccp/ipv6.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,9 +1075,15 @@ static void __net_exit dccp_v6_exit_net(struct net *net)
10751075
inet_ctl_sock_destroy(net->dccp.v6_ctl_sk);
10761076
}
10771077

1078+
static void __net_exit dccp_v6_exit_batch(struct list_head *net_exit_list)
1079+
{
1080+
inet_twsk_purge(&dccp_hashinfo, AF_INET6);
1081+
}
1082+
10781083
static struct pernet_operations dccp_v6_ops = {
10791084
.init = dccp_v6_init_net,
10801085
.exit = dccp_v6_exit_net,
1086+
.exit_batch = dccp_v6_exit_batch,
10811087
};
10821088

10831089
static int __init dccp_v6_init(void)

0 commit comments

Comments
 (0)