Commit eb1231f7 authored by Paul Moore's avatar Paul Moore

selinux: clarify task subjective and objective credentials

SELinux has a function, task_sid(), which returns the task's
objective credentials, but unfortunately is used in a few places
where the subjective task credentials should be used.  Most notably
in the new security_task_getsecid_subj() LSM hook.

This patch fixes this and attempts to make things more obvious by
introducing a new function, task_sid_subj(), and renaming the
existing task_sid() function to task_sid_obj().

This patch also adds an interesting function in task_sid_binder().
The task_sid_binder() function has a comment which hopefully
describes it's reason for being, but it basically boils down to the
simple fact that we can't safely access another task's subjective
credentials so in the case of binder we need to stick with the
objective credentials regardless.
Reviewed-by: default avatarRichard Guy Briggs <rgb@redhat.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 4ebd7651
...@@ -229,10 +229,23 @@ static inline u32 cred_sid(const struct cred *cred) ...@@ -229,10 +229,23 @@ static inline u32 cred_sid(const struct cred *cred)
return tsec->sid; return tsec->sid;
} }
/*
* get the subjective security ID of a task
*/
static inline u32 task_sid_subj(const struct task_struct *task)
{
u32 sid;
rcu_read_lock();
sid = cred_sid(rcu_dereference(task->cred));
rcu_read_unlock();
return sid;
}
/* /*
* get the objective security ID of a task * get the objective security ID of a task
*/ */
static inline u32 task_sid(const struct task_struct *task) static inline u32 task_sid_obj(const struct task_struct *task)
{ {
u32 sid; u32 sid;
...@@ -242,6 +255,29 @@ static inline u32 task_sid(const struct task_struct *task) ...@@ -242,6 +255,29 @@ static inline u32 task_sid(const struct task_struct *task)
return sid; return sid;
} }
/*
* get the security ID of a task for use with binder
*/
static inline u32 task_sid_binder(const struct task_struct *task)
{
/*
* In many case where this function is used we should be using the
* task's subjective SID, but we can't reliably access the subjective
* creds of a task other than our own so we must use the objective
* creds/SID, 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.
*
* If this ever changes and we can safely reference the subjective
* creds/SID of another task, this function will make it easier to
* identify the various places where we make use of the task SIDs in
* the binder code. It is also likely that we will need to adjust
* the main drivers/android binder code as well.
*/
return task_sid_obj(task);
}
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
/* /*
...@@ -2035,11 +2071,8 @@ static inline u32 open_file_to_av(struct file *file) ...@@ -2035,11 +2071,8 @@ static inline u32 open_file_to_av(struct file *file)
static int selinux_binder_set_context_mgr(struct task_struct *mgr) static int selinux_binder_set_context_mgr(struct task_struct *mgr)
{ {
u32 mysid = current_sid();
u32 mgrsid = task_sid(mgr);
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
mysid, mgrsid, SECCLASS_BINDER, current_sid(), task_sid_binder(mgr), SECCLASS_BINDER,
BINDER__SET_CONTEXT_MGR, NULL); BINDER__SET_CONTEXT_MGR, NULL);
} }
...@@ -2047,8 +2080,7 @@ static int selinux_binder_transaction(struct task_struct *from, ...@@ -2047,8 +2080,7 @@ static int selinux_binder_transaction(struct task_struct *from,
struct task_struct *to) struct task_struct *to)
{ {
u32 mysid = current_sid(); u32 mysid = current_sid();
u32 fromsid = task_sid(from); u32 fromsid = task_sid_binder(from);
u32 tosid = task_sid(to);
int rc; int rc;
if (mysid != fromsid) { if (mysid != fromsid) {
...@@ -2059,19 +2091,16 @@ static int selinux_binder_transaction(struct task_struct *from, ...@@ -2059,19 +2091,16 @@ static int selinux_binder_transaction(struct task_struct *from,
return rc; return rc;
} }
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
fromsid, tosid, SECCLASS_BINDER, BINDER__CALL, SECCLASS_BINDER, BINDER__CALL, NULL);
NULL);
} }
static int selinux_binder_transfer_binder(struct task_struct *from, static int selinux_binder_transfer_binder(struct task_struct *from,
struct task_struct *to) struct task_struct *to)
{ {
u32 fromsid = task_sid(from);
u32 tosid = task_sid(to);
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER, task_sid_binder(from), task_sid_binder(to),
SECCLASS_BINDER, BINDER__TRANSFER,
NULL); NULL);
} }
...@@ -2079,7 +2108,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, ...@@ -2079,7 +2108,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
struct task_struct *to, struct task_struct *to,
struct file *file) struct file *file)
{ {
u32 sid = task_sid(to); u32 sid = task_sid_binder(to);
struct file_security_struct *fsec = selinux_file(file); struct file_security_struct *fsec = selinux_file(file);
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
struct inode_security_struct *isec; struct inode_security_struct *isec;
...@@ -2115,10 +2144,10 @@ static int selinux_binder_transfer_file(struct task_struct *from, ...@@ -2115,10 +2144,10 @@ static int selinux_binder_transfer_file(struct task_struct *from,
} }
static int selinux_ptrace_access_check(struct task_struct *child, static int selinux_ptrace_access_check(struct task_struct *child,
unsigned int mode) unsigned int mode)
{ {
u32 sid = current_sid(); u32 sid = current_sid();
u32 csid = task_sid(child); u32 csid = task_sid_obj(child);
if (mode & PTRACE_MODE_READ) if (mode & PTRACE_MODE_READ)
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
...@@ -2131,15 +2160,15 @@ static int selinux_ptrace_access_check(struct task_struct *child, ...@@ -2131,15 +2160,15 @@ static int selinux_ptrace_access_check(struct task_struct *child,
static int selinux_ptrace_traceme(struct task_struct *parent) static int selinux_ptrace_traceme(struct task_struct *parent)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
task_sid(parent), current_sid(), SECCLASS_PROCESS, task_sid_subj(parent), task_sid_obj(current),
PROCESS__PTRACE, NULL); SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
} }
static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
kernel_cap_t *inheritable, kernel_cap_t *permitted) kernel_cap_t *inheritable, kernel_cap_t *permitted)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(target), SECCLASS_PROCESS, current_sid(), task_sid_obj(target), SECCLASS_PROCESS,
PROCESS__GETCAP, NULL); PROCESS__GETCAP, NULL);
} }
...@@ -2264,7 +2293,7 @@ static u32 ptrace_parent_sid(void) ...@@ -2264,7 +2293,7 @@ static u32 ptrace_parent_sid(void)
rcu_read_lock(); rcu_read_lock();
tracer = ptrace_parent(current); tracer = ptrace_parent(current);
if (tracer) if (tracer)
sid = task_sid(tracer); sid = task_sid_obj(tracer);
rcu_read_unlock(); rcu_read_unlock();
return sid; return sid;
...@@ -3976,7 +4005,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, ...@@ -3976,7 +4005,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int signum) struct fown_struct *fown, int signum)
{ {
struct file *file; struct file *file;
u32 sid = task_sid(tsk); u32 sid = task_sid_obj(tsk);
u32 perm; u32 perm;
struct file_security_struct *fsec; struct file_security_struct *fsec;
...@@ -4195,47 +4224,52 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents) ...@@ -4195,47 +4224,52 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__SETPGID, NULL); PROCESS__SETPGID, NULL);
} }
static int selinux_task_getpgid(struct task_struct *p) static int selinux_task_getpgid(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__GETPGID, NULL); PROCESS__GETPGID, NULL);
} }
static int selinux_task_getsid(struct task_struct *p) static int selinux_task_getsid(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__GETSESSION, NULL); PROCESS__GETSESSION, NULL);
} }
static void selinux_task_getsecid(struct task_struct *p, u32 *secid) static void selinux_task_getsecid_subj(struct task_struct *p, u32 *secid)
{
*secid = task_sid_subj(p);
}
static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid)
{ {
*secid = task_sid(p); *secid = task_sid_obj(p);
} }
static int selinux_task_setnice(struct task_struct *p, int nice) static int selinux_task_setnice(struct task_struct *p, int nice)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__SETSCHED, NULL); PROCESS__SETSCHED, NULL);
} }
static int selinux_task_setioprio(struct task_struct *p, int ioprio) static int selinux_task_setioprio(struct task_struct *p, int ioprio)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__SETSCHED, NULL); PROCESS__SETSCHED, NULL);
} }
static int selinux_task_getioprio(struct task_struct *p) static int selinux_task_getioprio(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__GETSCHED, NULL); PROCESS__GETSCHED, NULL);
} }
...@@ -4266,7 +4300,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, ...@@ -4266,7 +4300,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
upon context transitions. See selinux_bprm_committing_creds. */ upon context transitions. See selinux_bprm_committing_creds. */
if (old_rlim->rlim_max != new_rlim->rlim_max) if (old_rlim->rlim_max != new_rlim->rlim_max)
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), current_sid(), task_sid_obj(p),
SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL); SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
return 0; return 0;
...@@ -4275,21 +4309,21 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, ...@@ -4275,21 +4309,21 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
static int selinux_task_setscheduler(struct task_struct *p) static int selinux_task_setscheduler(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__SETSCHED, NULL); PROCESS__SETSCHED, NULL);
} }
static int selinux_task_getscheduler(struct task_struct *p) static int selinux_task_getscheduler(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__GETSCHED, NULL); PROCESS__GETSCHED, NULL);
} }
static int selinux_task_movememory(struct task_struct *p) static int selinux_task_movememory(struct task_struct *p)
{ {
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
current_sid(), task_sid(p), SECCLASS_PROCESS, current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
PROCESS__SETSCHED, NULL); PROCESS__SETSCHED, NULL);
} }
...@@ -4308,14 +4342,14 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info, ...@@ -4308,14 +4342,14 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
else else
secid = cred_sid(cred); secid = cred_sid(cred);
return avc_has_perm(&selinux_state, return avc_has_perm(&selinux_state,
secid, task_sid(p), SECCLASS_PROCESS, perm, NULL); secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
} }
static void selinux_task_to_inode(struct task_struct *p, static void selinux_task_to_inode(struct task_struct *p,
struct inode *inode) struct inode *inode)
{ {
struct inode_security_struct *isec = selinux_inode(inode); struct inode_security_struct *isec = selinux_inode(inode);
u32 sid = task_sid(p); u32 sid = task_sid_obj(p);
spin_lock(&isec->lock); spin_lock(&isec->lock);
isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sclass = inode_mode_to_security_class(inode->i_mode);
...@@ -6208,7 +6242,7 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m ...@@ -6208,7 +6242,7 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m
struct ipc_security_struct *isec; struct ipc_security_struct *isec;
struct msg_security_struct *msec; struct msg_security_struct *msec;
struct common_audit_data ad; struct common_audit_data ad;
u32 sid = task_sid(target); u32 sid = task_sid_subj(target);
int rc; int rc;
isec = selinux_ipc(msq); isec = selinux_ipc(msq);
...@@ -7205,8 +7239,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { ...@@ -7205,8 +7239,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
LSM_HOOK_INIT(task_getsid, selinux_task_getsid), LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid), LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid_subj),
LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid), LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid_obj),
LSM_HOOK_INIT(task_setnice, selinux_task_setnice), LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio), LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio), LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment