Commit be0554c9 authored by Stephen Smalley's avatar Stephen Smalley Committed by Paul Moore

selinux: clean up cred usage and simplify

SELinux was sometimes using the task "objective" credentials when
it could/should use the "subjective" credentials.  This was sometimes
hidden by the fact that we were unnecessarily passing around pointers
to the current task, making it appear as if the task could be something
other than current, so eliminate all such passing of current.  Inline
various permission checking helper functions that can be reduced to a
single avc_has_perm() call.

Since the credentials infrastructure only allows a task to alter
its own credentials, we can always assume that current must be the same
as the target task in selinux_setprocattr after the check. We likely
should move this check from selinux_setprocattr() to proc_pid_attr_write()
and drop the task argument to the security hook altogether; it can only
serve to confuse things.
Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 01593d32
This diff is collapsed.
......@@ -37,6 +37,16 @@ struct task_security_struct {
u32 sockcreate_sid; /* fscreate SID */
};
/*
* get the subjective security ID of the current task
*/
static inline u32 current_sid(void)
{
const struct task_security_struct *tsec = current_security();
return tsec->sid;
}
enum label_initialized {
LABEL_INVALID, /* invalid or not initialized */
LABEL_INITIALIZED, /* initialized */
......
......@@ -77,25 +77,6 @@ static char policy_opened;
/* global data for policy capabilities */
static struct dentry *policycap_dir;
/* Check whether a task is allowed to use a security operation. */
static int task_has_security(struct task_struct *tsk,
u32 perms)
{
const struct task_security_struct *tsec;
u32 sid = 0;
rcu_read_lock();
tsec = __task_cred(tsk)->security;
if (tsec)
sid = tsec->sid;
rcu_read_unlock();
if (!tsec)
return -EACCES;
return avc_has_perm(sid, SECINITSID_SECURITY,
SECCLASS_SECURITY, perms, NULL);
}
enum sel_inos {
SEL_ROOT_INO = 2,
SEL_LOAD, /* load policy */
......@@ -166,7 +147,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
new_value = !!new_value;
if (new_value != selinux_enforcing) {
length = task_has_security(current, SECURITY__SETENFORCE);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETENFORCE,
NULL);
if (length)
goto out;
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
......@@ -368,7 +351,8 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
mutex_lock(&sel_mutex);
rc = task_has_security(current, SECURITY__READ_POLICY);
rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
if (rc)
goto err;
......@@ -429,7 +413,8 @@ static ssize_t sel_read_policy(struct file *filp, char __user *buf,
mutex_lock(&sel_mutex);
ret = task_has_security(current, SECURITY__READ_POLICY);
ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL);
if (ret)
goto out;
......@@ -499,7 +484,8 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
mutex_lock(&sel_mutex);
length = task_has_security(current, SECURITY__LOAD_POLICY);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL);
if (length)
goto out;
......@@ -561,7 +547,8 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
u32 sid, len;
ssize_t length;
length = task_has_security(current, SECURITY__CHECK_CONTEXT);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, NULL);
if (length)
goto out;
......@@ -604,7 +591,9 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
ssize_t length;
unsigned int new_value;
length = task_has_security(current, SECURITY__SETCHECKREQPROT);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT,
NULL);
if (length)
return length;
......@@ -645,7 +634,8 @@ static ssize_t sel_write_validatetrans(struct file *file,
u16 tclass;
int rc;
rc = task_has_security(current, SECURITY__VALIDATE_TRANS);
rc = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__VALIDATE_TRANS, NULL);
if (rc)
goto out;
......@@ -772,7 +762,8 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
struct av_decision avd;
ssize_t length;
length = task_has_security(current, SECURITY__COMPUTE_AV);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__COMPUTE_AV, NULL);
if (length)
goto out;
......@@ -822,7 +813,9 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
u32 len;
int nargs;
length = task_has_security(current, SECURITY__COMPUTE_CREATE);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE,
NULL);
if (length)
goto out;
......@@ -919,7 +912,9 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
char *newcon = NULL;
u32 len;
length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL,
NULL);
if (length)
goto out;
......@@ -975,7 +970,9 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
int i, rc;
u32 len, nsids;
length = task_has_security(current, SECURITY__COMPUTE_USER);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__COMPUTE_USER,
NULL);
if (length)
goto out;
......@@ -1035,7 +1032,9 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
char *newcon = NULL;
u32 len;
length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER,
NULL);
if (length)
goto out;
......@@ -1142,7 +1141,9 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
mutex_lock(&sel_mutex);
length = task_has_security(current, SECURITY__SETBOOL);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETBOOL,
NULL);
if (length)
goto out;
......@@ -1198,7 +1199,9 @@ static ssize_t sel_commit_bools_write(struct file *filep,
mutex_lock(&sel_mutex);
length = task_has_security(current, SECURITY__SETBOOL);
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETBOOL,
NULL);
if (length)
goto out;
......@@ -1351,7 +1354,9 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
ssize_t ret;
unsigned int new_value;
ret = task_has_security(current, SECURITY__SETSECPARAM);
ret = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETSECPARAM,
NULL);
if (ret)
return ret;
......
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