aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodd Kjos <tkjos@android.com>2017-06-29 15:01:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-07-17 08:47:29 -0400
commitc44b1231ff1170971c1f27fc33a8cc3188de99cb (patch)
tree596016811d0f20e3a0672795b8c8a0bb5847be2c
parent1cf29cf4295ad2dc2009b421702ba4197b85acfd (diff)
binder: add protection for non-perf cases
Add binder_dead_nodes_lock, binder_procs_lock, and binder_context_mgr_node_lock to protect the associated global lists Signed-off-by: Todd Kjos <tkjos@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/android/binder.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 10fda7ab9fa5..fb484c6acd3e 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -46,12 +46,16 @@
46#include "binder_trace.h" 46#include "binder_trace.h"
47 47
48static DEFINE_MUTEX(binder_main_lock); 48static DEFINE_MUTEX(binder_main_lock);
49
50static HLIST_HEAD(binder_deferred_list);
49static DEFINE_MUTEX(binder_deferred_lock); 51static DEFINE_MUTEX(binder_deferred_lock);
50 52
51static HLIST_HEAD(binder_devices); 53static HLIST_HEAD(binder_devices);
52static HLIST_HEAD(binder_procs); 54static HLIST_HEAD(binder_procs);
53static HLIST_HEAD(binder_deferred_list); 55static DEFINE_MUTEX(binder_procs_lock);
56
54static HLIST_HEAD(binder_dead_nodes); 57static HLIST_HEAD(binder_dead_nodes);
58static DEFINE_SPINLOCK(binder_dead_nodes_lock);
55 59
56static struct dentry *binder_debugfs_dir_entry_root; 60static struct dentry *binder_debugfs_dir_entry_root;
57static struct dentry *binder_debugfs_dir_entry_proc; 61static struct dentry *binder_debugfs_dir_entry_proc;
@@ -219,6 +223,8 @@ static struct binder_transaction_log_entry *binder_transaction_log_add(
219 223
220struct binder_context { 224struct binder_context {
221 struct binder_node *binder_context_mgr_node; 225 struct binder_node *binder_context_mgr_node;
226 struct mutex context_mgr_node_lock;
227
222 kuid_t binder_context_mgr_uid; 228 kuid_t binder_context_mgr_uid;
223 const char *name; 229 const char *name;
224}; 230};
@@ -570,7 +576,9 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)
570 "refless node %d deleted\n", 576 "refless node %d deleted\n",
571 node->debug_id); 577 node->debug_id);
572 } else { 578 } else {
579 spin_lock(&binder_dead_nodes_lock);
573 hlist_del(&node->dead_node); 580 hlist_del(&node->dead_node);
581 spin_unlock(&binder_dead_nodes_lock);
574 binder_debug(BINDER_DEBUG_INTERNAL_REFS, 582 binder_debug(BINDER_DEBUG_INTERNAL_REFS,
575 "dead node %d deleted\n", 583 "dead node %d deleted\n",
576 node->debug_id); 584 node->debug_id);
@@ -1454,11 +1462,14 @@ static void binder_transaction(struct binder_proc *proc,
1454 } 1462 }
1455 target_node = ref->node; 1463 target_node = ref->node;
1456 } else { 1464 } else {
1465 mutex_lock(&context->context_mgr_node_lock);
1457 target_node = context->binder_context_mgr_node; 1466 target_node = context->binder_context_mgr_node;
1458 if (target_node == NULL) { 1467 if (target_node == NULL) {
1459 return_error = BR_DEAD_REPLY; 1468 return_error = BR_DEAD_REPLY;
1469 mutex_unlock(&context->context_mgr_node_lock);
1460 goto err_no_context_mgr_node; 1470 goto err_no_context_mgr_node;
1461 } 1471 }
1472 mutex_unlock(&context->context_mgr_node_lock);
1462 } 1473 }
1463 e->to_node = target_node->debug_id; 1474 e->to_node = target_node->debug_id;
1464 target_proc = target_node->proc; 1475 target_proc = target_node->proc;
@@ -1824,22 +1835,31 @@ static int binder_thread_write(struct binder_proc *proc,
1824 case BC_RELEASE: 1835 case BC_RELEASE:
1825 case BC_DECREFS: { 1836 case BC_DECREFS: {
1826 uint32_t target; 1837 uint32_t target;
1827 struct binder_ref *ref; 1838 struct binder_ref *ref = NULL;
1828 const char *debug_string; 1839 const char *debug_string;
1829 1840
1830 if (get_user(target, (uint32_t __user *)ptr)) 1841 if (get_user(target, (uint32_t __user *)ptr))
1831 return -EFAULT; 1842 return -EFAULT;
1843
1832 ptr += sizeof(uint32_t); 1844 ptr += sizeof(uint32_t);
1833 if (target == 0 && context->binder_context_mgr_node && 1845 if (target == 0 &&
1834 (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { 1846 (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
1835 ref = binder_get_ref_for_node(proc, 1847 struct binder_node *ctx_mgr_node;
1836 context->binder_context_mgr_node); 1848
1837 if (ref->desc != target) { 1849 mutex_lock(&context->context_mgr_node_lock);
1838 binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", 1850 ctx_mgr_node = context->binder_context_mgr_node;
1839 proc->pid, thread->pid, 1851 if (ctx_mgr_node) {
1840 ref->desc); 1852 ref = binder_get_ref_for_node(proc,
1853 ctx_mgr_node);
1854 if (ref && ref->desc != target) {
1855 binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n",
1856 proc->pid, thread->pid,
1857 ref->desc);
1858 }
1841 } 1859 }
1842 } else 1860 mutex_unlock(&context->context_mgr_node_lock);
1861 }
1862 if (ref == NULL)
1843 ref = binder_get_ref(proc, target, 1863 ref = binder_get_ref(proc, target,
1844 cmd == BC_ACQUIRE || 1864 cmd == BC_ACQUIRE ||
1845 cmd == BC_RELEASE); 1865 cmd == BC_RELEASE);
@@ -2753,9 +2773,10 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
2753 int ret = 0; 2773 int ret = 0;
2754 struct binder_proc *proc = filp->private_data; 2774 struct binder_proc *proc = filp->private_data;
2755 struct binder_context *context = proc->context; 2775 struct binder_context *context = proc->context;
2756 2776 struct binder_node *new_node;
2757 kuid_t curr_euid = current_euid(); 2777 kuid_t curr_euid = current_euid();
2758 2778
2779 mutex_lock(&context->context_mgr_node_lock);
2759 if (context->binder_context_mgr_node) { 2780 if (context->binder_context_mgr_node) {
2760 pr_err("BINDER_SET_CONTEXT_MGR already set\n"); 2781 pr_err("BINDER_SET_CONTEXT_MGR already set\n");
2761 ret = -EBUSY; 2782 ret = -EBUSY;
@@ -2776,16 +2797,18 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
2776 } else { 2797 } else {
2777 context->binder_context_mgr_uid = curr_euid; 2798 context->binder_context_mgr_uid = curr_euid;
2778 } 2799 }
2779 context->binder_context_mgr_node = binder_new_node(proc, 0, 0); 2800 new_node = binder_new_node(proc, 0, 0);
2780 if (!context->binder_context_mgr_node) { 2801 if (!new_node) {
2781 ret = -ENOMEM; 2802 ret = -ENOMEM;
2782 goto out; 2803 goto out;
2783 } 2804 }
2784 context->binder_context_mgr_node->local_weak_refs++; 2805 new_node->local_weak_refs++;
2785 context->binder_context_mgr_node->local_strong_refs++; 2806 new_node->local_strong_refs++;
2786 context->binder_context_mgr_node->has_strong_ref = 1; 2807 new_node->has_strong_ref = 1;
2787 context->binder_context_mgr_node->has_weak_ref = 1; 2808 new_node->has_weak_ref = 1;
2809 context->binder_context_mgr_node = new_node;
2788out: 2810out:
2811 mutex_unlock(&context->context_mgr_node_lock);
2789 return ret; 2812 return ret;
2790} 2813}
2791 2814
@@ -2965,13 +2988,16 @@ static int binder_open(struct inode *nodp, struct file *filp)
2965 binder_lock(__func__); 2988 binder_lock(__func__);
2966 2989
2967 binder_stats_created(BINDER_STAT_PROC); 2990 binder_stats_created(BINDER_STAT_PROC);
2968 hlist_add_head(&proc->proc_node, &binder_procs);
2969 proc->pid = current->group_leader->pid; 2991 proc->pid = current->group_leader->pid;
2970 INIT_LIST_HEAD(&proc->delivered_death); 2992 INIT_LIST_HEAD(&proc->delivered_death);
2971 filp->private_data = proc; 2993 filp->private_data = proc;
2972 2994
2973 binder_unlock(__func__); 2995 binder_unlock(__func__);
2974 2996
2997 mutex_lock(&binder_procs_lock);
2998 hlist_add_head(&proc->proc_node, &binder_procs);
2999 mutex_unlock(&binder_procs_lock);
3000
2975 if (binder_debugfs_dir_entry_proc) { 3001 if (binder_debugfs_dir_entry_proc) {
2976 char strbuf[11]; 3002 char strbuf[11];
2977 3003
@@ -3050,7 +3076,10 @@ static int binder_node_release(struct binder_node *node, int refs)
3050 node->proc = NULL; 3076 node->proc = NULL;
3051 node->local_strong_refs = 0; 3077 node->local_strong_refs = 0;
3052 node->local_weak_refs = 0; 3078 node->local_weak_refs = 0;
3079
3080 spin_lock(&binder_dead_nodes_lock);
3053 hlist_add_head(&node->dead_node, &binder_dead_nodes); 3081 hlist_add_head(&node->dead_node, &binder_dead_nodes);
3082 spin_unlock(&binder_dead_nodes_lock);
3054 3083
3055 hlist_for_each_entry(ref, &node->refs, node_entry) { 3084 hlist_for_each_entry(ref, &node->refs, node_entry) {
3056 refs++; 3085 refs++;
@@ -3084,8 +3113,11 @@ static void binder_deferred_release(struct binder_proc *proc)
3084 3113
3085 BUG_ON(proc->files); 3114 BUG_ON(proc->files);
3086 3115
3116 mutex_lock(&binder_procs_lock);
3087 hlist_del(&proc->proc_node); 3117 hlist_del(&proc->proc_node);
3118 mutex_unlock(&binder_procs_lock);
3088 3119
3120 mutex_lock(&context->context_mgr_node_lock);
3089 if (context->binder_context_mgr_node && 3121 if (context->binder_context_mgr_node &&
3090 context->binder_context_mgr_node->proc == proc) { 3122 context->binder_context_mgr_node->proc == proc) {
3091 binder_debug(BINDER_DEBUG_DEAD_BINDER, 3123 binder_debug(BINDER_DEBUG_DEAD_BINDER,
@@ -3093,6 +3125,7 @@ static void binder_deferred_release(struct binder_proc *proc)
3093 __func__, proc->pid); 3125 __func__, proc->pid);
3094 context->binder_context_mgr_node = NULL; 3126 context->binder_context_mgr_node = NULL;
3095 } 3127 }
3128 mutex_unlock(&context->context_mgr_node_lock);
3096 3129
3097 threads = 0; 3130 threads = 0;
3098 active_transactions = 0; 3131 active_transactions = 0;
@@ -3509,13 +3542,17 @@ static int binder_state_show(struct seq_file *m, void *unused)
3509 3542
3510 seq_puts(m, "binder state:\n"); 3543 seq_puts(m, "binder state:\n");
3511 3544
3545 spin_lock(&binder_dead_nodes_lock);
3512 if (!hlist_empty(&binder_dead_nodes)) 3546 if (!hlist_empty(&binder_dead_nodes))
3513 seq_puts(m, "dead nodes:\n"); 3547 seq_puts(m, "dead nodes:\n");
3514 hlist_for_each_entry(node, &binder_dead_nodes, dead_node) 3548 hlist_for_each_entry(node, &binder_dead_nodes, dead_node)
3515 print_binder_node(m, node); 3549 print_binder_node(m, node);
3550 spin_unlock(&binder_dead_nodes_lock);
3516 3551
3552 mutex_lock(&binder_procs_lock);
3517 hlist_for_each_entry(proc, &binder_procs, proc_node) 3553 hlist_for_each_entry(proc, &binder_procs, proc_node)
3518 print_binder_proc(m, proc, 1); 3554 print_binder_proc(m, proc, 1);
3555 mutex_unlock(&binder_procs_lock);
3519 binder_unlock(__func__); 3556 binder_unlock(__func__);
3520 return 0; 3557 return 0;
3521} 3558}
@@ -3530,8 +3567,10 @@ static int binder_stats_show(struct seq_file *m, void *unused)
3530 3567
3531 print_binder_stats(m, "", &binder_stats); 3568 print_binder_stats(m, "", &binder_stats);
3532 3569
3570 mutex_lock(&binder_procs_lock);
3533 hlist_for_each_entry(proc, &binder_procs, proc_node) 3571 hlist_for_each_entry(proc, &binder_procs, proc_node)
3534 print_binder_proc_stats(m, proc); 3572 print_binder_proc_stats(m, proc);
3573 mutex_unlock(&binder_procs_lock);
3535 binder_unlock(__func__); 3574 binder_unlock(__func__);
3536 return 0; 3575 return 0;
3537} 3576}
@@ -3543,8 +3582,10 @@ static int binder_transactions_show(struct seq_file *m, void *unused)
3543 binder_lock(__func__); 3582 binder_lock(__func__);
3544 3583
3545 seq_puts(m, "binder transactions:\n"); 3584 seq_puts(m, "binder transactions:\n");
3585 mutex_lock(&binder_procs_lock);
3546 hlist_for_each_entry(proc, &binder_procs, proc_node) 3586 hlist_for_each_entry(proc, &binder_procs, proc_node)
3547 print_binder_proc(m, proc, 0); 3587 print_binder_proc(m, proc, 0);
3588 mutex_unlock(&binder_procs_lock);
3548 binder_unlock(__func__); 3589 binder_unlock(__func__);
3549 return 0; 3590 return 0;
3550} 3591}
@@ -3556,12 +3597,15 @@ static int binder_proc_show(struct seq_file *m, void *unused)
3556 3597
3557 binder_lock(__func__); 3598 binder_lock(__func__);
3558 3599
3600 mutex_lock(&binder_procs_lock);
3559 hlist_for_each_entry(itr, &binder_procs, proc_node) { 3601 hlist_for_each_entry(itr, &binder_procs, proc_node) {
3560 if (itr->pid == pid) { 3602 if (itr->pid == pid) {
3561 seq_puts(m, "binder proc state:\n"); 3603 seq_puts(m, "binder proc state:\n");
3562 print_binder_proc(m, itr, 1); 3604 print_binder_proc(m, itr, 1);
3563 } 3605 }
3564 } 3606 }
3607 mutex_unlock(&binder_procs_lock);
3608
3565 binder_unlock(__func__); 3609 binder_unlock(__func__);
3566 return 0; 3610 return 0;
3567} 3611}
@@ -3622,6 +3666,7 @@ static int __init init_binder_device(const char *name)
3622 3666
3623 binder_device->context.binder_context_mgr_uid = INVALID_UID; 3667 binder_device->context.binder_context_mgr_uid = INVALID_UID;
3624 binder_device->context.name = name; 3668 binder_device->context.name = name;
3669 mutex_init(&binder_device->context.context_mgr_node_lock);
3625 3670
3626 ret = misc_register(&binder_device->miscdev); 3671 ret = misc_register(&binder_device->miscdev);
3627 if (ret < 0) { 3672 if (ret < 0) {