aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2012-02-01 18:29:13 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-08 17:14:13 -0500
commitbd1eff9741af27378b241b347041c724bb28e857 (patch)
tree47ec1db37ae76c3b8b4b2908cc6a5129191b5089 /drivers/staging
parentb0d017e80e9f4e6b37e699b9a944646e64deb473 (diff)
Staging: android: binder: Fix crashes when sharing a binder file between processes
Opening the binder driver and sharing the file returned with other processes (e.g. by calling fork) can crash the kernel. Prevent these crashes with the following changes: - Add a mutex to protect against two processes mmapping the same binder_proc. - After locking mmap_sem, check that the vma we want to access (still) points to the same mm_struct. - Use proc->tsk instead of current to get the files struct since this is where we get the rlimit from. Signed-off-by: Arve Hjønnevåg <arve@android.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/android/binder.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 48cf27cdb51a..f0b7e6605ab5 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -38,6 +38,7 @@
38 38
39static DEFINE_MUTEX(binder_lock); 39static DEFINE_MUTEX(binder_lock);
40static DEFINE_MUTEX(binder_deferred_lock); 40static DEFINE_MUTEX(binder_deferred_lock);
41static DEFINE_MUTEX(binder_mmap_lock);
41 42
42static HLIST_HEAD(binder_procs); 43static HLIST_HEAD(binder_procs);
43static HLIST_HEAD(binder_deferred_list); 44static HLIST_HEAD(binder_deferred_list);
@@ -632,6 +633,11 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
632 if (mm) { 633 if (mm) {
633 down_write(&mm->mmap_sem); 634 down_write(&mm->mmap_sem);
634 vma = proc->vma; 635 vma = proc->vma;
636 if (vma && mm != vma->vm_mm) {
637 pr_err("binder: %d: vma mm and task mm mismatch\n",
638 proc->pid);
639 vma = NULL;
640 }
635 } 641 }
636 642
637 if (allocate == 0) 643 if (allocate == 0)
@@ -2802,6 +2808,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
2802 } 2808 }
2803 vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; 2809 vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
2804 2810
2811 mutex_lock(&binder_mmap_lock);
2805 if (proc->buffer) { 2812 if (proc->buffer) {
2806 ret = -EBUSY; 2813 ret = -EBUSY;
2807 failure_string = "already mapped"; 2814 failure_string = "already mapped";
@@ -2816,6 +2823,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
2816 } 2823 }
2817 proc->buffer = area->addr; 2824 proc->buffer = area->addr;
2818 proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; 2825 proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;
2826 mutex_unlock(&binder_mmap_lock);
2819 2827
2820#ifdef CONFIG_CPU_CACHE_VIPT 2828#ifdef CONFIG_CPU_CACHE_VIPT
2821 if (cache_is_vipt_aliasing()) { 2829 if (cache_is_vipt_aliasing()) {
@@ -2848,7 +2856,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
2848 binder_insert_free_buffer(proc, buffer); 2856 binder_insert_free_buffer(proc, buffer);
2849 proc->free_async_space = proc->buffer_size / 2; 2857 proc->free_async_space = proc->buffer_size / 2;
2850 barrier(); 2858 barrier();
2851 proc->files = get_files_struct(current); 2859 proc->files = get_files_struct(proc->tsk);
2852 proc->vma = vma; 2860 proc->vma = vma;
2853 2861
2854 /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", 2862 /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
@@ -2859,10 +2867,12 @@ err_alloc_small_buf_failed:
2859 kfree(proc->pages); 2867 kfree(proc->pages);
2860 proc->pages = NULL; 2868 proc->pages = NULL;
2861err_alloc_pages_failed: 2869err_alloc_pages_failed:
2870 mutex_lock(&binder_mmap_lock);
2862 vfree(proc->buffer); 2871 vfree(proc->buffer);
2863 proc->buffer = NULL; 2872 proc->buffer = NULL;
2864err_get_vm_area_failed: 2873err_get_vm_area_failed:
2865err_already_mapped: 2874err_already_mapped:
2875 mutex_unlock(&binder_mmap_lock);
2866err_bad_arg: 2876err_bad_arg:
2867 printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", 2877 printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
2868 proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); 2878 proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);