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