Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-09-12 Thread Greg KH
On Fri, Sep 07, 2018 at 12:34:19PM +0900, Minchan Kim wrote:
> Thanks, Martijn,
> 
> Greg, could you have a look to pick up?

Now queued up, thanks.

greg k-h


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-09-12 Thread Greg KH
On Fri, Sep 07, 2018 at 12:34:19PM +0900, Minchan Kim wrote:
> Thanks, Martijn,
> 
> Greg, could you have a look to pick up?

Now queued up, thanks.

greg k-h


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-09-06 Thread Minchan Kim
Thanks, Martijn,

Greg, could you have a look to pick up?

On Mon, Aug 27, 2018 at 03:35:24PM +0200, Martijn Coenen wrote:
> Thanks Minchan!
> 
> On Thu, Aug 23, 2018 at 7:29 AM, Minchan Kim  wrote:
> > Signed-off-by: Todd Kjos 
> > Signed-off-by: Minchan Kim 
> Reviewed-by: Martijn Coenen 
> 
> > ---
> >  drivers/android/binder_alloc.c | 43 +++---
> >  1 file changed, 35 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> > index 3f3b7b253445..64fd96eada31 100644
> > --- a/drivers/android/binder_alloc.c
> > +++ b/drivers/android/binder_alloc.c
> > @@ -332,6 +332,35 @@ static int binder_update_page_range(struct 
> > binder_alloc *alloc, int allocate,
> > return vma ? -ENOMEM : -ESRCH;
> >  }
> >
> > +
> > +static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
> > +   struct vm_area_struct *vma)
> > +{
> > +   if (vma)
> > +   alloc->vma_vm_mm = vma->vm_mm;
> > +   /*
> > +* If we see alloc->vma is not NULL, buffer data structures set up
> > +* completely. Look at smp_rmb side binder_alloc_get_vma.
> > +* We also want to guarantee new alloc->vma_vm_mm is always visible
> > +* if alloc->vma is set.
> > +*/
> > +   smp_wmb();
> > +   alloc->vma = vma;
> > +}
> > +
> > +static inline struct vm_area_struct *binder_alloc_get_vma(
> > +   struct binder_alloc *alloc)
> > +{
> > +   struct vm_area_struct *vma = NULL;
> > +
> > +   if (alloc->vma) {
> > +   /* Look at description in binder_alloc_set_vma */
> > +   smp_rmb();
> > +   vma = alloc->vma;
> > +   }
> > +   return vma;
> > +}
> > +
> >  static struct binder_buffer *binder_alloc_new_buf_locked(
> > struct binder_alloc *alloc,
> > size_t data_size,
> > @@ -348,7 +377,7 @@ static struct binder_buffer 
> > *binder_alloc_new_buf_locked(
> > size_t size, data_offsets_size;
> > int ret;
> >
> > -   if (alloc->vma == NULL) {
> > +   if (!binder_alloc_get_vma(alloc)) {
> > binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
> >"%d: binder_alloc_buf, no vma\n",
> >alloc->pid);
> > @@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc 
> > *alloc,
> > buffer->free = 1;
> > binder_insert_free_buffer(alloc, buffer);
> > alloc->free_async_space = alloc->buffer_size / 2;
> > -   barrier();
> > -   alloc->vma = vma;
> > -   alloc->vma_vm_mm = vma->vm_mm;
> > +   binder_alloc_set_vma(alloc, vma);
> > mmgrab(alloc->vma_vm_mm);
> >
> > return 0;
> > @@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct 
> > binder_alloc *alloc)
> > int buffers, page_count;
> > struct binder_buffer *buffer;
> >
> > -   BUG_ON(alloc->vma);
> > -
> > buffers = 0;
> > mutex_lock(>mutex);
> > +   BUG_ON(alloc->vma);
> > +
> > while ((n = rb_first(>allocated_buffers))) {
> > buffer = rb_entry(n, struct binder_buffer, rb_node);
> >
> > @@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct 
> > binder_alloc *alloc)
> >   */
> >  void binder_alloc_vma_close(struct binder_alloc *alloc)
> >  {
> > -   WRITE_ONCE(alloc->vma, NULL);
> > +   binder_alloc_set_vma(alloc, NULL);
> >  }
> >
> >  /**
> > @@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head 
> > *item,
> >
> > index = page - alloc->pages;
> > page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
> > -   vma = alloc->vma;
> > +   vma = binder_alloc_get_vma(alloc);
> > if (vma) {
> > if (!mmget_not_zero(alloc->vma_vm_mm))
> > goto err_mmget;
> > --
> > 2.18.0.1017.ga543ac7ca45-goog
> >
> >
> >
> >


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-09-06 Thread Minchan Kim
Thanks, Martijn,

Greg, could you have a look to pick up?

On Mon, Aug 27, 2018 at 03:35:24PM +0200, Martijn Coenen wrote:
> Thanks Minchan!
> 
> On Thu, Aug 23, 2018 at 7:29 AM, Minchan Kim  wrote:
> > Signed-off-by: Todd Kjos 
> > Signed-off-by: Minchan Kim 
> Reviewed-by: Martijn Coenen 
> 
> > ---
> >  drivers/android/binder_alloc.c | 43 +++---
> >  1 file changed, 35 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> > index 3f3b7b253445..64fd96eada31 100644
> > --- a/drivers/android/binder_alloc.c
> > +++ b/drivers/android/binder_alloc.c
> > @@ -332,6 +332,35 @@ static int binder_update_page_range(struct 
> > binder_alloc *alloc, int allocate,
> > return vma ? -ENOMEM : -ESRCH;
> >  }
> >
> > +
> > +static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
> > +   struct vm_area_struct *vma)
> > +{
> > +   if (vma)
> > +   alloc->vma_vm_mm = vma->vm_mm;
> > +   /*
> > +* If we see alloc->vma is not NULL, buffer data structures set up
> > +* completely. Look at smp_rmb side binder_alloc_get_vma.
> > +* We also want to guarantee new alloc->vma_vm_mm is always visible
> > +* if alloc->vma is set.
> > +*/
> > +   smp_wmb();
> > +   alloc->vma = vma;
> > +}
> > +
> > +static inline struct vm_area_struct *binder_alloc_get_vma(
> > +   struct binder_alloc *alloc)
> > +{
> > +   struct vm_area_struct *vma = NULL;
> > +
> > +   if (alloc->vma) {
> > +   /* Look at description in binder_alloc_set_vma */
> > +   smp_rmb();
> > +   vma = alloc->vma;
> > +   }
> > +   return vma;
> > +}
> > +
> >  static struct binder_buffer *binder_alloc_new_buf_locked(
> > struct binder_alloc *alloc,
> > size_t data_size,
> > @@ -348,7 +377,7 @@ static struct binder_buffer 
> > *binder_alloc_new_buf_locked(
> > size_t size, data_offsets_size;
> > int ret;
> >
> > -   if (alloc->vma == NULL) {
> > +   if (!binder_alloc_get_vma(alloc)) {
> > binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
> >"%d: binder_alloc_buf, no vma\n",
> >alloc->pid);
> > @@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc 
> > *alloc,
> > buffer->free = 1;
> > binder_insert_free_buffer(alloc, buffer);
> > alloc->free_async_space = alloc->buffer_size / 2;
> > -   barrier();
> > -   alloc->vma = vma;
> > -   alloc->vma_vm_mm = vma->vm_mm;
> > +   binder_alloc_set_vma(alloc, vma);
> > mmgrab(alloc->vma_vm_mm);
> >
> > return 0;
> > @@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct 
> > binder_alloc *alloc)
> > int buffers, page_count;
> > struct binder_buffer *buffer;
> >
> > -   BUG_ON(alloc->vma);
> > -
> > buffers = 0;
> > mutex_lock(>mutex);
> > +   BUG_ON(alloc->vma);
> > +
> > while ((n = rb_first(>allocated_buffers))) {
> > buffer = rb_entry(n, struct binder_buffer, rb_node);
> >
> > @@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct 
> > binder_alloc *alloc)
> >   */
> >  void binder_alloc_vma_close(struct binder_alloc *alloc)
> >  {
> > -   WRITE_ONCE(alloc->vma, NULL);
> > +   binder_alloc_set_vma(alloc, NULL);
> >  }
> >
> >  /**
> > @@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head 
> > *item,
> >
> > index = page - alloc->pages;
> > page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
> > -   vma = alloc->vma;
> > +   vma = binder_alloc_get_vma(alloc);
> > if (vma) {
> > if (!mmget_not_zero(alloc->vma_vm_mm))
> > goto err_mmget;
> > --
> > 2.18.0.1017.ga543ac7ca45-goog
> >
> >
> >
> >


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-27 Thread Martijn Coenen
Thanks Minchan!

On Thu, Aug 23, 2018 at 7:29 AM, Minchan Kim  wrote:
> Signed-off-by: Todd Kjos 
> Signed-off-by: Minchan Kim 
Reviewed-by: Martijn Coenen 

> ---
>  drivers/android/binder_alloc.c | 43 +++---
>  1 file changed, 35 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> index 3f3b7b253445..64fd96eada31 100644
> --- a/drivers/android/binder_alloc.c
> +++ b/drivers/android/binder_alloc.c
> @@ -332,6 +332,35 @@ static int binder_update_page_range(struct binder_alloc 
> *alloc, int allocate,
> return vma ? -ENOMEM : -ESRCH;
>  }
>
> +
> +static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
> +   struct vm_area_struct *vma)
> +{
> +   if (vma)
> +   alloc->vma_vm_mm = vma->vm_mm;
> +   /*
> +* If we see alloc->vma is not NULL, buffer data structures set up
> +* completely. Look at smp_rmb side binder_alloc_get_vma.
> +* We also want to guarantee new alloc->vma_vm_mm is always visible
> +* if alloc->vma is set.
> +*/
> +   smp_wmb();
> +   alloc->vma = vma;
> +}
> +
> +static inline struct vm_area_struct *binder_alloc_get_vma(
> +   struct binder_alloc *alloc)
> +{
> +   struct vm_area_struct *vma = NULL;
> +
> +   if (alloc->vma) {
> +   /* Look at description in binder_alloc_set_vma */
> +   smp_rmb();
> +   vma = alloc->vma;
> +   }
> +   return vma;
> +}
> +
>  static struct binder_buffer *binder_alloc_new_buf_locked(
> struct binder_alloc *alloc,
> size_t data_size,
> @@ -348,7 +377,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
> size_t size, data_offsets_size;
> int ret;
>
> -   if (alloc->vma == NULL) {
> +   if (!binder_alloc_get_vma(alloc)) {
> binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
>"%d: binder_alloc_buf, no vma\n",
>alloc->pid);
> @@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
> buffer->free = 1;
> binder_insert_free_buffer(alloc, buffer);
> alloc->free_async_space = alloc->buffer_size / 2;
> -   barrier();
> -   alloc->vma = vma;
> -   alloc->vma_vm_mm = vma->vm_mm;
> +   binder_alloc_set_vma(alloc, vma);
> mmgrab(alloc->vma_vm_mm);
>
> return 0;
> @@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct binder_alloc 
> *alloc)
> int buffers, page_count;
> struct binder_buffer *buffer;
>
> -   BUG_ON(alloc->vma);
> -
> buffers = 0;
> mutex_lock(>mutex);
> +   BUG_ON(alloc->vma);
> +
> while ((n = rb_first(>allocated_buffers))) {
> buffer = rb_entry(n, struct binder_buffer, rb_node);
>
> @@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc 
> *alloc)
>   */
>  void binder_alloc_vma_close(struct binder_alloc *alloc)
>  {
> -   WRITE_ONCE(alloc->vma, NULL);
> +   binder_alloc_set_vma(alloc, NULL);
>  }
>
>  /**
> @@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head 
> *item,
>
> index = page - alloc->pages;
> page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
> -   vma = alloc->vma;
> +   vma = binder_alloc_get_vma(alloc);
> if (vma) {
> if (!mmget_not_zero(alloc->vma_vm_mm))
> goto err_mmget;
> --
> 2.18.0.1017.ga543ac7ca45-goog
>
>
>
>


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-27 Thread Martijn Coenen
Thanks Minchan!

On Thu, Aug 23, 2018 at 7:29 AM, Minchan Kim  wrote:
> Signed-off-by: Todd Kjos 
> Signed-off-by: Minchan Kim 
Reviewed-by: Martijn Coenen 

> ---
>  drivers/android/binder_alloc.c | 43 +++---
>  1 file changed, 35 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
> index 3f3b7b253445..64fd96eada31 100644
> --- a/drivers/android/binder_alloc.c
> +++ b/drivers/android/binder_alloc.c
> @@ -332,6 +332,35 @@ static int binder_update_page_range(struct binder_alloc 
> *alloc, int allocate,
> return vma ? -ENOMEM : -ESRCH;
>  }
>
> +
> +static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
> +   struct vm_area_struct *vma)
> +{
> +   if (vma)
> +   alloc->vma_vm_mm = vma->vm_mm;
> +   /*
> +* If we see alloc->vma is not NULL, buffer data structures set up
> +* completely. Look at smp_rmb side binder_alloc_get_vma.
> +* We also want to guarantee new alloc->vma_vm_mm is always visible
> +* if alloc->vma is set.
> +*/
> +   smp_wmb();
> +   alloc->vma = vma;
> +}
> +
> +static inline struct vm_area_struct *binder_alloc_get_vma(
> +   struct binder_alloc *alloc)
> +{
> +   struct vm_area_struct *vma = NULL;
> +
> +   if (alloc->vma) {
> +   /* Look at description in binder_alloc_set_vma */
> +   smp_rmb();
> +   vma = alloc->vma;
> +   }
> +   return vma;
> +}
> +
>  static struct binder_buffer *binder_alloc_new_buf_locked(
> struct binder_alloc *alloc,
> size_t data_size,
> @@ -348,7 +377,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
> size_t size, data_offsets_size;
> int ret;
>
> -   if (alloc->vma == NULL) {
> +   if (!binder_alloc_get_vma(alloc)) {
> binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
>"%d: binder_alloc_buf, no vma\n",
>alloc->pid);
> @@ -723,9 +752,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
> buffer->free = 1;
> binder_insert_free_buffer(alloc, buffer);
> alloc->free_async_space = alloc->buffer_size / 2;
> -   barrier();
> -   alloc->vma = vma;
> -   alloc->vma_vm_mm = vma->vm_mm;
> +   binder_alloc_set_vma(alloc, vma);
> mmgrab(alloc->vma_vm_mm);
>
> return 0;
> @@ -754,10 +781,10 @@ void binder_alloc_deferred_release(struct binder_alloc 
> *alloc)
> int buffers, page_count;
> struct binder_buffer *buffer;
>
> -   BUG_ON(alloc->vma);
> -
> buffers = 0;
> mutex_lock(>mutex);
> +   BUG_ON(alloc->vma);
> +
> while ((n = rb_first(>allocated_buffers))) {
> buffer = rb_entry(n, struct binder_buffer, rb_node);
>
> @@ -900,7 +927,7 @@ int binder_alloc_get_allocated_count(struct binder_alloc 
> *alloc)
>   */
>  void binder_alloc_vma_close(struct binder_alloc *alloc)
>  {
> -   WRITE_ONCE(alloc->vma, NULL);
> +   binder_alloc_set_vma(alloc, NULL);
>  }
>
>  /**
> @@ -935,7 +962,7 @@ enum lru_status binder_alloc_free_page(struct list_head 
> *item,
>
> index = page - alloc->pages;
> page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
> -   vma = alloc->vma;
> +   vma = binder_alloc_get_vma(alloc);
> if (vma) {
> if (!mmget_not_zero(alloc->vma_vm_mm))
> goto err_mmget;
> --
> 2.18.0.1017.ga543ac7ca45-goog
>
>
>
>


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-23 Thread Minchan Kim
On Thu, Aug 23, 2018 at 07:03:34PM +0900, Dae R. Jeong wrote:
> > Could you test this patch? I found that bug a month ago but didn't submit
> > yet.
> 
> I don't have a reproducer now. I manually analzed a root cause of the
> crash using a fuzzer's log. The log reported a race on 'alloc->vma'.
> Because I don't have a reproducer, I can't test the patch. I'm sorry.

Ah, Okay. Anyway, one of author for the patch is already binder maintainer.
If other maintainers don't object it, let's fix the race in this chance.

Thanks.


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-23 Thread Minchan Kim
On Thu, Aug 23, 2018 at 07:03:34PM +0900, Dae R. Jeong wrote:
> > Could you test this patch? I found that bug a month ago but didn't submit
> > yet.
> 
> I don't have a reproducer now. I manually analzed a root cause of the
> crash using a fuzzer's log. The log reported a race on 'alloc->vma'.
> Because I don't have a reproducer, I can't test the patch. I'm sorry.

Ah, Okay. Anyway, one of author for the patch is already binder maintainer.
If other maintainers don't object it, let's fix the race in this chance.

Thanks.


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-23 Thread Dae R. Jeong
> Could you test this patch? I found that bug a month ago but didn't submit
> yet.

I don't have a reproducer now. I manually analzed a root cause of the
crash using a fuzzer's log. The log reported a race on 'alloc->vma'.
Because I don't have a reproducer, I can't test the patch. I'm sorry.


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-23 Thread Dae R. Jeong
> Could you test this patch? I found that bug a month ago but didn't submit
> yet.

I don't have a reproducer now. I manually analzed a root cause of the
crash using a fuzzer's log. The log reported a race on 'alloc->vma'.
Because I don't have a reproducer, I can't test the patch. I'm sorry.


Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-22 Thread Minchan Kim
Hi,

On Wed, Aug 22, 2018 at 03:07:04PM +0900, Dae R. Jeong wrote:
> Reporting the crash: KASAN: null-ptr-deref Write in binder_update_page_range
> 
> This crash has been found in v4.18-rc3 using RaceFuzzer (a modified
> version of Syzkaller), which we describe more at the end of this
> report.
> 
> Our analysis shows that the race occurs when invoking two syscalls
> concurrently, mmap$binder() and ioctl$BINDER_WRITE_READ. More
> specifically, since two code lines `alloc->vma = vma;` and
> `alloc->vma_vm_mm = vma->vm_mm;` in binder_alloc_mmap_handler() is not
> an atomic operation during mmap$binder() syscall, there is a time
> window that `alloc->vma` is assigned but `alloc->vma_vm_mm` isn't
> assigned. It causes the null pointer dereference in
> binder_alloc_new_buf_locked() since it checks whether `alloc->vma` is
> NULL, but it doesn't check that `alloc->vma_vm_mm` is NULL. More
> details on the thread interleaving and the crash log are follows.
> 
> 
> Thread interleaving:
> CPU0 (binder_alloc_mmap_handler)  CPU1 
> (binder_alloc_new_buf_locked)
> = =
> // drivers/android/binder_alloc.c
> // #L718 (v4.18-rc3)
> alloc->vma = vma;
>   // 
> drivers/android/binder_alloc.c
>   // #L346 (v4.18-rc3)
>   if (alloc->vma == NULL) {
>   ...
>   // alloc->vma is not NULL 
> at this point
>   return ERR_PTR(-ESRCH);
>   }
>   ...
>   // #L438
>   binder_update_page_range(alloc, 
> 0,
>   (void 
> *)PAGE_ALIGN((uintptr_t)buffer->data),
>   end_page_addr);
> 
>   // In 
> binder_update_page_range() #L218
>   // But still alloc->vma_vm_mm 
> is NULL here
>   if (need_mm && 
> mmget_not_zero(alloc->vma_vm_mm))
> alloc->vma_vm_mm = vma->vm_mm;
> 
> 
> Crash Log:
> ==
> BUG: KASAN: null-ptr-deref in __atomic_add_unless 
> include/asm-generic/atomic-instrumented.h:89 [inline]
> BUG: KASAN: null-ptr-deref in atomic_add_unless include/linux/atomic.h:533 
> [inline]
> BUG: KASAN: null-ptr-deref in mmget_not_zero include/linux/sched/mm.h:75 
> [inline]
> BUG: KASAN: null-ptr-deref in binder_update_page_range+0xece/0x18e0 
> drivers/android/binder_alloc.c:218
> Write of size 4 at addr 0058 by task syz-executor0/11184
> 
> CPU: 1 PID: 11184 Comm: syz-executor0 Not tainted 4.18.0-rc3 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
> Call Trace:
>  __dump_stack lib/dump_stack.c:77 [inline]
>  dump_stack+0x16e/0x22c lib/dump_stack.c:113
>  kasan_report_error mm/kasan/report.c:352 [inline]
>  kasan_report+0x163/0x380 mm/kasan/report.c:412
>  check_memory_region_inline mm/kasan/kasan.c:260 [inline]
>  check_memory_region+0x140/0x1a0 mm/kasan/kasan.c:267
>  kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278
>  __atomic_add_unless include/asm-generic/atomic-instrumented.h:89 [inline]
>  atomic_add_unless include/linux/atomic.h:533 [inline]
>  mmget_not_zero include/linux/sched/mm.h:75 [inline]
>  binder_update_page_range+0xece/0x18e0 drivers/android/binder_alloc.c:218
>  binder_alloc_new_buf_locked drivers/android/binder_alloc.c:443 [inline]
>  binder_alloc_new_buf+0x467/0xc30 drivers/android/binder_alloc.c:513
>  binder_transaction+0x125b/0x4fb0 drivers/android/binder.c:2957
>  binder_thread_write+0xc08/0x2770 drivers/android/binder.c:3528
>  binder_ioctl_write_read.isra.39+0x24f/0x8e0 drivers/android/binder.c:4456
>  binder_ioctl+0xa86/0xf34 drivers/android/binder.c:4596
>  vfs_ioctl fs/ioctl.c:46 [inline]
>  do_vfs_ioctl+0x154/0xd40 fs/ioctl.c:686
>  ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
>  __do_sys_ioctl fs/ioctl.c:708 [inline]
>  __se_sys_ioctl fs/ioctl.c:706 [inline]
>  __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
>  do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
>  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> RIP: 0033:0x456469
> Code: 1d ba fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 
> 8

Re: KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-22 Thread Minchan Kim
Hi,

On Wed, Aug 22, 2018 at 03:07:04PM +0900, Dae R. Jeong wrote:
> Reporting the crash: KASAN: null-ptr-deref Write in binder_update_page_range
> 
> This crash has been found in v4.18-rc3 using RaceFuzzer (a modified
> version of Syzkaller), which we describe more at the end of this
> report.
> 
> Our analysis shows that the race occurs when invoking two syscalls
> concurrently, mmap$binder() and ioctl$BINDER_WRITE_READ. More
> specifically, since two code lines `alloc->vma = vma;` and
> `alloc->vma_vm_mm = vma->vm_mm;` in binder_alloc_mmap_handler() is not
> an atomic operation during mmap$binder() syscall, there is a time
> window that `alloc->vma` is assigned but `alloc->vma_vm_mm` isn't
> assigned. It causes the null pointer dereference in
> binder_alloc_new_buf_locked() since it checks whether `alloc->vma` is
> NULL, but it doesn't check that `alloc->vma_vm_mm` is NULL. More
> details on the thread interleaving and the crash log are follows.
> 
> 
> Thread interleaving:
> CPU0 (binder_alloc_mmap_handler)  CPU1 
> (binder_alloc_new_buf_locked)
> = =
> // drivers/android/binder_alloc.c
> // #L718 (v4.18-rc3)
> alloc->vma = vma;
>   // 
> drivers/android/binder_alloc.c
>   // #L346 (v4.18-rc3)
>   if (alloc->vma == NULL) {
>   ...
>   // alloc->vma is not NULL 
> at this point
>   return ERR_PTR(-ESRCH);
>   }
>   ...
>   // #L438
>   binder_update_page_range(alloc, 
> 0,
>   (void 
> *)PAGE_ALIGN((uintptr_t)buffer->data),
>   end_page_addr);
> 
>   // In 
> binder_update_page_range() #L218
>   // But still alloc->vma_vm_mm 
> is NULL here
>   if (need_mm && 
> mmget_not_zero(alloc->vma_vm_mm))
> alloc->vma_vm_mm = vma->vm_mm;
> 
> 
> Crash Log:
> ==
> BUG: KASAN: null-ptr-deref in __atomic_add_unless 
> include/asm-generic/atomic-instrumented.h:89 [inline]
> BUG: KASAN: null-ptr-deref in atomic_add_unless include/linux/atomic.h:533 
> [inline]
> BUG: KASAN: null-ptr-deref in mmget_not_zero include/linux/sched/mm.h:75 
> [inline]
> BUG: KASAN: null-ptr-deref in binder_update_page_range+0xece/0x18e0 
> drivers/android/binder_alloc.c:218
> Write of size 4 at addr 0058 by task syz-executor0/11184
> 
> CPU: 1 PID: 11184 Comm: syz-executor0 Not tainted 4.18.0-rc3 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
> rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
> Call Trace:
>  __dump_stack lib/dump_stack.c:77 [inline]
>  dump_stack+0x16e/0x22c lib/dump_stack.c:113
>  kasan_report_error mm/kasan/report.c:352 [inline]
>  kasan_report+0x163/0x380 mm/kasan/report.c:412
>  check_memory_region_inline mm/kasan/kasan.c:260 [inline]
>  check_memory_region+0x140/0x1a0 mm/kasan/kasan.c:267
>  kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278
>  __atomic_add_unless include/asm-generic/atomic-instrumented.h:89 [inline]
>  atomic_add_unless include/linux/atomic.h:533 [inline]
>  mmget_not_zero include/linux/sched/mm.h:75 [inline]
>  binder_update_page_range+0xece/0x18e0 drivers/android/binder_alloc.c:218
>  binder_alloc_new_buf_locked drivers/android/binder_alloc.c:443 [inline]
>  binder_alloc_new_buf+0x467/0xc30 drivers/android/binder_alloc.c:513
>  binder_transaction+0x125b/0x4fb0 drivers/android/binder.c:2957
>  binder_thread_write+0xc08/0x2770 drivers/android/binder.c:3528
>  binder_ioctl_write_read.isra.39+0x24f/0x8e0 drivers/android/binder.c:4456
>  binder_ioctl+0xa86/0xf34 drivers/android/binder.c:4596
>  vfs_ioctl fs/ioctl.c:46 [inline]
>  do_vfs_ioctl+0x154/0xd40 fs/ioctl.c:686
>  ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
>  __do_sys_ioctl fs/ioctl.c:708 [inline]
>  __se_sys_ioctl fs/ioctl.c:706 [inline]
>  __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
>  do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
>  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> RIP: 0033:0x456469
> Code: 1d ba fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 
> 8

KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-22 Thread Dae R. Jeong
Reporting the crash: KASAN: null-ptr-deref Write in binder_update_page_range

This crash has been found in v4.18-rc3 using RaceFuzzer (a modified
version of Syzkaller), which we describe more at the end of this
report.

Our analysis shows that the race occurs when invoking two syscalls
concurrently, mmap$binder() and ioctl$BINDER_WRITE_READ. More
specifically, since two code lines `alloc->vma = vma;` and
`alloc->vma_vm_mm = vma->vm_mm;` in binder_alloc_mmap_handler() is not
an atomic operation during mmap$binder() syscall, there is a time
window that `alloc->vma` is assigned but `alloc->vma_vm_mm` isn't
assigned. It causes the null pointer dereference in
binder_alloc_new_buf_locked() since it checks whether `alloc->vma` is
NULL, but it doesn't check that `alloc->vma_vm_mm` is NULL. More
details on the thread interleaving and the crash log are follows.


Thread interleaving:
CPU0 (binder_alloc_mmap_handler)  CPU1 (binder_alloc_new_buf_locked)
= =
// drivers/android/binder_alloc.c
// #L718 (v4.18-rc3)
alloc->vma = vma;
  // drivers/android/binder_alloc.c
  // #L346 (v4.18-rc3)
  if (alloc->vma == NULL) {
  ...
  // alloc->vma is not NULL at 
this point
  return ERR_PTR(-ESRCH);
  }
  ...
  // #L438
  binder_update_page_range(alloc, 0,
  (void 
*)PAGE_ALIGN((uintptr_t)buffer->data),
  end_page_addr);

  // In binder_update_page_range() 
#L218
  // But still alloc->vma_vm_mm is 
NULL here
  if (need_mm && 
mmget_not_zero(alloc->vma_vm_mm))
alloc->vma_vm_mm = vma->vm_mm;


Crash Log:
==
BUG: KASAN: null-ptr-deref in __atomic_add_unless 
include/asm-generic/atomic-instrumented.h:89 [inline]
BUG: KASAN: null-ptr-deref in atomic_add_unless include/linux/atomic.h:533 
[inline]
BUG: KASAN: null-ptr-deref in mmget_not_zero include/linux/sched/mm.h:75 
[inline]
BUG: KASAN: null-ptr-deref in binder_update_page_range+0xece/0x18e0 
drivers/android/binder_alloc.c:218
Write of size 4 at addr 0058 by task syz-executor0/11184

CPU: 1 PID: 11184 Comm: syz-executor0 Not tainted 4.18.0-rc3 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x16e/0x22c lib/dump_stack.c:113
 kasan_report_error mm/kasan/report.c:352 [inline]
 kasan_report+0x163/0x380 mm/kasan/report.c:412
 check_memory_region_inline mm/kasan/kasan.c:260 [inline]
 check_memory_region+0x140/0x1a0 mm/kasan/kasan.c:267
 kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278
 __atomic_add_unless include/asm-generic/atomic-instrumented.h:89 [inline]
 atomic_add_unless include/linux/atomic.h:533 [inline]
 mmget_not_zero include/linux/sched/mm.h:75 [inline]
 binder_update_page_range+0xece/0x18e0 drivers/android/binder_alloc.c:218
 binder_alloc_new_buf_locked drivers/android/binder_alloc.c:443 [inline]
 binder_alloc_new_buf+0x467/0xc30 drivers/android/binder_alloc.c:513
 binder_transaction+0x125b/0x4fb0 drivers/android/binder.c:2957
 binder_thread_write+0xc08/0x2770 drivers/android/binder.c:3528
 binder_ioctl_write_read.isra.39+0x24f/0x8e0 drivers/android/binder.c:4456
 binder_ioctl+0xa86/0xf34 drivers/android/binder.c:4596
 vfs_ioctl fs/ioctl.c:46 [inline]
 do_vfs_ioctl+0x154/0xd40 fs/ioctl.c:686
 ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
 __do_sys_ioctl fs/ioctl.c:708 [inline]
 __se_sys_ioctl fs/ioctl.c:706 [inline]
 __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
 do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x456469
Code: 1d ba fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 
89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 
eb b9 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:7f575f268b28 EFLAGS: 0246 ORIG_RAX: 0010
RAX: ffda RBX: 0072bfa0 RCX: 00456469
RDX: 23c0 RSI: c0306201 RDI: 0016
RBP: 01a2 R08:  R09: 
R10:  R11: 0246 R12: 7f575f2696d4
R13:  R14: 006f77d0 R15: 

KASAN: null-ptr-deref Write in binder_update_page_range

2018-08-22 Thread Dae R. Jeong
Reporting the crash: KASAN: null-ptr-deref Write in binder_update_page_range

This crash has been found in v4.18-rc3 using RaceFuzzer (a modified
version of Syzkaller), which we describe more at the end of this
report.

Our analysis shows that the race occurs when invoking two syscalls
concurrently, mmap$binder() and ioctl$BINDER_WRITE_READ. More
specifically, since two code lines `alloc->vma = vma;` and
`alloc->vma_vm_mm = vma->vm_mm;` in binder_alloc_mmap_handler() is not
an atomic operation during mmap$binder() syscall, there is a time
window that `alloc->vma` is assigned but `alloc->vma_vm_mm` isn't
assigned. It causes the null pointer dereference in
binder_alloc_new_buf_locked() since it checks whether `alloc->vma` is
NULL, but it doesn't check that `alloc->vma_vm_mm` is NULL. More
details on the thread interleaving and the crash log are follows.


Thread interleaving:
CPU0 (binder_alloc_mmap_handler)  CPU1 (binder_alloc_new_buf_locked)
= =
// drivers/android/binder_alloc.c
// #L718 (v4.18-rc3)
alloc->vma = vma;
  // drivers/android/binder_alloc.c
  // #L346 (v4.18-rc3)
  if (alloc->vma == NULL) {
  ...
  // alloc->vma is not NULL at 
this point
  return ERR_PTR(-ESRCH);
  }
  ...
  // #L438
  binder_update_page_range(alloc, 0,
  (void 
*)PAGE_ALIGN((uintptr_t)buffer->data),
  end_page_addr);

  // In binder_update_page_range() 
#L218
  // But still alloc->vma_vm_mm is 
NULL here
  if (need_mm && 
mmget_not_zero(alloc->vma_vm_mm))
alloc->vma_vm_mm = vma->vm_mm;


Crash Log:
==
BUG: KASAN: null-ptr-deref in __atomic_add_unless 
include/asm-generic/atomic-instrumented.h:89 [inline]
BUG: KASAN: null-ptr-deref in atomic_add_unless include/linux/atomic.h:533 
[inline]
BUG: KASAN: null-ptr-deref in mmget_not_zero include/linux/sched/mm.h:75 
[inline]
BUG: KASAN: null-ptr-deref in binder_update_page_range+0xece/0x18e0 
drivers/android/binder_alloc.c:218
Write of size 4 at addr 0058 by task syz-executor0/11184

CPU: 1 PID: 11184 Comm: syz-executor0 Not tainted 4.18.0-rc3 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x16e/0x22c lib/dump_stack.c:113
 kasan_report_error mm/kasan/report.c:352 [inline]
 kasan_report+0x163/0x380 mm/kasan/report.c:412
 check_memory_region_inline mm/kasan/kasan.c:260 [inline]
 check_memory_region+0x140/0x1a0 mm/kasan/kasan.c:267
 kasan_check_write+0x14/0x20 mm/kasan/kasan.c:278
 __atomic_add_unless include/asm-generic/atomic-instrumented.h:89 [inline]
 atomic_add_unless include/linux/atomic.h:533 [inline]
 mmget_not_zero include/linux/sched/mm.h:75 [inline]
 binder_update_page_range+0xece/0x18e0 drivers/android/binder_alloc.c:218
 binder_alloc_new_buf_locked drivers/android/binder_alloc.c:443 [inline]
 binder_alloc_new_buf+0x467/0xc30 drivers/android/binder_alloc.c:513
 binder_transaction+0x125b/0x4fb0 drivers/android/binder.c:2957
 binder_thread_write+0xc08/0x2770 drivers/android/binder.c:3528
 binder_ioctl_write_read.isra.39+0x24f/0x8e0 drivers/android/binder.c:4456
 binder_ioctl+0xa86/0xf34 drivers/android/binder.c:4596
 vfs_ioctl fs/ioctl.c:46 [inline]
 do_vfs_ioctl+0x154/0xd40 fs/ioctl.c:686
 ksys_ioctl+0x94/0xb0 fs/ioctl.c:701
 __do_sys_ioctl fs/ioctl.c:708 [inline]
 __se_sys_ioctl fs/ioctl.c:706 [inline]
 __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:706
 do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x456469
Code: 1d ba fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 
89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 
eb b9 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:7f575f268b28 EFLAGS: 0246 ORIG_RAX: 0010
RAX: ffda RBX: 0072bfa0 RCX: 00456469
RDX: 23c0 RSI: c0306201 RDI: 0016
RBP: 01a2 R08:  R09: 
R10:  R11: 0246 R12: 7f575f2696d4
R13:  R14: 006f77d0 R15: