[apparmor] [PATCH 08/24] apparmor: provide the ability to boot with a default profile set on init
John Johansen
john.johansen at canonical.com
Wed Feb 27 18:14:07 UTC 2013
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.johansen at 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 | 19 +++++++++++++++++++
security/apparmor/procattr.c | 8 +++++---
7 files changed, 55 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 3ed56e2..d5f8d04 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -346,6 +346,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 6d2b949..27bf183 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 8fea2ca..eb840ee 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -746,6 +746,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;
@@ -874,8 +879,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)
{
@@ -886,7 +889,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 77d9d58..54fbe5d 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -755,6 +755,25 @@ 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_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
More information about the AppArmor
mailing list