Skip to content

Commit

Permalink
N986BXX3FCV8
Browse files Browse the repository at this point in the history
  • Loading branch information
corsicanu committed May 5, 2022
1 parent 25f6f62 commit a917a16
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 64 deletions.
35 changes: 27 additions & 8 deletions drivers/android/binder.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ struct binder_priority {
* @files files_struct for process
* (protected by @files_lock)
* @files_lock mutex to protect @files
* @cred struct cred associated with the `struct file`
* in binder_open()
* (invariant after initialized)
* @deferred_work_node: element for binder_deferred_list
* (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform
Expand Down Expand Up @@ -574,6 +577,7 @@ struct binder_proc {
struct task_struct *tsk;
struct files_struct *files;
struct mutex files_lock;
const struct cred *cred;
struct hlist_node deferred_work_node;
int deferred_work;
bool is_dead;
Expand Down Expand Up @@ -2802,7 +2806,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;
}
Expand Down Expand Up @@ -2848,7 +2852,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,
proc->pid, thread->pid, proc->tsk->comm, thread->task->comm, 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;
}
Expand Down Expand Up @@ -2932,7 +2936,7 @@ static int binder_translate_fd(int fd,
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;
Expand Down Expand Up @@ -3469,8 +3473,14 @@ static void binder_transaction(struct binder_proc *proc,
freecess_sync_binder_report(proc, target_proc, tr);
#endif

if (security_binder_transaction(proc->tsk,
target_proc->tsk) < 0) {
if (WARN_ON(proc == target_proc)) {
return_error = BR_FAILED_REPLY;
return_error_param = -EINVAL;
return_error_line = __LINE__;
goto err_invalid_target_handle;
}
if (security_binder_transaction(proc->cred,
target_proc->cred) < 0) {
return_error = BR_FAILED_REPLY;
return_error_param = -EPERM;
return_error_line = __LINE__;
Expand Down Expand Up @@ -3809,7 +3819,7 @@ static void binder_transaction(struct binder_proc *proc,
binder_size_t parent_offset;
struct binder_fd_array_object *fda =
to_binder_fd_array_object(hdr);
size_t num_valid = (buffer_offset - off_start_offset) /
size_t num_valid = (buffer_offset - off_start_offset) /
sizeof(binder_size_t);
struct binder_buffer_object *parent =
binder_validate_ptr(target_proc, t->buffer,
Expand Down Expand Up @@ -4102,10 +4112,17 @@ static int binder_thread_write(struct binder_proc *proc,
struct binder_node *ctx_mgr_node;
mutex_lock(&context->context_mgr_node_lock);
ctx_mgr_node = context->binder_context_mgr_node;
if (ctx_mgr_node)
if (ctx_mgr_node) {
if (ctx_mgr_node->proc == proc) {
binder_user_error("%d:%d context manager tried to acquire desc 0\n",
proc->pid, thread->pid);
mutex_unlock(&context->context_mgr_node_lock);
return -EINVAL;
}
ret = binder_inc_ref_for_node(
proc, ctx_mgr_node,
strong, NULL, &rdata);
}
mutex_unlock(&context->context_mgr_node_lock);
}
if (ret)
Expand Down Expand Up @@ -5109,6 +5126,7 @@ static void binder_free_proc(struct binder_proc *proc)
BUG_ON(!list_empty(&proc->delivered_death));
binder_alloc_deferred_release(&proc->alloc);
put_task_struct(proc->tsk);
put_cred(proc->cred);
binder_stats_deleted(BINDER_STAT_PROC);
kfree(proc);
}
Expand Down Expand Up @@ -5315,7 +5333,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)) {
Expand Down Expand Up @@ -5649,6 +5667,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
get_task_struct(current->group_leader);
proc->tsk = current->group_leader;
mutex_init(&proc->files_lock);
proc->cred = get_cred(filp->f_cred);
INIT_LIST_HEAD(&proc->todo);
#ifdef CONFIG_FAST_TRACK
INIT_LIST_HEAD(&proc->fg_todo);
Expand Down
28 changes: 14 additions & 14 deletions include/linux/lsm_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -1211,22 +1211,22 @@
*
* @binder_set_context_mgr:
* Check whether @mgr is allowed to be the binder context manager.
* @mgr contains the task_struct for the task being registered.
* @mgr contains the struct cred for the current binder process.
* Return 0 if permission is granted.
* @binder_transaction:
* Check whether @from is allowed to invoke a binder transaction call
* to @to.
* @from contains the task_struct for the sending task.
* @to contains the task_struct for the receiving task.
* @from contains the struct cred for the sending process.
* @to contains the struct cred for the receiving process.
* @binder_transfer_binder:
* Check whether @from is allowed to transfer a binder reference to @to.
* @from contains the task_struct for the sending task.
* @to contains the task_struct for the receiving task.
* @from contains the struct cred for the sending process.
* @to contains the struct cred for the receiving process.
* @binder_transfer_file:
* Check whether @from is allowed to transfer @file to @to.
* @from contains the task_struct for the sending task.
* @from contains the struct cred for the sending process.
* @file contains the struct file being transferred.
* @to contains the task_struct for the receiving task.
* @to contains the struct cred for the receiving process.
*
* @ptrace_access_check:
* Check permission before allowing the current process to trace the
Expand Down Expand Up @@ -1428,13 +1428,13 @@
*
*/
union security_list_options {
int (*binder_set_context_mgr)(struct task_struct *mgr);
int (*binder_transaction)(struct task_struct *from,
struct task_struct *to);
int (*binder_transfer_binder)(struct task_struct *from,
struct task_struct *to);
int (*binder_transfer_file)(struct task_struct *from,
struct task_struct *to,
int (*binder_set_context_mgr)(const struct cred *mgr);
int (*binder_transaction)(const struct cred *from,
const struct cred *to);
int (*binder_transfer_binder)(const struct cred *from,
const struct cred *to);
int (*binder_transfer_file)(const struct cred *from,
const struct cred *to,
struct file *file);

int (*ptrace_access_check)(struct task_struct *child,
Expand Down
28 changes: 14 additions & 14 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
extern int security_init(void);

/* Security operations */
int security_binder_set_context_mgr(struct task_struct *mgr);
int security_binder_transaction(struct task_struct *from,
struct task_struct *to);
int security_binder_transfer_binder(struct task_struct *from,
struct task_struct *to);
int security_binder_transfer_file(struct task_struct *from,
struct task_struct *to, struct file *file);
int security_binder_set_context_mgr(const struct cred *mgr);
int security_binder_transaction(const struct cred *from,
const struct cred *to);
int security_binder_transfer_binder(const struct cred *from,
const struct cred *to);
int security_binder_transfer_file(const struct cred *from,
const struct cred *to, struct file *file);
int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
int security_ptrace_traceme(struct task_struct *parent);
int security_capget(struct task_struct *target,
Expand Down Expand Up @@ -448,25 +448,25 @@ static inline int security_init(void)
return 0;
}

static inline int security_binder_set_context_mgr(struct task_struct *mgr)
static inline int security_binder_set_context_mgr(const struct cred *mgr)
{
return 0;
}

static inline int security_binder_transaction(struct task_struct *from,
struct task_struct *to)
static inline int security_binder_transaction(const struct cred *from,
const struct cred *to)
{
return 0;
}

static inline int security_binder_transfer_binder(struct task_struct *from,
struct task_struct *to)
static inline int security_binder_transfer_binder(const struct cred *from,
const struct cred *to)
{
return 0;
}

static inline int security_binder_transfer_file(struct task_struct *from,
struct task_struct *to,
static inline int security_binder_transfer_file(const struct cred *from,
const struct cred *to,
struct file *file)
{
return 0;
Expand Down
2 changes: 2 additions & 0 deletions lib/iov_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
return 0;
pipe->nrbufs++;
buf->ops = &page_cache_pipe_buf_ops;
buf->flags = 0;
get_page(buf->page = page);
buf->offset = offset;
buf->len = bytes;
Expand Down Expand Up @@ -517,6 +518,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size,
break;
pipe->nrbufs++;
pipe->bufs[idx].ops = &default_pipe_buf_ops;
pipe->bufs[idx].flags = 0;
pipe->bufs[idx].page = page;
pipe->bufs[idx].offset = 0;
if (left <= PAGE_SIZE) {
Expand Down
14 changes: 7 additions & 7 deletions security/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,25 +244,25 @@ EXPORT_SYMBOL(unregister_lsm_notifier);

/* Security operations */

int security_binder_set_context_mgr(struct task_struct *mgr)
int security_binder_set_context_mgr(const struct cred *mgr)
{
return call_int_hook(binder_set_context_mgr, 0, mgr);
}

int security_binder_transaction(struct task_struct *from,
struct task_struct *to)
int security_binder_transaction(const struct cred *from,
const struct cred *to)
{
return call_int_hook(binder_transaction, 0, from, to);
}

int security_binder_transfer_binder(struct task_struct *from,
struct task_struct *to)
int security_binder_transfer_binder(const struct cred *from,
const struct cred *to)
{
return call_int_hook(binder_transfer_binder, 0, from, to);
}

int security_binder_transfer_file(struct task_struct *from,
struct task_struct *to, struct file *file)
int security_binder_transfer_file(const struct cred *from,
const struct cred *to, struct file *file)
{
return call_int_hook(binder_transfer_file, 0, from, to, file);
}
Expand Down
36 changes: 15 additions & 21 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2344,22 +2344,19 @@ static inline u32 open_file_to_av(struct file *file)

/* Hook functions begin here. */

static int selinux_binder_set_context_mgr(struct task_struct *mgr)
static int selinux_binder_set_context_mgr(const struct cred *mgr)
{
u32 mysid = current_sid();
u32 mgrsid = task_sid(mgr);

return avc_has_perm(&selinux_state,
mysid, mgrsid, SECCLASS_BINDER,
current_sid(), cred_sid(mgr), SECCLASS_BINDER,
BINDER__SET_CONTEXT_MGR, NULL);
}

static int selinux_binder_transaction(struct task_struct *from,
struct task_struct *to)
static int selinux_binder_transaction(const struct cred *from,
const struct cred *to)
{
u32 mysid = current_sid();
u32 fromsid = task_sid(from);
u32 tosid = task_sid(to);
u32 fromsid = cred_sid(from);
u32 tosid = cred_sid(to);
int rc;

if (mysid != fromsid) {
Expand All @@ -2370,27 +2367,24 @@ static int selinux_binder_transaction(struct task_struct *from,
return rc;
}

return avc_has_perm(&selinux_state,
fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
NULL);
return avc_has_perm(&selinux_state, fromsid, tosid,
SECCLASS_BINDER, BINDER__CALL, NULL);
}

static int selinux_binder_transfer_binder(struct task_struct *from,
struct task_struct *to)
static int selinux_binder_transfer_binder(const struct cred *from,
const struct cred *to)
{
u32 fromsid = task_sid(from);
u32 tosid = task_sid(to);

return avc_has_perm(&selinux_state,
fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
cred_sid(from), cred_sid(to),
SECCLASS_BINDER, BINDER__TRANSFER,
NULL);
}

static int selinux_binder_transfer_file(struct task_struct *from,
struct task_struct *to,
static int selinux_binder_transfer_file(const struct cred *from,
const struct cred *to,
struct file *file)
{
u32 sid = task_sid(to);
u32 sid = cred_sid(to);
struct file_security_struct *fsec = file->f_security;
struct dentry *dentry = file->f_path.dentry;
struct inode_security_struct *isec;
Expand Down

0 comments on commit a917a16

Please sign in to comment.