Skip to content

Commit 52f8869

Browse files
toddkjospcmoore
authored andcommitted
binder: use cred instead of task for selinux checks
Since binder was integrated with selinux, it has passed 'struct task_struct' associated with the binder_proc to represent the source and target of transactions. The conversion of task to SID was then done in the hook implementations. It turns out that there are race conditions which can result in an incorrect security context being used. Fix by using the 'struct cred' saved during binder_open and pass it to the selinux subsystem. Cc: [email protected] # 5.14 (need backport for earlier stables) Fixes: 79af730 ("Add security hooks to binder and implement the hooks for SELinux.") Suggested-by: Jann Horn <[email protected]> Signed-off-by: Todd Kjos <[email protected]> Acked-by: Casey Schaufler <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 29bc22a commit 52f8869

File tree

6 files changed

+54
-76
lines changed

6 files changed

+54
-76
lines changed

drivers/android/binder.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,7 +2047,7 @@ static int binder_translate_binder(struct flat_binder_object *fp,
20472047
ret = -EINVAL;
20482048
goto done;
20492049
}
2050-
if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
2050+
if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
20512051
ret = -EPERM;
20522052
goto done;
20532053
}
@@ -2093,7 +2093,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,
20932093
proc->pid, thread->pid, fp->handle);
20942094
return -EINVAL;
20952095
}
2096-
if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
2096+
if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
20972097
ret = -EPERM;
20982098
goto done;
20992099
}
@@ -2181,7 +2181,7 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
21812181
ret = -EBADF;
21822182
goto err_fget;
21832183
}
2184-
ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
2184+
ret = security_binder_transfer_file(proc->cred, target_proc->cred, file);
21852185
if (ret < 0) {
21862186
ret = -EPERM;
21872187
goto err_security;
@@ -2586,8 +2586,8 @@ static void binder_transaction(struct binder_proc *proc,
25862586
return_error_line = __LINE__;
25872587
goto err_invalid_target_handle;
25882588
}
2589-
if (security_binder_transaction(proc->tsk,
2590-
target_proc->tsk) < 0) {
2589+
if (security_binder_transaction(proc->cred,
2590+
target_proc->cred) < 0) {
25912591
return_error = BR_FAILED_REPLY;
25922592
return_error_param = -EPERM;
25932593
return_error_line = __LINE__;
@@ -4555,7 +4555,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp,
45554555
ret = -EBUSY;
45564556
goto out;
45574557
}
4558-
ret = security_binder_set_context_mgr(proc->tsk);
4558+
ret = security_binder_set_context_mgr(proc->cred);
45594559
if (ret < 0)
45604560
goto out;
45614561
if (uid_valid(context->binder_context_mgr_uid)) {

include/linux/lsm_hook_defs.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
* #undef LSM_HOOK
2727
* };
2828
*/
29-
LSM_HOOK(int, 0, binder_set_context_mgr, struct task_struct *mgr)
30-
LSM_HOOK(int, 0, binder_transaction, struct task_struct *from,
31-
struct task_struct *to)
32-
LSM_HOOK(int, 0, binder_transfer_binder, struct task_struct *from,
33-
struct task_struct *to)
34-
LSM_HOOK(int, 0, binder_transfer_file, struct task_struct *from,
35-
struct task_struct *to, struct file *file)
29+
LSM_HOOK(int, 0, binder_set_context_mgr, const struct cred *mgr)
30+
LSM_HOOK(int, 0, binder_transaction, const struct cred *from,
31+
const struct cred *to)
32+
LSM_HOOK(int, 0, binder_transfer_binder, const struct cred *from,
33+
const struct cred *to)
34+
LSM_HOOK(int, 0, binder_transfer_file, const struct cred *from,
35+
const struct cred *to, struct file *file)
3636
LSM_HOOK(int, 0, ptrace_access_check, struct task_struct *child,
3737
unsigned int mode)
3838
LSM_HOOK(int, 0, ptrace_traceme, struct task_struct *parent)

include/linux/lsm_hooks.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,22 +1313,22 @@
13131313
*
13141314
* @binder_set_context_mgr:
13151315
* Check whether @mgr is allowed to be the binder context manager.
1316-
* @mgr contains the task_struct for the task being registered.
1316+
* @mgr contains the struct cred for the current binder process.
13171317
* Return 0 if permission is granted.
13181318
* @binder_transaction:
13191319
* Check whether @from is allowed to invoke a binder transaction call
13201320
* to @to.
1321-
* @from contains the task_struct for the sending task.
1322-
* @to contains the task_struct for the receiving task.
1321+
* @from contains the struct cred for the sending process.
1322+
* @to contains the struct cred for the receiving process.
13231323
* @binder_transfer_binder:
13241324
* Check whether @from is allowed to transfer a binder reference to @to.
1325-
* @from contains the task_struct for the sending task.
1326-
* @to contains the task_struct for the receiving task.
1325+
* @from contains the struct cred for the sending process.
1326+
* @to contains the struct cred for the receiving process.
13271327
* @binder_transfer_file:
13281328
* Check whether @from is allowed to transfer @file to @to.
1329-
* @from contains the task_struct for the sending task.
1329+
* @from contains the struct cred for the sending process.
13301330
* @file contains the struct file being transferred.
1331-
* @to contains the task_struct for the receiving task.
1331+
* @to contains the struct cred for the receiving process.
13321332
*
13331333
* @ptrace_access_check:
13341334
* Check permission before allowing the current process to trace the

include/linux/security.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,13 @@ extern int security_init(void);
258258
extern int early_security_init(void);
259259

260260
/* Security operations */
261-
int security_binder_set_context_mgr(struct task_struct *mgr);
262-
int security_binder_transaction(struct task_struct *from,
263-
struct task_struct *to);
264-
int security_binder_transfer_binder(struct task_struct *from,
265-
struct task_struct *to);
266-
int security_binder_transfer_file(struct task_struct *from,
267-
struct task_struct *to, struct file *file);
261+
int security_binder_set_context_mgr(const struct cred *mgr);
262+
int security_binder_transaction(const struct cred *from,
263+
const struct cred *to);
264+
int security_binder_transfer_binder(const struct cred *from,
265+
const struct cred *to);
266+
int security_binder_transfer_file(const struct cred *from,
267+
const struct cred *to, struct file *file);
268268
int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
269269
int security_ptrace_traceme(struct task_struct *parent);
270270
int security_capget(struct task_struct *target,
@@ -508,25 +508,25 @@ static inline int early_security_init(void)
508508
return 0;
509509
}
510510

511-
static inline int security_binder_set_context_mgr(struct task_struct *mgr)
511+
static inline int security_binder_set_context_mgr(const struct cred *mgr)
512512
{
513513
return 0;
514514
}
515515

516-
static inline int security_binder_transaction(struct task_struct *from,
517-
struct task_struct *to)
516+
static inline int security_binder_transaction(const struct cred *from,
517+
const struct cred *to)
518518
{
519519
return 0;
520520
}
521521

522-
static inline int security_binder_transfer_binder(struct task_struct *from,
523-
struct task_struct *to)
522+
static inline int security_binder_transfer_binder(const struct cred *from,
523+
const struct cred *to)
524524
{
525525
return 0;
526526
}
527527

528-
static inline int security_binder_transfer_file(struct task_struct *from,
529-
struct task_struct *to,
528+
static inline int security_binder_transfer_file(const struct cred *from,
529+
const struct cred *to,
530530
struct file *file)
531531
{
532532
return 0;

security/security.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -747,25 +747,25 @@ static int lsm_superblock_alloc(struct super_block *sb)
747747

748748
/* Security operations */
749749

750-
int security_binder_set_context_mgr(struct task_struct *mgr)
750+
int security_binder_set_context_mgr(const struct cred *mgr)
751751
{
752752
return call_int_hook(binder_set_context_mgr, 0, mgr);
753753
}
754754

755-
int security_binder_transaction(struct task_struct *from,
756-
struct task_struct *to)
755+
int security_binder_transaction(const struct cred *from,
756+
const struct cred *to)
757757
{
758758
return call_int_hook(binder_transaction, 0, from, to);
759759
}
760760

761-
int security_binder_transfer_binder(struct task_struct *from,
762-
struct task_struct *to)
761+
int security_binder_transfer_binder(const struct cred *from,
762+
const struct cred *to)
763763
{
764764
return call_int_hook(binder_transfer_binder, 0, from, to);
765765
}
766766

767-
int security_binder_transfer_file(struct task_struct *from,
768-
struct task_struct *to, struct file *file)
767+
int security_binder_transfer_file(const struct cred *from,
768+
const struct cred *to, struct file *file)
769769
{
770770
return call_int_hook(binder_transfer_file, 0, from, to, file);
771771
}

security/selinux/hooks.c

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,6 @@ static inline u32 task_sid_obj(const struct task_struct *task)
255255
return sid;
256256
}
257257

258-
/*
259-
* get the security ID of a task for use with binder
260-
*/
261-
static inline u32 task_sid_binder(const struct task_struct *task)
262-
{
263-
/*
264-
* In many case where this function is used we should be using the
265-
* task's subjective SID, but we can't reliably access the subjective
266-
* creds of a task other than our own so we must use the objective
267-
* creds/SID, which are safe to access. The downside is that if a task
268-
* is temporarily overriding it's creds it will not be reflected here;
269-
* however, it isn't clear that binder would handle that case well
270-
* anyway.
271-
*
272-
* If this ever changes and we can safely reference the subjective
273-
* creds/SID of another task, this function will make it easier to
274-
* identify the various places where we make use of the task SIDs in
275-
* the binder code. It is also likely that we will need to adjust
276-
* the main drivers/android binder code as well.
277-
*/
278-
return task_sid_obj(task);
279-
}
280-
281258
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
282259

283260
/*
@@ -2067,18 +2044,19 @@ static inline u32 open_file_to_av(struct file *file)
20672044

20682045
/* Hook functions begin here. */
20692046

2070-
static int selinux_binder_set_context_mgr(struct task_struct *mgr)
2047+
static int selinux_binder_set_context_mgr(const struct cred *mgr)
20712048
{
20722049
return avc_has_perm(&selinux_state,
2073-
current_sid(), task_sid_binder(mgr), SECCLASS_BINDER,
2050+
current_sid(), cred_sid(mgr), SECCLASS_BINDER,
20742051
BINDER__SET_CONTEXT_MGR, NULL);
20752052
}
20762053

2077-
static int selinux_binder_transaction(struct task_struct *from,
2078-
struct task_struct *to)
2054+
static int selinux_binder_transaction(const struct cred *from,
2055+
const struct cred *to)
20792056
{
20802057
u32 mysid = current_sid();
2081-
u32 fromsid = task_sid_binder(from);
2058+
u32 fromsid = cred_sid(from);
2059+
u32 tosid = cred_sid(to);
20822060
int rc;
20832061

20842062
if (mysid != fromsid) {
@@ -2089,24 +2067,24 @@ static int selinux_binder_transaction(struct task_struct *from,
20892067
return rc;
20902068
}
20912069

2092-
return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
2070+
return avc_has_perm(&selinux_state, fromsid, tosid,
20932071
SECCLASS_BINDER, BINDER__CALL, NULL);
20942072
}
20952073

2096-
static int selinux_binder_transfer_binder(struct task_struct *from,
2097-
struct task_struct *to)
2074+
static int selinux_binder_transfer_binder(const struct cred *from,
2075+
const struct cred *to)
20982076
{
20992077
return avc_has_perm(&selinux_state,
2100-
task_sid_binder(from), task_sid_binder(to),
2078+
cred_sid(from), cred_sid(to),
21012079
SECCLASS_BINDER, BINDER__TRANSFER,
21022080
NULL);
21032081
}
21042082

2105-
static int selinux_binder_transfer_file(struct task_struct *from,
2106-
struct task_struct *to,
2083+
static int selinux_binder_transfer_file(const struct cred *from,
2084+
const struct cred *to,
21072085
struct file *file)
21082086
{
2109-
u32 sid = task_sid_binder(to);
2087+
u32 sid = cred_sid(to);
21102088
struct file_security_struct *fsec = selinux_file(file);
21112089
struct dentry *dentry = file->f_path.dentry;
21122090
struct inode_security_struct *isec;

0 commit comments

Comments
 (0)