Commit 2d9da9b1 authored by John Johansen's avatar John Johansen

apparmor: allow restricting unprivileged change_profile

unprivileged unconfined can use change_profile to alter the confinement
set by the mac admin.

Allow restricting unprivileged unconfined by still allowing change_profile
but stacking the change against unconfined. This allows unconfined to
still apply system policy but allows the task to enter the new confinement.

If unprivileged unconfined is required a sysctl is provided to switch
to the previous behavior.
Reviewed-by: default avatarGeorgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: default avatarJohn Johansen <john.johansen@canonical.com>
parent e105d807
...@@ -2341,6 +2341,11 @@ static struct aa_sfs_entry aa_sfs_entry_domain[] = { ...@@ -2341,6 +2341,11 @@ static struct aa_sfs_entry aa_sfs_entry_domain[] = {
{ } { }
}; };
static struct aa_sfs_entry aa_sfs_entry_unconfined[] = {
AA_SFS_FILE_BOOLEAN("change_profile", 1),
{ }
};
static struct aa_sfs_entry aa_sfs_entry_versions[] = { static struct aa_sfs_entry aa_sfs_entry_versions[] = {
AA_SFS_FILE_BOOLEAN("v5", 1), AA_SFS_FILE_BOOLEAN("v5", 1),
AA_SFS_FILE_BOOLEAN("v6", 1), AA_SFS_FILE_BOOLEAN("v6", 1),
...@@ -2358,6 +2363,7 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = { ...@@ -2358,6 +2363,7 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
AA_SFS_FILE_U64("outofband", MAX_OOB_SUPPORTED), AA_SFS_FILE_U64("outofband", MAX_OOB_SUPPORTED),
AA_SFS_FILE_U64("permstable32_version", 1), AA_SFS_FILE_U64("permstable32_version", 1),
AA_SFS_FILE_STRING("permstable32", PERMS32STR), AA_SFS_FILE_STRING("permstable32", PERMS32STR),
AA_SFS_DIR("unconfined_restrictions", aa_sfs_entry_unconfined),
{ } { }
}; };
......
...@@ -1311,6 +1311,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name, ...@@ -1311,6 +1311,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
return error; return error;
} }
const char *stack_msg = "change_profile unprivileged unconfined converted to stacking";
/** /**
* aa_change_profile - perform a one-way profile transition * aa_change_profile - perform a one-way profile transition
* @fqname: name of profile may include namespace (NOT NULL) * @fqname: name of profile may include namespace (NOT NULL)
...@@ -1370,6 +1372,28 @@ int aa_change_profile(const char *fqname, int flags) ...@@ -1370,6 +1372,28 @@ int aa_change_profile(const char *fqname, int flags)
op = OP_CHANGE_PROFILE; op = OP_CHANGE_PROFILE;
} }
/* This should move to a per profile test. Requires pushing build
* into callback
*/
if (!stack && unconfined(label) &&
label == &labels_ns(label)->unconfined->label &&
aa_unprivileged_unconfined_restricted &&
/* TODO: refactor so this check is a fn */
cap_capable(current_cred(), &init_user_ns, CAP_MAC_OVERRIDE,
CAP_OPT_NOAUDIT)) {
/* regardless of the request in this case apparmor
* stacks against unconfined so admin set policy can't be
* by-passed
*/
stack = true;
perms.audit = request;
(void) fn_for_each_in_ns(label, profile,
aa_audit_file(subj_cred, profile, &perms, op,
request, auditname, NULL, target,
GLOBAL_ROOT_UID, stack_msg, 0));
perms.audit = 0;
}
if (*fqname == '&') { if (*fqname == '&') {
stack = true; stack = true;
/* don't have label_parse() do stacking */ /* don't have label_parse() do stacking */
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
struct aa_ns; struct aa_ns;
extern int unprivileged_userns_apparmor_policy; extern int unprivileged_userns_apparmor_policy;
extern int aa_unprivileged_unconfined_restricted;
extern const char *const aa_profile_mode_names[]; extern const char *const aa_profile_mode_names[];
#define APPARMOR_MODE_NAMES_MAX_INDEX 4 #define APPARMOR_MODE_NAMES_MAX_INDEX 4
......
...@@ -1798,6 +1798,13 @@ static struct ctl_table apparmor_sysctl_table[] = { ...@@ -1798,6 +1798,13 @@ static struct ctl_table apparmor_sysctl_table[] = {
.mode = 0600, .mode = 0600,
.proc_handler = apparmor_dointvec, .proc_handler = apparmor_dointvec,
}, },
{
.procname = "apparmor_restrict_unprivileged_unconfined",
.data = &aa_unprivileged_unconfined_restricted,
.maxlen = sizeof(int),
.mode = 0600,
.proc_handler = apparmor_dointvec,
},
{ } { }
}; };
......
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
#include "include/resource.h" #include "include/resource.h"
int unprivileged_userns_apparmor_policy = 1; int unprivileged_userns_apparmor_policy = 1;
int aa_unprivileged_unconfined_restricted;
const char *const aa_profile_mode_names[] = { const char *const aa_profile_mode_names[] = {
"enforce", "enforce",
......
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