Skip to content

Commit

Permalink
SELinux: Add selfattr hooks
Browse files Browse the repository at this point in the history
Add hooks for setselfattr and getselfattr. These hooks are not very
different from their setprocattr and getprocattr equivalents, and
much of the code is shared.

Cc: selinux@vger.kernel.org
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
  • Loading branch information
Casey Schaufler authored and Paul Moore committed Nov 13, 2023
1 parent 223981d commit 762c934
Showing 1 changed file with 107 additions and 27 deletions.
134 changes: 107 additions & 27 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -6285,8 +6285,8 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
inode_doinit_with_dentry(inode, dentry);
}

static int selinux_getprocattr(struct task_struct *p,
const char *name, char **value)
static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p,
char **value)
{
const struct task_security_struct *__tsec;
u32 sid;
Expand All @@ -6303,20 +6303,27 @@ static int selinux_getprocattr(struct task_struct *p,
goto bad;
}

if (!strcmp(name, "current"))
switch (attr) {
case LSM_ATTR_CURRENT:
sid = __tsec->sid;
else if (!strcmp(name, "prev"))
break;
case LSM_ATTR_PREV:
sid = __tsec->osid;
else if (!strcmp(name, "exec"))
break;
case LSM_ATTR_EXEC:
sid = __tsec->exec_sid;
else if (!strcmp(name, "fscreate"))
break;
case LSM_ATTR_FSCREATE:
sid = __tsec->create_sid;
else if (!strcmp(name, "keycreate"))
break;
case LSM_ATTR_KEYCREATE:
sid = __tsec->keycreate_sid;
else if (!strcmp(name, "sockcreate"))
break;
case LSM_ATTR_SOCKCREATE:
sid = __tsec->sockcreate_sid;
else {
error = -EINVAL;
break;
default:
error = -EOPNOTSUPP;
goto bad;
}
rcu_read_unlock();
Expand All @@ -6334,7 +6341,7 @@ static int selinux_getprocattr(struct task_struct *p,
return error;
}

static int selinux_setprocattr(const char *name, void *value, size_t size)
static int selinux_lsm_setattr(u64 attr, void *value, size_t size)
{
struct task_security_struct *tsec;
struct cred *new;
Expand All @@ -6345,23 +6352,31 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
/*
* Basic control over ability to set these attributes at all.
*/
if (!strcmp(name, "exec"))
switch (attr) {
case LSM_ATTR_EXEC:
error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
PROCESS__SETEXEC, NULL);
else if (!strcmp(name, "fscreate"))
break;
case LSM_ATTR_FSCREATE:
error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
PROCESS__SETFSCREATE, NULL);
else if (!strcmp(name, "keycreate"))
break;
case LSM_ATTR_KEYCREATE:
error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
PROCESS__SETKEYCREATE, NULL);
else if (!strcmp(name, "sockcreate"))
break;
case LSM_ATTR_SOCKCREATE:
error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
PROCESS__SETSOCKCREATE, NULL);
else if (!strcmp(name, "current"))
break;
case LSM_ATTR_CURRENT:
error = avc_has_perm(mysid, mysid, SECCLASS_PROCESS,
PROCESS__SETCURRENT, NULL);
else
error = -EINVAL;
break;
default:
error = -EOPNOTSUPP;
break;
}
if (error)
return error;

Expand All @@ -6373,13 +6388,14 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
}
error = security_context_to_sid(value, size,
&sid, GFP_KERNEL);
if (error == -EINVAL && !strcmp(name, "fscreate")) {
if (error == -EINVAL && attr == LSM_ATTR_FSCREATE) {
if (!has_cap_mac_admin(true)) {
struct audit_buffer *ab;
size_t audit_size;

/* We strip a nul only if it is at the end, otherwise the
* context contains a nul and we should audit that */
/* We strip a nul only if it is at the end,
* otherwise the context contains a nul and
* we should audit that */
if (str[size - 1] == '\0')
audit_size = size - 1;
else
Expand All @@ -6390,7 +6406,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
if (!ab)
return error;
audit_log_format(ab, "op=fscreate invalid_context=");
audit_log_n_untrustedstring(ab, value, audit_size);
audit_log_n_untrustedstring(ab, value,
audit_size);
audit_log_end(ab);

return error;
Expand All @@ -6413,21 +6430,21 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
checks and may_create for the file creation checks. The
operation will then fail if the context is not permitted. */
tsec = selinux_cred(new);
if (!strcmp(name, "exec")) {
if (attr == LSM_ATTR_EXEC) {
tsec->exec_sid = sid;
} else if (!strcmp(name, "fscreate")) {
} else if (attr == LSM_ATTR_FSCREATE) {
tsec->create_sid = sid;
} else if (!strcmp(name, "keycreate")) {
} else if (attr == LSM_ATTR_KEYCREATE) {
if (sid) {
error = avc_has_perm(mysid, sid,
SECCLASS_KEY, KEY__CREATE, NULL);
if (error)
goto abort_change;
}
tsec->keycreate_sid = sid;
} else if (!strcmp(name, "sockcreate")) {
} else if (attr == LSM_ATTR_SOCKCREATE) {
tsec->sockcreate_sid = sid;
} else if (!strcmp(name, "current")) {
} else if (attr == LSM_ATTR_CURRENT) {
error = -EINVAL;
if (sid == 0)
goto abort_change;
Expand Down Expand Up @@ -6469,6 +6486,67 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
return error;
}

static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t *size, u32 flags)
{
char *value;
size_t total_len;
int len;
int rc = 0;

len = selinux_lsm_getattr(attr, current, &value);
if (len < 0)
return len;

total_len = ALIGN(struct_size(ctx, ctx, len), 8);

if (total_len > *size)
rc = -E2BIG;
else if (ctx)
rc = lsm_fill_user_ctx(ctx, value, len, LSM_ID_SELINUX, 0);

kfree(value);
*size = total_len;
if (rc < 0)
return rc;
return 1;
}

static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, u32 flags)
{
int rc;

rc = selinux_lsm_setattr(attr, ctx->ctx, ctx->ctx_len);
if (rc > 0)
return 0;
return rc;
}

static int selinux_getprocattr(struct task_struct *p,
const char *name, char **value)
{
unsigned int attr = lsm_name_to_attr(name);
int rc;

if (attr) {
rc = selinux_lsm_getattr(attr, p, value);
if (rc != -EOPNOTSUPP)
return rc;
}

return -EINVAL;
}

static int selinux_setprocattr(const char *name, void *value, size_t size)
{
int attr = lsm_name_to_attr(name);

if (attr)
return selinux_lsm_setattr(attr, value, size);
return -EINVAL;
}

static int selinux_ismaclabel(const char *name)
{
return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
Expand Down Expand Up @@ -7097,6 +7175,8 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {

LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),

LSM_HOOK_INIT(getselfattr, selinux_getselfattr),
LSM_HOOK_INIT(setselfattr, selinux_setselfattr),
LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
LSM_HOOK_INIT(setprocattr, selinux_setprocattr),

Expand Down

0 comments on commit 762c934

Please sign in to comment.