Commit 2a90957f authored by Arve Hjønnevåg's avatar Arve Hjønnevåg Committed by Greg Kroah-Hartman

Staging: android: binder: Fix use-after-free bug

binder_update_page_range could read freed memory if the vma of the
selected process was freed right before the check that the vma
belongs to the mm struct it just locked.

If the vm_mm pointer in that freed vma struct had also been rewritten
with a value that matched the locked mm struct, then the code would
proceed and possibly modify the freed vma.
Signed-off-by: default avatarArve Hjønnevåg <arve@android.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 06caa417
...@@ -288,6 +288,7 @@ struct binder_proc { ...@@ -288,6 +288,7 @@ struct binder_proc {
struct rb_root refs_by_node; struct rb_root refs_by_node;
int pid; int pid;
struct vm_area_struct *vma; struct vm_area_struct *vma;
struct mm_struct *vma_vm_mm;
struct task_struct *tsk; struct task_struct *tsk;
struct files_struct *files; struct files_struct *files;
struct hlist_node deferred_work_node; struct hlist_node deferred_work_node;
...@@ -633,7 +634,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, ...@@ -633,7 +634,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
if (mm) { if (mm) {
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
vma = proc->vma; vma = proc->vma;
if (vma && mm != vma->vm_mm) { if (vma && mm != proc->vma_vm_mm) {
pr_err("binder: %d: vma mm and task mm mismatch\n", pr_err("binder: %d: vma mm and task mm mismatch\n",
proc->pid); proc->pid);
vma = NULL; vma = NULL;
...@@ -2776,6 +2777,7 @@ static void binder_vma_close(struct vm_area_struct *vma) ...@@ -2776,6 +2777,7 @@ static void binder_vma_close(struct vm_area_struct *vma)
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot)); (unsigned long)pgprot_val(vma->vm_page_prot));
proc->vma = NULL; proc->vma = NULL;
proc->vma_vm_mm = NULL;
binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
} }
...@@ -2858,6 +2860,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -2858,6 +2860,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
barrier(); barrier();
proc->files = get_files_struct(proc->tsk); proc->files = get_files_struct(proc->tsk);
proc->vma = vma; proc->vma = vma;
proc->vma_vm_mm = vma->vm_mm;
/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment