mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
AppArmor: Add selfattr hooks
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. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Acked-by: John Johansen <john.johansen@canonical.com> [PM: forward ported beyond v6.6 due merge window changes] Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
38b323e588
commit
223981db9b
@ -11,7 +11,7 @@
|
|||||||
#ifndef __AA_PROCATTR_H
|
#ifndef __AA_PROCATTR_H
|
||||||
#define __AA_PROCATTR_H
|
#define __AA_PROCATTR_H
|
||||||
|
|
||||||
int aa_getprocattr(struct aa_label *label, char **string);
|
int aa_getprocattr(struct aa_label *label, char **string, bool newline);
|
||||||
int aa_setprocattr_changehat(char *args, size_t size, int flags);
|
int aa_setprocattr_changehat(char *args, size_t size, int flags);
|
||||||
|
|
||||||
#endif /* __AA_PROCATTR_H */
|
#endif /* __AA_PROCATTR_H */
|
||||||
|
@ -776,6 +776,55 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx,
|
||||||
|
size_t *size, u32 flags)
|
||||||
|
{
|
||||||
|
int error = -ENOENT;
|
||||||
|
struct aa_task_ctx *ctx = task_ctx(current);
|
||||||
|
struct aa_label *label = NULL;
|
||||||
|
size_t total_len = 0;
|
||||||
|
char *value;
|
||||||
|
|
||||||
|
switch (attr) {
|
||||||
|
case LSM_ATTR_CURRENT:
|
||||||
|
label = aa_get_newest_label(cred_label(current_cred()));
|
||||||
|
break;
|
||||||
|
case LSM_ATTR_PREV:
|
||||||
|
if (ctx->previous)
|
||||||
|
label = aa_get_newest_label(ctx->previous);
|
||||||
|
break;
|
||||||
|
case LSM_ATTR_EXEC:
|
||||||
|
if (ctx->onexec)
|
||||||
|
label = aa_get_newest_label(ctx->onexec);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = -EOPNOTSUPP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
error = aa_getprocattr(label, &value, false);
|
||||||
|
if (error > 0) {
|
||||||
|
total_len = ALIGN(struct_size(lx, ctx, error), 8);
|
||||||
|
if (total_len > *size)
|
||||||
|
error = -E2BIG;
|
||||||
|
else if (lx)
|
||||||
|
error = lsm_fill_user_ctx(lx, value, error,
|
||||||
|
LSM_ID_APPARMOR, 0);
|
||||||
|
else
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
kfree(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
aa_put_label(label);
|
||||||
|
|
||||||
|
*size = total_len;
|
||||||
|
if (error < 0)
|
||||||
|
return error;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int apparmor_getprocattr(struct task_struct *task, const char *name,
|
static int apparmor_getprocattr(struct task_struct *task, const char *name,
|
||||||
char **value)
|
char **value)
|
||||||
{
|
{
|
||||||
@ -795,7 +844,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
|
|||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
error = aa_getprocattr(label, value);
|
error = aa_getprocattr(label, value, true);
|
||||||
|
|
||||||
aa_put_label(label);
|
aa_put_label(label);
|
||||||
put_cred(cred);
|
put_cred(cred);
|
||||||
@ -803,8 +852,7 @@ static int apparmor_getprocattr(struct task_struct *task, const char *name,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apparmor_setprocattr(const char *name, void *value,
|
static int do_setattr(u64 attr, void *value, size_t size)
|
||||||
size_t size)
|
|
||||||
{
|
{
|
||||||
char *command, *largs = NULL, *args = value;
|
char *command, *largs = NULL, *args = value;
|
||||||
size_t arg_size;
|
size_t arg_size;
|
||||||
@ -835,7 +883,7 @@ static int apparmor_setprocattr(const char *name, void *value,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
arg_size = size - (args - (largs ? largs : (char *) value));
|
arg_size = size - (args - (largs ? largs : (char *) value));
|
||||||
if (strcmp(name, "current") == 0) {
|
if (attr == LSM_ATTR_CURRENT) {
|
||||||
if (strcmp(command, "changehat") == 0) {
|
if (strcmp(command, "changehat") == 0) {
|
||||||
error = aa_setprocattr_changehat(args, arg_size,
|
error = aa_setprocattr_changehat(args, arg_size,
|
||||||
AA_CHANGE_NOFLAGS);
|
AA_CHANGE_NOFLAGS);
|
||||||
@ -850,7 +898,7 @@ static int apparmor_setprocattr(const char *name, void *value,
|
|||||||
error = aa_change_profile(args, AA_CHANGE_STACK);
|
error = aa_change_profile(args, AA_CHANGE_STACK);
|
||||||
} else
|
} else
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (strcmp(name, "exec") == 0) {
|
} else if (attr == LSM_ATTR_EXEC) {
|
||||||
if (strcmp(command, "exec") == 0)
|
if (strcmp(command, "exec") == 0)
|
||||||
error = aa_change_profile(args, AA_CHANGE_ONEXEC);
|
error = aa_change_profile(args, AA_CHANGE_ONEXEC);
|
||||||
else if (strcmp(command, "stack") == 0)
|
else if (strcmp(command, "stack") == 0)
|
||||||
@ -870,13 +918,42 @@ static int apparmor_setprocattr(const char *name, void *value,
|
|||||||
|
|
||||||
fail:
|
fail:
|
||||||
ad.subj_label = begin_current_label_crit_section();
|
ad.subj_label = begin_current_label_crit_section();
|
||||||
ad.info = name;
|
if (attr == LSM_ATTR_CURRENT)
|
||||||
|
ad.info = "current";
|
||||||
|
else if (attr == LSM_ATTR_EXEC)
|
||||||
|
ad.info = "exec";
|
||||||
|
else
|
||||||
|
ad.info = "invalid";
|
||||||
ad.error = error = -EINVAL;
|
ad.error = error = -EINVAL;
|
||||||
aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
|
aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
|
||||||
end_current_label_crit_section(ad.subj_label);
|
end_current_label_crit_section(ad.subj_label);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
|
||||||
|
size_t size, u32 flags)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (attr != LSM_ATTR_CURRENT && attr != LSM_ATTR_EXEC)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
rc = do_setattr(attr, ctx->ctx, ctx->ctx_len);
|
||||||
|
if (rc > 0)
|
||||||
|
return 0;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apparmor_setprocattr(const char *name, void *value,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
int attr = lsm_name_to_attr(name);
|
||||||
|
|
||||||
|
if (attr)
|
||||||
|
return do_setattr(attr, value, size);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apparmor_bprm_committing_creds - do task cleanup on committing new creds
|
* apparmor_bprm_committing_creds - do task cleanup on committing new creds
|
||||||
* @bprm: binprm for the exec (NOT NULL)
|
* @bprm: binprm for the exec (NOT NULL)
|
||||||
@ -1424,6 +1501,8 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
|
|||||||
LSM_HOOK_INIT(file_lock, apparmor_file_lock),
|
LSM_HOOK_INIT(file_lock, apparmor_file_lock),
|
||||||
LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),
|
LSM_HOOK_INIT(file_truncate, apparmor_file_truncate),
|
||||||
|
|
||||||
|
LSM_HOOK_INIT(getselfattr, apparmor_getselfattr),
|
||||||
|
LSM_HOOK_INIT(setselfattr, apparmor_setselfattr),
|
||||||
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
|
LSM_HOOK_INIT(getprocattr, apparmor_getprocattr),
|
||||||
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
|
LSM_HOOK_INIT(setprocattr, apparmor_setprocattr),
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
* aa_getprocattr - Return the label information for @label
|
* aa_getprocattr - Return the label information for @label
|
||||||
* @label: the label to print label info about (NOT NULL)
|
* @label: the label to print label info about (NOT NULL)
|
||||||
* @string: Returns - string containing the label info (NOT NULL)
|
* @string: Returns - string containing the label info (NOT NULL)
|
||||||
|
* @newline: indicates that a newline should be added
|
||||||
*
|
*
|
||||||
* Requires: label != NULL && string != NULL
|
* Requires: label != NULL && string != NULL
|
||||||
*
|
*
|
||||||
@ -27,7 +28,7 @@
|
|||||||
*
|
*
|
||||||
* Returns: size of string placed in @string else error code on failure
|
* Returns: size of string placed in @string else error code on failure
|
||||||
*/
|
*/
|
||||||
int aa_getprocattr(struct aa_label *label, char **string)
|
int aa_getprocattr(struct aa_label *label, char **string, bool newline)
|
||||||
{
|
{
|
||||||
struct aa_ns *ns = labels_ns(label);
|
struct aa_ns *ns = labels_ns(label);
|
||||||
struct aa_ns *current_ns = aa_get_current_ns();
|
struct aa_ns *current_ns = aa_get_current_ns();
|
||||||
@ -57,11 +58,12 @@ int aa_getprocattr(struct aa_label *label, char **string)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*string)[len] = '\n';
|
if (newline)
|
||||||
(*string)[len + 1] = 0;
|
(*string)[len++] = '\n';
|
||||||
|
(*string)[len] = 0;
|
||||||
|
|
||||||
aa_put_ns(current_ns);
|
aa_put_ns(current_ns);
|
||||||
return len + 1;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user