diff options
Diffstat (limited to 'drivers/android/binder.c')
| -rw-r--r-- | drivers/android/binder.c | 41 | 
1 files changed, 17 insertions, 24 deletions
| diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 9edacc8b9768..49fb74196d02 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1870,7 +1870,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,  		binder_dec_node(buffer->target_node, 1, 0);  	off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); -	off_end_offset = is_failure ? failed_at : +	off_end_offset = is_failure && failed_at ? failed_at :  				off_start_offset + buffer->offsets_size;  	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;  	     buffer_offset += sizeof(binder_size_t)) { @@ -1956,9 +1956,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,  			binder_size_t fd_buf_size;  			binder_size_t num_valid; -			if (proc->tsk != current->group_leader) { +			if (is_failure) {  				/* -				 * Nothing to do if running in sender context  				 * The fd fixups have not been applied so no  				 * fds need to be closed.  				 */ @@ -2056,7 +2055,7 @@ static int binder_translate_binder(struct flat_binder_object *fp,  		ret = -EINVAL;  		goto done;  	} -	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { +	if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {  		ret = -EPERM;  		goto done;  	} @@ -2102,7 +2101,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,  				  proc->pid, thread->pid, fp->handle);  		return -EINVAL;  	} -	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { +	if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {  		ret = -EPERM;  		goto done;  	} @@ -2190,7 +2189,7 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,  		ret = -EBADF;  		goto err_fget;  	} -	ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file); +	ret = security_binder_transfer_file(proc->cred, target_proc->cred, file);  	if (ret < 0) {  		ret = -EPERM;  		goto err_security; @@ -2595,8 +2594,8 @@ static void binder_transaction(struct binder_proc *proc,  			return_error_line = __LINE__;  			goto err_invalid_target_handle;  		} -		if (security_binder_transaction(proc->tsk, -						target_proc->tsk) < 0) { +		if (security_binder_transaction(proc->cred, +						target_proc->cred) < 0) {  			return_error = BR_FAILED_REPLY;  			return_error_param = -EPERM;  			return_error_line = __LINE__; @@ -2711,7 +2710,7 @@ static void binder_transaction(struct binder_proc *proc,  		t->from = thread;  	else  		t->from = NULL; -	t->sender_euid = task_euid(proc->tsk); +	t->sender_euid = proc->cred->euid;  	t->to_proc = target_proc;  	t->to_thread = target_thread;  	t->code = tr->code; @@ -2722,16 +2721,7 @@ static void binder_transaction(struct binder_proc *proc,  		u32 secid;  		size_t added_size; -		/* -		 * Arguably this should be the task's subjective LSM secid but -		 * we can't reliably access the subjective creds of a task -		 * other than our own so we must use the objective creds, which -		 * are safe to access.  The downside is that if a task is -		 * temporarily overriding it's creds it will not be reflected -		 * here; however, it isn't clear that binder would handle that -		 * case well anyway. -		 */ -		security_task_getsecid_obj(proc->tsk, &secid); +		security_cred_getsecid(proc->cred, &secid);  		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);  		if (ret) {  			return_error = BR_FAILED_REPLY; @@ -3185,6 +3175,7 @@ err_invalid_target_handle:   * binder_free_buf() - free the specified buffer   * @proc:	binder proc that owns buffer   * @buffer:	buffer to be freed + * @is_failure:	failed to send transaction   *   * If buffer for an async transaction, enqueue the next async   * transaction from the node. @@ -3194,7 +3185,7 @@ err_invalid_target_handle:  static void  binder_free_buf(struct binder_proc *proc,  		struct binder_thread *thread, -		struct binder_buffer *buffer) +		struct binder_buffer *buffer, bool is_failure)  {  	binder_inner_proc_lock(proc);  	if (buffer->transaction) { @@ -3222,7 +3213,7 @@ binder_free_buf(struct binder_proc *proc,  		binder_node_inner_unlock(buf_node);  	}  	trace_binder_transaction_buffer_release(buffer); -	binder_transaction_buffer_release(proc, thread, buffer, 0, false); +	binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);  	binder_alloc_free_buf(&proc->alloc, buffer);  } @@ -3424,7 +3415,7 @@ static int binder_thread_write(struct binder_proc *proc,  				     proc->pid, thread->pid, (u64)data_ptr,  				     buffer->debug_id,  				     buffer->transaction ? "active" : "finished"); -			binder_free_buf(proc, thread, buffer); +			binder_free_buf(proc, thread, buffer, false);  			break;  		} @@ -4117,7 +4108,7 @@ retry:  			buffer->transaction = NULL;  			binder_cleanup_transaction(t, "fd fixups failed",  						   BR_FAILED_REPLY); -			binder_free_buf(proc, thread, buffer); +			binder_free_buf(proc, thread, buffer, true);  			binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,  				     "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n",  				     proc->pid, thread->pid, @@ -4353,6 +4344,7 @@ static void binder_free_proc(struct binder_proc *proc)  	}  	binder_alloc_deferred_release(&proc->alloc);  	put_task_struct(proc->tsk); +	put_cred(proc->cred);  	binder_stats_deleted(BINDER_STAT_PROC);  	kfree(proc);  } @@ -4564,7 +4556,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp,  		ret = -EBUSY;  		goto out;  	} -	ret = security_binder_set_context_mgr(proc->tsk); +	ret = security_binder_set_context_mgr(proc->cred);  	if (ret < 0)  		goto out;  	if (uid_valid(context->binder_context_mgr_uid)) { @@ -5055,6 +5047,7 @@ static int binder_open(struct inode *nodp, struct file *filp)  	spin_lock_init(&proc->outer_lock);  	get_task_struct(current->group_leader);  	proc->tsk = current->group_leader; +	proc->cred = get_cred(filp->f_cred);  	INIT_LIST_HEAD(&proc->todo);  	init_waitqueue_head(&proc->freeze_wait);  	proc->default_priority = task_nice(current); | 
