]> git.pld-linux.org Git - packages/kernel.git/blob - 0001-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
- 4.14.87
[packages/kernel.git] / 0001-UBUNTU-SAUCE-apparmor-af_unix-mediation.patch
1 From a3b0cb6676a04cdad5cc357bc422d0398083b435 Mon Sep 17 00:00:00 2001
2 From: John Johansen <john.johansen@canonical.com>
3 Date: Tue, 18 Jul 2017 23:27:23 -0700
4 Subject: [PATCH 17/17] UBUNTU: SAUCE: apparmor: af_unix mediation
5
6 af_socket mediation did not make it into 4.14 so add remaining out
7 of tree patch
8
9 Signed-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
25 diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
26 index dafdd387d42b..ef39226ff4aa 100644
27 --- a/security/apparmor/Makefile
28 +++ b/security/apparmor/Makefile
29 @@ -4,7 +4,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
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
39 diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
40 new file mode 100644
41 index 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 +}
696 diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
697 index 125dad5c3fde..20cdb1c4b266 100644
698 --- a/security/apparmor/apparmorfs.c
699 +++ b/security/apparmor/apparmorfs.c
700 @@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
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  };
720 diff --git a/security/apparmor/file.c b/security/apparmor/file.c
721 index db80221891c6..e62791106900 100644
722 --- a/security/apparmor/file.c
723 +++ b/security/apparmor/file.c
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)
742 diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
743 new file mode 100644
744 index 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 */
862 diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
863 index 140c8efcf364..0ae45240c352 100644
864 --- a/security/apparmor/include/net.h
865 +++ b/security/apparmor/include/net.h
866 @@ -90,8 +90,6 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
867  void audit_net_cb(struct audit_buffer *ab, void *va);
868  int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
869                        u32 request, u16 family, int type);
870 -int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
871 -              int type, int protocol);
872  static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
873                                         struct common_audit_data *sa,
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  
897 diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
898 index 05fb3305671e..26762db2207d 100644
899 --- a/security/apparmor/include/path.h
900 +++ b/security/apparmor/include/path.h
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 */
909 diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
910 index 4364088a0b9e..26660a1a50b0 100644
911 --- a/security/apparmor/include/policy.h
912 +++ b/security/apparmor/include/policy.h
913 @@ -226,7 +226,7 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
914  static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
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;
922 diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
923 index cc5ab23a2d84..0ede66d80a53 100644
924 --- a/security/apparmor/lsm.c
925 +++ b/security/apparmor/lsm.c
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),
1174 diff --git a/security/apparmor/net.c b/security/apparmor/net.c
1175 index 33d54435f8d6..dd1953b08e58 100644
1176 --- a/security/apparmor/net.c
1177 +++ b/security/apparmor/net.c
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 -- 
1393 2.11.0
1394
This page took 0.123353 seconds and 3 git commands to generate.