]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
apparmor: add a kernel label to use on kernel objects
authorJohn Johansen <john.johansen@canonical.com>
Tue, 24 May 2022 09:38:12 +0000 (02:38 -0700)
committerJohn Johansen <john.johansen@canonical.com>
Wed, 13 Jul 2022 23:37:21 +0000 (16:37 -0700)
Separate kernel objects from unconfined. This is done so we can
distinguish between the two in debugging, auditing and in preparation
for being able to replace unconfined, which is not appropriate for the
kernel.

The kernel label will continue to behave similar to unconfined.

Acked-by: Jon Tourville <jon.tourville@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/include/policy_ns.h
security/apparmor/lsm.c
security/apparmor/net.c
security/apparmor/policy_ns.c

index 3df6f804922da3e327bbefd0b9e3af333bc76921..33d665516fc11687142d78e98a0b99001520d88f 100644 (file)
@@ -74,6 +74,7 @@ struct aa_ns {
        struct dentry *dents[AAFS_NS_SIZEOF];
 };
 
+extern struct aa_label *kernel_t;
 extern struct aa_ns *root_ns;
 
 extern const char *aa_hidden_ns_name;
index 1ebcf1a6e1d003ee330df128d93fa4c31122b553..9efb7ac60c7cdc4ba5a1c802f1ba96ccd751cf7c 100644 (file)
@@ -886,10 +886,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
        struct aa_label *label;
 
        if (kern) {
-               struct aa_ns *ns = aa_get_current_ns();
-
-               label = aa_get_label(ns_unconfined(ns));
-               aa_put_ns(ns);
+               label = aa_get_label(kernel_t);
        } else
                label = aa_get_current_label();
 
index e0c1b50d6eddcb32993c57f207bc9c1ed20997da..7efe4d17273d944ab175fea090728ade94fc048b 100644 (file)
@@ -145,12 +145,13 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
 static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
                            struct sock *sk)
 {
+       struct aa_sk_ctx *ctx = SK_CTX(sk);
        int error = 0;
 
        AA_BUG(!label);
        AA_BUG(!sk);
 
-       if (!unconfined(label)) {
+       if (ctx->label != kernel_t && !unconfined(label)) {
                struct aa_profile *profile;
                DEFINE_AUDIT_SK(sa, op, sk);
 
index 70921d95fb406a395462f2f3b9f0e4b10b116af7..300953a02a245f8e291bf48fcf99f29a51e1d37b 100644 (file)
@@ -22,6 +22,9 @@
 #include "include/label.h"
 #include "include/policy.h"
 
+/* kernel label */
+struct aa_label *kernel_t;
+
 /* root profile namespace */
 struct aa_ns *root_ns;
 const char *aa_hidden_ns_name = "---";
@@ -77,6 +80,23 @@ const char *aa_ns_name(struct aa_ns *curr, struct aa_ns *view, bool subns)
        return aa_hidden_ns_name;
 }
 
+struct aa_profile *alloc_unconfined(const char *name)
+{
+       struct aa_profile *profile;
+
+       profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
+       if (!profile)
+               return NULL;
+
+       profile->label.flags |= FLAG_IX_ON_NAME_ERROR |
+               FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
+       profile->mode = APPARMOR_UNCONFINED;
+       profile->file.dfa = aa_get_dfa(nulldfa);
+       profile->policy.dfa = aa_get_dfa(nulldfa);
+
+       return profile;
+}
+
 /**
  * alloc_ns - allocate, initialize and return a new namespace
  * @prefix: parent namespace name (MAYBE NULL)
@@ -101,16 +121,9 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
        init_waitqueue_head(&ns->wait);
 
        /* released by aa_free_ns() */
-       ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
+       ns->unconfined = alloc_unconfined("unconfined");
        if (!ns->unconfined)
                goto fail_unconfined;
-
-       ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
-               FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
-       ns->unconfined->mode = APPARMOR_UNCONFINED;
-       ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
-       ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
-
        /* ns and ns->unconfined share ns->unconfined refcount */
        ns->unconfined->ns = ns;
 
@@ -388,11 +401,22 @@ static void __ns_list_release(struct list_head *head)
  */
 int __init aa_alloc_root_ns(void)
 {
+       struct aa_profile *kernel_p;
+
        /* released by aa_free_root_ns - used as list ref*/
        root_ns = alloc_ns(NULL, "root");
        if (!root_ns)
                return -ENOMEM;
 
+       kernel_p = alloc_unconfined("kernel_t");
+       if (!kernel_p) {
+               destroy_ns(root_ns);
+               aa_free_ns(root_ns);
+               return -ENOMEM;
+       }
+       kernel_t = &kernel_p->label;
+       root_ns->unconfined->ns = aa_get_ns(root_ns);
+
        return 0;
 }
 
@@ -405,6 +429,7 @@ void __init aa_free_root_ns(void)
 
         root_ns = NULL;
 
+        aa_label_free(kernel_t);
         destroy_ns(ns);
         aa_put_ns(ns);
 }