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: Georgia Garcia <georgia.garcia@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
e105d8079f
commit
2d9da9b188
@ -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[] = {
|
||||
AA_SFS_FILE_BOOLEAN("v5", 1),
|
||||
AA_SFS_FILE_BOOLEAN("v6", 1),
|
||||
@ -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("permstable32_version", 1),
|
||||
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,
|
||||
return error;
|
||||
}
|
||||
|
||||
const char *stack_msg = "change_profile unprivileged unconfined converted to stacking";
|
||||
|
||||
/**
|
||||
* aa_change_profile - perform a one-way profile transition
|
||||
* @fqname: name of profile may include namespace (NOT NULL)
|
||||
@ -1370,6 +1372,28 @@ int aa_change_profile(const char *fqname, int flags)
|
||||
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 == '&') {
|
||||
stack = true;
|
||||
/* don't have label_parse() do stacking */
|
||||
|
@ -34,6 +34,7 @@
|
||||
struct aa_ns;
|
||||
|
||||
extern int unprivileged_userns_apparmor_policy;
|
||||
extern int aa_unprivileged_unconfined_restricted;
|
||||
|
||||
extern const char *const aa_profile_mode_names[];
|
||||
#define APPARMOR_MODE_NAMES_MAX_INDEX 4
|
||||
|
@ -1798,6 +1798,13 @@ static struct ctl_table apparmor_sysctl_table[] = {
|
||||
.mode = 0600,
|
||||
.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 @@
|
||||
#include "include/resource.h"
|
||||
|
||||
int unprivileged_userns_apparmor_policy = 1;
|
||||
int aa_unprivileged_unconfined_restricted;
|
||||
|
||||
const char *const aa_profile_mode_names[] = {
|
||||
"enforce",
|
||||
|
Loading…
x
Reference in New Issue
Block a user