1 From 8f0a917911fe19f9911d972fe85c43243f7eaa37 Mon Sep 17 00:00:00 2001
2 From: John Johansen <john.johansen@canonical.com>
3 Date: Tue, 18 Jul 2017 23:27:23 -0700
4 Subject: [PATCH 2/2] apparmor: af_unix mediation
6 af_socket mediation did not make it into 4.14 so add remaining out
9 Signed-off-by: John Johansen <john.johansen@canonical.com>
10 Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
12 security/apparmor/Makefile | 3 +-
13 security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++
14 security/apparmor/apparmorfs.c | 6 +
15 security/apparmor/file.c | 4 +-
16 security/apparmor/include/af_unix.h | 114 +++++++
17 security/apparmor/include/net.h | 16 +-
18 security/apparmor/include/path.h | 1 +
19 security/apparmor/include/policy.h | 2 +-
20 security/apparmor/lsm.c | 169 ++++++----
21 security/apparmor/net.c | 174 +++++++++-
22 10 files changed, 1072 insertions(+), 68 deletions(-)
23 create mode 100644 security/apparmor/af_unix.c
24 create mode 100644 security/apparmor/include/af_unix.h
26 diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
27 index e7ff2183532a..90c118f39e13 100644
28 --- a/security/apparmor/Makefile
29 +++ b/security/apparmor/Makefile
30 @@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
32 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
33 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
34 - resource.o secid.o file.o policy_ns.o label.o mount.o net.o
35 + resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
37 apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
39 clean-files := capability_names.h rlim_names.h net_names.h
40 diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
42 index 000000000000..c6876db2dbde
44 +++ b/security/apparmor/af_unix.c
47 + * AppArmor security module
49 + * This file contains AppArmor af_unix fine grained mediation
51 + * Copyright 2014 Canonical Ltd.
53 + * This program is free software; you can redistribute it and/or
54 + * modify it under the terms of the GNU General Public License as
55 + * published by the Free Software Foundation, version 2 of the
59 +#include <net/tcp_states.h>
61 +#include "include/af_unix.h"
62 +#include "include/apparmor.h"
63 +#include "include/context.h"
64 +#include "include/file.h"
65 +#include "include/label.h"
66 +#include "include/path.h"
67 +#include "include/policy.h"
69 +static inline struct sock *aa_sock(struct unix_sock *u)
74 +static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
75 + struct unix_sock *u, int flags)
79 + AA_BUG(!UNIX_FS(aa_sock(u)));
81 + if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
84 + mask &= NET_FS_PERMS;
85 + if (!u->path.dentry) {
86 + struct path_cond cond = { };
87 + struct aa_perms perms = { };
88 + struct aa_profile *profile;
90 + /* socket path has been cleared because it is being shutdown
91 + * can only fall back to original sun_path request
93 + struct aa_sk_ctx *ctx = SK_CTX(&u->sk);
94 + if (ctx->path.dentry)
95 + return aa_path_perm(op, label, &ctx->path, flags, mask,
97 + return fn_for_each_confined(label, profile,
98 + ((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
99 + __aa_path_perm(op, profile,
100 + u->addr->name->sun_path, mask,
101 + &cond, flags, &perms) :
102 + aa_audit_file(profile, &nullperms, op, mask,
103 + u->addr->name->sun_path, NULL,
105 + "Failed name lookup - "
106 + "deleted entry", -EACCES));
108 + /* the sunpath may not be valid for this ns so use the path */
109 + struct path_cond cond = { u->path.dentry->d_inode->i_uid,
110 + u->path.dentry->d_inode->i_mode
113 + return aa_path_perm(op, label, &u->path, flags, mask, &cond);
119 +/* passing in state returned by PROFILE_MEDIATES_AF */
120 +static unsigned int match_to_prot(struct aa_profile *profile,
121 + unsigned int state, int type, int protocol,
125 + buffer[0] = cpu_to_be16(type);
126 + buffer[1] = cpu_to_be16(protocol);
127 + state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
130 + *info = "failed type and protocol match";
134 +static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
135 + struct sockaddr_un *addr, int addrlen)
138 + /* include leading \0 */
139 + state = aa_dfa_match_len(profile->policy.dfa, state,
141 + unix_addr_len(addrlen));
143 + /* anonymous end point */
144 + state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
146 + /* todo change to out of band */
147 + state = aa_dfa_null_transition(profile->policy.dfa, state);
151 +static unsigned int match_to_local(struct aa_profile *profile,
152 + unsigned int state, int type, int protocol,
153 + struct sockaddr_un *addr, int addrlen,
156 + state = match_to_prot(profile, state, type, protocol, info);
158 + state = match_addr(profile, state, addr, addrlen);
160 + /* todo: local label matching */
161 + state = aa_dfa_null_transition(profile->policy.dfa,
164 + *info = "failed local label match";
166 + *info = "failed local address match";
172 +static unsigned int match_to_sk(struct aa_profile *profile,
173 + unsigned int state, struct unix_sock *u,
176 + struct sockaddr_un *addr = NULL;
180 + addr = u->addr->name;
181 + addrlen = u->addr->len;
184 + return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
185 + addr, addrlen, info);
189 +#define CMD_LISTEN 2
192 +static inline unsigned int match_to_cmd(struct aa_profile *profile,
193 + unsigned int state, struct unix_sock *u,
194 + char cmd, const char **info)
196 + state = match_to_sk(profile, state, u, info);
198 + state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
200 + *info = "failed cmd selection match";
206 +static inline unsigned int match_to_peer(struct aa_profile *profile,
207 + unsigned int state,
208 + struct unix_sock *u,
209 + struct sockaddr_un *peer_addr,
213 + state = match_to_cmd(profile, state, u, CMD_ADDR, info);
215 + state = match_addr(profile, state, peer_addr, peer_addrlen);
217 + *info = "failed peer address match";
222 +static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
223 + struct common_audit_data *sa)
225 + struct aa_perms perms;
229 + aa_compute_perms(profile->policy.dfa, state, &perms);
230 + aa_apply_modes_to_perms(profile, &perms);
231 + return aa_check_perms(profile, &perms, request, sa,
235 +static int match_label(struct aa_profile *profile, struct aa_profile *peer,
236 + unsigned int state, u32 request,
237 + struct common_audit_data *sa)
242 + aad(sa)->peer = &peer->label;
245 + state = aa_dfa_match(profile->policy.dfa, state,
248 + aad(sa)->info = "failed peer label match";
250 + return do_perms(profile, state, request, sa);
254 +/* unix sock creation comes before we know if the socket will be an fs
256 + * v6 - semantics are handled by mapping in profile load
257 + * v7 - semantics require sock create for tasks creating an fs socket.
259 +static int profile_create_perm(struct aa_profile *profile, int family,
260 + int type, int protocol)
262 + unsigned int state;
263 + DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
266 + AA_BUG(profile_unconfined(profile));
268 + if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
269 + state = match_to_prot(profile, state, type, protocol,
271 + return do_perms(profile, state, AA_MAY_CREATE, &sa);
274 + return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
277 +int aa_unix_create_perm(struct aa_label *label, int family, int type,
280 + struct aa_profile *profile;
282 + if (unconfined(label))
285 + return fn_for_each_confined(label, profile,
286 + profile_create_perm(profile, family, type, protocol));
290 +static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
291 + u32 request, struct sock *sk)
293 + unsigned int state;
294 + DEFINE_AUDIT_SK(sa, op, sk);
298 + AA_BUG(UNIX_FS(sk));
299 + AA_BUG(profile_unconfined(profile));
301 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
303 + state = match_to_sk(profile, state, unix_sk(sk),
305 + return do_perms(profile, state, request, &sa);
308 + return aa_profile_af_sk_perm(profile, &sa, request, sk);
311 +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
314 + struct aa_profile *profile;
316 + return fn_for_each_confined(label, profile,
317 + profile_sk_perm(profile, op, request, sk));
320 +static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
321 + struct socket *sock)
323 + if (unconfined(label))
325 + if (UNIX_FS(sock->sk))
326 + return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
328 + return aa_unix_label_sk_perm(label, op, request, sock->sk);
331 +/* revaliation, get/set attr */
332 +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
334 + struct aa_label *label;
337 + label = begin_current_label_crit_section();
338 + error = unix_label_sock_perm(label, op, request, sock);
339 + end_current_label_crit_section(label);
344 +static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
345 + struct sockaddr *addr, int addrlen)
347 + unsigned int state;
348 + DEFINE_AUDIT_SK(sa, OP_BIND, sk);
352 + AA_BUG(addr->sa_family != AF_UNIX);
353 + AA_BUG(profile_unconfined(profile));
354 + AA_BUG(unix_addr_fs(addr, addrlen));
356 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
358 + /* bind for abstract socket */
359 + aad(&sa)->net.addr = unix_addr(addr);
360 + aad(&sa)->net.addrlen = addrlen;
362 + state = match_to_local(profile, state,
363 + sk->sk_type, sk->sk_protocol,
364 + unix_addr(addr), addrlen,
366 + return do_perms(profile, state, AA_MAY_BIND, &sa);
369 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
372 +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
375 + struct aa_profile *profile;
376 + struct aa_label *label;
379 + label = begin_current_label_crit_section();
380 + /* fs bind is handled by mknod */
381 + if (!(unconfined(label) || unix_addr_fs(address, addrlen)))
382 + error = fn_for_each_confined(label, profile,
383 + profile_bind_perm(profile, sock->sk, address,
385 + end_current_label_crit_section(label);
390 +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
393 + /* unix connections are covered by the
394 + * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
395 + * - fs connect is handled by open
400 +static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
403 + unsigned int state;
404 + DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
408 + AA_BUG(UNIX_FS(sk));
409 + AA_BUG(profile_unconfined(profile));
411 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
413 + __be16 b = cpu_to_be16(backlog);
415 + state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
418 + state = aa_dfa_match_len(profile->policy.dfa, state,
421 + aad(&sa)->info = "failed listen backlog match";
423 + return do_perms(profile, state, AA_MAY_LISTEN, &sa);
426 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
429 +int aa_unix_listen_perm(struct socket *sock, int backlog)
431 + struct aa_profile *profile;
432 + struct aa_label *label;
435 + label = begin_current_label_crit_section();
436 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
437 + error = fn_for_each_confined(label, profile,
438 + profile_listen_perm(profile, sock->sk,
440 + end_current_label_crit_section(label);
446 +static inline int profile_accept_perm(struct aa_profile *profile,
448 + struct sock *newsk)
450 + unsigned int state;
451 + DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
455 + AA_BUG(UNIX_FS(sk));
456 + AA_BUG(profile_unconfined(profile));
458 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
460 + state = match_to_sk(profile, state, unix_sk(sk),
462 + return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
465 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
468 +/* ability of sock to connect, not peer address binding */
469 +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
471 + struct aa_profile *profile;
472 + struct aa_label *label;
475 + label = begin_current_label_crit_section();
476 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
477 + error = fn_for_each_confined(label, profile,
478 + profile_accept_perm(profile, sock->sk,
480 + end_current_label_crit_section(label);
486 +/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
487 + * could do per msg unix_stream here
489 +/* sendmsg, recvmsg */
490 +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
491 + struct msghdr *msg, int size)
497 +static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
498 + struct sock *sk, int level, int optname)
500 + unsigned int state;
501 + DEFINE_AUDIT_SK(sa, op, sk);
505 + AA_BUG(UNIX_FS(sk));
506 + AA_BUG(profile_unconfined(profile));
508 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
510 + __be16 b = cpu_to_be16(optname);
512 + state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
515 + state = aa_dfa_match_len(profile->policy.dfa, state,
518 + aad(&sa)->info = "failed sockopt match";
520 + return do_perms(profile, state, request, &sa);
523 + return aa_profile_af_sk_perm(profile, &sa, request, sk);
526 +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
529 + struct aa_profile *profile;
530 + struct aa_label *label;
533 + label = begin_current_label_crit_section();
534 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
535 + error = fn_for_each_confined(label, profile,
536 + profile_opt_perm(profile, op, request,
537 + sock->sk, level, optname));
538 + end_current_label_crit_section(label);
543 +/* null peer_label is allowed, in which case the peer_sk label is used */
544 +static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request,
545 + struct sock *sk, struct sock *peer_sk,
546 + struct aa_label *peer_label,
547 + struct common_audit_data *sa)
549 + unsigned int state;
552 + AA_BUG(profile_unconfined(profile));
555 + AA_BUG(UNIX_FS(peer_sk));
557 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
559 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
560 + struct aa_profile *peerp;
561 + struct sockaddr_un *addr = NULL;
563 + if (unix_sk(peer_sk)->addr) {
564 + addr = unix_sk(peer_sk)->addr->name;
565 + len = unix_sk(peer_sk)->addr->len;
567 + state = match_to_peer(profile, state, unix_sk(sk),
568 + addr, len, &aad(sa)->info);
570 + peer_label = peer_ctx->label;
571 + return fn_for_each_in_ns(peer_label, peerp,
572 + match_label(profile, peerp, state, request,
576 + return aa_profile_af_sk_perm(profile, sa, request, sk);
581 + * Requires: lock held on both @sk and @peer_sk
583 +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
584 + struct sock *sk, struct sock *peer_sk,
585 + struct aa_label *peer_label)
587 + struct unix_sock *peeru = unix_sk(peer_sk);
588 + struct unix_sock *u = unix_sk(sk);
594 + if (UNIX_FS(aa_sock(peeru)))
595 + return unix_fs_perm(op, request, label, peeru, 0);
596 + else if (UNIX_FS(aa_sock(u)))
597 + return unix_fs_perm(op, request, label, u, 0);
599 + struct aa_profile *profile;
600 + DEFINE_AUDIT_SK(sa, op, sk);
601 + aad(&sa)->net.peer_sk = peer_sk;
604 + if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
608 + if (unconfined(label))
611 + return fn_for_each_confined(label, profile,
612 + profile_peer_perm(profile, op, request, sk,
613 + peer_sk, peer_label, &sa));
618 +/* from net/unix/af_unix.c */
619 +static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
621 + if (unlikely(sk1 == sk2) || !sk2) {
622 + unix_state_lock(sk1);
626 + unix_state_lock(sk1);
627 + unix_state_lock_nested(sk2);
629 + unix_state_lock(sk2);
630 + unix_state_lock_nested(sk1);
634 +static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
636 + if (unlikely(sk1 == sk2) || !sk2) {
637 + unix_state_unlock(sk1);
640 + unix_state_unlock(sk1);
641 + unix_state_unlock(sk2);
644 +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
645 + struct socket *sock)
647 + struct sock *peer_sk = NULL;
648 + u32 sk_req = request & ~NET_PEER_MASK;
654 + AA_BUG(sock->sk->sk_family != AF_UNIX);
656 + /* TODO: update sock label with new task label */
657 + unix_state_lock(sock->sk);
658 + peer_sk = unix_peer(sock->sk);
660 + sock_hold(peer_sk);
661 + if (!unix_connected(sock) && sk_req) {
662 + error = unix_label_sock_perm(label, op, sk_req, sock);
667 + unix_state_unlock(sock->sk);
671 + unix_state_double_lock(sock->sk, peer_sk);
672 + if (UNIX_FS(sock->sk)) {
673 + error = unix_fs_perm(op, request, label, unix_sk(sock->sk),
675 + } else if (UNIX_FS(peer_sk)) {
676 + error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
679 + struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
681 + error = aa_unix_label_sk_perm(label, op, sk_req,
684 + xcheck(aa_unix_peer_perm(label, op,
685 + MAY_READ | MAY_WRITE,
686 + sock->sk, peer_sk, NULL),
687 + aa_unix_peer_perm(pctx->label, op,
688 + MAY_READ | MAY_WRITE,
689 + peer_sk, sock->sk, label)));
692 + unix_state_double_unlock(sock->sk, peer_sk);
697 diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
698 index 694c4f48a975..850c401502f1 100644
699 --- a/security/apparmor/apparmorfs.c
700 +++ b/security/apparmor/apparmorfs.c
701 @@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
705 +static struct aa_sfs_entry aa_sfs_entry_dbus[] = {
706 + AA_SFS_FILE_STRING("mask", "acquire send receive"),
710 static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
711 AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
712 AA_SFS_FILE_BOOLEAN("data", 1),
713 @@ -2210,6 +2215,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
714 AA_SFS_DIR("caps", aa_sfs_entry_caps),
715 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
716 AA_SFS_DIR("signal", aa_sfs_entry_signal),
717 + AA_SFS_DIR("dbus", aa_sfs_entry_dbus),
718 AA_SFS_DIR("query", aa_sfs_entry_query),
721 diff --git a/security/apparmor/file.c b/security/apparmor/file.c
722 index 86d57e56fabe..348c9ff3da4e 100644
723 --- a/security/apparmor/file.c
724 +++ b/security/apparmor/file.c
726 #include <linux/fdtable.h>
727 #include <linux/file.h>
729 +#include "include/af_unix.h"
730 #include "include/apparmor.h"
731 #include "include/audit.h"
732 #include "include/context.h"
733 @@ -283,7 +284,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
737 - if (profile_unconfined(profile))
738 + if (profile_unconfined(profile) ||
739 + ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
741 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
742 if (request & ~perms->allow)
743 diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
745 index 000000000000..d1b7f2316be4
747 +++ b/security/apparmor/include/af_unix.h
750 + * AppArmor security module
752 + * This file contains AppArmor af_unix fine grained mediation
754 + * Copyright 2014 Canonical Ltd.
756 + * This program is free software; you can redistribute it and/or
757 + * modify it under the terms of the GNU General Public License as
758 + * published by the Free Software Foundation, version 2 of the
761 +#ifndef __AA_AF_UNIX_H
763 +#include <net/af_unix.h>
766 +//#include "include/net.h"
768 +#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
769 +#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
770 +#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
771 +#define addr_unix_abstract_name(B) ((B)[0] == 0)
772 +#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
773 +#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
774 +//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
776 +#define unix_addr(A) ((struct sockaddr_un *)(A))
777 +#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
778 +#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
780 +#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
781 +/* from net/unix/af_unix.c */
782 +#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \
783 + unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
784 +#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
785 +#define unix_peer(sk) (unix_sk(sk)->peer)
786 +#define unix_connected(S) ((S)->state == SS_CONNECTED)
788 +static inline void print_unix_addr(struct sockaddr_un *A, int L)
790 + char *buf = (A) ? (char *) &(A)->sun_path : NULL;
791 + int len = unix_addr_len(L);
792 + if (!buf || len <= 0)
793 + printk(" <anonymous>");
795 + printk(" %s", buf);
797 + /* abstract name len includes leading \0 */
798 + printk(" %d @%.*s", len - 1, len - 1, buf+1);
802 + printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \
805 +#define print_unix_sk(SK) \
807 + struct unix_sock *u = unix_sk(SK); \
808 + printk("%s: f %d, t %d, p %d", #SK , \
809 + (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \
811 + print_unix_addr(u->addr->name, u->addr->len); \
813 + print_unix_addr(NULL, sizeof(sa_family_t)); \
814 + /* printk("\n");*/ \
817 +#define print_sk(SK) \
820 + printk("%s: %s is null\n", __FUNCTION__, #SK); \
821 + } else if ((SK)->sk_family == PF_UNIX) { \
822 + print_unix_sk(SK); \
825 + printk("%s: %s: family %d\n", __FUNCTION__, #SK , \
826 + (SK)->sk_family); \
830 +#define print_sock_addr(U) \
832 + printk("%s:\n", __FUNCTION__); \
833 + printk(" sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
834 + printk(" other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
835 + printk(" new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
841 +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
842 + struct sock *sk, struct sock *peer_sk,
843 + struct aa_label *peer_label);
844 +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
846 +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
847 +int aa_unix_create_perm(struct aa_label *label, int family, int type,
849 +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
851 +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
853 +int aa_unix_listen_perm(struct socket *sock, int backlog);
854 +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
855 +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
856 + struct msghdr *msg, int size);
857 +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
859 +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
860 + struct socket *sock);
862 +#endif /* __AA_AF_UNIX_H */
863 diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
864 index 140c8efcf364..0ae45240c352 100644
865 --- a/security/apparmor/include/net.h
866 +++ b/security/apparmor/include/net.h
867 @@ -90,8 +90,6 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
868 void audit_net_cb(struct audit_buffer *ab, void *va);
869 int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
870 u32 request, u16 family, int type);
871 -int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
872 - int type, int protocol);
873 static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
874 struct common_audit_data *sa,
876 @@ -100,8 +98,20 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
877 return aa_profile_af_perm(profile, sa, request, sk->sk_family,
880 -int aa_sk_perm(const char *op, u32 request, struct sock *sk);
882 +int aa_sock_perm(const char *op, u32 request, struct socket *sock);
883 +int aa_sock_create_perm(struct aa_label *label, int family, int type,
885 +int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
887 +int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
889 +int aa_sock_listen_perm(struct socket *sock, int backlog);
890 +int aa_sock_accept_perm(struct socket *sock, struct socket *newsock);
891 +int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
892 + struct msghdr *msg, int size);
893 +int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
895 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
896 struct socket *sock);
898 diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
899 index 05fb3305671e..26762db2207d 100644
900 --- a/security/apparmor/include/path.h
901 +++ b/security/apparmor/include/path.h
905 PATH_IS_DIR = 0x1, /* path is a directory */
906 + PATH_SOCK_COND = 0x2,
907 PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */
908 PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */
909 PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
910 diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
911 index 4364088a0b9e..26660a1a50b0 100644
912 --- a/security/apparmor/include/policy.h
913 +++ b/security/apparmor/include/policy.h
914 @@ -226,7 +226,7 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
915 static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
917 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
918 - u16 be_af = cpu_to_be16(AF);
919 + __be16 be_af = cpu_to_be16(AF);
923 diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
924 index 0cd717614fd0..245c98ef311e 100644
925 --- a/security/apparmor/lsm.c
926 +++ b/security/apparmor/lsm.c
928 #include <linux/kmemleak.h>
929 #include <net/sock.h>
931 +#include "include/af_unix.h"
932 #include "include/apparmor.h"
933 #include "include/apparmorfs.h"
934 #include "include/audit.h"
935 @@ -782,16 +783,96 @@ static void apparmor_sk_clone_security(const struct sock *sk,
936 path_get(&new->path);
939 -static int aa_sock_create_perm(struct aa_label *label, int family, int type,
941 +static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
944 - AA_BUG(in_interrupt());
945 + if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
946 + return &unix_sk(sk)->path;
947 + else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
948 + return &unix_sk(newsk)->path;
953 + * apparmor_unix_stream_connect - check perms before making unix domain conn
955 + * peer is locked when this hook is called
957 +static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
958 + struct sock *newsk)
960 + struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
961 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
962 + struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
963 + struct aa_label *label;
967 - return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
969 + label = __begin_current_label_crit_section();
970 + error = aa_unix_peer_perm(label, OP_CONNECT,
971 + (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
972 + sk, peer_sk, NULL);
973 + if (!UNIX_FS(peer_sk)) {
975 + aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
976 + (AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
977 + peer_sk, sk, label));
979 + __end_current_label_crit_section(label);
984 + /* label newsk if it wasn't labeled in post_create. Normally this
985 + * would be done in sock_graft, but because we are directly looking
986 + * at the peer_sk to obtain peer_labeling for unix socks this
989 + if (!new_ctx->label)
990 + new_ctx->label = aa_get_label(peer_ctx->label);
992 + /* Cross reference the peer labels for SO_PEERSEC */
994 + aa_put_label(new_ctx->peer);
997 + aa_put_label(sk_ctx->peer);
999 + new_ctx->peer = aa_get_label(sk_ctx->label);
1000 + sk_ctx->peer = aa_get_label(peer_ctx->label);
1002 + path = UNIX_FS_CONN_PATH(sk, peer_sk);
1004 + new_ctx->path = *path;
1005 + sk_ctx->path = *path;
1013 + * apparmor_unix_may_send - check perms before conn or sending unix dgrams
1015 + * other is locked when this hook is called
1017 + * dgram connect calls may_send, peer setup but path not copied?????
1019 +static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
1021 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
1022 + struct aa_label *label;
1025 + label = __begin_current_label_crit_section();
1026 + error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
1027 + sock->sk, peer->sk, NULL),
1028 + aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG,
1030 + peer->sk, sock->sk, label));
1031 + __end_current_label_crit_section(label);
1037 * apparmor_socket_create - check perms before creating a new socket
1038 @@ -849,12 +930,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
1039 static int apparmor_socket_bind(struct socket *sock,
1040 struct sockaddr *address, int addrlen)
1043 - AA_BUG(!sock->sk);
1045 - AA_BUG(in_interrupt());
1047 - return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
1048 + return aa_sock_bind_perm(sock, address, addrlen);
1052 @@ -863,12 +939,7 @@ static int apparmor_socket_bind(struct socket *sock,
1053 static int apparmor_socket_connect(struct socket *sock,
1054 struct sockaddr *address, int addrlen)
1057 - AA_BUG(!sock->sk);
1059 - AA_BUG(in_interrupt());
1061 - return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
1062 + return aa_sock_connect_perm(sock, address, addrlen);
1066 @@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock,
1068 static int apparmor_socket_listen(struct socket *sock, int backlog)
1071 - AA_BUG(!sock->sk);
1072 - AA_BUG(in_interrupt());
1074 - return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
1075 + return aa_sock_listen_perm(sock, backlog);
1079 @@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog)
1081 static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
1084 - AA_BUG(!sock->sk);
1086 - AA_BUG(in_interrupt());
1088 - return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
1091 -static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1092 - struct msghdr *msg, int size)
1095 - AA_BUG(!sock->sk);
1097 - AA_BUG(in_interrupt());
1099 - return aa_sk_perm(op, request, sock->sk);
1100 + return aa_sock_accept_perm(sock, newsock);
1104 @@ -928,16 +979,6 @@ static int apparmor_socket_recvmsg(struct socket *sock,
1105 return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
1108 -/* revaliation, get/set attr, shutdown */
1109 -static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1112 - AA_BUG(!sock->sk);
1113 - AA_BUG(in_interrupt());
1115 - return aa_sk_perm(op, request, sock->sk);
1119 * apparmor_socket_getsockname - check perms before getting the local address
1121 @@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock)
1122 return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
1125 -/* revaliation, get/set attr, opt */
1126 -static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
1127 - int level, int optname)
1130 - AA_BUG(!sock->sk);
1131 - AA_BUG(in_interrupt());
1133 - return aa_sk_perm(op, request, sock->sk);
1137 * apparmor_getsockopt - check perms before getting socket options
1139 @@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1141 static struct aa_label *sk_peer_label(struct sock *sk)
1143 + struct sock *peer_sk;
1144 struct aa_sk_ctx *ctx = SK_CTX(sk);
1149 + if (sk->sk_family != PF_UNIX)
1150 + return ERR_PTR(-ENOPROTOOPT);
1152 + /* check for sockpair peering which does not go through
1153 + * security_unix_stream_connect
1155 + peer_sk = unix_peer(sk);
1157 + ctx = SK_CTX(peer_sk);
1159 + return ctx->label;
1162 return ERR_PTR(-ENOPROTOOPT);
1165 @@ -1137,6 +1181,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1166 LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
1167 LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
1169 + LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
1170 + LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
1172 LSM_HOOK_INIT(socket_create, apparmor_socket_create),
1173 LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
1174 LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
1175 diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1176 index 33d54435f8d6..dd1953b08e58 100644
1177 --- a/security/apparmor/net.c
1178 +++ b/security/apparmor/net.c
1183 +#include "include/af_unix.h"
1184 #include "include/apparmor.h"
1185 #include "include/audit.h"
1186 #include "include/context.h"
1189 struct aa_sfs_entry aa_sfs_entry_network[] = {
1190 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
1191 + AA_SFS_FILE_BOOLEAN("af_unix", 1),
1195 @@ -69,6 +71,36 @@ static const char * const net_mask_names[] = {
1199 +static void audit_unix_addr(struct audit_buffer *ab, const char *str,
1200 + struct sockaddr_un *addr, int addrlen)
1202 + int len = unix_addr_len(addrlen);
1204 + if (!addr || len <= 0) {
1205 + audit_log_format(ab, " %s=none", str);
1206 + } else if (addr->sun_path[0]) {
1207 + audit_log_format(ab, " %s=", str);
1208 + audit_log_untrustedstring(ab, addr->sun_path);
1210 + audit_log_format(ab, " %s=\"@", str);
1211 + if (audit_string_contains_control(&addr->sun_path[1], len - 1))
1212 + audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
1214 + audit_log_format(ab, "%.*s", len - 1,
1215 + &addr->sun_path[1]);
1216 + audit_log_format(ab, "\"");
1220 +static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
1223 + struct unix_sock *u = unix_sk(sk);
1225 + audit_unix_addr(ab, str, u->addr->name, u->addr->len);
1227 + audit_unix_addr(ab, str, NULL, 0);
1230 /* audit callback for net specific fields */
1231 void audit_net_cb(struct audit_buffer *ab, void *va)
1232 @@ -98,6 +130,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
1233 net_mask_names, NET_PERMS_MASK);
1236 + if (sa->u.net->family == AF_UNIX) {
1237 + if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
1238 + audit_unix_addr(ab, "addr",
1239 + unix_addr(aad(sa)->net.addr),
1240 + aad(sa)->net.addrlen);
1242 + audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
1243 + if (aad(sa)->request & NET_PEER_MASK) {
1244 + if (aad(sa)->net.addr)
1245 + audit_unix_addr(ab, "peer_addr",
1246 + unix_addr(aad(sa)->net.addr),
1247 + aad(sa)->net.addrlen);
1249 + audit_unix_sk_addr(ab, "peer_addr",
1250 + aad(sa)->net.peer_sk);
1253 if (aad(sa)->peer) {
1254 audit_log_format(ab, " peer=");
1255 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
1256 @@ -172,6 +221,127 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)
1260 +#define af_select(FAMILY, FN, DEF_FN) \
1263 + switch ((FAMILY)) { \
1265 + __e = aa_unix_ ## FN; \
1273 +/* TODO: push into lsm.c ???? */
1275 +/* revaliation, get/set attr, shutdown */
1276 +int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1279 + AA_BUG(!sock->sk);
1280 + AA_BUG(in_interrupt());
1282 + return af_select(sock->sk->sk_family,
1283 + sock_perm(op, request, sock),
1284 + aa_sk_perm(op, request, sock->sk));
1287 +int aa_sock_create_perm(struct aa_label *label, int family, int type,
1292 + AA_BUG(in_interrupt());
1294 + return af_select(family,
1295 + create_perm(label, family, type, protocol),
1296 + aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
1300 +int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
1304 + AA_BUG(!sock->sk);
1307 + AA_BUG(in_interrupt());
1309 + return af_select(sock->sk->sk_family,
1310 + bind_perm(sock, address, addrlen),
1311 + aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
1314 +int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
1318 + AA_BUG(!sock->sk);
1321 + AA_BUG(in_interrupt());
1323 + return af_select(sock->sk->sk_family,
1324 + connect_perm(sock, address, addrlen),
1325 + aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
1328 +int aa_sock_listen_perm(struct socket *sock, int backlog)
1331 + AA_BUG(!sock->sk);
1333 + AA_BUG(in_interrupt());
1335 + return af_select(sock->sk->sk_family,
1336 + listen_perm(sock, backlog),
1337 + aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
1340 +/* ability of sock to connect, not peer address binding */
1341 +int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
1344 + AA_BUG(!sock->sk);
1347 + AA_BUG(in_interrupt());
1349 + return af_select(sock->sk->sk_family,
1350 + accept_perm(sock, newsock),
1351 + aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
1354 +/* sendmsg, recvmsg */
1355 +int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1356 + struct msghdr *msg, int size)
1359 + AA_BUG(!sock->sk);
1362 + AA_BUG(in_interrupt());
1364 + return af_select(sock->sk->sk_family,
1365 + msg_perm(op, request, sock, msg, size),
1366 + aa_sk_perm(op, request, sock->sk));
1369 +/* revaliation, get/set attr, opt */
1370 +int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
1374 + AA_BUG(!sock->sk);
1375 + AA_BUG(in_interrupt());
1377 + return af_select(sock->sk->sk_family,
1378 + opt_perm(op, request, sock, level, optname),
1379 + aa_sk_perm(op, request, sock->sk));
1382 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1383 struct socket *sock)
1384 @@ -180,5 +350,7 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1388 - return aa_label_sk_perm(label, op, request, sock->sk);
1389 + return af_select(sock->sk->sk_family,
1390 + file_perm(label, op, request, sock),
1391 + aa_label_sk_perm(label, op, request, sock->sk));