Hi all, I've been running into this use-after-free in mprotect() with trinity on latest linus/master. It's relatively easy to reproduce, it takes anything from 1-6 hours and I've hit it some ~12 times in total (on different VMs with no preceding errors/taints other than OOM stack traces). The problem seems to be triggered when both calls to anon_vma_chain_alloc() in anon_vma_clone() fail -- it jumps to 'enomem_failure' and backs up through vma_merge() to mprotect_fixup() where it does the 'if (start != vma->vm_start)' and by this point 'vma' has apparently been freed. I'll attach what I think is the best example since everything (alloc + free + use-after-free) seems to happen in sys_mprotect() in the same process and it has a little bit of debugging info that I inserted in anon_vma_clone(), although I've also seen the alloc + free + use-after-free happen in 3 different processes, with alloc happening in clone() and free happening in exit(). my printks in anon_vma_clone() (at 'enomem_failure'), just before the crash: dst: ->vm_start=00007f77982d0000 ->vm_end =00007f77983d0000 ->vm_mm =ffff8800b8956900 ->vm_flags=100173 VM_READ|VM_WRITE VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC VM_GROWSDOWN VM_ACCOUNT ->vm_ops = (null) ->anon_vma=ffff8800b8668300 src: ->vm_start=00007f77983d0000 ->vm_end =00007f77985d1000 ->vm_mm =ffff8800b8956900 ->vm_flags=100173 ->vm_ops = (null) ->anon_vma=ffff8800b8668300 The stack trace where the use-after-free happens: [] mprotect_fixup+0x523/0x5a0 - mm/mprotect.c:312 if (start != vma->vm_start) { [] SyS_mprotect+0x397/0x790 - mm/mprotect.c:437 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); From KASAN (annotated with lines/line numbers): INFO: Allocated in __split_vma.isra.34+0x161/0x730 age=753 cpu=3 pid=16769 kmem_cache_alloc+0x1af/0x1e0 __split_vma.isra.34+0x161/0x730 - mm/mmap.c:2341 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); split_vma+0x7f/0xc0 - mm/mmap.c:2400 return __split_vma(mm, vma, addr, new_below); mprotect_fixup+0x3e8/0x5a0 - mm/mprotect.c:320 error = split_vma(mm, vma, end, 0); SyS_mprotect+0x397/0x790 INFO: Freed in vma_adjust+0x8e6/0x1390 age=32 cpu=3 pid=16769 kmem_cache_free+0x19a/0x1b0 vma_adjust+0x8e6/0x1390 - mm/mmap.c:797 kmem_cache_free(vm_area_cachep, next); vma_merge+0x7c7/0xc20 - mm/mmap.c:977 /* (cases 1, 6) */ mprotect_fixup+0x1b6/0x5a0 - mm/mprotect.c:305 *pprev = vma_merge(mm, *pprev, start, end, newflags, SyS_mprotect+0x397/0x790 So it *looks* to me like it all happens within one call to mprotect() and that this is the very general flow: SyS_mprotect() - mprotect_fixup() - split_vma() - split_vma.isra.34() - vma = kmem_cache_alloc() // succeeds - vma_merge() - vma_adjust() - kmem_cache_free(vma) - goto again; // ??? - anon_vma_clone() - kmem_cache_alloc() - return NULL - kmem_cache_alloc() - return NULL - return -ENOMEM - return -ENOMEM - return NULL - vma->vm_start // use-after-free I'll try adding some more printk()s and also see if I can narrow it down so reproducing is faster. Vegard