summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--security/apparmor/include/policy_ns.h1
-rw-r--r--security/apparmor/lsm.c5
-rw-r--r--security/apparmor/net.c3
-rw-r--r--security/apparmor/policy_ns.c41
4 files changed, 37 insertions, 13 deletions
diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
index 3df6f804922d..33d665516fc1 100644
--- a/security/apparmor/include/policy_ns.h
+++ b/security/apparmor/include/policy_ns.h
@@ -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;
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 1ebcf1a6e1d0..9efb7ac60c7c 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -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();
 
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index e0c1b50d6edd..7efe4d17273d 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -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);
 
diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
index 70921d95fb40..300953a02a24 100644
--- a/security/apparmor/policy_ns.c
+++ b/security/apparmor/policy_ns.c
@@ -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);
 }