]> git.pld-linux.org Git - packages/kernel.git/blame - 0002-apparmor-af_unix-mediation.patch
- up to 4.17, apparmor needs update
[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 */
daaa955e 910diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
d75b40d3 911index 0cd717614fd0..245c98ef311e 100644
daaa955e
AM
912--- a/security/apparmor/lsm.c
913+++ b/security/apparmor/lsm.c
914@@ -26,6 +26,7 @@
915 #include <linux/kmemleak.h>
916 #include <net/sock.h>
917
918+#include "include/af_unix.h"
919 #include "include/apparmor.h"
920 #include "include/apparmorfs.h"
921 #include "include/audit.h"
922@@ -782,16 +783,96 @@ static void apparmor_sk_clone_security(const struct sock *sk,
923 path_get(&new->path);
924 }
925
926-static int aa_sock_create_perm(struct aa_label *label, int family, int type,
927- int protocol)
928+static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
929 {
930- AA_BUG(!label);
931- AA_BUG(in_interrupt());
932+ if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
933+ return &unix_sk(sk)->path;
934+ else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
935+ return &unix_sk(newsk)->path;
936+ return NULL;
937+}
938+
939+/**
940+ * apparmor_unix_stream_connect - check perms before making unix domain conn
941+ *
942+ * peer is locked when this hook is called
943+ */
944+static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
945+ struct sock *newsk)
946+{
947+ struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
948+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
949+ struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
950+ struct aa_label *label;
951+ struct path *path;
952+ int error;
953
954- return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type,
955- protocol);
956+ label = __begin_current_label_crit_section();
957+ error = aa_unix_peer_perm(label, OP_CONNECT,
958+ (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
959+ sk, peer_sk, NULL);
960+ if (!UNIX_FS(peer_sk)) {
961+ last_error(error,
962+ aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
963+ (AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
964+ peer_sk, sk, label));
965+ }
966+ __end_current_label_crit_section(label);
967+
968+ if (error)
969+ return error;
970+
971+ /* label newsk if it wasn't labeled in post_create. Normally this
972+ * would be done in sock_graft, but because we are directly looking
973+ * at the peer_sk to obtain peer_labeling for unix socks this
974+ * does not work
975+ */
976+ if (!new_ctx->label)
977+ new_ctx->label = aa_get_label(peer_ctx->label);
978+
979+ /* Cross reference the peer labels for SO_PEERSEC */
980+ if (new_ctx->peer)
981+ aa_put_label(new_ctx->peer);
982+
983+ if (sk_ctx->peer)
984+ aa_put_label(sk_ctx->peer);
985+
986+ new_ctx->peer = aa_get_label(sk_ctx->label);
987+ sk_ctx->peer = aa_get_label(peer_ctx->label);
988+
989+ path = UNIX_FS_CONN_PATH(sk, peer_sk);
990+ if (path) {
991+ new_ctx->path = *path;
992+ sk_ctx->path = *path;
993+ path_get(path);
994+ path_get(path);
995+ }
996+ return 0;
997 }
998
999+/**
1000+ * apparmor_unix_may_send - check perms before conn or sending unix dgrams
1001+ *
1002+ * other is locked when this hook is called
1003+ *
1004+ * dgram connect calls may_send, peer setup but path not copied?????
1005+ */
1006+static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
1007+{
1008+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
1009+ struct aa_label *label;
1010+ int error;
1011+
1012+ label = __begin_current_label_crit_section();
1013+ error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
1014+ sock->sk, peer->sk, NULL),
1015+ aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG,
1016+ AA_MAY_RECEIVE,
1017+ peer->sk, sock->sk, label));
1018+ __end_current_label_crit_section(label);
1019+
1020+ return error;
1021+}
1022
1023 /**
1024 * apparmor_socket_create - check perms before creating a new socket
1025@@ -849,12 +930,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family,
1026 static int apparmor_socket_bind(struct socket *sock,
1027 struct sockaddr *address, int addrlen)
1028 {
1029- AA_BUG(!sock);
1030- AA_BUG(!sock->sk);
1031- AA_BUG(!address);
1032- AA_BUG(in_interrupt());
1033-
1034- return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk);
1035+ return aa_sock_bind_perm(sock, address, addrlen);
1036 }
1037
1038 /**
1039@@ -863,12 +939,7 @@ static int apparmor_socket_bind(struct socket *sock,
1040 static int apparmor_socket_connect(struct socket *sock,
1041 struct sockaddr *address, int addrlen)
1042 {
1043- AA_BUG(!sock);
1044- AA_BUG(!sock->sk);
1045- AA_BUG(!address);
1046- AA_BUG(in_interrupt());
1047-
1048- return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk);
1049+ return aa_sock_connect_perm(sock, address, addrlen);
1050 }
1051
1052 /**
1053@@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock,
1054 */
1055 static int apparmor_socket_listen(struct socket *sock, int backlog)
1056 {
1057- AA_BUG(!sock);
1058- AA_BUG(!sock->sk);
1059- AA_BUG(in_interrupt());
1060-
1061- return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk);
1062+ return aa_sock_listen_perm(sock, backlog);
1063 }
1064
1065 /**
1066@@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog)
1067 */
1068 static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
1069 {
1070- AA_BUG(!sock);
1071- AA_BUG(!sock->sk);
1072- AA_BUG(!newsock);
1073- AA_BUG(in_interrupt());
1074-
1075- return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk);
1076-}
1077-
1078-static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1079- struct msghdr *msg, int size)
1080-{
1081- AA_BUG(!sock);
1082- AA_BUG(!sock->sk);
1083- AA_BUG(!msg);
1084- AA_BUG(in_interrupt());
1085-
1086- return aa_sk_perm(op, request, sock->sk);
1087+ return aa_sock_accept_perm(sock, newsock);
1088 }
1089
1090 /**
1091@@ -928,16 +979,6 @@ static int apparmor_socket_recvmsg(struct socket *sock,
1092 return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size);
1093 }
1094
1095-/* revaliation, get/set attr, shutdown */
1096-static int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1097-{
1098- AA_BUG(!sock);
1099- AA_BUG(!sock->sk);
1100- AA_BUG(in_interrupt());
1101-
1102- return aa_sk_perm(op, request, sock->sk);
1103-}
1104-
1105 /**
1106 * apparmor_socket_getsockname - check perms before getting the local address
1107 */
1108@@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock)
1109 return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock);
1110 }
1111
1112-/* revaliation, get/set attr, opt */
1113-static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock,
1114- int level, int optname)
1115-{
1116- AA_BUG(!sock);
1117- AA_BUG(!sock->sk);
1118- AA_BUG(in_interrupt());
1119-
1120- return aa_sk_perm(op, request, sock->sk);
1121-}
1122-
1123 /**
1124 * apparmor_getsockopt - check perms before getting socket options
1125 */
1126@@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1127
1128 static struct aa_label *sk_peer_label(struct sock *sk)
1129 {
1130+ struct sock *peer_sk;
1131 struct aa_sk_ctx *ctx = SK_CTX(sk);
1132
1133 if (ctx->peer)
1134 return ctx->peer;
1135
1136+ if (sk->sk_family != PF_UNIX)
1137+ return ERR_PTR(-ENOPROTOOPT);
1138+
1139+ /* check for sockpair peering which does not go through
1140+ * security_unix_stream_connect
1141+ */
1142+ peer_sk = unix_peer(sk);
1143+ if (peer_sk) {
1144+ ctx = SK_CTX(peer_sk);
1145+ if (ctx->label)
1146+ return ctx->label;
1147+ }
1148+
1149 return ERR_PTR(-ENOPROTOOPT);
1150 }
1151
1152@@ -1137,6 +1181,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1153 LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
1154 LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
1155
1156+ LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
1157+ LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
1158+
1159 LSM_HOOK_INIT(socket_create, apparmor_socket_create),
1160 LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
1161 LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
1162diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1163index 33d54435f8d6..dd1953b08e58 100644
1164--- a/security/apparmor/net.c
1165+++ b/security/apparmor/net.c
1166@@ -12,6 +12,7 @@
1167 * License.
1168 */
1169
1170+#include "include/af_unix.h"
1171 #include "include/apparmor.h"
1172 #include "include/audit.h"
1173 #include "include/context.h"
1174@@ -24,6 +25,7 @@
1175
1176 struct aa_sfs_entry aa_sfs_entry_network[] = {
1177 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
1178+ AA_SFS_FILE_BOOLEAN("af_unix", 1),
1179 { }
1180 };
1181
1182@@ -69,6 +71,36 @@ static const char * const net_mask_names[] = {
1183 "unknown",
1184 };
1185
1186+static void audit_unix_addr(struct audit_buffer *ab, const char *str,
1187+ struct sockaddr_un *addr, int addrlen)
1188+{
1189+ int len = unix_addr_len(addrlen);
1190+
1191+ if (!addr || len <= 0) {
1192+ audit_log_format(ab, " %s=none", str);
1193+ } else if (addr->sun_path[0]) {
1194+ audit_log_format(ab, " %s=", str);
1195+ audit_log_untrustedstring(ab, addr->sun_path);
1196+ } else {
1197+ audit_log_format(ab, " %s=\"@", str);
1198+ if (audit_string_contains_control(&addr->sun_path[1], len - 1))
1199+ audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
1200+ else
1201+ audit_log_format(ab, "%.*s", len - 1,
1202+ &addr->sun_path[1]);
1203+ audit_log_format(ab, "\"");
1204+ }
1205+}
1206+
1207+static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
1208+ struct sock *sk)
1209+{
1210+ struct unix_sock *u = unix_sk(sk);
1211+ if (u && u->addr)
1212+ audit_unix_addr(ab, str, u->addr->name, u->addr->len);
1213+ else
1214+ audit_unix_addr(ab, str, NULL, 0);
1215+}
1216
1217 /* audit callback for net specific fields */
1218 void audit_net_cb(struct audit_buffer *ab, void *va)
1219@@ -98,6 +130,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
1220 net_mask_names, NET_PERMS_MASK);
1221 }
1222 }
1223+ if (sa->u.net->family == AF_UNIX) {
1224+ if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
1225+ audit_unix_addr(ab, "addr",
1226+ unix_addr(aad(sa)->net.addr),
1227+ aad(sa)->net.addrlen);
1228+ else
1229+ audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
1230+ if (aad(sa)->request & NET_PEER_MASK) {
1231+ if (aad(sa)->net.addr)
1232+ audit_unix_addr(ab, "peer_addr",
1233+ unix_addr(aad(sa)->net.addr),
1234+ aad(sa)->net.addrlen);
1235+ else
1236+ audit_unix_sk_addr(ab, "peer_addr",
1237+ aad(sa)->net.peer_sk);
1238+ }
1239+ }
1240 if (aad(sa)->peer) {
1241 audit_log_format(ab, " peer=");
1242 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
1243@@ -172,6 +221,127 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)
1244 return error;
1245 }
1246
1247+#define af_select(FAMILY, FN, DEF_FN) \
1248+({ \
1249+ int __e; \
1250+ switch ((FAMILY)) { \
1251+ case AF_UNIX: \
1252+ __e = aa_unix_ ## FN; \
1253+ break; \
1254+ default: \
1255+ __e = DEF_FN; \
1256+ } \
1257+ __e; \
1258+})
1259+
1260+/* TODO: push into lsm.c ???? */
1261+
1262+/* revaliation, get/set attr, shutdown */
1263+int aa_sock_perm(const char *op, u32 request, struct socket *sock)
1264+{
1265+ AA_BUG(!sock);
1266+ AA_BUG(!sock->sk);
1267+ AA_BUG(in_interrupt());
1268+
1269+ return af_select(sock->sk->sk_family,
1270+ sock_perm(op, request, sock),
1271+ aa_sk_perm(op, request, sock->sk));
1272+}
1273+
1274+int aa_sock_create_perm(struct aa_label *label, int family, int type,
1275+ int protocol)
1276+{
1277+ AA_BUG(!label);
1278+ /* TODO: .... */
1279+ AA_BUG(in_interrupt());
1280+
1281+ return af_select(family,
1282+ create_perm(label, family, type, protocol),
1283+ aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
1284+ type, protocol));
1285+}
1286+
1287+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
1288+ int addrlen)
1289+{
1290+ AA_BUG(!sock);
1291+ AA_BUG(!sock->sk);
1292+ AA_BUG(!address);
1293+ /* TODO: .... */
1294+ AA_BUG(in_interrupt());
1295+
1296+ return af_select(sock->sk->sk_family,
1297+ bind_perm(sock, address, addrlen),
1298+ aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
1299+}
1300+
1301+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
1302+ int addrlen)
1303+{
1304+ AA_BUG(!sock);
1305+ AA_BUG(!sock->sk);
1306+ AA_BUG(!address);
1307+ /* TODO: .... */
1308+ AA_BUG(in_interrupt());
1309+
1310+ return af_select(sock->sk->sk_family,
1311+ connect_perm(sock, address, addrlen),
1312+ aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
1313+}
1314+
1315+int aa_sock_listen_perm(struct socket *sock, int backlog)
1316+{
1317+ AA_BUG(!sock);
1318+ AA_BUG(!sock->sk);
1319+ /* TODO: .... */
1320+ AA_BUG(in_interrupt());
1321+
1322+ return af_select(sock->sk->sk_family,
1323+ listen_perm(sock, backlog),
1324+ aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
1325+}
1326+
1327+/* ability of sock to connect, not peer address binding */
1328+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
1329+{
1330+ AA_BUG(!sock);
1331+ AA_BUG(!sock->sk);
1332+ AA_BUG(!newsock);
1333+ /* TODO: .... */
1334+ AA_BUG(in_interrupt());
1335+
1336+ return af_select(sock->sk->sk_family,
1337+ accept_perm(sock, newsock),
1338+ aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
1339+}
1340+
1341+/* sendmsg, recvmsg */
1342+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
1343+ struct msghdr *msg, int size)
1344+{
1345+ AA_BUG(!sock);
1346+ AA_BUG(!sock->sk);
1347+ AA_BUG(!msg);
1348+ /* TODO: .... */
1349+ AA_BUG(in_interrupt());
1350+
1351+ return af_select(sock->sk->sk_family,
1352+ msg_perm(op, request, sock, msg, size),
1353+ aa_sk_perm(op, request, sock->sk));
1354+}
1355+
1356+/* revaliation, get/set attr, opt */
1357+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
1358+ int optname)
1359+{
1360+ AA_BUG(!sock);
1361+ AA_BUG(!sock->sk);
1362+ AA_BUG(in_interrupt());
1363+
1364+ return af_select(sock->sk->sk_family,
1365+ opt_perm(op, request, sock, level, optname),
1366+ aa_sk_perm(op, request, sock->sk));
1367+}
1368
1369 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1370 struct socket *sock)
1371@@ -180,5 +350,7 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
1372 AA_BUG(!sock);
1373 AA_BUG(!sock->sk);
1374
1375- return aa_label_sk_perm(label, op, request, sock->sk);
1376+ return af_select(sock->sk->sk_family,
1377+ file_perm(label, op, request, sock),
1378+ aa_label_sk_perm(label, op, request, sock->sk));
1379 }
1380--
d75b40d3 13812.14.1
daaa955e 1382
This page took 0.230592 seconds and 4 git commands to generate.