add the ability to boot with a basic default profile instead of the unconfined state. This provides a way to provide total system confinement without having to load policy in the init ramfs.
The basic default profile can be replaced during early boot to achieve system confinement. Signed-off-by: John Johansen <john.johan...@canonical.com> --- security/apparmor/Kconfig | 11 +++++++++++ security/apparmor/apparmorfs.c | 4 ++++ security/apparmor/include/apparmor.h | 1 + security/apparmor/include/policy.h | 1 + security/apparmor/lsm.c | 17 ++++++++++++++--- security/apparmor/policy.c | 21 +++++++++++++++++++++ security/apparmor/procattr.c | 8 +++++--- 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig index 9b9013b..9ede3b1 100644 --- a/security/apparmor/Kconfig +++ b/security/apparmor/Kconfig @@ -29,3 +29,14 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE boot. If you are unsure how to answer this question, answer 1. + +config SECURITY_APPARMOR_UNCONFINED_INIT + bool "Set init to unconfined on boot" + depends on SECURITY_APPARMOR + default y + help + This option determines policy behavior during early boot by + placing the init process in the unconfined state, or the + 'default' profile. + + If you are unsure how to answer this question, answer Y. diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index b73e59b..1266724 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -347,6 +347,10 @@ static int __init aa_create_aafs(void) if (error) goto error; + if (!aa_g_unconfined_init) { + /* TODO: add default profile to apparmorfs */ + } + /* TODO: add support for apparmorfs_null and apparmorfs_mnt */ /* Report that AppArmor fs is enabled */ diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index 8fb1488..3172801 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h @@ -41,6 +41,7 @@ extern bool aa_g_lock_policy; extern bool aa_g_logsyscall; extern bool aa_g_paranoid_load; extern unsigned int aa_g_path_max; +extern bool aa_g_unconfined_init; /* * DEBUG remains global (no per profile flag) since it is mostly used in sysctl diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 3166550..eedd402 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -227,6 +227,7 @@ struct aa_namespace *aa_find_namespace(struct aa_namespace *root, void aa_free_replacedby_kref(struct kref *kref); struct aa_profile *aa_alloc_profile(const char *name); struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat); +struct aa_profile *aa_setup_default_profile(void); void aa_free_profile(struct aa_profile *profile); void aa_free_profile_kref(struct kref *kref); struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name); diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 3834890..705346d 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -741,6 +741,11 @@ module_param_named(paranoid_load, aa_g_paranoid_load, aabool, static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; module_param_named(enabled, apparmor_enabled, aabool, S_IRUSR); +/* Boot time to set use of default or unconfined as initial profile */ +bool aa_g_unconfined_init = CONFIG_SECURITY_APPARMOR_UNCONFINED_INIT; +module_param_named(unconfined, aa_g_unconfined_init, bool, S_IRUSR); + + static int __init apparmor_enabled_setup(char *str) { unsigned long enabled; @@ -869,8 +874,6 @@ static int param_set_mode(const char *val, struct kernel_param *kp) /** * set_init_cxt - set a task context and profile on the first task. - * - * TODO: allow setting an alternate profile than unconfined */ static int __init set_init_cxt(void) { @@ -881,7 +884,15 @@ static int __init set_init_cxt(void) if (!cxt) return -ENOMEM; - cxt->profile = aa_get_profile(root_ns->unconfined); + if (!aa_g_unconfined_init) { + cxt->profile = aa_setup_default_profile(); + if (!cxt->profile) { + aa_free_task_context(cxt); + return -ENOMEM; + } + /* fs setup of default is done in aa_create_aafs() */ + } else + cxt->profile = aa_get_profile(root_ns->unconfined); cred_cxt(cred) = cxt; return 0; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 9b621f0..d664557 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -754,6 +754,27 @@ fail: return NULL; } +/** + * aa_setup_default_profile - create the initial default profile + */ +struct aa_profile *aa_setup_default_profile(void) +{ + struct aa_profile *profile = aa_alloc_profile("default"); + if (!profile) + return NULL; + + /* the default profile pretends to be unconfined until it is replaced */ + profile->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR; + + profile->ns = aa_get_namespace(root_ns); + + /* list ref */ + aa_get_profile(profile); + __list_add_profile(&root_ns->base.profiles, profile); + + return profile; +} + /* TODO: profile accounting - setup in remove */ /** diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c index 6c93901..9c4995b 100644 --- a/security/apparmor/procattr.c +++ b/security/apparmor/procattr.c @@ -41,6 +41,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string) const char *ns_name = NULL; struct aa_namespace *ns = profile->ns; struct aa_namespace *current_ns = __aa_current_profile()->ns; + bool unconfined; char *s; if (!aa_ns_visible(current_ns, ns)) @@ -53,8 +54,9 @@ int aa_getprocattr(struct aa_profile *profile, char **string) if (ns_len) ns_len += 4; - /* unconfined profiles don't have a mode string appended */ - if (!unconfined(profile)) + /* 'unconfined' profile don't have a mode string appended */ + unconfined = profile == profile->ns->unconfined; + if (!unconfined) mode_len = strlen(mode_str) + 3; /* + 3 for _() */ name_len = strlen(profile->base.hname); @@ -68,7 +70,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string) sprintf(s, ":%s://", ns_name); s += ns_len; } - if (unconfined(profile)) + if (unconfined) /* mode string not being appended */ sprintf(s, "%s\n", profile->base.hname); else -- 1.7.10.4 -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor