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
