Allele Security Alert
ASA-2019-00083
Identifier(s)
ASA-2019-00083, A-120025196, CVE-2019-1999
Title
Binder use-after-free of VMA via race between reclaim and munmap
Vendor(s)
The Linux foundation
Google
Product(s)
Linux
Android
Affected version(s)
Android Security Patch Level before February 2019
Fixed version(s)
Android Security Patch Level February 2019
Proof of concept
Yes
Description
There is a race condition between the direct reclaim path (enters binder through the binder_shrinker) and the munmap() syscall (enters binder through the ->close handler of binder_vm_ops).
Technical details
Coming from the munmap() syscall:
binder_vma_close() -> binder_alloc_vma_close() -> binder_alloc_set_vma() sets alloc->vma to NULL without taking any extra locks; binder_vma_close() is called from remove_vma() <- remove_vma_list() <- __do_munmap() <- __vm_munmap() <- sys_munmap() with only the mmap_sem held for writing.
Coming through the direct reclaim path:
binder_alloc_free_page() doesn’t hold the mmap_sem on entry. It contains the following code:
enum lru_status binder_alloc_free_page(struct list_head *item, struct list_lru_one *lru, spinlock_t *lock, void *cb_arg) { [...] alloc = page->alloc; if (!mutex_trylock(&alloc->mutex)) goto err_get_alloc_mutex_failed; if (!page->page_ptr) goto err_page_already_freed; index = page - alloc->pages; page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE; // unprotected pointer read! `vma` can immediately be freed vma = binder_alloc_get_vma(alloc); if (vma) { if (!mmget_not_zero(alloc->vma_vm_mm)) goto err_mmget; mm = alloc->vma_vm_mm; if (!down_write_trylock(&mm->mmap_sem)) goto err_down_write_mmap_sem_failed; // mmap_sem is held at this point, but the vma pointer was read // before and can be dangling } list_lru_isolate(lru, item); spin_unlock(lock); if (vma) { trace_binder_unmap_user_start(alloc, index); // dangling vma pointer passed to zap_page_range zap_page_range(vma, page_addr + alloc->user_buffer_offset, PAGE_SIZE); trace_binder_unmap_user_end(alloc, index); up_write(&mm->mmap_sem); mmput(mm); }
Credits
Jann Horn (Google Project Zero)
Reference(s)
1721 – Android: binder use-after-free of VMA via race between reclaim and munmap – project-zero – Monorail
https://bugs.chromium.org/p/project-zero/issues/detail?id=1721
Android Security Bulletin — February 2019
https://source.android.com/security/bulletin/2019-02-01.html
CVE-2019-1999
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1999
CVE-2019-1999
https://nvd.nist.gov/vuln/detail/CVE-2019-1999
If there is any error in this alert or you wish a comprehensive analysis, let us know.
Last modified: February 18, 2019