Re: [PATCH] android: binder: fix dangling pointer comparison

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





在 2016/6/16 6:39, Jann Horn 写道:
On Thu, Jun 16, 2016 at 12:31 AM, Arve Hjønnevåg <arve@xxxxxxxxxxx> wrote:
On Wed, Jun 15, 2016 at 3:09 PM, Jann Horn <jannh@xxxxxxxxxx> wrote:
If /dev/binder is opened and the opener process then e.g. calls execve,
proc->vma_vm_mm will still point to the location of the now-freed
mm_struct. If the process then calls ioctl(binder_fd, ...), the dangling
proc->vma_vm_mm pointer will be compared to current->mm.

Let the binder take a reference to the mm_struct to avoid this.

In the current code, the BUG_ON() will never trigger; it's just there
in case someone changes the conditions under which get_task_mm() can
fail. Just WARN_ON() wouldn't work because of the mmput(), and I don't
want to complicate the code with a dead error handling code path.
(If the BUG_ON() is unacceptable, I'd replace the get_task_mm() with
a direct refcount increment or just omit the BUG_ON().)

This shouldn't cause additional memory usage in a well-behaved system
because you're not supposed to keep binder fds open over fork() or
execve().

Fixes: a906d6931f3ccaf7de805643190765ddd7378e27
Signed-off-by: Jann Horn <jannh@xxxxxxxxxx>
---
  drivers/android/binder.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 16288e7..4e9131d 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2962,7 +2962,8 @@ static int binder_open(struct inode *nodp, struct file *filp)
                 return -ENOMEM;
         get_task_struct(current);
         proc->tsk = current;
-       proc->vma_vm_mm = current->mm;
+       proc->vma_vm_mm = get_task_mm(current);
+       BUG_ON(proc->vma_vm_mm == NULL);
         INIT_LIST_HEAD(&proc->todo);
         init_waitqueue_head(&proc->wait);
         proc->default_priority = task_nice(current);
@@ -3167,6 +3168,7 @@ static void binder_deferred_release(struct binder_proc *proc)
                 vfree(proc->buffer);
         }

+       mmput(proc->vma_vm_mm);
         put_task_struct(proc->tsk);

         binder_debug(BINDER_DEBUG_OPEN_CLOSE,
--
2.8.0.rc3.226.g39d4020


Does this work? In the past, holding a reference to a task's mm while
the driver is open would prevent vma close which in turn would prevent
release of the fd.

Ah, right, mm_struct has two refcounters. I think that should be
atomic_inc(&current->mm->mm_count) / mmdrop() instead.

.

Hi Jann Horn:
  In android platform, the libbinder use the O_CLOEXEC flag:
  static int open_driver()
  {
    int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
    ...
    return fd;
  }
  So I think you don't need to consider the case:
  "If the process then calls ioctl(binder_fd, ...), the dangling
   proc->vma_vm_mm pointer will be compared to current->mm."

Thanks
Zhaojunmin



_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux