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

Reply via email to