Re: mm: BUG in expand_downwards
From: Dmitry Vyukov <dvyukov@google.com>
Date: 2016-01-27 14:43:08
Also in:
lkml
On Wed, Jan 27, 2016 at 1:24 PM, Dmitry Vyukov [off-list ref] wrote:
On Wed, Jan 27, 2016 at 12:49 PM, Konstantin Khlebnikov [off-list ref] wrote:quoted
It seems anon_vma appeared between lock and unlock. This should fix the bug and make code faster (write lock isn't required here)--- a/mm/mmap.c +++ b/mm/mmap.c@@ -453,12 +453,16 @@ static void validate_mm(struct mm_struct *mm) struct vm_area_struct *vma = mm->mmap; while (vma) { + struct anon_vma *anon_vma = vma->anon_vma; struct anon_vma_chain *avc; - vma_lock_anon_vma(vma); - list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) - anon_vma_interval_tree_verify(avc); - vma_unlock_anon_vma(vma); + if (anon_vma) { + anon_vma_lock_read(anon_vma); + list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) + anon_vma_interval_tree_verify(avc); + anon_vma_unlock_read(anon_vma); + } + highest_address = vma->vm_end; vma = vma->vm_next; i++;Now testing with this patch. Thanks for quick fix!
Hit the same BUG with this patch. Please try to reproduce it locally and test.
quoted
On Wed, Jan 27, 2016 at 1:51 PM, Dmitry Vyukov [off-list ref] wrote:quoted
Hello, The following program trigger BUG in expand_downwards (run it in tight parallel loop for a while): // autogenerated by syzkaller (http://github.com/google/syzkaller) #include <pthread.h> #include <stdint.h> #include <string.h> #include <sys/syscall.h> #include <unistd.h> long r[10]; void* thr(void* arg) { switch ((long)arg) { case 0: r[0] = syscall(SYS_mmap, 0x20731000ul, 0x2000ul, 0x2ul, 0x22132ul, 0xfffffffffffffffful, 0x0ul); break; case 1: r[1] = syscall(SYS_mremap, 0x20732000ul, 0x1000ul, 0x3000ul, 0x3ul, 0x2015b000ul, 0); break; case 2: r[2] = syscall(SYS_fanotify_init, 0x20ul, 0x40002ul, 0, 0, 0, 0); break; case 3: r[3] = syscall(SYS_mremap, 0x2015c000ul, 0x1000ul, 0x4000ul, 0x3ul, 0x204eb000ul, 0); break; case 4: r[4] = syscall(SYS_munlock, 0x204eb000ul, 0x4000ul, 0, 0, 0, 0); break; case 5: r[5] = syscall(SYS_mremap, 0x204ec000ul, 0x1000ul, 0x1000ul, 0x3ul, 0x2015d000ul, 0); break; case 6: r[6] = syscall(SYS_mmap, 0x20000000ul, 0x1000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); break; case 7: r[7] = syscall(SYS_sigaltstack, 0x204ec000ul, 0x20000000ul, 0, 0, 0, 0); break; case 8: memcpy((void*)0x2015bffa, "\x2e\x2f\x62\x75\x73\x00", 6); r[9] = syscall(SYS_mkdir, 0x2015bffaul, 0x108ul, 0, 0, 0, 0); break; } return 0; } int main() { long i; pthread_t th[9]; srand(getpid()); memset(r, -1, sizeof(r)); for (i = 0; i < 9; i++) { pthread_create(&th[i], 0, thr, (void*)i); usleep(1000); } for (i = 0; i < 9; i++) { pthread_create(&th[i], 0, thr, (void*)i); usleep(rand()%1000); } usleep(10000); return 0; } ===================================== [ BUG: bad unlock balance detected! ] 4.5.0-rc1+ #292 Not tainted ------------------------------------- a.out/7506 is trying to release lock (&anon_vma->rwsem) at: [< inline >] vma_unlock_anon_vma include/linux/rmap.h:123 [<ffffffff816f8e5d>] validate_mm+0x12d/0x850 mm/mmap.c:461 but there are no more locks to release! other info that might help us debug this: 1 lock held by a.out/7506: #0: (&mm->mmap_sem){++++++}, at: [<ffffffff8127dfd7>] __do_page_fault+0x737/0x960 arch/x86/mm/fault.c:1184 stack backtrace: CPU: 1 PID: 7506 Comm: a.out Not tainted 4.5.0-rc1+ #292 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 00000000ffffffff ffff88005d107b50 ffffffff829e79ad ffff8800603b4ce8 ffff88005f15df00 ffffffff816f8e5d ffff88005d107b80 ffffffff81450884 ffff8800603b4ce8 ffff88005f15e720 ffff88005f15e720 00000000ffffffff Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [<ffffffff829e79ad>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50 [<ffffffff81450884>] print_unlock_imbalance_bug+0x174/0x1a0 kernel/locking/lockdep.c:3261 [< inline >] __lock_release kernel/locking/lockdep.c:3385 [<ffffffff8145c687>] lock_release+0x937/0xce0 kernel/locking/lockdep.c:3606 [<ffffffff814490ba>] up_write+0x1a/0x60 kernel/locking/rwsem.c:91 [< inline >] vma_unlock_anon_vma include/linux/rmap.h:123 [<ffffffff816f8e5d>] validate_mm+0x12d/0x850 mm/mmap.c:461 [<ffffffff817034be>] expand_downwards+0x19e/0xb30 mm/mmap.c:2283 [<ffffffff81703ecb>] expand_stack+0x7b/0xe0 mm/mmap.c:2338 [<ffffffff8127df88>] __do_page_fault+0x6e8/0x960 arch/x86/mm/fault.c:1217 [<ffffffff8127e358>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331 [<ffffffff8126f514>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264 [<ffffffff8645bdf8>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986 [< inline >] SYSC_sigaltstack kernel/signal.c:3157 [<ffffffff8138600c>] SyS_sigaltstack+0x6c/0x90 kernel/signal.c:3155 [<ffffffff86459ab6>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 mmap: free gap 1000, correct 0 mm ffff8800603a4e00 mmap ffff88005fc794c0 seqnum 12 task_size 140737488351232 get_unmapped_area ffffffff811af470 mmap_base 140584500215808 mmap_legacy_base 47048170172416 highest_vm_end 140737437655040 pgd ffff88005fc20000 mm_users 2 mm_count 1 nr_ptes 25 nr_pmds 3 map_count 49 hiwater_rss 7 hiwater_vm 813a total_vm 913e locked_vm 2 pinned_vm 0 data_vm 902e exec_vm d1 stack_vm 2a start_code 400000 end_code 4ce986 start_data 6cee90 end_data 6d0d88 start_brk 934000 brk 957000 start_stack 7ffffcf5e660 arg_start 7ffffcf5feae arg_end 7ffffcf5feb6 env_start 7ffffcf5feb6 env_end 7ffffcf5fff0 binfmt ffffffff8797c260 flags cd core_state (null) ioctx_table (null) owner ffff88005d99df00 exe_file ffff880033321680 mmu_notifier_mm (null) flags: 0x0() ------------[ cut here ]------------ kernel BUG at mm/mmap.c:481! invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN Modules linked in: CPU: 1 PID: 9534 Comm: a.out Not tainted 4.5.0-rc1+ #292 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 task: ffff880031522f80 ti: ffff8800314f8000 task.ti: ffff8800314f8000 RIP: 0010:[<ffffffff816f922c>] [<ffffffff816f922c>] validate_mm+0x4fc/0x850 RSP: 0018:ffff8800314ffc60 EFLAGS: 00010286 RAX: 0000000000000001 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffffed000629ff22 RBP: ffff8800314ffcc8 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000003 R11: 1ffffffff12e43c4 R12: 0000000000000031 R13: 0000000000000000 R14: 00007ffffcfa4000 R15: dffffc0000000000 FS: 00007fdc59313700(0000) GS:ffff88003ed00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00000000204ec000 CR3: 000000005fc20000 CR4: 00000000000006e0 Stack: 0000000000486f70 ffff8800603a4e60 ffff8800603a4e00 0000003100000001 0000000000000000 0000000000041000 ffff88005fc78538 ffff88005fc78530 ffff880032870a60 0000000000000000 ffff880031e61e00 000000001f6a9000 Call Trace: [<ffffffff817034be>] expand_downwards+0x19e/0xb30 mm/mmap.c:2283 [<ffffffff81703ecb>] expand_stack+0x7b/0xe0 mm/mmap.c:2338 [<ffffffff8127df88>] __do_page_fault+0x6e8/0x960 arch/x86/mm/fault.c:1217 [<ffffffff8127e358>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331 [<ffffffff8126f514>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264 [<ffffffff8645bdf8>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986 [< inline >] SYSC_sigaltstack kernel/signal.c:3157 [<ffffffff8138600c>] SyS_sigaltstack+0x6c/0x90 kernel/signal.c:3155 [<ffffffff86459ab6>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 Code: 58 60 44 39 e3 74 73 e8 03 0f e7 ff 44 89 e2 89 de 48 c7 c7 a0 dc 5a 86 e8 e7 c3 f4 ff e8 ed 0e e7 ff 48 8b 7d a8 e8 24 00 fe ff <0f> 0b e8 dd 0e e7 ff 8b 55 b4 44 89 e6 48 c7 c7 40 dc 5a 86 e8 RIP [<ffffffff816f922c>] validate_mm+0x4fc/0x850 mm/mmap.c:481 RSP <ffff8800314ffc60> ---[ end trace 5282aed32b3391b4 ]--- And there seems to be some locking issue in validate_mm. On commit 92e963f50fc74041b5e9e744c330dca48e04f08d (Jan 24).
-- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>