1 From a3b0cb6676a04cdad5cc357bc422d0398083b435 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 17/17] UBUNTU: SAUCE: 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>
11 security/apparmor/Makefile | 3 +-
12 security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++
13 security/apparmor/apparmorfs.c | 6 +
14 security/apparmor/file.c | 4 +-
15 security/apparmor/include/af_unix.h | 114 +++++++
16 security/apparmor/include/net.h | 16 +-
17 security/apparmor/include/path.h | 1 +
18 security/apparmor/include/policy.h | 2 +-
19 security/apparmor/lsm.c | 169 ++++++----
20 security/apparmor/net.c | 174 +++++++++-
21 10 files changed, 1072 insertions(+), 68 deletions(-)
22 create mode 100644 security/apparmor/af_unix.c
23 create mode 100644 security/apparmor/include/af_unix.h
25 diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
26 index dafdd387d42b..ef39226ff4aa 100644
27 --- a/security/apparmor/Makefile
28 +++ b/security/apparmor/Makefile
29 @@ -4,7 +4,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
31 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
32 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
33 - resource.o secid.o file.o policy_ns.o label.o mount.o net.o
34 + resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
36 apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
38 clean-files := capability_names.h rlim_names.h net_names.h
39 diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
41 index 000000000000..c6876db2dbde
43 +++ b/security/apparmor/af_unix.c
46 + * AppArmor security module
48 + * This file contains AppArmor af_unix fine grained mediation
50 + * Copyright 2014 Canonical Ltd.
52 + * This program is free software; you can redistribute it and/or
53 + * modify it under the terms of the GNU General Public License as
54 + * published by the Free Software Foundation, version 2 of the
58 +#include <net/tcp_states.h>
60 +#include "include/af_unix.h"
61 +#include "include/apparmor.h"
62 +#include "include/context.h"
63 +#include "include/file.h"
64 +#include "include/label.h"
65 +#include "include/path.h"
66 +#include "include/policy.h"
68 +static inline struct sock *aa_sock(struct unix_sock *u)
73 +static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
74 + struct unix_sock *u, int flags)
78 + AA_BUG(!UNIX_FS(aa_sock(u)));
80 + if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
83 + mask &= NET_FS_PERMS;
84 + if (!u->path.dentry) {
85 + struct path_cond cond = { };
86 + struct aa_perms perms = { };
87 + struct aa_profile *profile;
89 + /* socket path has been cleared because it is being shutdown
90 + * can only fall back to original sun_path request
92 + struct aa_sk_ctx *ctx = SK_CTX(&u->sk);
93 + if (ctx->path.dentry)
94 + return aa_path_perm(op, label, &ctx->path, flags, mask,
96 + return fn_for_each_confined(label, profile,
97 + ((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
98 + __aa_path_perm(op, profile,
99 + u->addr->name->sun_path, mask,
100 + &cond, flags, &perms) :
101 + aa_audit_file(profile, &nullperms, op, mask,
102 + u->addr->name->sun_path, NULL,
104 + "Failed name lookup - "
105 + "deleted entry", -EACCES));
107 + /* the sunpath may not be valid for this ns so use the path */
108 + struct path_cond cond = { u->path.dentry->d_inode->i_uid,
109 + u->path.dentry->d_inode->i_mode
112 + return aa_path_perm(op, label, &u->path, flags, mask, &cond);
118 +/* passing in state returned by PROFILE_MEDIATES_AF */
119 +static unsigned int match_to_prot(struct aa_profile *profile,
120 + unsigned int state, int type, int protocol,
124 + buffer[0] = cpu_to_be16(type);
125 + buffer[1] = cpu_to_be16(protocol);
126 + state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
129 + *info = "failed type and protocol match";
133 +static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
134 + struct sockaddr_un *addr, int addrlen)
137 + /* include leading \0 */
138 + state = aa_dfa_match_len(profile->policy.dfa, state,
140 + unix_addr_len(addrlen));
142 + /* anonymous end point */
143 + state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
145 + /* todo change to out of band */
146 + state = aa_dfa_null_transition(profile->policy.dfa, state);
150 +static unsigned int match_to_local(struct aa_profile *profile,
151 + unsigned int state, int type, int protocol,
152 + struct sockaddr_un *addr, int addrlen,
155 + state = match_to_prot(profile, state, type, protocol, info);
157 + state = match_addr(profile, state, addr, addrlen);
159 + /* todo: local label matching */
160 + state = aa_dfa_null_transition(profile->policy.dfa,
163 + *info = "failed local label match";
165 + *info = "failed local address match";
171 +static unsigned int match_to_sk(struct aa_profile *profile,
172 + unsigned int state, struct unix_sock *u,
175 + struct sockaddr_un *addr = NULL;
179 + addr = u->addr->name;
180 + addrlen = u->addr->len;
183 + return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
184 + addr, addrlen, info);
188 +#define CMD_LISTEN 2
191 +static inline unsigned int match_to_cmd(struct aa_profile *profile,
192 + unsigned int state, struct unix_sock *u,
193 + char cmd, const char **info)
195 + state = match_to_sk(profile, state, u, info);
197 + state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
199 + *info = "failed cmd selection match";
205 +static inline unsigned int match_to_peer(struct aa_profile *profile,
206 + unsigned int state,
207 + struct unix_sock *u,
208 + struct sockaddr_un *peer_addr,
212 + state = match_to_cmd(profile, state, u, CMD_ADDR, info);
214 + state = match_addr(profile, state, peer_addr, peer_addrlen);
216 + *info = "failed peer address match";
221 +static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
222 + struct common_audit_data *sa)
224 + struct aa_perms perms;
228 + aa_compute_perms(profile->policy.dfa, state, &perms);
229 + aa_apply_modes_to_perms(profile, &perms);
230 + return aa_check_perms(profile, &perms, request, sa,
234 +static int match_label(struct aa_profile *profile, struct aa_profile *peer,
235 + unsigned int state, u32 request,
236 + struct common_audit_data *sa)
241 + aad(sa)->peer = &peer->label;
244 + state = aa_dfa_match(profile->policy.dfa, state,
247 + aad(sa)->info = "failed peer label match";
249 + return do_perms(profile, state, request, sa);
253 +/* unix sock creation comes before we know if the socket will be an fs
255 + * v6 - semantics are handled by mapping in profile load
256 + * v7 - semantics require sock create for tasks creating an fs socket.
258 +static int profile_create_perm(struct aa_profile *profile, int family,
259 + int type, int protocol)
261 + unsigned int state;
262 + DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
265 + AA_BUG(profile_unconfined(profile));
267 + if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
268 + state = match_to_prot(profile, state, type, protocol,
270 + return do_perms(profile, state, AA_MAY_CREATE, &sa);
273 + return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
276 +int aa_unix_create_perm(struct aa_label *label, int family, int type,
279 + struct aa_profile *profile;
281 + if (unconfined(label))
284 + return fn_for_each_confined(label, profile,
285 + profile_create_perm(profile, family, type, protocol));
289 +static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
290 + u32 request, struct sock *sk)
292 + unsigned int state;
293 + DEFINE_AUDIT_SK(sa, op, sk);
297 + AA_BUG(UNIX_FS(sk));
298 + AA_BUG(profile_unconfined(profile));
300 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
302 + state = match_to_sk(profile, state, unix_sk(sk),
304 + return do_perms(profile, state, request, &sa);
307 + return aa_profile_af_sk_perm(profile, &sa, request, sk);
310 +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
313 + struct aa_profile *profile;
315 + return fn_for_each_confined(label, profile,
316 + profile_sk_perm(profile, op, request, sk));
319 +static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
320 + struct socket *sock)
322 + if (unconfined(label))
324 + if (UNIX_FS(sock->sk))
325 + return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
327 + return aa_unix_label_sk_perm(label, op, request, sock->sk);
330 +/* revaliation, get/set attr */
331 +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
333 + struct aa_label *label;
336 + label = begin_current_label_crit_section();
337 + error = unix_label_sock_perm(label, op, request, sock);
338 + end_current_label_crit_section(label);
343 +static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
344 + struct sockaddr *addr, int addrlen)
346 + unsigned int state;
347 + DEFINE_AUDIT_SK(sa, OP_BIND, sk);
351 + AA_BUG(addr->sa_family != AF_UNIX);
352 + AA_BUG(profile_unconfined(profile));
353 + AA_BUG(unix_addr_fs(addr, addrlen));
355 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
357 + /* bind for abstract socket */
358 + aad(&sa)->net.addr = unix_addr(addr);
359 + aad(&sa)->net.addrlen = addrlen;
361 + state = match_to_local(profile, state,
362 + sk->sk_type, sk->sk_protocol,
363 + unix_addr(addr), addrlen,
365 + return do_perms(profile, state, AA_MAY_BIND, &sa);
368 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
371 +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
374 + struct aa_profile *profile;
375 + struct aa_label *label;
378 + label = begin_current_label_crit_section();
379 + /* fs bind is handled by mknod */
380 + if (!(unconfined(label) || unix_addr_fs(address, addrlen)))
381 + error = fn_for_each_confined(label, profile,
382 + profile_bind_perm(profile, sock->sk, address,
384 + end_current_label_crit_section(label);
389 +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
392 + /* unix connections are covered by the
393 + * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
394 + * - fs connect is handled by open
399 +static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
402 + unsigned int state;
403 + DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
407 + AA_BUG(UNIX_FS(sk));
408 + AA_BUG(profile_unconfined(profile));
410 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
412 + __be16 b = cpu_to_be16(backlog);
414 + state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
417 + state = aa_dfa_match_len(profile->policy.dfa, state,
420 + aad(&sa)->info = "failed listen backlog match";
422 + return do_perms(profile, state, AA_MAY_LISTEN, &sa);
425 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
428 +int aa_unix_listen_perm(struct socket *sock, int backlog)
430 + struct aa_profile *profile;
431 + struct aa_label *label;
434 + label = begin_current_label_crit_section();
435 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
436 + error = fn_for_each_confined(label, profile,
437 + profile_listen_perm(profile, sock->sk,
439 + end_current_label_crit_section(label);
445 +static inline int profile_accept_perm(struct aa_profile *profile,
447 + struct sock *newsk)
449 + unsigned int state;
450 + DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
454 + AA_BUG(UNIX_FS(sk));
455 + AA_BUG(profile_unconfined(profile));
457 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
459 + state = match_to_sk(profile, state, unix_sk(sk),
461 + return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
464 + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
467 +/* ability of sock to connect, not peer address binding */
468 +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
470 + struct aa_profile *profile;
471 + struct aa_label *label;
474 + label = begin_current_label_crit_section();
475 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
476 + error = fn_for_each_confined(label, profile,
477 + profile_accept_perm(profile, sock->sk,
479 + end_current_label_crit_section(label);
485 +/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
486 + * could do per msg unix_stream here
488 +/* sendmsg, recvmsg */
489 +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
490 + struct msghdr *msg, int size)
496 +static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
497 + struct sock *sk, int level, int optname)
499 + unsigned int state;
500 + DEFINE_AUDIT_SK(sa, op, sk);
504 + AA_BUG(UNIX_FS(sk));
505 + AA_BUG(profile_unconfined(profile));
507 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
509 + __be16 b = cpu_to_be16(optname);
511 + state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
514 + state = aa_dfa_match_len(profile->policy.dfa, state,
517 + aad(&sa)->info = "failed sockopt match";
519 + return do_perms(profile, state, request, &sa);
522 + return aa_profile_af_sk_perm(profile, &sa, request, sk);
525 +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
528 + struct aa_profile *profile;
529 + struct aa_label *label;
532 + label = begin_current_label_crit_section();
533 + if (!(unconfined(label) || UNIX_FS(sock->sk)))
534 + error = fn_for_each_confined(label, profile,
535 + profile_opt_perm(profile, op, request,
536 + sock->sk, level, optname));
537 + end_current_label_crit_section(label);
542 +/* null peer_label is allowed, in which case the peer_sk label is used */
543 +static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request,
544 + struct sock *sk, struct sock *peer_sk,
545 + struct aa_label *peer_label,
546 + struct common_audit_data *sa)
548 + unsigned int state;
551 + AA_BUG(profile_unconfined(profile));
554 + AA_BUG(UNIX_FS(peer_sk));
556 + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
558 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
559 + struct aa_profile *peerp;
560 + struct sockaddr_un *addr = NULL;
562 + if (unix_sk(peer_sk)->addr) {
563 + addr = unix_sk(peer_sk)->addr->name;
564 + len = unix_sk(peer_sk)->addr->len;
566 + state = match_to_peer(profile, state, unix_sk(sk),
567 + addr, len, &aad(sa)->info);
569 + peer_label = peer_ctx->label;
570 + return fn_for_each_in_ns(peer_label, peerp,
571 + match_label(profile, peerp, state, request,
575 + return aa_profile_af_sk_perm(profile, sa, request, sk);
580 + * Requires: lock held on both @sk and @peer_sk
582 +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
583 + struct sock *sk, struct sock *peer_sk,
584 + struct aa_label *peer_label)
586 + struct unix_sock *peeru = unix_sk(peer_sk);
587 + struct unix_sock *u = unix_sk(sk);
593 + if (UNIX_FS(aa_sock(peeru)))
594 + return unix_fs_perm(op, request, label, peeru, 0);
595 + else if (UNIX_FS(aa_sock(u)))
596 + return unix_fs_perm(op, request, label, u, 0);
598 + struct aa_profile *profile;
599 + DEFINE_AUDIT_SK(sa, op, sk);
600 + aad(&sa)->net.peer_sk = peer_sk;
603 + if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
607 + if (unconfined(label))
610 + return fn_for_each_confined(label, profile,
611 + profile_peer_perm(profile, op, request, sk,
612 + peer_sk, peer_label, &sa));
617 +/* from net/unix/af_unix.c */
618 +static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
620 + if (unlikely(sk1 == sk2) || !sk2) {
621 + unix_state_lock(sk1);
625 + unix_state_lock(sk1);
626 + unix_state_lock_nested(sk2);
628 + unix_state_lock(sk2);
629 + unix_state_lock_nested(sk1);
633 +static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
635 + if (unlikely(sk1 == sk2) || !sk2) {
636 + unix_state_unlock(sk1);
639 + unix_state_unlock(sk1);
640 + unix_state_unlock(sk2);
643 +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
644 + struct socket *sock)
646 + struct sock *peer_sk = NULL;
647 + u32 sk_req = request & ~NET_PEER_MASK;
653 + AA_BUG(sock->sk->sk_family != AF_UNIX);
655 + /* TODO: update sock label with new task label */
656 + unix_state_lock(sock->sk);
657 + peer_sk = unix_peer(sock->sk);
659 + sock_hold(peer_sk);
660 + if (!unix_connected(sock) && sk_req) {
661 + error = unix_label_sock_perm(label, op, sk_req, sock);
666 + unix_state_unlock(sock->sk);
670 + unix_state_double_lock(sock->sk, peer_sk);
671 + if (UNIX_FS(sock->sk)) {
672 + error = unix_fs_perm(op, request, label, unix_sk(sock->sk),
674 + } else if (UNIX_FS(peer_sk)) {
675 + error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
678 + struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
680 + error = aa_unix_label_sk_perm(label, op, sk_req,
683 + xcheck(aa_unix_peer_perm(label, op,
684 + MAY_READ | MAY_WRITE,
685 + sock->sk, peer_sk, NULL),
686 + aa_unix_peer_perm(pctx->label, op,
687 + MAY_READ | MAY_WRITE,
688 + peer_sk, sock->sk, label)));
691 + unix_state_double_unlock(sock->sk, peer_sk);
696 diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
697 index 125dad5c3fde..20cdb1c4b266 100644
698 --- a/security/apparmor/apparmorfs.c
699 +++ b/security/apparmor/apparmorfs.c
700 @@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
704 +static struct aa_sfs_entry aa_sfs_entry_dbus[] = {
705 + AA_SFS_FILE_STRING("mask", "acquire send receive"),
709 static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
710 AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
711 AA_SFS_FILE_BOOLEAN("data", 1),
712 @@ -2210,6 +2215,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
713 AA_SFS_DIR("caps", aa_sfs_entry_caps),
714 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
715 AA_SFS_DIR("signal", aa_sfs_entry_signal),
716 + AA_SFS_DIR("dbus", aa_sfs_entry_dbus),
717 AA_SFS_DIR("query", aa_sfs_entry_query),
720 diff --git a/security/apparmor/file.c b/security/apparmor/file.c
721 index db80221891c6..e62791106900 100644
722 --- a/security/apparmor/file.c
723 +++ b/security/apparmor/file.c
725 #include <linux/fdtable.h>
726 #include <linux/file.h>
728 +#include "include/af_unix.h"
729 #include "include/apparmor.h"
730 #include "include/audit.h"
731 #include "include/context.h"
732 @@ -289,7 +290,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
736 - if (profile_unconfined(profile))
737 + if (profile_unconfined(profile) ||
738 + ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
740 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
741 if (request & ~perms->allow)
742 diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
744 index 000000000000..d1b7f2316be4
746 +++ b/security/apparmor/include/af_unix.h
749 + * AppArmor security module
751 + * This file contains AppArmor af_unix fine grained mediation
753 + * Copyright 2014 Canonical Ltd.
755 + * This program is free software; you can redistribute it and/or
756 + * modify it under the terms of the GNU General Public License as
757 + * published by the Free Software Foundation, version 2 of the
760 +#ifndef __AA_AF_UNIX_H
762 +#include <net/af_unix.h>
765 +//#include "include/net.h"
767 +#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
768 +#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
769 +#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
770 +#define addr_unix_abstract_name(B) ((B)[0] == 0)
771 +#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
772 +#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
773 +//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
775 +#define unix_addr(A) ((struct sockaddr_un *)(A))
776 +#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
777 +#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
779 +#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
780 +/* from net/unix/af_unix.c */
781 +#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \
782 + unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
783 +#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
784 +#define unix_peer(sk) (unix_sk(sk)->peer)
785 +#define unix_connected(S) ((S)->state == SS_CONNECTED)
787 +static inline void print_unix_addr(struct sockaddr_un *A, int L)
789 + char *buf = (A) ? (char *) &(A)->sun_path : NULL;
790 + int len = unix_addr_len(L);
791 + if (!buf || len <= 0)
792 + printk(" <anonymous>");
794 + printk(" %s", buf);
796 + /* abstract name len includes leading \0 */
797 + printk(" %d @%.*s", len - 1, len - 1, buf+1);
801 + printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \
804 +#define print_unix_sk(SK) \
806 + struct unix_sock *u = unix_sk(SK); \
807 + printk("%s: f %d, t %d, p %d", #SK , \
808 + (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \
810 + print_unix_addr(u->addr->name, u->addr->len); \
812 + print_unix_addr(NULL, sizeof(sa_family_t)); \
813 + /* printk("\n");*/ \
816 +#define print_sk(SK) \
819 + printk("%s: %s is null\n", __FUNCTION__, #SK); \
820 + } else if ((SK)->sk_family == PF_UNIX) { \
821 + print_unix_sk(SK); \
824 + printk("%s: %s: family %d\n", __FUNCTION__, #SK , \
825 + (SK)->sk_family); \
829 +#define print_sock_addr(U) \
831 + printk("%s:\n", __FUNCTION__); \
832 + printk(" sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
833 + printk(" other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
834 + printk(" new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
840 +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
841 + struct sock *sk, struct sock *peer_sk,
842 + struct aa_label *peer_label);
843 +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
845 +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
846 +int aa_unix_create_perm(struct aa_label *label, int family, int type,
848 +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
850 +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
852 +int aa_unix_listen_perm(struct socket *sock, int backlog);
853 +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
854 +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
855 + struct msghdr *msg, int size);
856 +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
858 +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
859 + struct socket *sock);
861 +#endif /* __AA_AF_UNIX_H */
862 diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
863 index 140c8efcf364..0ae45240c352 100644
864 --- a/security/apparmor/include/net.h
865 +++ b/security/apparmor/include/net.h
866 @@ -90,8 +90,6 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
867 void audit_net_cb(struct audit_buffer *ab, void *va);
868 int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
869 u32 request, u16 family, int type);
870 -int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
871 - int type, int protocol);
872 static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
873 struct common_audit_data *sa,
875 @@ -100,8 +98,20 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
876 return aa_profile_af_perm(profile, sa, request, sk->sk_family,
879 -int aa_sk_perm(const char *op, u32 request, struct sock *sk);
881 +int aa_sock_perm(const char *op, u32 request, struct socket *sock);
882 +int aa_sock_create_perm(struct aa_label *label, int family, int type,
884 +int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
886 +int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
888 +int aa_sock_listen_perm(struct socket *sock, int backlog);
889 +int aa_sock_accept_perm(struct socket *sock, struct socket *newsock);
890 +int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
891 + struct msghdr *msg, int size);
892 +int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
894 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
895 struct socket *sock);
897 diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
898 index 05fb3305671e..26762db2207d 100644
899 --- a/security/apparmor/include/path.h
900 +++ b/security/apparmor/include/path.h
904 PATH_IS_DIR = 0x1, /* path is a directory */
905 + PATH_SOCK_COND = 0x2,
906 PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */
907 PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */
908 PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
909 diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
910 index 4364088a0b9e..26660a1a50b0 100644
911 --- a/security/apparmor/include/policy.h
912 +++ b/security/apparmor/include/policy.h
913 @@ -226,7 +226,7 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
914 static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
916 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
917 - u16 be_af = cpu_to_be16(AF);
918 + __be16 be_af = cpu_to_be16(AF);
922 diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
923 index cc5ab23a2d84..0ede66d80a53 100644
924 --- a/security/apparmor/lsm.c
925 +++ b/security/apparmor/lsm.c
927 #include <linux/kmemleak.h>
928 #include <net/sock.h>
930 +#include "include/af_unix.h"
931 #include "include/apparmor.h"
932 #include "include/apparmorfs.h"
933 #include "include/audit.h"
934 @@ -782,16 +783,96 @@ static void apparmor_sk_clone_security(const struct sock *sk,
935 path_get(&new->path);
938 -static int aa_sock_create_perm(struct aa_label *label, int family, int type,
940 +static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
943 - AA_BUG(in_interrupt());
944 + if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
945 + return &unix_sk(sk)->path;
946 + else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
947 + return &unix_sk(newsk)->path;
952 + * apparmor_unix_stream_connect - check perms before making unix domain conn
954 + * peer is locked when this hook is called
956 +static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
957 + struct sock *newsk)
959 + struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
960 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
961 + struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
962 + struct aa_label *label;
966 - return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
968 + label = __begin_current_label_crit_section();
969 + error = aa_unix_peer_perm(label, OP_CONNECT,
970 + (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
971 + sk, peer_sk, NULL);
972 + if (!UNIX_FS(peer_sk)) {
974 + aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
975 + (AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
976 + peer_sk, sk, label));
978 + __end_current_label_crit_section(label);
983 + /* label newsk if it wasn't labeled in post_create. Normally this
984 + * would be done in sock_graft, but because we are directly looking
985 + * at the peer_sk to obtain peer_labeling for unix socks this
988 + if (!new_ctx->label)
989 + new_ctx->label = aa_get_label(peer_ctx->label);
991 + /* Cross reference the peer labels for SO_PEERSEC */
993 + aa_put_label(new_ctx->peer);
996 + aa_put_label(sk_ctx->peer);
998 + new_ctx->peer = aa_get_label(sk_ctx->label);
999 + sk_ctx->peer = aa_get_label(peer_ctx->label);
1001 + path = UNIX_FS_CONN_PATH(sk, peer_sk);
1003 + new_ctx->path = *path;
1004 + sk_ctx->path = *path;
1012 + * apparmor_unix_may_send - check perms before conn or sending unix dgrams
1014 + * other is locked when this hook is called
1016 + * dgram connect calls may_send, peer setup but path not copied?????
1018 +static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
1020 + struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
1021 + struct aa_label *label;
1024 + label = __begin_current_label_crit_section();
1025 + error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
1026 + sock->sk, peer->sk, NULL),
1027 + aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG,
1029 + peer->sk, sock->sk, label));
1030 + __end_current_label_crit_section(label);
1036 * apparmor_socket_create - check perms before creating a new socket
1037 @@ -849,12 +930,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
1038 static int apparmor_socket_bind(struct socket *sock,
1039 struct sockaddr *address, int addrlen)
1042 - AA_BUG(!sock->sk);
1044 - AA_BUG(in_interrupt());
1046 - return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
1047 + return aa_sock_bind_perm(sock, address, addrlen);
1051 @@ -863,12 +939,7 @@ static int apparmor_socket_bind(struct socket *sock,
1052 static int apparmor_socket_connect(struct socket *sock,
1053 struct sockaddr *address, int addrlen)
1056 - AA_BUG(!sock->sk);
1058 - AA_BUG(in_interrupt());
1060 - return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
1061 + return aa_sock_connect_perm(sock, address, addrlen);
1065 @@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock,
1067 static int apparmor_socket_listen(struct socket *sock, int backlog)
1070 - AA_BUG(!sock->sk);
1071 - AA_BUG(in_interrupt());
1073 - return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
1074 + return aa_sock_listen_perm(sock, backlog);
1078 @@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog)
1080 static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
1083 - AA_BUG(!sock->sk);
1085 - AA_BUG(in_interrupt());
1087 - return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
1090 -static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1091 - struct msghdr *msg, int size)
1094 - AA_BUG(!sock->sk);
1096 - AA_BUG(in_interrupt());
1098 - return aa_sk_perm(op, request, sock->sk);
1099 + return aa_sock_accept_perm(sock, newsock);
1103 @@ -928,16 +979,6 @@ static int apparmor_socket_recvmsg(struct socket *sock,
1104 return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
1107 -/* revaliation, get/set attr, shutdown */
1108 -static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1111 - AA_BUG(!sock->sk);
1112 - AA_BUG(in_interrupt());
1114 - return aa_sk_perm(op, request, sock->sk);
1118 * apparmor_socket_getsockname - check perms before getting the local address
1120 @@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock)
1121 return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
1124 -/* revaliation, get/set attr, opt */
1125 -static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
1126 - int level, int optname)
1129 - AA_BUG(!sock->sk);
1130 - AA_BUG(in_interrupt());
1132 - return aa_sk_perm(op, request, sock->sk);
1136 * apparmor_getsockopt - check perms before getting socket options
1138 @@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1140 static struct aa_label *sk_peer_label(struct sock *sk)
1142 + struct sock *peer_sk;
1143 struct aa_sk_ctx *ctx = SK_CTX(sk);
1148 + if (sk->sk_family != PF_UNIX)
1149 + return ERR_PTR(-ENOPROTOOPT);
1151 + /* check for sockpair peering which does not go through
1152 + * security_unix_stream_connect
1154 + peer_sk = unix_peer(sk);
1156 + ctx = SK_CTX(peer_sk);
1158 + return ctx->label;
1161 return ERR_PTR(-ENOPROTOOPT);
1164 @@ -1137,6 +1181,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1165 LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
1166 LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
1168 + LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
1169 + LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
1171 LSM_HOOK_INIT(socket_create, apparmor_socket_create),
1172 LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
1173 LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
1174 diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1175 index 33d54435f8d6..dd1953b08e58 100644
1176 --- a/security/apparmor/net.c
1177 +++ b/security/apparmor/net.c
1182 +#include "include/af_unix.h"
1183 #include "include/apparmor.h"
1184 #include "include/audit.h"
1185 #include "include/context.h"
1188 struct aa_sfs_entry aa_sfs_entry_network[] = {
1189 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
1190 + AA_SFS_FILE_BOOLEAN("af_unix", 1),
1194 @@ -69,6 +71,36 @@ static const char * const net_mask_names[] = {
1198 +static void audit_unix_addr(struct audit_buffer *ab, const char *str,
1199 + struct sockaddr_un *addr, int addrlen)
1201 + int len = unix_addr_len(addrlen);
1203 + if (!addr || len <= 0) {
1204 + audit_log_format(ab, " %s=none", str);
1205 + } else if (addr->sun_path[0]) {
1206 + audit_log_format(ab, " %s=", str);
1207 + audit_log_untrustedstring(ab, addr->sun_path);
1209 + audit_log_format(ab, " %s=\"@", str);
1210 + if (audit_string_contains_control(&addr->sun_path[1], len - 1))
1211 + audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
1213 + audit_log_format(ab, "%.*s", len - 1,
1214 + &addr->sun_path[1]);
1215 + audit_log_format(ab, "\"");
1219 +static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
1222 + struct unix_sock *u = unix_sk(sk);
1224 + audit_unix_addr(ab, str, u->addr->name, u->addr->len);
1226 + audit_unix_addr(ab, str, NULL, 0);
1229 /* audit callback for net specific fields */
1230 void audit_net_cb(struct audit_buffer *ab, void *va)
1231 @@ -98,6 +130,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
1232 net_mask_names, NET_PERMS_MASK);
1235 + if (sa->u.net->family == AF_UNIX) {
1236 + if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
1237 + audit_unix_addr(ab, "addr",
1238 + unix_addr(aad(sa)->net.addr),
1239 + aad(sa)->net.addrlen);
1241 + audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
1242 + if (aad(sa)->request & NET_PEER_MASK) {
1243 + if (aad(sa)->net.addr)
1244 + audit_unix_addr(ab, "peer_addr",
1245 + unix_addr(aad(sa)->net.addr),
1246 + aad(sa)->net.addrlen);
1248 + audit_unix_sk_addr(ab, "peer_addr",
1249 + aad(sa)->net.peer_sk);
1252 if (aad(sa)->peer) {
1253 audit_log_format(ab, " peer=");
1254 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
1255 @@ -172,6 +221,127 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)
1259 +#define af_select(FAMILY, FN, DEF_FN) \
1262 + switch ((FAMILY)) { \
1264 + __e = aa_unix_ ## FN; \
1272 +/* TODO: push into lsm.c ???? */
1274 +/* revaliation, get/set attr, shutdown */
1275 +int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1278 + AA_BUG(!sock->sk);
1279 + AA_BUG(in_interrupt());
1281 + return af_select(sock->sk->sk_family,
1282 + sock_perm(op, request, sock),
1283 + aa_sk_perm(op, request, sock->sk));
1286 +int aa_sock_create_perm(struct aa_label *label, int family, int type,
1291 + AA_BUG(in_interrupt());
1293 + return af_select(family,
1294 + create_perm(label, family, type, protocol),
1295 + aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
1299 +int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
1303 + AA_BUG(!sock->sk);
1306 + AA_BUG(in_interrupt());
1308 + return af_select(sock->sk->sk_family,
1309 + bind_perm(sock, address, addrlen),
1310 + aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
1313 +int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
1317 + AA_BUG(!sock->sk);
1320 + AA_BUG(in_interrupt());
1322 + return af_select(sock->sk->sk_family,
1323 + connect_perm(sock, address, addrlen),
1324 + aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
1327 +int aa_sock_listen_perm(struct socket *sock, int backlog)
1330 + AA_BUG(!sock->sk);
1332 + AA_BUG(in_interrupt());
1334 + return af_select(sock->sk->sk_family,
1335 + listen_perm(sock, backlog),
1336 + aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
1339 +/* ability of sock to connect, not peer address binding */
1340 +int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
1343 + AA_BUG(!sock->sk);
1346 + AA_BUG(in_interrupt());
1348 + return af_select(sock->sk->sk_family,
1349 + accept_perm(sock, newsock),
1350 + aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
1353 +/* sendmsg, recvmsg */
1354 +int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1355 + struct msghdr *msg, int size)
1358 + AA_BUG(!sock->sk);
1361 + AA_BUG(in_interrupt());
1363 + return af_select(sock->sk->sk_family,
1364 + msg_perm(op, request, sock, msg, size),
1365 + aa_sk_perm(op, request, sock->sk));
1368 +/* revaliation, get/set attr, opt */
1369 +int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
1373 + AA_BUG(!sock->sk);
1374 + AA_BUG(in_interrupt());
1376 + return af_select(sock->sk->sk_family,
1377 + opt_perm(op, request, sock, level, optname),
1378 + aa_sk_perm(op, request, sock->sk));
1381 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1382 struct socket *sock)
1383 @@ -180,5 +350,7 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1387 - return aa_label_sk_perm(label, op, request, sock->sk);
1388 + return af_select(sock->sk->sk_family,
1389 + file_perm(label, op, request, sock),
1390 + aa_label_sk_perm(label, op, request, sock->sk));