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