Currently apparmor makes the assumption that kernel sockets are unmediated
because mediation is only done against tasks that have a profile attached.
Ensure we never get in a situation where a kernel socket is being mediated
by tagging the sk_security field for kernel sockets.

Signed-off-by: John Johansen <[email protected]>
---
 security/apparmor/include/net.h |    2 ++
 security/apparmor/lsm.c         |   18 ++++++++++++++++++
 security/apparmor/net.c         |    3 +++
 3 files changed, 23 insertions(+)

diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 3c7d599..cdb3320 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -17,6 +17,8 @@
 
 #include <net/sock.h>
 
+#define AA_SOCK_KERN 0xAA
+
 /* struct aa_net - network confinement data
  * @allowed: basic network families permissions
  * @audit_network: which network permissions to force audit
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 7459547..8cebf66 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -637,6 +637,16 @@ static int apparmor_socket_create(int family, int type, 
int protocol, int kern)
        return error;
 }
 
+static int apparmor_socket_post_create(struct socket *sock, int family,
+                                      int type, int protocol, int kern)
+{
+       if (kern)
+               /* tag kernel sockets so we don't mediate them later */
+               sock->sk->sk_security = (void *) AA_SOCK_KERN;
+
+       return 0;
+}
+
 static int apparmor_socket_bind(struct socket *sock,
                                struct sockaddr *address, int addrlen)
 {
@@ -720,6 +730,12 @@ static int apparmor_socket_shutdown(struct socket *sock, 
int how)
        return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
 }
 
+static void apparmor_sk_clone_security(const struct sock *sk,
+                                      struct sock *newsk)
+{
+       newsk->sk_security = sk->sk_security;
+}
+
 static struct security_operations apparmor_ops = {
        .name =                         "apparmor",
 
@@ -752,6 +768,7 @@ static struct security_operations apparmor_ops = {
        .setprocattr =                  apparmor_setprocattr,
 
        .socket_create =                apparmor_socket_create,
+       .socket_post_create =           apparmor_socket_post_create,
        .socket_bind =                  apparmor_socket_bind,
        .socket_connect =               apparmor_socket_connect,
        .socket_listen =                apparmor_socket_listen,
@@ -763,6 +780,7 @@ static struct security_operations apparmor_ops = {
        .socket_getsockopt =            apparmor_socket_getsockopt,
        .socket_setsockopt =            apparmor_socket_setsockopt,
        .socket_shutdown =              apparmor_socket_shutdown,
+       .sk_clone_security =            apparmor_sk_clone_security,
 
        .cred_alloc_blank =             apparmor_cred_alloc_blank,
        .cred_free =                    apparmor_cred_free,
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index cf90973..f56987e 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -161,6 +161,9 @@ int aa_revalidate_sk(int op, struct sock *sk)
        if (in_interrupt())
                return 0;
 
+       if (sk->sk_security == (void *) AA_SOCK_KERN)
+               return 0;
+
        profile = __aa_current_profile();
        if (!unconfined(profile))
                error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
-- 
1.7.9.5


-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to