From e252b3d1a1744af1431aca30e091420734c2b012 Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Tue, 25 Aug 2015 10:38:53 -0700 Subject: route: fix a use-after-free This patch fixes the following crash: general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.2.0-rc7+ #166 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 task: ffff88010656d280 ti: ffff880106570000 task.ti: ffff880106570000 RIP: 0010:[] [] dst_destroy+0xa6/0xef RSP: 0018:ffff880107603e38 EFLAGS: 00010202 RAX: 0000000000000001 RBX: ffff8800d225a000 RCX: ffffffff82250fd0 RDX: 0000000000000001 RSI: ffffffff82250fd0 RDI: 6b6b6b6b6b6b6b6b RBP: ffff880107603e58 R08: 0000000000000001 R09: 0000000000000001 R10: 000000000000b530 R11: ffff880107609000 R12: 0000000000000000 R13: ffffffff82343c40 R14: 0000000000000000 R15: ffffffff8182fb4f FS: 0000000000000000(0000) GS:ffff880107600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007fcabd9d3000 CR3: 00000000d7279000 CR4: 00000000000006e0 Stack: ffffffff82250fd0 ffff8801077d6f00 ffffffff82253c40 ffff8800d225a000 ffff880107603e68 ffffffff8182fb5d ffff880107603f08 ffffffff810d795e ffffffff810d7648 ffff880106574000 ffff88010656d280 ffff88010656d280 Call Trace: [] dst_destroy_rcu+0xe/0x1d [] rcu_process_callbacks+0x618/0x7eb [] ? rcu_process_callbacks+0x302/0x7eb [] ? dst_gc_task+0x1eb/0x1eb [] __do_softirq+0x178/0x39f [] irq_exit+0x41/0x95 [] smp_apic_timer_interrupt+0x34/0x40 [] apic_timer_interrupt+0x6d/0x80 [] ? default_idle+0x21/0x32 [] ? default_idle+0x1f/0x32 [] arch_cpu_idle+0xf/0x11 [] default_idle_call+0x1f/0x21 [] cpu_startup_entry+0x1ad/0x273 [] start_secondary+0x135/0x156 dst is freed right before lwtstate_put(), this is not correct... Fixes: 61adedf3e3f1 ("route: move lwtunnel state to dst_entry") Acked-by: Jiri Benc Signed-off-by: Cong Wang Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- net/core/dst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/core') diff --git a/net/core/dst.c b/net/core/dst.c index 50dcdbb0ee46..477035ed7903 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -262,11 +262,12 @@ again: if (dst->dev) dev_put(dst->dev); + lwtstate_put(dst->lwtstate); + if (dst->flags & DST_METADATA) kfree(dst); else kmem_cache_free(dst->ops->kmem_cachep, dst); - lwtstate_put(dst->lwtstate); dst = child; if (dst) { -- cgit v1.2.3