[PATCH] android: binder: fix dangling pointer comparison

ZhaoJunmin Zhao(Junmin) zhaojunmin at huawei.com
Sat Jun 18 09:19:01 UTC 2016



在 2016/6/16 6:39, Jann Horn 写道:
> On Thu, Jun 16, 2016 at 12:31 AM, Arve Hjønnevåg <arve at android.com> wrote:
>> On Wed, Jun 15, 2016 at 3:09 PM, Jann Horn <jannh at google.com> 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 at google.com>
>>> ---
>>>   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





More information about the devel mailing list