Commit 0a3ffab93fe52530602fe47cd74802cffdb19c05

Authored by Arve Hjønnevåg
Committed by Greg Kroah-Hartman
1 parent 07d9a38068

ANDROID: binder: Add strong ref checks

Prevent using a binder_ref with only weak references where a strong
reference is required.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Martijn Coenen <maco@android.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 21 additions and 9 deletions Side-by-side Diff

drivers/android/binder.c
... ... @@ -1002,7 +1002,7 @@
1002 1002  
1003 1003  
1004 1004 static struct binder_ref *binder_get_ref(struct binder_proc *proc,
1005   - uint32_t desc)
  1005 + u32 desc, bool need_strong_ref)
1006 1006 {
1007 1007 struct rb_node *n = proc->refs_by_desc.rb_node;
1008 1008 struct binder_ref *ref;
1009 1009  
1010 1010  
1011 1011  
... ... @@ -1010,12 +1010,16 @@
1010 1010 while (n) {
1011 1011 ref = rb_entry(n, struct binder_ref, rb_node_desc);
1012 1012  
1013   - if (desc < ref->desc)
  1013 + if (desc < ref->desc) {
1014 1014 n = n->rb_left;
1015   - else if (desc > ref->desc)
  1015 + } else if (desc > ref->desc) {
1016 1016 n = n->rb_right;
1017   - else
  1017 + } else if (need_strong_ref && !ref->strong) {
  1018 + binder_user_error("tried to use weak ref as strong ref\n");
  1019 + return NULL;
  1020 + } else {
1018 1021 return ref;
  1022 + }
1019 1023 }
1020 1024 return NULL;
1021 1025 }
1022 1026  
... ... @@ -1285,8 +1289,11 @@
1285 1289 } break;
1286 1290 case BINDER_TYPE_HANDLE:
1287 1291 case BINDER_TYPE_WEAK_HANDLE: {
1288   - struct binder_ref *ref = binder_get_ref(proc, fp->handle);
  1292 + struct binder_ref *ref;
1289 1293  
  1294 + ref = binder_get_ref(proc, fp->handle,
  1295 + fp->type == BINDER_TYPE_HANDLE);
  1296 +
1290 1297 if (ref == NULL) {
1291 1298 pr_err("transaction release %d bad handle %d\n",
1292 1299 debug_id, fp->handle);
... ... @@ -1380,7 +1387,7 @@
1380 1387 if (tr->target.handle) {
1381 1388 struct binder_ref *ref;
1382 1389  
1383   - ref = binder_get_ref(proc, tr->target.handle);
  1390 + ref = binder_get_ref(proc, tr->target.handle, true);
1384 1391 if (ref == NULL) {
1385 1392 binder_user_error("%d:%d got transaction to invalid handle\n",
1386 1393 proc->pid, thread->pid);
1387 1394  
... ... @@ -1589,8 +1596,11 @@
1589 1596 } break;
1590 1597 case BINDER_TYPE_HANDLE:
1591 1598 case BINDER_TYPE_WEAK_HANDLE: {
1592   - struct binder_ref *ref = binder_get_ref(proc, fp->handle);
  1599 + struct binder_ref *ref;
1593 1600  
  1601 + ref = binder_get_ref(proc, fp->handle,
  1602 + fp->type == BINDER_TYPE_HANDLE);
  1603 +
1594 1604 if (ref == NULL) {
1595 1605 binder_user_error("%d:%d got transaction with invalid handle, %d\n",
1596 1606 proc->pid,
... ... @@ -1800,7 +1810,9 @@
1800 1810 ref->desc);
1801 1811 }
1802 1812 } else
1803   - ref = binder_get_ref(proc, target);
  1813 + ref = binder_get_ref(proc, target,
  1814 + cmd == BC_ACQUIRE ||
  1815 + cmd == BC_RELEASE);
1804 1816 if (ref == NULL) {
1805 1817 binder_user_error("%d:%d refcount change on invalid ref %d\n",
1806 1818 proc->pid, thread->pid, target);
... ... @@ -1996,7 +2008,7 @@
1996 2008 if (get_user(cookie, (binder_uintptr_t __user *)ptr))
1997 2009 return -EFAULT;
1998 2010 ptr += sizeof(binder_uintptr_t);
1999   - ref = binder_get_ref(proc, target);
  2011 + ref = binder_get_ref(proc, target, false);
2000 2012 if (ref == NULL) {
2001 2013 binder_user_error("%d:%d %s invalid ref %d\n",
2002 2014 proc->pid, thread->pid,