summaryrefslogtreecommitdiffstats
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);
}