]> git.pld-linux.org Git - packages/kernel.git/blame - 0002-apparmor-af_unix-mediation.patch
- up to 4.15.6
[packages/kernel.git] / 0002-apparmor-af_unix-mediation.patch
CommitLineData
d75b40d3 1From 8f0a917911fe19f9911d972fe85c43243f7eaa37 Mon Sep 17 00:00:00 2001
daaa955e
AM
2From: John Johansen <john.johansen@canonical.com>
3Date: Tue, 18 Jul 2017 23:27:23 -0700
d75b40d3 4Subject: [PATCH 2/2] apparmor: af_unix mediation
daaa955e
AM
5
6af_socket mediation did not make it into 4.14 so add remaining out
7of tree patch
8
9Signed-off-by: John Johansen <john.johansen@canonical.com>
d75b40d3 10Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
daaa955e
AM
11---
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
25
26diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
d75b40d3 27index e7ff2183532a..90c118f39e13 100644
daaa955e
AM
28--- a/security/apparmor/Makefile
29+++ b/security/apparmor/Makefile
d75b40d3 30@@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
daaa955e
AM
31
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 \
36+ af_unix.o
37 apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
38
39 clean-files := capability_names.h rlim_names.h net_names.h
40diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
41new file mode 100644
42index 000000000000..c6876db2dbde
43--- /dev/null
44+++ b/security/apparmor/af_unix.c
45@@ -0,0 +1,651 @@
46+/*
47+ * AppArmor security module
48+ *
49+ * This file contains AppArmor af_unix fine grained mediation
50+ *
51+ * Copyright 2014 Canonical Ltd.
52+ *
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
56+ * License.
57+ */
58+
59+#include <net/tcp_states.h>
60+
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"
68+
69+static inline struct sock *aa_sock(struct unix_sock *u)
70+{
71+ return &u->sk;
72+}
73+
74+static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
75+ struct unix_sock *u, int flags)
76+{
77+ AA_BUG(!label);
78+ AA_BUG(!u);
79+ AA_BUG(!UNIX_FS(aa_sock(u)));
80+
81+ if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
82+ return 0;
83+
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;
89+
90+ /* socket path has been cleared because it is being shutdown
91+ * can only fall back to original sun_path request
92+ */
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,
96+ &cond);
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,
104+ NULL, cond.uid,
105+ "Failed name lookup - "
106+ "deleted entry", -EACCES));
107+ } else {
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
111+ };
112+
113+ return aa_path_perm(op, label, &u->path, flags, mask, &cond);
114+ }
115+
116+ return 0;
117+}
118+
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,
122+ const char **info)
123+{
124+ __be16 buffer[2];
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,
128+ 4);
129+ if (!state)
130+ *info = "failed type and protocol match";
131+ return state;
132+}
133+
134+static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
135+ struct sockaddr_un *addr, int addrlen)
136+{
137+ if (addr)
138+ /* include leading \0 */
139+ state = aa_dfa_match_len(profile->policy.dfa, state,
140+ addr->sun_path,
141+ unix_addr_len(addrlen));
142+ else
143+ /* anonymous end point */
144+ state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
145+ 1);
146+ /* todo change to out of band */
147+ state = aa_dfa_null_transition(profile->policy.dfa, state);
148+ return state;
149+}
150+
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,
154+ const char **info)
155+{
156+ state = match_to_prot(profile, state, type, protocol, info);
157+ if (state) {
158+ state = match_addr(profile, state, addr, addrlen);
159+ if (state) {
160+ /* todo: local label matching */
161+ state = aa_dfa_null_transition(profile->policy.dfa,
162+ state);
163+ if (!state)
164+ *info = "failed local label match";
165+ } else
166+ *info = "failed local address match";
167+ }
168+
169+ return state;
170+}
171+
172+static unsigned int match_to_sk(struct aa_profile *profile,
173+ unsigned int state, struct unix_sock *u,
174+ const char **info)
175+{
176+ struct sockaddr_un *addr = NULL;
177+ int addrlen = 0;
178+
179+ if (u->addr) {
180+ addr = u->addr->name;
181+ addrlen = u->addr->len;
182+ }
183+
184+ return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
185+ addr, addrlen, info);
186+}
187+
188+#define CMD_ADDR 1
189+#define CMD_LISTEN 2
190+#define CMD_OPT 4
191+
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)
195+{
196+ state = match_to_sk(profile, state, u, info);
197+ if (state) {
198+ state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
199+ if (!state)
200+ *info = "failed cmd selection match";
201+ }
202+
203+ return state;
204+}
205+
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,
210+ int peer_addrlen,
211+ const char **info)
212+{
213+ state = match_to_cmd(profile, state, u, CMD_ADDR, info);
214+ if (state) {
215+ state = match_addr(profile, state, peer_addr, peer_addrlen);
216+ if (!state)
217+ *info = "failed peer address match";
218+ }
219+ return state;
220+}
221+
222+static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
223+ struct common_audit_data *sa)
224+{
225+ struct aa_perms perms;
226+
227+ AA_BUG(!profile);
228+
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,
232+ audit_net_cb);
233+}
234+
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)
238+{
239+ AA_BUG(!profile);
240+ AA_BUG(!peer);
241+
242+ aad(sa)->peer = &peer->label;
243+
244+ if (state) {
245+ state = aa_dfa_match(profile->policy.dfa, state,
246+ peer->base.hname);
247+ if (!state)
248+ aad(sa)->info = "failed peer label match";
249+ }
250+ return do_perms(profile, state, request, sa);
251+}
252+
253+
254+/* unix sock creation comes before we know if the socket will be an fs
255+ * socket
256+ * v6 - semantics are handled by mapping in profile load
257+ * v7 - semantics require sock create for tasks creating an fs socket.
258+ */
259+static int profile_create_perm(struct aa_profile *profile, int family,
260+ int type, int protocol)
261+{
262+ unsigned int state;
263+ DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
264+
265+ AA_BUG(!profile);
266+ AA_BUG(profile_unconfined(profile));
267+
268+ if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
269+ state = match_to_prot(profile, state, type, protocol,
270+ &aad(&sa)->info);
271+ return do_perms(profile, state, AA_MAY_CREATE, &sa);
272+ }
273+
274+ return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
275+}
276+
277+int aa_unix_create_perm(struct aa_label *label, int family, int type,
278+ int protocol)
279+{
280+ struct aa_profile *profile;
281+
282+ if (unconfined(label))
283+ return 0;
284+
285+ return fn_for_each_confined(label, profile,
286+ profile_create_perm(profile, family, type, protocol));
287+}
288+
289+
290+static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
291+ u32 request, struct sock *sk)
292+{
293+ unsigned int state;
294+ DEFINE_AUDIT_SK(sa, op, sk);
295+
296+ AA_BUG(!profile);
297+ AA_BUG(!sk);
298+ AA_BUG(UNIX_FS(sk));
299+ AA_BUG(profile_unconfined(profile));
300+
301+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
302+ if (state) {
303+ state = match_to_sk(profile, state, unix_sk(sk),
304+ &aad(&sa)->info);
305+ return do_perms(profile, state, request, &sa);
306+ }
307+
308+ return aa_profile_af_sk_perm(profile, &sa, request, sk);
309+}
310+
311+int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
312+ struct sock *sk)
313+{
314+ struct aa_profile *profile;
315+
316+ return fn_for_each_confined(label, profile,
317+ profile_sk_perm(profile, op, request, sk));
318+}
319+
320+static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
321+ struct socket *sock)
322+{
323+ if (unconfined(label))
324+ return 0;
325+ if (UNIX_FS(sock->sk))
326+ return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
327+
328+ return aa_unix_label_sk_perm(label, op, request, sock->sk);
329+}
330+
331+/* revaliation, get/set attr */
332+int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
333+{
334+ struct aa_label *label;
335+ int error;
336+
337+ label = begin_current_label_crit_section();
338+ error = unix_label_sock_perm(label, op, request, sock);
339+ end_current_label_crit_section(label);
340+
341+ return error;
342+}
343+
344+static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
345+ struct sockaddr *addr, int addrlen)
346+{
347+ unsigned int state;
348+ DEFINE_AUDIT_SK(sa, OP_BIND, sk);
349+
350+ AA_BUG(!profile);
351+ AA_BUG(!sk);
352+ AA_BUG(addr->sa_family != AF_UNIX);
353+ AA_BUG(profile_unconfined(profile));
354+ AA_BUG(unix_addr_fs(addr, addrlen));
355+
356+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
357+ if (state) {
358+ /* bind for abstract socket */
359+ aad(&sa)->net.addr = unix_addr(addr);
360+ aad(&sa)->net.addrlen = addrlen;
361+
362+ state = match_to_local(profile, state,
363+ sk->sk_type, sk->sk_protocol,
364+ unix_addr(addr), addrlen,
365+ &aad(&sa)->info);
366+ return do_perms(profile, state, AA_MAY_BIND, &sa);
367+ }
368+
369+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
370+}
371+
372+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
373+ int addrlen)
374+{
375+ struct aa_profile *profile;
376+ struct aa_label *label;
377+ int error = 0;
378+
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,
384+ addrlen));
385+ end_current_label_crit_section(label);
386+
387+ return error;
388+}
389+
390+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
391+ int addrlen)
392+{
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
396+ */
397+ return 0;
398+}
399+
400+static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
401+ int backlog)
402+{
403+ unsigned int state;
404+ DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
405+
406+ AA_BUG(!profile);
407+ AA_BUG(!sk);
408+ AA_BUG(UNIX_FS(sk));
409+ AA_BUG(profile_unconfined(profile));
410+
411+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
412+ if (state) {
413+ __be16 b = cpu_to_be16(backlog);
414+
415+ state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
416+ &aad(&sa)->info);
417+ if (state) {
418+ state = aa_dfa_match_len(profile->policy.dfa, state,
419+ (char *) &b, 2);
420+ if (!state)
421+ aad(&sa)->info = "failed listen backlog match";
422+ }
423+ return do_perms(profile, state, AA_MAY_LISTEN, &sa);
424+ }
425+
426+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
427+}
428+
429+int aa_unix_listen_perm(struct socket *sock, int backlog)
430+{
431+ struct aa_profile *profile;
432+ struct aa_label *label;
433+ int error = 0;
434+
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,
439+ backlog));
440+ end_current_label_crit_section(label);
441+
442+ return error;
443+}
444+
445+
446+static inline int profile_accept_perm(struct aa_profile *profile,
447+ struct sock *sk,
448+ struct sock *newsk)
449+{
450+ unsigned int state;
451+ DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
452+
453+ AA_BUG(!profile);
454+ AA_BUG(!sk);
455+ AA_BUG(UNIX_FS(sk));
456+ AA_BUG(profile_unconfined(profile));
457+
458+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
459+ if (state) {
460+ state = match_to_sk(profile, state, unix_sk(sk),
461+ &aad(&sa)->info);
462+ return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
463+ }
464+
465+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
466+}
467+
468+/* ability of sock to connect, not peer address binding */
469+int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
470+{
471+ struct aa_profile *profile;
472+ struct aa_label *label;
473+ int error = 0;
474+
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,
479+ newsock->sk));
480+ end_current_label_crit_section(label);
481+
482+ return error;
483+}
484+
485+
486+/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
487+ * could do per msg unix_stream here
488+ */
489+/* sendmsg, recvmsg */
490+int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
491+ struct msghdr *msg, int size)
492+{
493+ return 0;
494+}
495+
496+
497+static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
498+ struct sock *sk, int level, int optname)
499+{
500+ unsigned int state;
501+ DEFINE_AUDIT_SK(sa, op, sk);
502+
503+ AA_BUG(!profile);
504+ AA_BUG(!sk);
505+ AA_BUG(UNIX_FS(sk));
506+ AA_BUG(profile_unconfined(profile));
507+
508+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
509+ if (state) {
510+ __be16 b = cpu_to_be16(optname);
511+
512+ state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
513+ &aad(&sa)->info);
514+ if (state) {
515+ state = aa_dfa_match_len(profile->policy.dfa, state,
516+ (char *) &b, 2);
517+ if (!state)
518+ aad(&sa)->info = "failed sockopt match";
519+ }
520+ return do_perms(profile, state, request, &sa);
521+ }
522+
523+ return aa_profile_af_sk_perm(profile, &sa, request, sk);
524+}
525+
526+int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
527+ int optname)
528+{
529+ struct aa_profile *profile;
530+ struct aa_label *label;
531+ int error = 0;
532+
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);
539+
540+ return error;
541+}
542+
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)
548+{
549+ unsigned int state;
550+
551+ AA_BUG(!profile);
552+ AA_BUG(profile_unconfined(profile));
553+ AA_BUG(!sk);
554+ AA_BUG(!peer_sk);
555+ AA_BUG(UNIX_FS(peer_sk));
556+
557+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
558+ if (state) {
559+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
560+ struct aa_profile *peerp;
561+ struct sockaddr_un *addr = NULL;
562+ int len = 0;
563+ if (unix_sk(peer_sk)->addr) {
564+ addr = unix_sk(peer_sk)->addr->name;
565+ len = unix_sk(peer_sk)->addr->len;
566+ }
567+ state = match_to_peer(profile, state, unix_sk(sk),
568+ addr, len, &aad(sa)->info);
569+ if (!peer_label)
570+ peer_label = peer_ctx->label;
571+ return fn_for_each_in_ns(peer_label, peerp,
572+ match_label(profile, peerp, state, request,
573+ sa));
574+ }
575+
576+ return aa_profile_af_sk_perm(profile, sa, request, sk);
577+}
578+
579+/**
580+ *
581+ * Requires: lock held on both @sk and @peer_sk
582+ */
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)
586+{
587+ struct unix_sock *peeru = unix_sk(peer_sk);
588+ struct unix_sock *u = unix_sk(sk);
589+
590+ AA_BUG(!label);
591+ AA_BUG(!sk);
592+ AA_BUG(!peer_sk);
593+
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);
598+ else {
599+ struct aa_profile *profile;
600+ DEFINE_AUDIT_SK(sa, op, sk);
601+ aad(&sa)->net.peer_sk = peer_sk;
602+
603+ /* TODO: ns!!! */
604+ if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
605+ ;
606+ }
607+
608+ if (unconfined(label))
609+ return 0;
610+
611+ return fn_for_each_confined(label, profile,
612+ profile_peer_perm(profile, op, request, sk,
613+ peer_sk, peer_label, &sa));
614+ }
615+}
616+
617+
618+/* from net/unix/af_unix.c */
619+static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
620+{
621+ if (unlikely(sk1 == sk2) || !sk2) {
622+ unix_state_lock(sk1);
623+ return;
624+ }
625+ if (sk1 < sk2) {
626+ unix_state_lock(sk1);
627+ unix_state_lock_nested(sk2);
628+ } else {
629+ unix_state_lock(sk2);
630+ unix_state_lock_nested(sk1);
631+ }
632+}
633+
634+static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
635+{
636+ if (unlikely(sk1 == sk2) || !sk2) {
637+ unix_state_unlock(sk1);
638+ return;
639+ }
640+ unix_state_unlock(sk1);
641+ unix_state_unlock(sk2);
642+}
643+
644+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
645+ struct socket *sock)
646+{
647+ struct sock *peer_sk = NULL;
648+ u32 sk_req = request & ~NET_PEER_MASK;
649+ int error = 0;
650+
651+ AA_BUG(!label);
652+ AA_BUG(!sock);
653+ AA_BUG(!sock->sk);
654+ AA_BUG(sock->sk->sk_family != AF_UNIX);
655+
656+ /* TODO: update sock label with new task label */
657+ unix_state_lock(sock->sk);
658+ peer_sk = unix_peer(sock->sk);
659+ if (peer_sk)
660+ sock_hold(peer_sk);
661+ if (!unix_connected(sock) && sk_req) {
662+ error = unix_label_sock_perm(label, op, sk_req, sock);
663+ if (!error) {
664+ // update label
665+ }
666+ }
667+ unix_state_unlock(sock->sk);
668+ if (!peer_sk)
669+ return error;
670+
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),
674+ PATH_SOCK_COND);
675+ } else if (UNIX_FS(peer_sk)) {
676+ error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
677+ PATH_SOCK_COND);
678+ } else {
679+ struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
680+ if (sk_req)
681+ error = aa_unix_label_sk_perm(label, op, sk_req,
682+ sock->sk);
683+ last_error(error,
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)));
690+ }
691+
692+ unix_state_double_unlock(sock->sk, peer_sk);
693+ sock_put(peer_sk);
694+
695+ return error;
696+}
697diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
d75b40d3 698index 694c4f48a975..850c401502f1 100644
daaa955e
AM
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[] = {
702 { }
703 };
704
705+static struct aa_sfs_entry aa_sfs_entry_dbus[] = {
706+ AA_SFS_FILE_STRING("mask", "acquire send receive"),
707+ { }
708+};
709+
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),
719 { }
720 };
721diff --git a/security/apparmor/file.c b/security/apparmor/file.c
d75b40d3 722index 86d57e56fabe..348c9ff3da4e 100644
daaa955e
AM
723--- a/security/apparmor/file.c
724+++ b/security/apparmor/file.c
725@@ -16,6 +16,7 @@
726 #include <linux/fdtable.h>
727 #include <linux/file.h>
728
729+#include "include/af_unix.h"
730 #include "include/apparmor.h"
731 #include "include/audit.h"
732 #include "include/context.h"
d75b40d3 733@@ -283,7 +284,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
daaa955e
AM
734 {
735 int e = 0;
736
737- if (profile_unconfined(profile))
738+ if (profile_unconfined(profile) ||
739+ ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
740 return 0;
741 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
742 if (request & ~perms->allow)
743diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
744new file mode 100644
745index 000000000000..d1b7f2316be4
746--- /dev/null
747+++ b/security/apparmor/include/af_unix.h
748@@ -0,0 +1,114 @@
749+/*
750+ * AppArmor security module
751+ *
752+ * This file contains AppArmor af_unix fine grained mediation
753+ *
754+ * Copyright 2014 Canonical Ltd.
755+ *
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
759+ * License.
760+ */
761+#ifndef __AA_AF_UNIX_H
762+
763+#include <net/af_unix.h>
764+
765+#include "label.h"
766+//#include "include/net.h"
767+
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))
775+
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))
779+
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)
787+
788+static inline void print_unix_addr(struct sockaddr_un *A, int L)
789+{
790+ char *buf = (A) ? (char *) &(A)->sun_path : NULL;
791+ int len = unix_addr_len(L);
792+ if (!buf || len <= 0)
793+ printk(" <anonymous>");
794+ else if (buf[0])
795+ printk(" %s", buf);
796+ else
797+ /* abstract name len includes leading \0 */
798+ printk(" %d @%.*s", len - 1, len - 1, buf+1);
799+};
800+
801+/*
802+ printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \
803+ #SK , \
804+*/
805+#define print_unix_sk(SK) \
806+do { \
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); \
810+ if (u->addr) \
811+ print_unix_addr(u->addr->name, u->addr->len); \
812+ else \
813+ print_unix_addr(NULL, sizeof(sa_family_t)); \
814+ /* printk("\n");*/ \
815+} while (0)
816+
817+#define print_sk(SK) \
818+do { \
819+ if (!(SK)) { \
820+ printk("%s: %s is null\n", __FUNCTION__, #SK); \
821+ } else if ((SK)->sk_family == PF_UNIX) { \
822+ print_unix_sk(SK); \
823+ printk("\n"); \
824+ } else { \
825+ printk("%s: %s: family %d\n", __FUNCTION__, #SK , \
826+ (SK)->sk_family); \
827+ } \
828+} while (0)
829+
830+#define print_sock_addr(U) \
831+do { \
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); \
836+} while (0)
837+
838+
839+
840+
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,
845+ struct sock *sk);
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,
848+ int protocol);
849+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
850+ int addrlen);
851+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
852+ int addrlen);
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,
858+ int optname);
859+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
860+ struct socket *sock);
861+
862+#endif /* __AA_AF_UNIX_H */
863diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
864index 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,
875 u32 request,
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,
878 sk->sk_type);
879 }
880-int aa_sk_perm(const char *op, u32 request, struct sock *sk);
881
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,
884+ int protocol);
885+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
886+ int addrlen);
887+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
888+ int addrlen);
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,
894+ int optname);
895 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
896 struct socket *sock);
897
898diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
899index 05fb3305671e..26762db2207d 100644
900--- a/security/apparmor/include/path.h
901+++ b/security/apparmor/include/path.h
902@@ -18,6 +18,7 @@
903
904 enum path_flags {
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 */
910diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
911index 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,
916 u16 AF) {
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);
920
921 if (!state)
922 return 0;
923diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
d75b40d3 924index 0cd717614fd0..245c98ef311e 100644
daaa955e
AM
925--- a/security/apparmor/lsm.c
926+++ b/security/apparmor/lsm.c
927@@ -26,6 +26,7 @@
928 #include <linux/kmemleak.h>
929 #include <net/sock.h>
930
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);
937 }
938
939-static int aa_sock_create_perm(struct aa_label *label, int family, int type,
940- int protocol)
941+static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
942 {
943- AA_BUG(!label);
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;
949+ return NULL;
950+}
951+
952+/**
953+ * apparmor_unix_stream_connect - check perms before making unix domain conn
954+ *
955+ * peer is locked when this hook is called
956+ */
957+static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
958+ struct sock *newsk)
959+{
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;
964+ struct path *path;
965+ int error;
966
967- return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
968- protocol);
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)) {
974+ last_error(error,
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));
978+ }
979+ __end_current_label_crit_section(label);
980+
981+ if (error)
982+ return error;
983+
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
987+ * does not work
988+ */
989+ if (!new_ctx->label)
990+ new_ctx->label = aa_get_label(peer_ctx->label);
991+
992+ /* Cross reference the peer labels for SO_PEERSEC */
993+ if (new_ctx->peer)
994+ aa_put_label(new_ctx->peer);
995+
996+ if (sk_ctx->peer)
997+ aa_put_label(sk_ctx->peer);
998+
999+ new_ctx->peer = aa_get_label(sk_ctx->label);
1000+ sk_ctx->peer = aa_get_label(peer_ctx->label);
1001+
1002+ path = UNIX_FS_CONN_PATH(sk, peer_sk);
1003+ if (path) {
1004+ new_ctx->path = *path;
1005+ sk_ctx->path = *path;
1006+ path_get(path);
1007+ path_get(path);
1008+ }
1009+ return 0;
1010 }
1011
1012+/**
1013+ * apparmor_unix_may_send - check perms before conn or sending unix dgrams
1014+ *
1015+ * other is locked when this hook is called
1016+ *
1017+ * dgram connect calls may_send, peer setup but path not copied?????
1018+ */
1019+static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
1020+{
1021+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
1022+ struct aa_label *label;
1023+ int error;
1024+
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,
1029+ AA_MAY_RECEIVE,
1030+ peer->sk, sock->sk, label));
1031+ __end_current_label_crit_section(label);
1032+
1033+ return error;
1034+}
1035
1036 /**
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)
1041 {
1042- AA_BUG(!sock);
1043- AA_BUG(!sock->sk);
1044- AA_BUG(!address);
1045- AA_BUG(in_interrupt());
1046-
1047- return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
1048+ return aa_sock_bind_perm(sock, address, addrlen);
1049 }
1050
1051 /**
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)
1055 {
1056- AA_BUG(!sock);
1057- AA_BUG(!sock->sk);
1058- AA_BUG(!address);
1059- AA_BUG(in_interrupt());
1060-
1061- return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
1062+ return aa_sock_connect_perm(sock, address, addrlen);
1063 }
1064
1065 /**
1066@@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock,
1067 */
1068 static int apparmor_socket_listen(struct socket *sock, int backlog)
1069 {
1070- AA_BUG(!sock);
1071- AA_BUG(!sock->sk);
1072- AA_BUG(in_interrupt());
1073-
1074- return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
1075+ return aa_sock_listen_perm(sock, backlog);
1076 }
1077
1078 /**
1079@@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog)
1080 */
1081 static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
1082 {
1083- AA_BUG(!sock);
1084- AA_BUG(!sock->sk);
1085- AA_BUG(!newsock);
1086- AA_BUG(in_interrupt());
1087-
1088- return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
1089-}
1090-
1091-static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1092- struct msghdr *msg, int size)
1093-{
1094- AA_BUG(!sock);
1095- AA_BUG(!sock->sk);
1096- AA_BUG(!msg);
1097- AA_BUG(in_interrupt());
1098-
1099- return aa_sk_perm(op, request, sock->sk);
1100+ return aa_sock_accept_perm(sock, newsock);
1101 }
1102
1103 /**
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);
1106 }
1107
1108-/* revaliation, get/set attr, shutdown */
1109-static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1110-{
1111- AA_BUG(!sock);
1112- AA_BUG(!sock->sk);
1113- AA_BUG(in_interrupt());
1114-
1115- return aa_sk_perm(op, request, sock->sk);
1116-}
1117-
1118 /**
1119 * apparmor_socket_getsockname - check perms before getting the local address
1120 */
1121@@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock)
1122 return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
1123 }
1124
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)
1128-{
1129- AA_BUG(!sock);
1130- AA_BUG(!sock->sk);
1131- AA_BUG(in_interrupt());
1132-
1133- return aa_sk_perm(op, request, sock->sk);
1134-}
1135-
1136 /**
1137 * apparmor_getsockopt - check perms before getting socket options
1138 */
1139@@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1140
1141 static struct aa_label *sk_peer_label(struct sock *sk)
1142 {
1143+ struct sock *peer_sk;
1144 struct aa_sk_ctx *ctx = SK_CTX(sk);
1145
1146 if (ctx->peer)
1147 return ctx->peer;
1148
1149+ if (sk->sk_family != PF_UNIX)
1150+ return ERR_PTR(-ENOPROTOOPT);
1151+
1152+ /* check for sockpair peering which does not go through
1153+ * security_unix_stream_connect
1154+ */
1155+ peer_sk = unix_peer(sk);
1156+ if (peer_sk) {
1157+ ctx = SK_CTX(peer_sk);
1158+ if (ctx->label)
1159+ return ctx->label;
1160+ }
1161+
1162 return ERR_PTR(-ENOPROTOOPT);
1163 }
1164
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),
1168
1169+ LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
1170+ LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
1171+
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),
1175diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1176index 33d54435f8d6..dd1953b08e58 100644
1177--- a/security/apparmor/net.c
1178+++ b/security/apparmor/net.c
1179@@ -12,6 +12,7 @@
1180 * License.
1181 */
1182
1183+#include "include/af_unix.h"
1184 #include "include/apparmor.h"
1185 #include "include/audit.h"
1186 #include "include/context.h"
1187@@ -24,6 +25,7 @@
1188
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),
1192 { }
1193 };
1194
1195@@ -69,6 +71,36 @@ static const char * const net_mask_names[] = {
1196 "unknown",
1197 };
1198
1199+static void audit_unix_addr(struct audit_buffer *ab, const char *str,
1200+ struct sockaddr_un *addr, int addrlen)
1201+{
1202+ int len = unix_addr_len(addrlen);
1203+
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);
1209+ } else {
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);
1213+ else
1214+ audit_log_format(ab, "%.*s", len - 1,
1215+ &addr->sun_path[1]);
1216+ audit_log_format(ab, "\"");
1217+ }
1218+}
1219+
1220+static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
1221+ struct sock *sk)
1222+{
1223+ struct unix_sock *u = unix_sk(sk);
1224+ if (u && u->addr)
1225+ audit_unix_addr(ab, str, u->addr->name, u->addr->len);
1226+ else
1227+ audit_unix_addr(ab, str, NULL, 0);
1228+}
1229
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);
1234 }
1235 }
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);
1241+ else
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);
1248+ else
1249+ audit_unix_sk_addr(ab, "peer_addr",
1250+ aad(sa)->net.peer_sk);
1251+ }
1252+ }
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)
1257 return error;
1258 }
1259
1260+#define af_select(FAMILY, FN, DEF_FN) \
1261+({ \
1262+ int __e; \
1263+ switch ((FAMILY)) { \
1264+ case AF_UNIX: \
1265+ __e = aa_unix_ ## FN; \
1266+ break; \
1267+ default: \
1268+ __e = DEF_FN; \
1269+ } \
1270+ __e; \
1271+})
1272+
1273+/* TODO: push into lsm.c ???? */
1274+
1275+/* revaliation, get/set attr, shutdown */
1276+int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1277+{
1278+ AA_BUG(!sock);
1279+ AA_BUG(!sock->sk);
1280+ AA_BUG(in_interrupt());
1281+
1282+ return af_select(sock->sk->sk_family,
1283+ sock_perm(op, request, sock),
1284+ aa_sk_perm(op, request, sock->sk));
1285+}
1286+
1287+int aa_sock_create_perm(struct aa_label *label, int family, int type,
1288+ int protocol)
1289+{
1290+ AA_BUG(!label);
1291+ /* TODO: .... */
1292+ AA_BUG(in_interrupt());
1293+
1294+ return af_select(family,
1295+ create_perm(label, family, type, protocol),
1296+ aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
1297+ type, protocol));
1298+}
1299+
1300+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
1301+ int addrlen)
1302+{
1303+ AA_BUG(!sock);
1304+ AA_BUG(!sock->sk);
1305+ AA_BUG(!address);
1306+ /* TODO: .... */
1307+ AA_BUG(in_interrupt());
1308+
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));
1312+}
1313+
1314+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
1315+ int addrlen)
1316+{
1317+ AA_BUG(!sock);
1318+ AA_BUG(!sock->sk);
1319+ AA_BUG(!address);
1320+ /* TODO: .... */
1321+ AA_BUG(in_interrupt());
1322+
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));
1326+}
1327+
1328+int aa_sock_listen_perm(struct socket *sock, int backlog)
1329+{
1330+ AA_BUG(!sock);
1331+ AA_BUG(!sock->sk);
1332+ /* TODO: .... */
1333+ AA_BUG(in_interrupt());
1334+
1335+ return af_select(sock->sk->sk_family,
1336+ listen_perm(sock, backlog),
1337+ aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
1338+}
1339+
1340+/* ability of sock to connect, not peer address binding */
1341+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
1342+{
1343+ AA_BUG(!sock);
1344+ AA_BUG(!sock->sk);
1345+ AA_BUG(!newsock);
1346+ /* TODO: .... */
1347+ AA_BUG(in_interrupt());
1348+
1349+ return af_select(sock->sk->sk_family,
1350+ accept_perm(sock, newsock),
1351+ aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
1352+}
1353+
1354+/* sendmsg, recvmsg */
1355+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1356+ struct msghdr *msg, int size)
1357+{
1358+ AA_BUG(!sock);
1359+ AA_BUG(!sock->sk);
1360+ AA_BUG(!msg);
1361+ /* TODO: .... */
1362+ AA_BUG(in_interrupt());
1363+
1364+ return af_select(sock->sk->sk_family,
1365+ msg_perm(op, request, sock, msg, size),
1366+ aa_sk_perm(op, request, sock->sk));
1367+}
1368+
1369+/* revaliation, get/set attr, opt */
1370+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
1371+ int optname)
1372+{
1373+ AA_BUG(!sock);
1374+ AA_BUG(!sock->sk);
1375+ AA_BUG(in_interrupt());
1376+
1377+ return af_select(sock->sk->sk_family,
1378+ opt_perm(op, request, sock, level, optname),
1379+ aa_sk_perm(op, request, sock->sk));
1380+}
1381
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,
1385 AA_BUG(!sock);
1386 AA_BUG(!sock->sk);
1387
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));
1392 }
1393--
d75b40d3 13942.14.1
daaa955e 1395
This page took 3.314726 seconds and 4 git commands to generate.