aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2017-02-03 17:40:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-10 10:00:01 -0500
commit342e5c90b60134ddd6e4d59e521b6aa66b75bdad (patch)
tree9d8852e540c0cb23bb67065b721d9cae8a36c226
parentfeba3900cabb8e7c87368faa28e7a6936809ba22 (diff)
binder: Support multiple context managers
Move the context manager state into a separate struct context, and allow for each process to have its own context associated with it. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Martijn Coenen <maco@google.com> Cc: Arve Hjønnevåg <arve@android.com> Cc: Amit Pundir <amit.pundir@linaro.org> Cc: Serban Constantinescu <serban.constantinescu@arm.com> Cc: Dmitry Shmidt <dimitrysh@google.com> Cc: Rom Lemarchand <romlem@google.com> Cc: Android Kernel Team <kernel-team@android.com> Signed-off-by: Martijn Coenen <maco@google.com> [jstultz: Minor checkpatch fix] Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/android/binder.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 331d2abca9a2..59cb6d9ddbc0 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -56,8 +56,6 @@ static HLIST_HEAD(binder_dead_nodes);
56 56
57static struct dentry *binder_debugfs_dir_entry_root; 57static struct dentry *binder_debugfs_dir_entry_root;
58static struct dentry *binder_debugfs_dir_entry_proc; 58static struct dentry *binder_debugfs_dir_entry_proc;
59static struct binder_node *binder_context_mgr_node;
60static kuid_t binder_context_mgr_uid = INVALID_UID;
61static int binder_last_id; 59static int binder_last_id;
62 60
63#define BINDER_DEBUG_ENTRY(name) \ 61#define BINDER_DEBUG_ENTRY(name) \
@@ -215,6 +213,15 @@ static struct binder_transaction_log_entry *binder_transaction_log_add(
215 return e; 213 return e;
216} 214}
217 215
216struct binder_context {
217 struct binder_node *binder_context_mgr_node;
218 kuid_t binder_context_mgr_uid;
219};
220
221static struct binder_context global_context = {
222 .binder_context_mgr_uid = INVALID_UID,
223};
224
218struct binder_work { 225struct binder_work {
219 struct list_head entry; 226 struct list_head entry;
220 enum { 227 enum {
@@ -330,6 +337,7 @@ struct binder_proc {
330 int ready_threads; 337 int ready_threads;
331 long default_priority; 338 long default_priority;
332 struct dentry *debugfs_entry; 339 struct dentry *debugfs_entry;
340 struct binder_context *context;
333}; 341};
334 342
335enum { 343enum {
@@ -934,8 +942,9 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal,
934 if (internal) { 942 if (internal) {
935 if (target_list == NULL && 943 if (target_list == NULL &&
936 node->internal_strong_refs == 0 && 944 node->internal_strong_refs == 0 &&
937 !(node == binder_context_mgr_node && 945 !(node->proc &&
938 node->has_strong_ref)) { 946 node == node->proc->context->binder_context_mgr_node &&
947 node->has_strong_ref)) {
939 pr_err("invalid inc strong node for %d\n", 948 pr_err("invalid inc strong node for %d\n",
940 node->debug_id); 949 node->debug_id);
941 return -EINVAL; 950 return -EINVAL;
@@ -1036,6 +1045,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
1036 struct rb_node **p = &proc->refs_by_node.rb_node; 1045 struct rb_node **p = &proc->refs_by_node.rb_node;
1037 struct rb_node *parent = NULL; 1046 struct rb_node *parent = NULL;
1038 struct binder_ref *ref, *new_ref; 1047 struct binder_ref *ref, *new_ref;
1048 struct binder_context *context = proc->context;
1039 1049
1040 while (*p) { 1050 while (*p) {
1041 parent = *p; 1051 parent = *p;
@@ -1058,7 +1068,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
1058 rb_link_node(&new_ref->rb_node_node, parent, p); 1068 rb_link_node(&new_ref->rb_node_node, parent, p);
1059 rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); 1069 rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node);
1060 1070
1061 new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; 1071 new_ref->desc = (node == context->binder_context_mgr_node) ? 0 : 1;
1062 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { 1072 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
1063 ref = rb_entry(n, struct binder_ref, rb_node_desc); 1073 ref = rb_entry(n, struct binder_ref, rb_node_desc);
1064 if (ref->desc > new_ref->desc) 1074 if (ref->desc > new_ref->desc)
@@ -1388,6 +1398,7 @@ static void binder_transaction(struct binder_proc *proc,
1388 struct binder_transaction *in_reply_to = NULL; 1398 struct binder_transaction *in_reply_to = NULL;
1389 struct binder_transaction_log_entry *e; 1399 struct binder_transaction_log_entry *e;
1390 uint32_t return_error; 1400 uint32_t return_error;
1401 struct binder_context *context = proc->context;
1391 1402
1392 e = binder_transaction_log_add(&binder_transaction_log); 1403 e = binder_transaction_log_add(&binder_transaction_log);
1393 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); 1404 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
@@ -1448,7 +1459,7 @@ static void binder_transaction(struct binder_proc *proc,
1448 } 1459 }
1449 target_node = ref->node; 1460 target_node = ref->node;
1450 } else { 1461 } else {
1451 target_node = binder_context_mgr_node; 1462 target_node = context->binder_context_mgr_node;
1452 if (target_node == NULL) { 1463 if (target_node == NULL) {
1453 return_error = BR_DEAD_REPLY; 1464 return_error = BR_DEAD_REPLY;
1454 goto err_no_context_mgr_node; 1465 goto err_no_context_mgr_node;
@@ -1839,6 +1850,7 @@ static int binder_thread_write(struct binder_proc *proc,
1839 binder_size_t *consumed) 1850 binder_size_t *consumed)
1840{ 1851{
1841 uint32_t cmd; 1852 uint32_t cmd;
1853 struct binder_context *context = proc->context;
1842 void __user *buffer = (void __user *)(uintptr_t)binder_buffer; 1854 void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
1843 void __user *ptr = buffer + *consumed; 1855 void __user *ptr = buffer + *consumed;
1844 void __user *end = buffer + size; 1856 void __user *end = buffer + size;
@@ -1865,10 +1877,10 @@ static int binder_thread_write(struct binder_proc *proc,
1865 if (get_user(target, (uint32_t __user *)ptr)) 1877 if (get_user(target, (uint32_t __user *)ptr))
1866 return -EFAULT; 1878 return -EFAULT;
1867 ptr += sizeof(uint32_t); 1879 ptr += sizeof(uint32_t);
1868 if (target == 0 && binder_context_mgr_node && 1880 if (target == 0 && context->binder_context_mgr_node &&
1869 (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { 1881 (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
1870 ref = binder_get_ref_for_node(proc, 1882 ref = binder_get_ref_for_node(proc,
1871 binder_context_mgr_node); 1883 context->binder_context_mgr_node);
1872 if (ref->desc != target) { 1884 if (ref->desc != target) {
1873 binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", 1885 binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n",
1874 proc->pid, thread->pid, 1886 proc->pid, thread->pid,
@@ -2774,9 +2786,11 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
2774{ 2786{
2775 int ret = 0; 2787 int ret = 0;
2776 struct binder_proc *proc = filp->private_data; 2788 struct binder_proc *proc = filp->private_data;
2789 struct binder_context *context = proc->context;
2790
2777 kuid_t curr_euid = current_euid(); 2791 kuid_t curr_euid = current_euid();
2778 2792
2779 if (binder_context_mgr_node != NULL) { 2793 if (context->binder_context_mgr_node) {
2780 pr_err("BINDER_SET_CONTEXT_MGR already set\n"); 2794 pr_err("BINDER_SET_CONTEXT_MGR already set\n");
2781 ret = -EBUSY; 2795 ret = -EBUSY;
2782 goto out; 2796 goto out;
@@ -2784,27 +2798,27 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
2784 ret = security_binder_set_context_mgr(proc->tsk); 2798 ret = security_binder_set_context_mgr(proc->tsk);
2785 if (ret < 0) 2799 if (ret < 0)
2786 goto out; 2800 goto out;
2787 if (uid_valid(binder_context_mgr_uid)) { 2801 if (uid_valid(context->binder_context_mgr_uid)) {
2788 if (!uid_eq(binder_context_mgr_uid, curr_euid)) { 2802 if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) {
2789 pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", 2803 pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",
2790 from_kuid(&init_user_ns, curr_euid), 2804 from_kuid(&init_user_ns, curr_euid),
2791 from_kuid(&init_user_ns, 2805 from_kuid(&init_user_ns,
2792 binder_context_mgr_uid)); 2806 context->binder_context_mgr_uid));
2793 ret = -EPERM; 2807 ret = -EPERM;
2794 goto out; 2808 goto out;
2795 } 2809 }
2796 } else { 2810 } else {
2797 binder_context_mgr_uid = curr_euid; 2811 context->binder_context_mgr_uid = curr_euid;
2798 } 2812 }
2799 binder_context_mgr_node = binder_new_node(proc, 0, 0); 2813 context->binder_context_mgr_node = binder_new_node(proc, 0, 0);
2800 if (binder_context_mgr_node == NULL) { 2814 if (!context->binder_context_mgr_node) {
2801 ret = -ENOMEM; 2815 ret = -ENOMEM;
2802 goto out; 2816 goto out;
2803 } 2817 }
2804 binder_context_mgr_node->local_weak_refs++; 2818 context->binder_context_mgr_node->local_weak_refs++;
2805 binder_context_mgr_node->local_strong_refs++; 2819 context->binder_context_mgr_node->local_strong_refs++;
2806 binder_context_mgr_node->has_strong_ref = 1; 2820 context->binder_context_mgr_node->has_strong_ref = 1;
2807 binder_context_mgr_node->has_weak_ref = 1; 2821 context->binder_context_mgr_node->has_weak_ref = 1;
2808out: 2822out:
2809 return ret; 2823 return ret;
2810} 2824}
@@ -3039,6 +3053,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
3039 get_task_struct(current); 3053 get_task_struct(current);
3040 proc->tsk = current; 3054 proc->tsk = current;
3041 proc->vma_vm_mm = current->mm; 3055 proc->vma_vm_mm = current->mm;
3056 proc->context = &global_context;
3042 INIT_LIST_HEAD(&proc->todo); 3057 INIT_LIST_HEAD(&proc->todo);
3043 init_waitqueue_head(&proc->wait); 3058 init_waitqueue_head(&proc->wait);
3044 proc->default_priority = task_nice(current); 3059 proc->default_priority = task_nice(current);
@@ -3151,6 +3166,7 @@ static int binder_node_release(struct binder_node *node, int refs)
3151static void binder_deferred_release(struct binder_proc *proc) 3166static void binder_deferred_release(struct binder_proc *proc)
3152{ 3167{
3153 struct binder_transaction *t; 3168 struct binder_transaction *t;
3169 struct binder_context *context = proc->context;
3154 struct rb_node *n; 3170 struct rb_node *n;
3155 int threads, nodes, incoming_refs, outgoing_refs, buffers, 3171 int threads, nodes, incoming_refs, outgoing_refs, buffers,
3156 active_transactions, page_count; 3172 active_transactions, page_count;
@@ -3160,11 +3176,12 @@ static void binder_deferred_release(struct binder_proc *proc)
3160 3176
3161 hlist_del(&proc->proc_node); 3177 hlist_del(&proc->proc_node);
3162 3178
3163 if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { 3179 if (context->binder_context_mgr_node &&
3180 context->binder_context_mgr_node->proc == proc) {
3164 binder_debug(BINDER_DEBUG_DEAD_BINDER, 3181 binder_debug(BINDER_DEBUG_DEAD_BINDER,
3165 "%s: %d context_mgr_node gone\n", 3182 "%s: %d context_mgr_node gone\n",
3166 __func__, proc->pid); 3183 __func__, proc->pid);
3167 binder_context_mgr_node = NULL; 3184 context->binder_context_mgr_node = NULL;
3168 } 3185 }
3169 3186
3170 threads = 0; 3187 threads = 0;