aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/android
diff options
context:
space:
mode:
authorTodd Kjos <tkjos@android.com>2019-01-14 12:10:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-22 07:55:08 -0500
commitec74136ded792deed80780a2f8baf3521eeb72f9 (patch)
treeba8f8c2506386a221b7efe1f5ac069819d281651 /drivers/android
parent8fdf90626588bc02af1200f6320d1d9c0540526f (diff)
binder: create node flag to request sender's security context
To allow servers to verify client identity, allow a node flag to be set that causes the sender's security context to be delivered with the transaction. The BR_TRANSACTION command is extended in BR_TRANSACTION_SEC_CTX to contain a pointer to the security context string. Signed-off-by: Todd Kjos <tkjos@google.com> Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/android')
-rw-r--r--drivers/android/binder.c106
1 files changed, 83 insertions, 23 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index cdfc87629efb..5f6ef5e63b91 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -329,6 +329,8 @@ struct binder_error {
329 * (invariant after initialized) 329 * (invariant after initialized)
330 * @min_priority: minimum scheduling priority 330 * @min_priority: minimum scheduling priority
331 * (invariant after initialized) 331 * (invariant after initialized)
332 * @txn_security_ctx: require sender's security context
333 * (invariant after initialized)
332 * @async_todo: list of async work items 334 * @async_todo: list of async work items
333 * (protected by @proc->inner_lock) 335 * (protected by @proc->inner_lock)
334 * 336 *
@@ -365,6 +367,7 @@ struct binder_node {
365 * invariant after initialization 367 * invariant after initialization
366 */ 368 */
367 u8 accept_fds:1; 369 u8 accept_fds:1;
370 u8 txn_security_ctx:1;
368 u8 min_priority; 371 u8 min_priority;
369 }; 372 };
370 bool has_async_transaction; 373 bool has_async_transaction;
@@ -615,6 +618,7 @@ struct binder_transaction {
615 long saved_priority; 618 long saved_priority;
616 kuid_t sender_euid; 619 kuid_t sender_euid;
617 struct list_head fd_fixups; 620 struct list_head fd_fixups;
621 binder_uintptr_t security_ctx;
618 /** 622 /**
619 * @lock: protects @from, @to_proc, and @to_thread 623 * @lock: protects @from, @to_proc, and @to_thread
620 * 624 *
@@ -1152,6 +1156,7 @@ static struct binder_node *binder_init_node_ilocked(
1152 node->work.type = BINDER_WORK_NODE; 1156 node->work.type = BINDER_WORK_NODE;
1153 node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; 1157 node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
1154 node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); 1158 node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
1159 node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX);
1155 spin_lock_init(&node->lock); 1160 spin_lock_init(&node->lock);
1156 INIT_LIST_HEAD(&node->work.entry); 1161 INIT_LIST_HEAD(&node->work.entry);
1157 INIT_LIST_HEAD(&node->async_todo); 1162 INIT_LIST_HEAD(&node->async_todo);
@@ -2778,6 +2783,8 @@ static void binder_transaction(struct binder_proc *proc,
2778 binder_size_t last_fixup_min_off = 0; 2783 binder_size_t last_fixup_min_off = 0;
2779 struct binder_context *context = proc->context; 2784 struct binder_context *context = proc->context;
2780 int t_debug_id = atomic_inc_return(&binder_last_id); 2785 int t_debug_id = atomic_inc_return(&binder_last_id);
2786 char *secctx = NULL;
2787 u32 secctx_sz = 0;
2781 2788
2782 e = binder_transaction_log_add(&binder_transaction_log); 2789 e = binder_transaction_log_add(&binder_transaction_log);
2783 e->debug_id = t_debug_id; 2790 e->debug_id = t_debug_id;
@@ -3020,6 +3027,20 @@ static void binder_transaction(struct binder_proc *proc,
3020 t->flags = tr->flags; 3027 t->flags = tr->flags;
3021 t->priority = task_nice(current); 3028 t->priority = task_nice(current);
3022 3029
3030 if (target_node && target_node->txn_security_ctx) {
3031 u32 secid;
3032
3033 security_task_getsecid(proc->tsk, &secid);
3034 ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
3035 if (ret) {
3036 return_error = BR_FAILED_REPLY;
3037 return_error_param = ret;
3038 return_error_line = __LINE__;
3039 goto err_get_secctx_failed;
3040 }
3041 extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
3042 }
3043
3023 trace_binder_transaction(reply, t, target_node); 3044 trace_binder_transaction(reply, t, target_node);
3024 3045
3025 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size, 3046 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
@@ -3036,6 +3057,19 @@ static void binder_transaction(struct binder_proc *proc,
3036 t->buffer = NULL; 3057 t->buffer = NULL;
3037 goto err_binder_alloc_buf_failed; 3058 goto err_binder_alloc_buf_failed;
3038 } 3059 }
3060 if (secctx) {
3061 size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
3062 ALIGN(tr->offsets_size, sizeof(void *)) +
3063 ALIGN(extra_buffers_size, sizeof(void *)) -
3064 ALIGN(secctx_sz, sizeof(u64));
3065 char *kptr = t->buffer->data + buf_offset;
3066
3067 t->security_ctx = (uintptr_t)kptr +
3068 binder_alloc_get_user_buffer_offset(&target_proc->alloc);
3069 memcpy(kptr, secctx, secctx_sz);
3070 security_release_secctx(secctx, secctx_sz);
3071 secctx = NULL;
3072 }
3039 t->buffer->debug_id = t->debug_id; 3073 t->buffer->debug_id = t->debug_id;
3040 t->buffer->transaction = t; 3074 t->buffer->transaction = t;
3041 t->buffer->target_node = target_node; 3075 t->buffer->target_node = target_node;
@@ -3305,6 +3339,9 @@ err_copy_data_failed:
3305 t->buffer->transaction = NULL; 3339 t->buffer->transaction = NULL;
3306 binder_alloc_free_buf(&target_proc->alloc, t->buffer); 3340 binder_alloc_free_buf(&target_proc->alloc, t->buffer);
3307err_binder_alloc_buf_failed: 3341err_binder_alloc_buf_failed:
3342 if (secctx)
3343 security_release_secctx(secctx, secctx_sz);
3344err_get_secctx_failed:
3308 kfree(tcomplete); 3345 kfree(tcomplete);
3309 binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); 3346 binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
3310err_alloc_tcomplete_failed: 3347err_alloc_tcomplete_failed:
@@ -4036,11 +4073,13 @@ retry:
4036 4073
4037 while (1) { 4074 while (1) {
4038 uint32_t cmd; 4075 uint32_t cmd;
4039 struct binder_transaction_data tr; 4076 struct binder_transaction_data_secctx tr;
4077 struct binder_transaction_data *trd = &tr.transaction_data;
4040 struct binder_work *w = NULL; 4078 struct binder_work *w = NULL;
4041 struct list_head *list = NULL; 4079 struct list_head *list = NULL;
4042 struct binder_transaction *t = NULL; 4080 struct binder_transaction *t = NULL;
4043 struct binder_thread *t_from; 4081 struct binder_thread *t_from;
4082 size_t trsize = sizeof(*trd);
4044 4083
4045 binder_inner_proc_lock(proc); 4084 binder_inner_proc_lock(proc);
4046 if (!binder_worklist_empty_ilocked(&thread->todo)) 4085 if (!binder_worklist_empty_ilocked(&thread->todo))
@@ -4240,8 +4279,8 @@ retry:
4240 if (t->buffer->target_node) { 4279 if (t->buffer->target_node) {
4241 struct binder_node *target_node = t->buffer->target_node; 4280 struct binder_node *target_node = t->buffer->target_node;
4242 4281
4243 tr.target.ptr = target_node->ptr; 4282 trd->target.ptr = target_node->ptr;
4244 tr.cookie = target_node->cookie; 4283 trd->cookie = target_node->cookie;
4245 t->saved_priority = task_nice(current); 4284 t->saved_priority = task_nice(current);
4246 if (t->priority < target_node->min_priority && 4285 if (t->priority < target_node->min_priority &&
4247 !(t->flags & TF_ONE_WAY)) 4286 !(t->flags & TF_ONE_WAY))
@@ -4251,22 +4290,23 @@ retry:
4251 binder_set_nice(target_node->min_priority); 4290 binder_set_nice(target_node->min_priority);
4252 cmd = BR_TRANSACTION; 4291 cmd = BR_TRANSACTION;
4253 } else { 4292 } else {
4254 tr.target.ptr = 0; 4293 trd->target.ptr = 0;
4255 tr.cookie = 0; 4294 trd->cookie = 0;
4256 cmd = BR_REPLY; 4295 cmd = BR_REPLY;
4257 } 4296 }
4258 tr.code = t->code; 4297 trd->code = t->code;
4259 tr.flags = t->flags; 4298 trd->flags = t->flags;
4260 tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid); 4299 trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid);
4261 4300
4262 t_from = binder_get_txn_from(t); 4301 t_from = binder_get_txn_from(t);
4263 if (t_from) { 4302 if (t_from) {
4264 struct task_struct *sender = t_from->proc->tsk; 4303 struct task_struct *sender = t_from->proc->tsk;
4265 4304
4266 tr.sender_pid = task_tgid_nr_ns(sender, 4305 trd->sender_pid =
4267 task_active_pid_ns(current)); 4306 task_tgid_nr_ns(sender,
4307 task_active_pid_ns(current));
4268 } else { 4308 } else {
4269 tr.sender_pid = 0; 4309 trd->sender_pid = 0;
4270 } 4310 }
4271 4311
4272 ret = binder_apply_fd_fixups(t); 4312 ret = binder_apply_fd_fixups(t);
@@ -4297,15 +4337,20 @@ retry:
4297 } 4337 }
4298 continue; 4338 continue;
4299 } 4339 }
4300 tr.data_size = t->buffer->data_size; 4340 trd->data_size = t->buffer->data_size;
4301 tr.offsets_size = t->buffer->offsets_size; 4341 trd->offsets_size = t->buffer->offsets_size;
4302 tr.data.ptr.buffer = (binder_uintptr_t) 4342 trd->data.ptr.buffer = (binder_uintptr_t)
4303 ((uintptr_t)t->buffer->data + 4343 ((uintptr_t)t->buffer->data +
4304 binder_alloc_get_user_buffer_offset(&proc->alloc)); 4344 binder_alloc_get_user_buffer_offset(&proc->alloc));
4305 tr.data.ptr.offsets = tr.data.ptr.buffer + 4345 trd->data.ptr.offsets = trd->data.ptr.buffer +
4306 ALIGN(t->buffer->data_size, 4346 ALIGN(t->buffer->data_size,
4307 sizeof(void *)); 4347 sizeof(void *));
4308 4348
4349 tr.secctx = t->security_ctx;
4350 if (t->security_ctx) {
4351 cmd = BR_TRANSACTION_SEC_CTX;
4352 trsize = sizeof(tr);
4353 }
4309 if (put_user(cmd, (uint32_t __user *)ptr)) { 4354 if (put_user(cmd, (uint32_t __user *)ptr)) {
4310 if (t_from) 4355 if (t_from)
4311 binder_thread_dec_tmpref(t_from); 4356 binder_thread_dec_tmpref(t_from);
@@ -4316,7 +4361,7 @@ retry:
4316 return -EFAULT; 4361 return -EFAULT;
4317 } 4362 }
4318 ptr += sizeof(uint32_t); 4363 ptr += sizeof(uint32_t);
4319 if (copy_to_user(ptr, &tr, sizeof(tr))) { 4364 if (copy_to_user(ptr, &tr, trsize)) {
4320 if (t_from) 4365 if (t_from)
4321 binder_thread_dec_tmpref(t_from); 4366 binder_thread_dec_tmpref(t_from);
4322 4367
@@ -4325,7 +4370,7 @@ retry:
4325 4370
4326 return -EFAULT; 4371 return -EFAULT;
4327 } 4372 }
4328 ptr += sizeof(tr); 4373 ptr += trsize;
4329 4374
4330 trace_binder_transaction_received(t); 4375 trace_binder_transaction_received(t);
4331 binder_stat_br(proc, thread, cmd); 4376 binder_stat_br(proc, thread, cmd);
@@ -4333,16 +4378,18 @@ retry:
4333 "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n", 4378 "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n",
4334 proc->pid, thread->pid, 4379 proc->pid, thread->pid,
4335 (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : 4380 (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
4336 "BR_REPLY", 4381 (cmd == BR_TRANSACTION_SEC_CTX) ?
4382 "BR_TRANSACTION_SEC_CTX" : "BR_REPLY",
4337 t->debug_id, t_from ? t_from->proc->pid : 0, 4383 t->debug_id, t_from ? t_from->proc->pid : 0,
4338 t_from ? t_from->pid : 0, cmd, 4384 t_from ? t_from->pid : 0, cmd,
4339 t->buffer->data_size, t->buffer->offsets_size, 4385 t->buffer->data_size, t->buffer->offsets_size,
4340 (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets); 4386 (u64)trd->data.ptr.buffer,
4387 (u64)trd->data.ptr.offsets);
4341 4388
4342 if (t_from) 4389 if (t_from)
4343 binder_thread_dec_tmpref(t_from); 4390 binder_thread_dec_tmpref(t_from);
4344 t->buffer->allow_user_free = 1; 4391 t->buffer->allow_user_free = 1;
4345 if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { 4392 if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) {
4346 binder_inner_proc_lock(thread->proc); 4393 binder_inner_proc_lock(thread->proc);
4347 t->to_parent = thread->transaction_stack; 4394 t->to_parent = thread->transaction_stack;
4348 t->to_thread = thread; 4395 t->to_thread = thread;
@@ -4690,7 +4737,8 @@ out:
4690 return ret; 4737 return ret;
4691} 4738}
4692 4739
4693static int binder_ioctl_set_ctx_mgr(struct file *filp) 4740static int binder_ioctl_set_ctx_mgr(struct file *filp,
4741 struct flat_binder_object *fbo)
4694{ 4742{
4695 int ret = 0; 4743 int ret = 0;
4696 struct binder_proc *proc = filp->private_data; 4744 struct binder_proc *proc = filp->private_data;
@@ -4719,7 +4767,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp)
4719 } else { 4767 } else {
4720 context->binder_context_mgr_uid = curr_euid; 4768 context->binder_context_mgr_uid = curr_euid;
4721 } 4769 }
4722 new_node = binder_new_node(proc, NULL); 4770 new_node = binder_new_node(proc, fbo);
4723 if (!new_node) { 4771 if (!new_node) {
4724 ret = -ENOMEM; 4772 ret = -ENOMEM;
4725 goto out; 4773 goto out;
@@ -4842,8 +4890,20 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
4842 binder_inner_proc_unlock(proc); 4890 binder_inner_proc_unlock(proc);
4843 break; 4891 break;
4844 } 4892 }
4893 case BINDER_SET_CONTEXT_MGR_EXT: {
4894 struct flat_binder_object fbo;
4895
4896 if (copy_from_user(&fbo, ubuf, sizeof(fbo))) {
4897 ret = -EINVAL;
4898 goto err;
4899 }
4900 ret = binder_ioctl_set_ctx_mgr(filp, &fbo);
4901 if (ret)
4902 goto err;
4903 break;
4904 }
4845 case BINDER_SET_CONTEXT_MGR: 4905 case BINDER_SET_CONTEXT_MGR:
4846 ret = binder_ioctl_set_ctx_mgr(filp); 4906 ret = binder_ioctl_set_ctx_mgr(filp, NULL);
4847 if (ret) 4907 if (ret)
4848 goto err; 4908 goto err;
4849 break; 4909 break;