mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
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[] = {
|
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[] = {
|
||||||
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,
|
||||||
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)
|
||||||
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 @@
|
||||||
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[] = {
|
||||||
.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 @@
|
||||||
#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",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user