]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-apparmor.patch
- up to 2.6.35.5
[packages/kernel.git] / kernel-apparmor.patch
1 From 3f980257e048429a1f0a5dbce0b027a93c0781cc Mon Sep 17 00:00:00 2001
2 From: John Johansen <john.johansen@canonical.com>
3 Date: Wed, 4 Aug 2010 04:42:50 -0700
4 Subject: [PATCH] AppArmor: security module v2.6 + compat patches as of 29-07-2010 (security-next)
5
6 AppArmor v2.6 module as synced to security-next 29-07-2010 backported to
7 2.6.35 + AppArmor 2.4 compatibility patches.
8
9 Signed-off-by: John Johansen <john.johansen@canonical.com>
10 ---
11  Documentation/apparmor.txt                |   40 +
12  Documentation/kernel-parameters.txt       |    8 +
13  MAINTAINERS                               |    8 +
14  include/linux/lsm_audit.h                 |   31 +
15  security/Kconfig                          |    6 +
16  security/Makefile                         |    2 +
17  security/apparmor/.gitignore              |    5 +
18  security/apparmor/Kconfig                 |   40 +
19  security/apparmor/Makefile                |   30 +
20  security/apparmor/apparmorfs-24.c         |  287 +++++++
21  security/apparmor/apparmorfs.c            |  253 ++++++
22  security/apparmor/audit.c                 |  215 ++++++
23  security/apparmor/capability.c            |  141 ++++
24  security/apparmor/context.c               |  216 ++++++
25  security/apparmor/domain.c                |  823 ++++++++++++++++++++
26  security/apparmor/file.c                  |  457 +++++++++++
27  security/apparmor/include/apparmor.h      |   92 +++
28  security/apparmor/include/apparmorfs.h    |   26 +
29  security/apparmor/include/audit.h         |  123 +++
30  security/apparmor/include/capability.h    |   45 ++
31  security/apparmor/include/context.h       |  154 ++++
32  security/apparmor/include/domain.h        |   36 +
33  security/apparmor/include/file.h          |  217 ++++++
34  security/apparmor/include/ipc.h           |   28 +
35  security/apparmor/include/match.h         |  132 ++++
36  security/apparmor/include/net.h           |   40 +
37  security/apparmor/include/path.h          |   31 +
38  security/apparmor/include/policy.h        |  308 ++++++++
39  security/apparmor/include/policy_unpack.h |   20 +
40  security/apparmor/include/procattr.h      |   26 +
41  security/apparmor/include/resource.h      |   46 ++
42  security/apparmor/include/sid.h           |   24 +
43  security/apparmor/ipc.c                   |  114 +++
44  security/apparmor/lib.c                   |  133 ++++
45  security/apparmor/lsm.c                   | 1051 +++++++++++++++++++++++++
46  security/apparmor/match.c                 |  370 +++++++++
47  security/apparmor/net.c                   |  169 ++++
48  security/apparmor/path.c                  |  235 ++++++
49  security/apparmor/policy.c                | 1185 +++++++++++++++++++++++++++++
50  security/apparmor/policy_unpack.c         |  740 ++++++++++++++++++
51  security/apparmor/policy_unpack.c.rej     |   11 +
52  security/apparmor/procattr.c              |  170 ++++
53  security/apparmor/resource.c              |  134 ++++
54  security/apparmor/sid.c                   |   55 ++
55  44 files changed, 8277 insertions(+), 0 deletions(-)
56  create mode 100644 Documentation/apparmor.txt
57  create mode 100644 security/apparmor/.gitignore
58  create mode 100644 security/apparmor/Kconfig
59  create mode 100644 security/apparmor/Makefile
60  create mode 100644 security/apparmor/apparmorfs-24.c
61  create mode 100644 security/apparmor/apparmorfs.c
62  create mode 100644 security/apparmor/audit.c
63  create mode 100644 security/apparmor/capability.c
64  create mode 100644 security/apparmor/context.c
65  create mode 100644 security/apparmor/domain.c
66  create mode 100644 security/apparmor/file.c
67  create mode 100644 security/apparmor/include/apparmor.h
68  create mode 100644 security/apparmor/include/apparmorfs.h
69  create mode 100644 security/apparmor/include/audit.h
70  create mode 100644 security/apparmor/include/capability.h
71  create mode 100644 security/apparmor/include/context.h
72  create mode 100644 security/apparmor/include/domain.h
73  create mode 100644 security/apparmor/include/file.h
74  create mode 100644 security/apparmor/include/ipc.h
75  create mode 100644 security/apparmor/include/match.h
76  create mode 100644 security/apparmor/include/net.h
77  create mode 100644 security/apparmor/include/path.h
78  create mode 100644 security/apparmor/include/policy.h
79  create mode 100644 security/apparmor/include/policy_unpack.h
80  create mode 100644 security/apparmor/include/procattr.h
81  create mode 100644 security/apparmor/include/resource.h
82  create mode 100644 security/apparmor/include/sid.h
83  create mode 100644 security/apparmor/ipc.c
84  create mode 100644 security/apparmor/lib.c
85  create mode 100644 security/apparmor/lsm.c
86  create mode 100644 security/apparmor/match.c
87  create mode 100644 security/apparmor/net.c
88  create mode 100644 security/apparmor/path.c
89  create mode 100644 security/apparmor/policy.c
90  create mode 100644 security/apparmor/policy_unpack.c
91  create mode 100644 security/apparmor/policy_unpack.c.rej
92  create mode 100644 security/apparmor/procattr.c
93  create mode 100644 security/apparmor/resource.c
94  create mode 100644 security/apparmor/sid.c
95
96 diff --git a/Documentation/apparmor.txt b/Documentation/apparmor.txt
97 new file mode 100644
98 index 0000000..6240438
99 --- /dev/null
100 +++ b/Documentation/apparmor.txt
101 @@ -0,0 +1,40 @@
102 +--- What is AppArmor? ---
103 +
104 +AppArmor is MAC style security extension for the Linux kernel.  It implements
105 +a task centered policy, with task "profiles" being created and loaded
106 +from user space.  Tasks on the system that do not have a profile defined for
107 +them run in an unconfined state which is equivalent to standard Linux DAC
108 +permissions.
109 +
110 +--- How to enable/disable ---
111 +
112 +set CONFIG_SECURITY_APPARMOR=y
113 +
114 +If AppArmor should be selected as the default security module then
115 +   set CONFIG_DEFAULT_SECURITY="apparmor"
116 +   and CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
117 +
118 +Build the kernel
119 +
120 +If AppArmor is not the default security module it can be enabled by passing
121 +security=apparmor on the kernel's command line.
122 +
123 +If AppArmor is the default security module it can be disabled by passing
124 +apparmor=0, security=XXXX (where XXX is valid security module), on the
125 +kernel's command line
126 +
127 +For AppArmor to enforce any restrictions beyond standard Linux DAC permissions
128 +policy must be loaded into the kernel from user space (see the Documentation
129 +and tools links).
130 +
131 +--- Documentation ---
132 +
133 +Documentation can be found on the wiki.
134 +
135 +--- Links ---
136 +
137 +Mailing List - apparmor@lists.ubuntu.com
138 +Wiki - http://apparmor.wiki.kernel.org/
139 +User space tools - https://launchpad.net/apparmor
140 +Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
141 +
142 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
143 index 2b2407d..b61f89f 100644
144 --- a/Documentation/kernel-parameters.txt
145 +++ b/Documentation/kernel-parameters.txt
146 @@ -93,6 +93,7 @@ parameter is applicable:
147                         Documentation/scsi/.
148         SECURITY Different security models are enabled.
149         SELINUX SELinux support is enabled.
150 +       APPARMOR AppArmor support is enabled.
151         SERIAL  Serial support is enabled.
152         SH      SuperH architecture is enabled.
153         SMP     The kernel is an SMP kernel.
154 @@ -2312,6 +2313,13 @@ and is between 256 and 4096 characters. It is defined in the file
155                         If enabled at boot time, /selinux/disable can be used
156                         later to disable prior to initial policy load.
157  
158 +       apparmor=       [APPARMOR] Disable or enable AppArmor at boot time
159 +                       Format: { "0" | "1" }
160 +                       See security/apparmor/Kconfig help text
161 +                       0 -- disable.
162 +                       1 -- enable.
163 +                       Default value is set via kernel config option.
164 +
165         serialnumber    [BUGS=X86-32]
166  
167         shapers=        [NET]
168 diff --git a/MAINTAINERS b/MAINTAINERS
169 index 02f75fc..a8d5851 100644
170 --- a/MAINTAINERS
171 +++ b/MAINTAINERS
172 @@ -5061,6 +5061,14 @@ S:       Supported
173  F:     include/linux/selinux*
174  F:     security/selinux/
175  
176 +APPARMOR SECURITY MODULE
177 +M:     John Johansen <john.johansen@canonical.com>
178 +L:     apparmor@lists.ubuntu.com (subscribers-only, general discussion)
179 +W:     apparmor.wiki.kernel.org
180 +T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
181 +S:     Supported
182 +F:     security/apparmor/
183 +
184  SENSABLE PHANTOM
185  M:     Jiri Slaby <jirislaby@gmail.com>
186  S:     Maintained
187 diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
188 index 6907251..3474e45 100644
189 --- a/include/linux/lsm_audit.h
190 +++ b/include/linux/lsm_audit.h
191 @@ -94,6 +94,37 @@ struct common_audit_data {
192                         int result;
193                 } selinux_audit_data;
194  #endif
195 +#ifdef CONFIG_SECURITY_APPARMOR
196 +               struct {
197 +                       int error;
198 +                       int op;
199 +                       int type;
200 +                       void *profile;
201 +                       const char *name;
202 +                       const char *info;
203 +                       union {
204 +                               void *target;
205 +                               struct {
206 +                                       long pos;
207 +                                       void *target;
208 +                               } iface;
209 +                               struct {
210 +                                       int rlim;
211 +                                       unsigned long max;
212 +                               } rlim;
213 +                               struct {
214 +                                       const char *target;
215 +                                       u32 request;
216 +                                       u32 denied;
217 +                                       uid_t ouid;
218 +                               } fs;
219 +                               struct {
220 +                                       int type, protocol;
221 +                                       struct sock *sk;
222 +                               } net;
223 +                       };
224 +               } apparmor_audit_data;
225 +#endif
226         };
227         /* these callback will be implemented by a specific LSM */
228         void (*lsm_pre_audit)(struct audit_buffer *, void *);
229 diff --git a/security/Kconfig b/security/Kconfig
230 index 226b955..bd72ae6 100644
231 --- a/security/Kconfig
232 +++ b/security/Kconfig
233 @@ -140,6 +140,7 @@ config LSM_MMAP_MIN_ADDR
234  source security/selinux/Kconfig
235  source security/smack/Kconfig
236  source security/tomoyo/Kconfig
237 +source security/apparmor/Kconfig
238  
239  source security/integrity/ima/Kconfig
240  
241 @@ -148,6 +149,7 @@ choice
242         default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
243         default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
244         default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
245 +       default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
246         default DEFAULT_SECURITY_DAC
247  
248         help
249 @@ -163,6 +165,9 @@ choice
250         config DEFAULT_SECURITY_TOMOYO
251                 bool "TOMOYO" if SECURITY_TOMOYO=y
252  
253 +       config DEFAULT_SECURITY_APPARMOR
254 +               bool "AppArmor" if SECURITY_APPARMOR=y
255 +
256         config DEFAULT_SECURITY_DAC
257                 bool "Unix Discretionary Access Controls"
258  
259 @@ -173,6 +178,7 @@ config DEFAULT_SECURITY
260         default "selinux" if DEFAULT_SECURITY_SELINUX
261         default "smack" if DEFAULT_SECURITY_SMACK
262         default "tomoyo" if DEFAULT_SECURITY_TOMOYO
263 +       default "apparmor" if DEFAULT_SECURITY_APPARMOR
264         default "" if DEFAULT_SECURITY_DAC
265  
266  endmenu
267 diff --git a/security/Makefile b/security/Makefile
268 index da20a19..8bb0fe9 100644
269 --- a/security/Makefile
270 +++ b/security/Makefile
271 @@ -6,6 +6,7 @@ obj-$(CONFIG_KEYS)                      += keys/
272  subdir-$(CONFIG_SECURITY_SELINUX)      += selinux
273  subdir-$(CONFIG_SECURITY_SMACK)                += smack
274  subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
275 +subdir-$(CONFIG_SECURITY_APPARMOR)     += apparmor
276  
277  # always enable default capabilities
278  obj-y                                  += commoncap.o
279 @@ -19,6 +20,7 @@ obj-$(CONFIG_SECURITY_SELINUX)                += selinux/built-in.o
280  obj-$(CONFIG_SECURITY_SMACK)           += smack/built-in.o
281  obj-$(CONFIG_AUDIT)                    += lsm_audit.o
282  obj-$(CONFIG_SECURITY_TOMOYO)          += tomoyo/built-in.o
283 +obj-$(CONFIG_SECURITY_APPARMOR)                += apparmor/built-in.o
284  obj-$(CONFIG_CGROUP_DEVICE)            += device_cgroup.o
285  
286  # Object integrity file lists
287 diff --git a/security/apparmor/.gitignore b/security/apparmor/.gitignore
288 new file mode 100644
289 index 0000000..0a0a99f
290 --- /dev/null
291 +++ b/security/apparmor/.gitignore
292 @@ -0,0 +1,5 @@
293 +#
294 +# Generated include files
295 +#
296 +af_names.h
297 +capability_names.h
298 diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
299 new file mode 100644
300 index 0000000..fdf3022
301 --- /dev/null
302 +++ b/security/apparmor/Kconfig
303 @@ -0,0 +1,40 @@
304 +config SECURITY_APPARMOR
305 +       bool "AppArmor support"
306 +       depends on SECURITY
307 +       select AUDIT
308 +       select SECURITY_PATH
309 +       select SECURITYFS
310 +       select SECURITY_NETWORK
311 +       default n
312 +       help
313 +         This enables the AppArmor security module.
314 +         Required userspace tools (if they are not included in your
315 +         distribution) and further information may be found at
316 +         http://apparmor.wiki.kernel.org
317 +
318 +         If you are unsure how to answer this question, answer N.
319 +
320 +config SECURITY_APPARMOR_BOOTPARAM_VALUE
321 +       int "AppArmor boot parameter default value"
322 +       depends on SECURITY_APPARMOR
323 +       range 0 1
324 +       default 1
325 +       help
326 +         This option sets the default value for the kernel parameter
327 +         'apparmor', which allows AppArmor to be enabled or disabled
328 +          at boot.  If this option is set to 0 (zero), the AppArmor
329 +         kernel parameter will default to 0, disabling AppArmor at
330 +         boot.  If this option is set to 1 (one), the AppArmor
331 +         kernel parameter will default to 1, enabling AppArmor at
332 +         boot.
333 +
334 +         If you are unsure how to answer this question, answer 1.
335 +
336 +config SECURITY_APPARMOR_COMPAT_24
337 +       bool "Enable AppArmor 2.4 compatability"
338 +       depends on SECURITY_APPARMOR
339 +       default y
340 +       help
341 +         This option enables compatability with AppArmor 2.4.  It is
342 +          recommended if compatability with older versions of AppArmor
343 +          is desired.
344 diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
345 new file mode 100644
346 index 0000000..e5e8968
347 --- /dev/null
348 +++ b/security/apparmor/Makefile
349 @@ -0,0 +1,30 @@
350 +# Makefile for AppArmor Linux Security Module
351 +#
352 +obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
353 +
354 +apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
355 +              path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
356 +              resource.o sid.o file.o net.o
357 +
358 +apparmor-$(CONFIG_SECURITY_APPARMOR_COMPAT_24) += apparmorfs-24.o
359 +
360 +clean-files: capability_names.h af_names.h
361 +
362 +quiet_cmd_make-caps = GEN     $@
363 +cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ; sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2]  = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
364 +
365 +quiet_cmd_make-af = GEN     $@
366 +cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ; sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2]  = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
367 +
368 +quiet_cmd_make-rlim = GEN     $@
369 +cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ; sed -n --e "/AF_MAX/d" -e "s/^\# \\?define[ \\t]\\+RLIMIT_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2]  = \"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@ ; echo "static const int rlim_map[] = {" >> $@ ; sed -n -e "/AF_MAX/d" -e "s/^\# \\?define[ \\t]\\+\\(RLIMIT_[A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/\\1,/p" $< >> $@ ; echo "};" >> $@
370 +
371 +$(obj)/capability.o : $(obj)/capability_names.h
372 +$(obj)/net.o : $(obj)/af_names.h
373 +$(obj)/resource.o : $(obj)/rlim_names.h
374 +$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
375 +       $(call cmd,make-caps)
376 +$(obj)/af_names.h : $(srctree)/include/linux/socket.h
377 +       $(call cmd,make-af)
378 +$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h
379 +       $(call cmd,make-rlim)
380 diff --git a/security/apparmor/apparmorfs-24.c b/security/apparmor/apparmorfs-24.c
381 new file mode 100644
382 index 0000000..dc8c744
383 --- /dev/null
384 +++ b/security/apparmor/apparmorfs-24.c
385 @@ -0,0 +1,287 @@
386 +/*
387 + * AppArmor security module
388 + *
389 + * This file contains AppArmor /sys/kernel/secrutiy/apparmor interface functions
390 + *
391 + * Copyright (C) 1998-2008 Novell/SUSE
392 + * Copyright 2009-2010 Canonical Ltd.
393 + *
394 + * This program is free software; you can redistribute it and/or
395 + * modify it under the terms of the GNU General Public License as
396 + * published by the Free Software Foundation, version 2 of the
397 + * License.
398 + *
399 + *
400 + * This file contain functions providing an interface for <= AppArmor 2.4
401 + * compatibility.  It is dependent on CONFIG_SECURITY_APPARMOR_COMPAT_24
402 + * being set (see Makefile).
403 + */
404 +
405 +#include <linux/security.h>
406 +#include <linux/vmalloc.h>
407 +#include <linux/module.h>
408 +#include <linux/seq_file.h>
409 +#include <linux/uaccess.h>
410 +#include <linux/namei.h>
411 +
412 +#include "include/apparmor.h"
413 +#include "include/audit.h"
414 +#include "include/context.h"
415 +#include "include/policy.h"
416 +
417 +
418 +/* apparmor/matching */
419 +static ssize_t aa_matching_read(struct file *file, char __user *buf,
420 +                               size_t size, loff_t *ppos)
421 +{
422 +       const char matching[] = "pattern=aadfa audit perms=crwxamlk/ "
423 +           "user::other";
424 +
425 +       return simple_read_from_buffer(buf, size, ppos, matching,
426 +                                      sizeof(matching) - 1);
427 +}
428 +
429 +const struct file_operations aa_fs_matching_fops = {
430 +       .read = aa_matching_read,
431 +};
432 +
433 +/* apparmor/features */
434 +static ssize_t aa_features_read(struct file *file, char __user *buf,
435 +                               size_t size, loff_t *ppos)
436 +{
437 +       const char features[] = "file=3.1 capability=2.0 network=1.0 "
438 +           "change_hat=1.5 change_profile=1.1 " "aanamespaces=1.1 rlimit=1.1";
439 +
440 +       return simple_read_from_buffer(buf, size, ppos, features,
441 +                                      sizeof(features) - 1);
442 +}
443 +
444 +const struct file_operations aa_fs_features_fops = {
445 +       .read = aa_features_read,
446 +};
447 +
448 +/**
449 + * __next_namespace - find the next namespace to list
450 + * @root: root namespace to stop search at (NOT NULL)
451 + * @ns: current ns position (NOT NULL)
452 + *
453 + * Find the next namespace from @ns under @root and handle all locking needed
454 + * while switching current namespace.
455 + *
456 + * Returns: next namespace or NULL if at last namespace under @root
457 + * NOTE: will not unlock root->lock
458 + */
459 +static struct aa_namespace *__next_namespace(struct aa_namespace *root,
460 +                                            struct aa_namespace *ns)
461 +{
462 +       struct aa_namespace *parent;
463 +
464 +       /* is next namespace a child */
465 +       if (!list_empty(&ns->sub_ns)) {
466 +               struct aa_namespace *next;
467 +               next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
468 +               read_lock(&next->lock);
469 +               return next;
470 +       }
471 +
472 +       /* check if the next ns is a sibling, parent, gp, .. */
473 +       parent = ns->parent;
474 +       while (parent) {
475 +               read_unlock(&ns->lock);
476 +               list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
477 +                       read_lock(&ns->lock);
478 +                       return ns;
479 +               }
480 +               if (parent == root)
481 +                       return NULL;
482 +               ns = parent;
483 +               parent = parent->parent;
484 +       }
485 +
486 +       return NULL;
487 +}
488 +
489 +/**
490 + * __first_profile - find the first profile in a namespace
491 + * @root: namespace that is root of profiles being displayed (NOT NULL)
492 + * @ns: namespace to start in   (NOT NULL)
493 + *
494 + * Returns: unrefcounted profile or NULL if no profile
495 + */
496 +static struct aa_profile *__first_profile(struct aa_namespace *root,
497 +                                         struct aa_namespace *ns)
498 +{
499 +       for ( ; ns; ns = __next_namespace(root, ns)) {
500 +               if (!list_empty(&ns->base.profiles))
501 +                       return list_first_entry(&ns->base.profiles,
502 +                                               struct aa_profile, base.list);
503 +       }
504 +       return NULL;
505 +}
506 +
507 +/**
508 + * __next_profile - step to the next profile in a profile tree
509 + * @profile: current profile in tree (NOT NULL)
510 + *
511 + * Perform a depth first taversal on the profile tree in a namespace
512 + *
513 + * Returns: next profile or NULL if done
514 + * Requires: profile->ns.lock to be held
515 + */
516 +static struct aa_profile *__next_profile(struct aa_profile *p)
517 +{
518 +       struct aa_profile *parent;
519 +       struct aa_namespace *ns = p->ns;
520 +
521 +       /* is next profile a child */
522 +       if (!list_empty(&p->base.profiles))
523 +               return list_first_entry(&p->base.profiles, typeof(*p),
524 +                                       base.list);
525 +
526 +       /* is next profile a sibling, parent sibling, gp, subling, .. */
527 +       parent = p->parent;
528 +       while (parent) {
529 +               list_for_each_entry_continue(p, &parent->base.profiles,
530 +                                            base.list)
531 +                               return p;
532 +               p = parent;
533 +               parent = parent->parent;
534 +       }
535 +
536 +       /* is next another profile in the namespace */
537 +       list_for_each_entry_continue(p, &ns->base.profiles, base.list)
538 +               return p;
539 +
540 +       return NULL;
541 +}
542 +
543 +/**
544 + * next_profile - step to the next profile in where ever it may be
545 + * @root: root namespace  (NOT NULL)
546 + * @profile: current profile  (NOT NULL)
547 + *
548 + * Returns: next profile or NULL if there isn't one
549 + */
550 +static struct aa_profile *next_profile(struct aa_namespace *root,
551 +                                      struct aa_profile *profile)
552 +{
553 +       struct aa_profile *next = __next_profile(profile);
554 +       if (next)
555 +               return next;
556 +
557 +       /* finished all profiles in namespace move to next namespace */
558 +       return __first_profile(root, __next_namespace(root, profile->ns));
559 +}
560 +
561 +/**
562 + * p_start - start a depth first traversal of profile tree
563 + * @f: seq_file to fill
564 + * @pos: current position
565 + *
566 + * Returns: first profile under current namespace or NULL if none found
567 + *
568 + * acquires first ns->lock
569 + */
570 +static void *p_start(struct seq_file *f, loff_t *pos)
571 +       __acquires(root->lock)
572 +{
573 +       struct aa_profile *profile = NULL;
574 +       struct aa_namespace *root = aa_current_profile()->ns;
575 +       loff_t l = *pos;
576 +       f->private = aa_get_namespace(root);
577 +
578 +
579 +       /* find the first profile */
580 +       read_lock(&root->lock);
581 +       profile = __first_profile(root, root);
582 +
583 +       /* skip to position */
584 +       for (; profile && l > 0; l--)
585 +               profile = next_profile(root, profile);
586 +
587 +       return profile;
588 +}
589 +
590 +/**
591 + * p_next - read the next profile entry
592 + * @f: seq_file to fill
593 + * @p: profile previously returned
594 + * @pos: current position
595 + *
596 + * Returns: next profile after @p or NULL if none
597 + *
598 + * may acquire/release locks in namespace tree as necessary
599 + */
600 +static void *p_next(struct seq_file *f, void *p, loff_t *pos)
601 +{
602 +       struct aa_profile *profile = p;
603 +       struct aa_namespace *root = f->private;
604 +       (*pos)++;
605 +
606 +       return next_profile(root, profile);
607 +}
608 +
609 +/**
610 + * p_stop - stop depth first traversal
611 + * @f: seq_file we are filling
612 + * @p: the last profile writen
613 + *
614 + * Release all locking done by p_start/p_next on namespace tree
615 + */
616 +static void p_stop(struct seq_file *f, void *p)
617 +       __releases(root->lock)
618 +{
619 +       struct aa_profile *profile = p;
620 +       struct aa_namespace *root = f->private, *ns;
621 +
622 +       if (profile) {
623 +               for (ns = profile->ns; ns && ns != root; ns = ns->parent)
624 +                       read_unlock(&ns->lock);
625 +       }
626 +       read_unlock(&root->lock);
627 +       aa_put_namespace(root);
628 +}
629 +
630 +/**
631 + * seq_show_profile - show a profile entry
632 + * @f: seq_file to file
633 + * @p: current position (profile)    (NOT NULL)
634 + *
635 + * Returns: error on failure
636 + */
637 +static int seq_show_profile(struct seq_file *f, void *p)
638 +{
639 +       struct aa_profile *profile = (struct aa_profile *)p;
640 +       struct aa_namespace *root = f->private;
641 +
642 +       if (profile->ns != root)
643 +               seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
644 +       seq_printf(f, "%s (%s)\n", profile->base.hname,
645 +                  COMPLAIN_MODE(profile) ? "complain" : "enforce");
646 +
647 +       return 0;
648 +}
649 +
650 +static const struct seq_operations aa_fs_profiles_op = {
651 +       .start = p_start,
652 +       .next = p_next,
653 +       .stop = p_stop,
654 +       .show = seq_show_profile,
655 +};
656 +
657 +static int profiles_open(struct inode *inode, struct file *file)
658 +{
659 +       return seq_open(file, &aa_fs_profiles_op);
660 +}
661 +
662 +static int profiles_release(struct inode *inode, struct file *file)
663 +{
664 +       return seq_release(inode, file);
665 +}
666 +
667 +const struct file_operations aa_fs_profiles_fops = {
668 +       .open = profiles_open,
669 +       .read = seq_read,
670 +       .llseek = seq_lseek,
671 +       .release = profiles_release,
672 +};
673 diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
674 new file mode 100644
675 index 0000000..0e27449
676 --- /dev/null
677 +++ b/security/apparmor/apparmorfs.c
678 @@ -0,0 +1,253 @@
679 +/*
680 + * AppArmor security module
681 + *
682 + * This file contains AppArmor /sys/kernel/security/apparmor interface functions
683 + *
684 + * Copyright (C) 1998-2008 Novell/SUSE
685 + * Copyright 2009-2010 Canonical Ltd.
686 + *
687 + * This program is free software; you can redistribute it and/or
688 + * modify it under the terms of the GNU General Public License as
689 + * published by the Free Software Foundation, version 2 of the
690 + * License.
691 + */
692 +
693 +#include <linux/security.h>
694 +#include <linux/vmalloc.h>
695 +#include <linux/module.h>
696 +#include <linux/seq_file.h>
697 +#include <linux/uaccess.h>
698 +#include <linux/namei.h>
699 +
700 +#include "include/apparmor.h"
701 +#include "include/apparmorfs.h"
702 +#include "include/audit.h"
703 +#include "include/context.h"
704 +#include "include/policy.h"
705 +
706 +/**
707 + * aa_simple_write_to_buffer - common routine for getting policy from user
708 + * @op: operation doing the user buffer copy
709 + * @userbuf: user buffer to copy data from  (NOT NULL)
710 + * @alloc_size: size of user buffer
711 + * @copy_size: size of data to copy from user buffer
712 + * @pos: position write is at in the file (NOT NULL)
713 + *
714 + * Returns: kernel buffer containing copy of user buffer data or an
715 + *          ERR_PTR on failure.
716 + */
717 +static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,
718 +                                      size_t alloc_size, size_t copy_size,
719 +                                      loff_t *pos)
720 +{
721 +       char *data;
722 +
723 +       if (*pos != 0)
724 +               /* only writes from pos 0, that is complete writes */
725 +               return ERR_PTR(-ESPIPE);
726 +
727 +       /*
728 +        * Don't allow profile load/replace/remove from profiles that don't
729 +        * have CAP_MAC_ADMIN
730 +        */
731 +       if (!aa_may_manage_policy(op))
732 +               return ERR_PTR(-EACCES);
733 +
734 +       /* freed by caller to simple_write_to_buffer */
735 +       data = kvmalloc(alloc_size);
736 +       if (data == NULL)
737 +               return ERR_PTR(-ENOMEM);
738 +
739 +       if (copy_from_user(data, userbuf, copy_size)) {
740 +               kvfree(data);
741 +               return ERR_PTR(-EFAULT);
742 +       }
743 +
744 +       return data;
745 +}
746 +
747 +
748 +/* .load file hook fn to load policy */
749 +static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
750 +                           loff_t *pos)
751 +{
752 +       char *data;
753 +       ssize_t error;
754 +
755 +       data = aa_simple_write_to_buffer(OP_PROF_LOAD, buf, size, size, pos);
756 +
757 +       error = PTR_ERR(data);
758 +       if (!IS_ERR(data)) {
759 +               error = aa_replace_profiles(data, size, PROF_ADD);
760 +               kvfree(data);
761 +       }
762 +
763 +       return error;
764 +}
765 +
766 +static const struct file_operations aa_fs_profile_load = {
767 +       .write = profile_load
768 +};
769 +
770 +/* .replace file hook fn to load and/or replace policy */
771 +static ssize_t profile_replace(struct file *f, const char __user *buf,
772 +                              size_t size, loff_t *pos)
773 +{
774 +       char *data;
775 +       ssize_t error;
776 +
777 +       data = aa_simple_write_to_buffer(OP_PROF_REPL, buf, size, size, pos);
778 +       error = PTR_ERR(data);
779 +       if (!IS_ERR(data)) {
780 +               error = aa_replace_profiles(data, size, PROF_REPLACE);
781 +               kvfree(data);
782 +       }
783 +
784 +       return error;
785 +}
786 +
787 +static const struct file_operations aa_fs_profile_replace = {
788 +       .write = profile_replace
789 +};
790 +
791 +/* .remove file hook fn to remove loaded policy */
792 +static ssize_t profile_remove(struct file *f, const char __user *buf,
793 +                             size_t size, loff_t *pos)
794 +{
795 +       char *data;
796 +       ssize_t error;
797 +
798 +       /*
799 +        * aa_remove_profile needs a null terminated string so 1 extra
800 +        * byte is allocated and the copied data is null terminated.
801 +        */
802 +       data = aa_simple_write_to_buffer(OP_PROF_RM, buf, size + 1, size, pos);
803 +
804 +       error = PTR_ERR(data);
805 +       if (!IS_ERR(data)) {
806 +               data[size] = 0;
807 +               error = aa_remove_profiles(data, size);
808 +               kvfree(data);
809 +       }
810 +
811 +       return error;
812 +}
813 +
814 +static const struct file_operations aa_fs_profile_remove = {
815 +       .write = profile_remove
816 +};
817 +
818 +/** Base file system setup **/
819 +
820 +static struct dentry *aa_fs_dentry __initdata;
821 +
822 +static void __init aafs_remove(const char *name)
823 +{
824 +       struct dentry *dentry;
825 +
826 +       dentry = lookup_one_len(name, aa_fs_dentry, strlen(name));
827 +       if (!IS_ERR(dentry)) {
828 +               securityfs_remove(dentry);
829 +               dput(dentry);
830 +       }
831 +}
832 +
833 +/**
834 + * aafs_create - create an entry in the apparmor filesystem
835 + * @name: name of the entry (NOT NULL)
836 + * @mask: file permission mask of the file
837 + * @fops: file operations for the file (NOT NULL)
838 + *
839 + * Used aafs_remove to remove entries created with this fn.
840 + */
841 +static int __init aafs_create(const char *name, int mask,
842 +                             const struct file_operations *fops)
843 +{
844 +       struct dentry *dentry;
845 +
846 +       dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry,
847 +                                       NULL, fops);
848 +
849 +       return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
850 +}
851 +
852 +/**
853 + * aa_destroy_aafs - cleanup and free aafs
854 + *
855 + * releases dentries allocated by aa_create_aafs
856 + */
857 +void __init aa_destroy_aafs(void)
858 +{
859 +       if (aa_fs_dentry) {
860 +               aafs_remove(".remove");
861 +               aafs_remove(".replace");
862 +               aafs_remove(".load");
863 +#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
864 +               aafs_remove("profiles");
865 +               aafs_remove("matching");
866 +               aafs_remove("features");
867 +#endif
868 +               securityfs_remove(aa_fs_dentry);
869 +               aa_fs_dentry = NULL;
870 +       }
871 +}
872 +
873 +/**
874 + * aa_create_aafs - create the apparmor security filesystem
875 + *
876 + * dentries created here are released by aa_destroy_aafs
877 + *
878 + * Returns: error on failure
879 + */
880 +int __init aa_create_aafs(void)
881 +{
882 +       int error;
883 +
884 +       if (!apparmor_initialized)
885 +               return 0;
886 +
887 +       if (aa_fs_dentry) {
888 +               AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
889 +               return -EEXIST;
890 +       }
891 +
892 +       aa_fs_dentry = securityfs_create_dir("apparmor", NULL);
893 +       if (IS_ERR(aa_fs_dentry)) {
894 +               error = PTR_ERR(aa_fs_dentry);
895 +               aa_fs_dentry = NULL;
896 +               goto error;
897 +       }
898 +#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
899 +       error = aafs_create("matching", 0444, &aa_fs_matching_fops);
900 +       if (error)
901 +               goto error;
902 +       error = aafs_create("features", 0444, &aa_fs_features_fops);
903 +       if (error)
904 +               goto error;
905 +#endif
906 +       error = aafs_create("profiles", 0440, &aa_fs_profiles_fops);
907 +       if (error)
908 +               goto error;
909 +       error = aafs_create(".load", 0640, &aa_fs_profile_load);
910 +       if (error)
911 +               goto error;
912 +       error = aafs_create(".replace", 0640, &aa_fs_profile_replace);
913 +       if (error)
914 +               goto error;
915 +       error = aafs_create(".remove", 0640, &aa_fs_profile_remove);
916 +       if (error)
917 +               goto error;
918 +
919 +       /* TODO: add support for apparmorfs_null and apparmorfs_mnt */
920 +
921 +       /* Report that AppArmor fs is enabled */
922 +       aa_info_message("AppArmor Filesystem Enabled");
923 +       return 0;
924 +
925 +error:
926 +       aa_destroy_aafs();
927 +       AA_ERROR("Error creating AppArmor securityfs\n");
928 +       return error;
929 +}
930 +
931 +fs_initcall(aa_create_aafs);
932 diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
933 new file mode 100644
934 index 0000000..96502b2
935 --- /dev/null
936 +++ b/security/apparmor/audit.c
937 @@ -0,0 +1,215 @@
938 +/*
939 + * AppArmor security module
940 + *
941 + * This file contains AppArmor auditing functions
942 + *
943 + * Copyright (C) 1998-2008 Novell/SUSE
944 + * Copyright 2009-2010 Canonical Ltd.
945 + *
946 + * This program is free software; you can redistribute it and/or
947 + * modify it under the terms of the GNU General Public License as
948 + * published by the Free Software Foundation, version 2 of the
949 + * License.
950 + */
951 +
952 +#include <linux/audit.h>
953 +#include <linux/socket.h>
954 +
955 +#include "include/apparmor.h"
956 +#include "include/audit.h"
957 +#include "include/policy.h"
958 +
959 +const char *op_table[] = {
960 +       "null",
961 +
962 +       "sysctl",
963 +       "capable",
964 +
965 +       "unlink",
966 +       "mkdir",
967 +       "rmdir",
968 +       "mknod",
969 +       "truncate",
970 +       "link",
971 +       "symlink",
972 +       "rename_src",
973 +       "rename_dest",
974 +       "chmod",
975 +       "chown",
976 +       "getattr",
977 +       "open",
978 +
979 +       "file_perm",
980 +       "file_lock",
981 +       "file_mmap",
982 +       "file_mprotect",
983 +
984 +       "create",
985 +       "post_create",
986 +       "bind",
987 +       "connect",
988 +       "listen",
989 +       "accept",
990 +       "sendmsg",
991 +       "recvmsg",
992 +       "getsockname",
993 +       "getpeername",
994 +       "getsockopt",
995 +       "setsockopt",
996 +       "socket_shutdown",
997 +
998 +       "ptrace",
999 +
1000 +       "exec",
1001 +       "change_hat",
1002 +       "change_profile",
1003 +       "change_onexec",
1004 +
1005 +       "setprocattr",
1006 +       "setrlimit",
1007 +
1008 +       "profile_replace",
1009 +       "profile_load",
1010 +       "profile_remove"
1011 +};
1012 +
1013 +const char *audit_mode_names[] = {
1014 +       "normal",
1015 +       "quiet_denied",
1016 +       "quiet",
1017 +       "noquiet",
1018 +       "all"
1019 +};
1020 +
1021 +static char *aa_audit_type[] = {
1022 +       "AUDIT",
1023 +       "ALLOWED",
1024 +       "DENIED",
1025 +       "HINT",
1026 +       "STATUS",
1027 +       "ERROR",
1028 +       "KILLED"
1029 +};
1030 +
1031 +/*
1032 + * Currently AppArmor auditing is fed straight into the audit framework.
1033 + *
1034 + * TODO:
1035 + * netlink interface for complain mode
1036 + * user auditing, - send user auditing to netlink interface
1037 + * system control of whether user audit messages go to system log
1038 + */
1039 +
1040 +/**
1041 + * audit_base - core AppArmor function.
1042 + * @ab: audit buffer to fill (NOT NULL)
1043 + * @ca: audit structure containing data to audit (NOT NULL)
1044 + *
1045 + * Record common AppArmor audit data from @sa
1046 + */
1047 +static void audit_pre(struct audit_buffer *ab, void *ca)
1048 +{
1049 +       struct common_audit_data *sa = ca;
1050 +       struct task_struct *tsk = sa->tsk ? sa->tsk : current;
1051 +
1052 +       if (aa_g_audit_header) {
1053 +               audit_log_format(ab, "apparmor=");
1054 +               audit_log_string(ab, aa_audit_type[sa->aad.type]);
1055 +       }
1056 +
1057 +       if (sa->aad.op) {
1058 +               audit_log_format(ab, " operation=");
1059 +               audit_log_string(ab, op_table[sa->aad.op]);
1060 +       }
1061 +
1062 +       if (sa->aad.info) {
1063 +               audit_log_format(ab, " info=");
1064 +               audit_log_string(ab, sa->aad.info);
1065 +               if (sa->aad.error)
1066 +                       audit_log_format(ab, " error=%d", sa->aad.error);
1067 +       }
1068 +
1069 +       if (sa->aad.profile) {
1070 +               struct aa_profile *profile = sa->aad.profile;
1071 +               pid_t pid;
1072 +               rcu_read_lock();
1073 +               pid = tsk->real_parent->pid;
1074 +               rcu_read_unlock();
1075 +               audit_log_format(ab, " parent=%d", pid);
1076 +               if (profile->ns != root_ns) {
1077 +                       audit_log_format(ab, " namespace=");
1078 +                       audit_log_untrustedstring(ab, profile->ns->base.hname);
1079 +               }
1080 +               audit_log_format(ab, " profile=");
1081 +               audit_log_untrustedstring(ab, profile->base.hname);
1082 +       }
1083 +
1084 +       if (sa->aad.name) {
1085 +               audit_log_format(ab, " name=");
1086 +               audit_log_untrustedstring(ab, sa->aad.name);
1087 +       }
1088 +}
1089 +
1090 +/**
1091 + * aa_audit_msg - Log a message to the audit subsystem
1092 + * @sa: audit event structure (NOT NULL)
1093 + * @cb: optional callback fn for type specific fields (MAYBE NULL)
1094 + */
1095 +void aa_audit_msg(int type, struct common_audit_data *sa,
1096 +                 void (*cb) (struct audit_buffer *, void *))
1097 +{
1098 +       sa->aad.type = type;
1099 +       sa->lsm_pre_audit = audit_pre;
1100 +       sa->lsm_post_audit = cb;
1101 +       common_lsm_audit(sa);
1102 +}
1103 +
1104 +/**
1105 + * aa_audit - Log a profile based audit event to the audit subsystem
1106 + * @type: audit type for the message
1107 + * @profile: profile to check against (NOT NULL)
1108 + * @gfp: allocation flags to use
1109 + * @sa: audit event (NOT NULL)
1110 + * @cb: optional callback fn for type specific fields (MAYBE NULL)
1111 + *
1112 + * Handle default message switching based off of audit mode flags
1113 + *
1114 + * Returns: error on failure
1115 + */
1116 +int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
1117 +            struct common_audit_data *sa,
1118 +            void (*cb) (struct audit_buffer *, void *))
1119 +{
1120 +       BUG_ON(!profile);
1121 +
1122 +       if (type == AUDIT_APPARMOR_AUTO) {
1123 +               if (likely(!sa->aad.error)) {
1124 +                       if (AUDIT_MODE(profile) != AUDIT_ALL)
1125 +                               return 0;
1126 +                       type = AUDIT_APPARMOR_AUDIT;
1127 +               } else if (COMPLAIN_MODE(profile))
1128 +                       type = AUDIT_APPARMOR_ALLOWED;
1129 +               else
1130 +                       type = AUDIT_APPARMOR_DENIED;
1131 +       }
1132 +       if (AUDIT_MODE(profile) == AUDIT_QUIET ||
1133 +           (type == AUDIT_APPARMOR_DENIED &&
1134 +            AUDIT_MODE(profile) == AUDIT_QUIET))
1135 +               return sa->aad.error;
1136 +
1137 +       if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
1138 +               type = AUDIT_APPARMOR_KILL;
1139 +
1140 +       if (!unconfined(profile))
1141 +               sa->aad.profile = profile;
1142 +
1143 +       aa_audit_msg(type, sa, cb);
1144 +
1145 +       if (sa->aad.type == AUDIT_APPARMOR_KILL)
1146 +               (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current);
1147 +
1148 +       if (sa->aad.type == AUDIT_APPARMOR_ALLOWED)
1149 +               return complain_error(sa->aad.error);
1150 +
1151 +       return sa->aad.error;
1152 +}
1153 diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
1154 new file mode 100644
1155 index 0000000..9982c48
1156 --- /dev/null
1157 +++ b/security/apparmor/capability.c
1158 @@ -0,0 +1,141 @@
1159 +/*
1160 + * AppArmor security module
1161 + *
1162 + * This file contains AppArmor capability mediation functions
1163 + *
1164 + * Copyright (C) 1998-2008 Novell/SUSE
1165 + * Copyright 2009-2010 Canonical Ltd.
1166 + *
1167 + * This program is free software; you can redistribute it and/or
1168 + * modify it under the terms of the GNU General Public License as
1169 + * published by the Free Software Foundation, version 2 of the
1170 + * License.
1171 + */
1172 +
1173 +#include <linux/capability.h>
1174 +#include <linux/errno.h>
1175 +#include <linux/gfp.h>
1176 +
1177 +#include "include/apparmor.h"
1178 +#include "include/capability.h"
1179 +#include "include/context.h"
1180 +#include "include/policy.h"
1181 +#include "include/audit.h"
1182 +
1183 +/*
1184 + * Table of capability names: we generate it from capabilities.h.
1185 + */
1186 +#include "capability_names.h"
1187 +
1188 +struct audit_cache {
1189 +       struct aa_profile *profile;
1190 +       kernel_cap_t caps;
1191 +};
1192 +
1193 +static DEFINE_PER_CPU(struct audit_cache, audit_cache);
1194 +
1195 +/**
1196 + * audit_cb - call back for capability components of audit struct
1197 + * @ab - audit buffer   (NOT NULL)
1198 + * @va - audit struct to audit data from  (NOT NULL)
1199 + */
1200 +static void audit_cb(struct audit_buffer *ab, void *va)
1201 +{
1202 +       struct common_audit_data *sa = va;
1203 +       audit_log_format(ab, " capname=");
1204 +       audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
1205 +}
1206 +
1207 +/**
1208 + * audit_caps - audit a capability
1209 + * @profile: profile confining task (NOT NULL)
1210 + * @task: task capability test was performed against (NOT NULL)
1211 + * @cap: capability tested
1212 + * @error: error code returned by test
1213 + *
1214 + * Do auditing of capability and handle, audit/complain/kill modes switching
1215 + * and duplicate message elimination.
1216 + *
1217 + * Returns: 0 or sa->error on success,  error code on failure
1218 + */
1219 +static int audit_caps(struct aa_profile *profile, struct task_struct *task,
1220 +                     int cap, int error)
1221 +{
1222 +       struct audit_cache *ent;
1223 +       int type = AUDIT_APPARMOR_AUTO;
1224 +       struct common_audit_data sa;
1225 +       COMMON_AUDIT_DATA_INIT(&sa, CAP);
1226 +       sa.tsk = task;
1227 +       sa.u.cap = cap;
1228 +       sa.aad.op = OP_CAPABLE;
1229 +       sa.aad.error = error;
1230 +
1231 +       if (likely(!error)) {
1232 +               /* test if auditing is being forced */
1233 +               if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
1234 +                          !cap_raised(profile->caps.audit, cap)))
1235 +                       return 0;
1236 +               type = AUDIT_APPARMOR_AUDIT;
1237 +       } else if (KILL_MODE(profile) ||
1238 +                  cap_raised(profile->caps.kill, cap)) {
1239 +               type = AUDIT_APPARMOR_KILL;
1240 +       } else if (cap_raised(profile->caps.quiet, cap) &&
1241 +                  AUDIT_MODE(profile) != AUDIT_NOQUIET &&
1242 +                  AUDIT_MODE(profile) != AUDIT_ALL) {
1243 +               /* quiet auditing */
1244 +               return error;
1245 +       }
1246 +
1247 +       /* Do simple duplicate message elimination */
1248 +       ent = &get_cpu_var(audit_cache);
1249 +       if (profile == ent->profile && cap_raised(ent->caps, cap)) {
1250 +               put_cpu_var(audit_cache);
1251 +               if (COMPLAIN_MODE(profile))
1252 +                       return complain_error(error);
1253 +               return error;
1254 +       } else {
1255 +               aa_put_profile(ent->profile);
1256 +               ent->profile = aa_get_profile(profile);
1257 +               cap_raise(ent->caps, cap);
1258 +       }
1259 +       put_cpu_var(audit_cache);
1260 +
1261 +       return aa_audit(type, profile, GFP_ATOMIC, &sa, audit_cb);
1262 +}
1263 +
1264 +/**
1265 + * profile_capable - test if profile allows use of capability @cap
1266 + * @profile: profile being enforced    (NOT NULL, NOT unconfined)
1267 + * @cap: capability to test if allowed
1268 + *
1269 + * Returns: 0 if allowed else -EPERM
1270 + */
1271 +static int profile_capable(struct aa_profile *profile, int cap)
1272 +{
1273 +       return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM;
1274 +}
1275 +
1276 +/**
1277 + * aa_capable - test permission to use capability
1278 + * @task: task doing capability test against (NOT NULL)
1279 + * @profile: profile confining @task (NOT NULL)
1280 + * @cap: capability to be tested
1281 + * @audit: whether an audit record should be generated
1282 + *
1283 + * Look up capability in profile capability set.
1284 + *
1285 + * Returns: 0 on success, or else an error code.
1286 + */
1287 +int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
1288 +              int audit)
1289 +{
1290 +       int error = profile_capable(profile, cap);
1291 +
1292 +       if (!audit) {
1293 +               if (COMPLAIN_MODE(profile))
1294 +                       return complain_error(error);
1295 +               return error;
1296 +       }
1297 +
1298 +       return audit_caps(profile, task, cap, error);
1299 +}
1300 diff --git a/security/apparmor/context.c b/security/apparmor/context.c
1301 new file mode 100644
1302 index 0000000..8a9b502
1303 --- /dev/null
1304 +++ b/security/apparmor/context.c
1305 @@ -0,0 +1,216 @@
1306 +/*
1307 + * AppArmor security module
1308 + *
1309 + * This file contains AppArmor functions used to manipulate object security
1310 + * contexts.
1311 + *
1312 + * Copyright (C) 1998-2008 Novell/SUSE
1313 + * Copyright 2009-2010 Canonical Ltd.
1314 + *
1315 + * This program is free software; you can redistribute it and/or
1316 + * modify it under the terms of the GNU General Public License as
1317 + * published by the Free Software Foundation, version 2 of the
1318 + * License.
1319 + *
1320 + *
1321 + * AppArmor sets confinement on every task, via the the aa_task_cxt and
1322 + * the aa_task_cxt.profile, both of which are required and are not allowed
1323 + * to be NULL.  The aa_task_cxt is not reference counted and is unique
1324 + * to each cred (which is reference count).  The profile pointed to by
1325 + * the task_cxt is reference counted.
1326 + *
1327 + * TODO
1328 + * If a task uses change_hat it currently does not return to the old
1329 + * cred or task context but instead creates a new one.  Ideally the task
1330 + * should return to the previous cred if it has not been modified.
1331 + *
1332 + */
1333 +
1334 +#include "include/context.h"
1335 +#include "include/policy.h"
1336 +
1337 +/**
1338 + * aa_alloc_task_context - allocate a new task_cxt
1339 + * @flags: gfp flags for allocation
1340 + *
1341 + * Returns: allocated buffer or NULL on failure
1342 + */
1343 +struct aa_task_cxt *aa_alloc_task_context(gfp_t flags)
1344 +{
1345 +       return kzalloc(sizeof(struct aa_task_cxt), flags);
1346 +}
1347 +
1348 +/**
1349 + * aa_free_task_context - free a task_cxt
1350 + * @cxt: task_cxt to free (MAYBE NULL)
1351 + */
1352 +void aa_free_task_context(struct aa_task_cxt *cxt)
1353 +{
1354 +       if (cxt) {
1355 +               aa_put_profile(cxt->profile);
1356 +               aa_put_profile(cxt->previous);
1357 +               aa_put_profile(cxt->onexec);
1358 +
1359 +               kzfree(cxt);
1360 +       }
1361 +}
1362 +
1363 +/**
1364 + * aa_dup_task_context - duplicate a task context, incrementing reference counts
1365 + * @new: a blank task context      (NOT NULL)
1366 + * @old: the task context to copy  (NOT NULL)
1367 + */
1368 +void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)
1369 +{
1370 +       *new = *old;
1371 +       aa_get_profile(new->profile);
1372 +       aa_get_profile(new->previous);
1373 +       aa_get_profile(new->onexec);
1374 +}
1375 +
1376 +/**
1377 + * aa_replace_current_profile - replace the current tasks profiles
1378 + * @profile: new profile  (NOT NULL)
1379 + *
1380 + * Returns: 0 or error on failure
1381 + */
1382 +int aa_replace_current_profile(struct aa_profile *profile)
1383 +{
1384 +       struct aa_task_cxt *cxt = current_cred()->security;
1385 +       struct cred *new;
1386 +       BUG_ON(!profile);
1387 +
1388 +       if (cxt->profile == profile)
1389 +               return 0;
1390 +
1391 +       new  = prepare_creds();
1392 +       if (!new)
1393 +               return -ENOMEM;
1394 +
1395 +       cxt = new->security;
1396 +       if (unconfined(profile) || (cxt->profile->ns != profile->ns)) {
1397 +               /* if switching to unconfined or a different profile namespace
1398 +                * clear out context state
1399 +                */
1400 +               aa_put_profile(cxt->previous);
1401 +               aa_put_profile(cxt->onexec);
1402 +               cxt->previous = NULL;
1403 +               cxt->onexec = NULL;
1404 +               cxt->token = 0;
1405 +       }
1406 +       /* be careful switching cxt->profile, when racing replacement it
1407 +        * is possible that cxt->profile->replacedby is the reference keeping
1408 +        * @profile valid, so make sure to get its reference before dropping
1409 +        * the reference on cxt->profile */
1410 +       aa_get_profile(profile);
1411 +       aa_put_profile(cxt->profile);
1412 +       cxt->profile = profile;
1413 +
1414 +       commit_creds(new);
1415 +       return 0;
1416 +}
1417 +
1418 +/**
1419 + * aa_set_current_onexec - set the tasks change_profile to happen onexec
1420 + * @profile: system profile to set at exec  (MAYBE NULL to clear value)
1421 + *
1422 + * Returns: 0 or error on failure
1423 + */
1424 +int aa_set_current_onexec(struct aa_profile *profile)
1425 +{
1426 +       struct aa_task_cxt *cxt;
1427 +       struct cred *new = prepare_creds();
1428 +       if (!new)
1429 +               return -ENOMEM;
1430 +
1431 +       cxt = new->security;
1432 +       aa_get_profile(profile);
1433 +       aa_put_profile(cxt->onexec);
1434 +       cxt->onexec = profile;
1435 +
1436 +       commit_creds(new);
1437 +       return 0;
1438 +}
1439 +
1440 +/**
1441 + * aa_set_current_hat - set the current tasks hat
1442 + * @profile: profile to set as the current hat  (NOT NULL)
1443 + * @token: token value that must be specified to change from the hat
1444 + *
1445 + * Do switch of tasks hat.  If the task is currently in a hat
1446 + * validate the token to match.
1447 + *
1448 + * Returns: 0 or error on failure
1449 + */
1450 +int aa_set_current_hat(struct aa_profile *profile, u64 token)
1451 +{
1452 +       struct aa_task_cxt *cxt;
1453 +       struct cred *new = prepare_creds();
1454 +       if (!new)
1455 +               return -ENOMEM;
1456 +       BUG_ON(!profile);
1457 +
1458 +       cxt = new->security;
1459 +       if (!cxt->previous) {
1460 +               /* transfer refcount */
1461 +               cxt->previous = cxt->profile;
1462 +               cxt->token = token;
1463 +       } else if (cxt->token == token) {
1464 +               aa_put_profile(cxt->profile);
1465 +       } else {
1466 +               /* previous_profile && cxt->token != token */
1467 +               abort_creds(new);
1468 +               return -EACCES;
1469 +       }
1470 +       cxt->profile = aa_get_profile(aa_newest_version(profile));
1471 +       /* clear exec on switching context */
1472 +       aa_put_profile(cxt->onexec);
1473 +       cxt->onexec = NULL;
1474 +
1475 +       commit_creds(new);
1476 +       return 0;
1477 +}
1478 +
1479 +/**
1480 + * aa_restore_previous_profile - exit from hat context restoring the profile
1481 + * @token: the token that must be matched to exit hat context
1482 + *
1483 + * Attempt to return out of a hat to the previous profile.  The token
1484 + * must match the stored token value.
1485 + *
1486 + * Returns: 0 or error of failure
1487 + */
1488 +int aa_restore_previous_profile(u64 token)
1489 +{
1490 +       struct aa_task_cxt *cxt;
1491 +       struct cred *new = prepare_creds();
1492 +       if (!new)
1493 +               return -ENOMEM;
1494 +
1495 +       cxt = new->security;
1496 +       if (cxt->token != token) {
1497 +               abort_creds(new);
1498 +               return -EACCES;
1499 +       }
1500 +       /* ignore restores when there is no saved profile */
1501 +       if (!cxt->previous) {
1502 +               abort_creds(new);
1503 +               return 0;
1504 +       }
1505 +
1506 +       aa_put_profile(cxt->profile);
1507 +       cxt->profile = aa_newest_version(cxt->previous);
1508 +       BUG_ON(!cxt->profile);
1509 +       if (unlikely(cxt->profile != cxt->previous)) {
1510 +               aa_get_profile(cxt->profile);
1511 +               aa_put_profile(cxt->previous);
1512 +       }
1513 +       /* clear exec && prev information when restoring to previous context */
1514 +       cxt->previous = NULL;
1515 +       cxt->token = 0;
1516 +       aa_put_profile(cxt->onexec);
1517 +       cxt->onexec = NULL;
1518 +
1519 +       commit_creds(new);
1520 +       return 0;
1521 +}
1522 diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
1523 new file mode 100644
1524 index 0000000..08bbe63
1525 --- /dev/null
1526 +++ b/security/apparmor/domain.c
1527 @@ -0,0 +1,823 @@
1528 +/*
1529 + * AppArmor security module
1530 + *
1531 + * This file contains AppArmor policy attachment and domain transitions
1532 + *
1533 + * Copyright (C) 2002-2008 Novell/SUSE
1534 + * Copyright 2009-2010 Canonical Ltd.
1535 + *
1536 + * This program is free software; you can redistribute it and/or
1537 + * modify it under the terms of the GNU General Public License as
1538 + * published by the Free Software Foundation, version 2 of the
1539 + * License.
1540 + */
1541 +
1542 +#include <linux/errno.h>
1543 +#include <linux/fdtable.h>
1544 +#include <linux/file.h>
1545 +#include <linux/mount.h>
1546 +#include <linux/syscalls.h>
1547 +#include <linux/tracehook.h>
1548 +#include <linux/personality.h>
1549 +
1550 +#include "include/audit.h"
1551 +#include "include/apparmorfs.h"
1552 +#include "include/context.h"
1553 +#include "include/domain.h"
1554 +#include "include/file.h"
1555 +#include "include/ipc.h"
1556 +#include "include/match.h"
1557 +#include "include/path.h"
1558 +#include "include/policy.h"
1559 +
1560 +/**
1561 + * aa_free_domain_entries - free entries in a domain table
1562 + * @domain: the domain table to free  (MAYBE NULL)
1563 + */
1564 +void aa_free_domain_entries(struct aa_domain *domain)
1565 +{
1566 +       int i;
1567 +       if (domain) {
1568 +               if (!domain->table)
1569 +                       return;
1570 +
1571 +               for (i = 0; i < domain->size; i++)
1572 +                       kzfree(domain->table[i]);
1573 +               kzfree(domain->table);
1574 +               domain->table = NULL;
1575 +       }
1576 +}
1577 +
1578 +/**
1579 + * may_change_ptraced_domain - check if can change profile on ptraced task
1580 + * @task: task we want to change profile of   (NOT NULL)
1581 + * @to_profile: profile to change to  (NOT NULL)
1582 + *
1583 + * Check if the task is ptraced and if so if the tracing task is allowed
1584 + * to trace the new domain
1585 + *
1586 + * Returns: %0 or error if change not allowed
1587 + */
1588 +static int may_change_ptraced_domain(struct task_struct *task,
1589 +                                    struct aa_profile *to_profile)
1590 +{
1591 +       struct task_struct *tracer;
1592 +       struct cred *cred = NULL;
1593 +       struct aa_profile *tracerp = NULL;
1594 +       int error = 0;
1595 +
1596 +       rcu_read_lock();
1597 +       tracer = tracehook_tracer_task(task);
1598 +       if (tracer) {
1599 +               /* released below */
1600 +               cred = get_task_cred(tracer);
1601 +               tracerp = aa_cred_profile(cred);
1602 +       }
1603 +       rcu_read_unlock();
1604 +
1605 +       /* not ptraced */
1606 +       if (!tracer || unconfined(tracerp))
1607 +               goto out;
1608 +
1609 +       error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
1610 +
1611 +out:
1612 +       if (cred)
1613 +               put_cred(cred);
1614 +
1615 +       return error;
1616 +}
1617 +
1618 +/**
1619 + * change_profile_perms - find permissions for change_profile
1620 + * @profile: the current profile  (NOT NULL)
1621 + * @ns: the namespace being switched to  (NOT NULL)
1622 + * @name: the name of the profile to change to  (NOT NULL)
1623 + * @request: requested perms
1624 + * @start: state to start matching in
1625 + *
1626 + * Returns: permission set
1627 + */
1628 +static struct file_perms change_profile_perms(struct aa_profile *profile,
1629 +                                             struct aa_namespace *ns,
1630 +                                             const char *name, u32 request,
1631 +                                             unsigned int start)
1632 +{
1633 +       struct file_perms perms;
1634 +       struct path_cond cond = { };
1635 +       unsigned int state;
1636 +
1637 +       if (unconfined(profile)) {
1638 +               perms.allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
1639 +               perms.audit = perms.quiet = perms.kill = 0;
1640 +               return perms;
1641 +       } else if (!profile->file.dfa) {
1642 +               return nullperms;
1643 +       } else if ((ns == profile->ns)) {
1644 +               /* try matching against rules with out namespace prepended */
1645 +               aa_str_perms(profile->file.dfa, start, name, &cond, &perms);
1646 +               if (COMBINED_PERM_MASK(perms) & request)
1647 +                       return perms;
1648 +       }
1649 +
1650 +       /* try matching with namespace name and then profile */
1651 +       state = aa_dfa_match(profile->file.dfa, start, ns->base.name);
1652 +       state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
1653 +       aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
1654 +
1655 +       return perms;
1656 +}
1657 +
1658 +/**
1659 + * __attach_match_ - find an attachment match
1660 + * @name - to match against  (NOT NULL)
1661 + * @head - profile list to walk  (NOT NULL)
1662 + *
1663 + * Do a linear search on the profiles in the list.  There is a matching
1664 + * preference where an exact match is preferred over a name which uses
1665 + * expressions to match, and matching expressions with the greatest
1666 + * xmatch_len are preferred.
1667 + *
1668 + * Requires: @head not be shared or have appropriate locks held
1669 + *
1670 + * Returns: profile or NULL if no match found
1671 + */
1672 +static struct aa_profile *__attach_match(const char *name,
1673 +                                        struct list_head *head)
1674 +{
1675 +       int len = 0;
1676 +       struct aa_profile *profile, *candidate = NULL;
1677 +
1678 +       list_for_each_entry(profile, head, base.list) {
1679 +               if (profile->flags & PFLAG_NULL)
1680 +                       continue;
1681 +               if (profile->xmatch && profile->xmatch_len > len) {
1682 +                       unsigned int state = aa_dfa_match(profile->xmatch,
1683 +                                                         DFA_START, name);
1684 +                       u32 perm = dfa_user_allow(profile->xmatch, state);
1685 +                       /* any accepting state means a valid match. */
1686 +                       if (perm & MAY_EXEC) {
1687 +                               candidate = profile;
1688 +                               len = profile->xmatch_len;
1689 +                       }
1690 +               } else if (!strcmp(profile->base.name, name))
1691 +                       /* exact non-re match, no more searching required */
1692 +                       return profile;
1693 +       }
1694 +
1695 +       return candidate;
1696 +}
1697 +
1698 +/**
1699 + * find_attach - do attachment search for unconfined processes
1700 + * @ns: the current namespace  (NOT NULL)
1701 + * @list: list to search  (NOT NULL)
1702 + * @name: the executable name to match against  (NOT NULL)
1703 + *
1704 + * Returns: profile or NULL if no match found
1705 + */
1706 +static struct aa_profile *find_attach(struct aa_namespace *ns,
1707 +                                     struct list_head *list, const char *name)
1708 +{
1709 +       struct aa_profile *profile;
1710 +
1711 +       read_lock(&ns->lock);
1712 +       profile = aa_get_profile(__attach_match(name, list));
1713 +       read_unlock(&ns->lock);
1714 +
1715 +       return profile;
1716 +}
1717 +
1718 +/**
1719 + * separate_fqname - separate the namespace and profile names
1720 + * @fqname: the fqname name to split  (NOT NULL)
1721 + * @ns_name: the namespace name if it exists  (NOT NULL)
1722 + *
1723 + * This is the xtable equivalent routine of aa_split_fqname.  It finds the
1724 + * split in an xtable fqname which contains an embedded \0 instead of a :
1725 + * if a namespace is specified.  This is done so the xtable is constant and
1726 + * isn't re-split on every lookup.
1727 + *
1728 + * Either the profile or namespace name may be optional but if the namespace
1729 + * is specified the profile name termination must be present.  This results
1730 + * in the following possible encodings:
1731 + * profile_name\0
1732 + * :ns_name\0profile_name\0
1733 + * :ns_name\0\0
1734 + *
1735 + * NOTE: the xtable fqname is pre-validated at load time in unpack_trans_table
1736 + *
1737 + * Returns: profile name if it is specified else NULL
1738 + */
1739 +static const char *separate_fqname(const char *fqname, const char **ns_name)
1740 +{
1741 +       const char *name;
1742 +
1743 +       if (fqname[0] == ':') {
1744 +               /* In this case there is guaranteed to be two \0 terminators
1745 +                * in the string.  They are verified at load time by
1746 +                * by unpack_trans_table
1747 +                */
1748 +               *ns_name = fqname + 1;          /* skip : */
1749 +               name = *ns_name + strlen(*ns_name) + 1;
1750 +               if (!*name)
1751 +                       name = NULL;
1752 +       } else {
1753 +               *ns_name = NULL;
1754 +               name = fqname;
1755 +       }
1756 +
1757 +       return name;
1758 +}
1759 +
1760 +static const char *next_name(int xtype, const char *name)
1761 +{
1762 +       return NULL;
1763 +}
1764 +
1765 +/**
1766 + * x_table_lookup - lookup an x transition name via transition table
1767 + * @profile: current profile (NOT NULL)
1768 + * @xindex: index into x transition table
1769 + *
1770 + * Returns: refcounted profile, or NULL on failure (MAYBE NULL)
1771 + */
1772 +static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
1773 +{
1774 +       struct aa_profile *new_profile = NULL;
1775 +       struct aa_namespace *ns = profile->ns;
1776 +       u32 xtype = xindex & AA_X_TYPE_MASK;
1777 +       int index = xindex & AA_X_INDEX_MASK;
1778 +       const char *name;
1779 +
1780 +       /* index is guaranteed to be in range, validated at load time */
1781 +       for (name = profile->file.trans.table[index]; !new_profile && name;
1782 +            name = next_name(xtype, name)) {
1783 +               struct aa_namespace *new_ns;
1784 +               const char *xname = NULL;
1785 +
1786 +               new_ns = NULL;
1787 +               if (xindex & AA_X_CHILD) {
1788 +                       /* release by caller */
1789 +                       new_profile = aa_find_child(profile, name);
1790 +                       continue;
1791 +               } else if (*name == ':') {
1792 +                       /* switching namespace */
1793 +                       const char *ns_name;
1794 +                       xname = name = separate_fqname(name, &ns_name);
1795 +                       if (!xname)
1796 +                               /* no name so use profile name */
1797 +                               xname = profile->base.hname;
1798 +                       if (*ns_name == '@') {
1799 +                               /* TODO: variable support */
1800 +                               ;
1801 +                       }
1802 +                       /* released below */
1803 +                       new_ns = aa_find_namespace(ns, ns_name);
1804 +                       if (!new_ns)
1805 +                               continue;
1806 +               } else if (*name == '@') {
1807 +                       /* TODO: variable support */
1808 +                       continue;
1809 +               } else {
1810 +                       /* basic namespace lookup */
1811 +                       xname = name;
1812 +               }
1813 +
1814 +               /* released by caller */
1815 +               new_profile = aa_lookup_profile(new_ns ? new_ns : ns, xname);
1816 +               aa_put_namespace(new_ns);
1817 +       }
1818 +
1819 +       /* released by caller */
1820 +       return new_profile;
1821 +}
1822 +
1823 +/**
1824 + * x_to_profile - get target profile for a given xindex
1825 + * @profile: current profile  (NOT NULL)
1826 + * @name: name to lookup (NOT NULL)
1827 + * @xindex: index into x transition table
1828 + *
1829 + * find profile for a transition index
1830 + *
1831 + * Returns: refcounted profile or NULL if not found available
1832 + */
1833 +static struct aa_profile *x_to_profile(struct aa_profile *profile,
1834 +                                      const char *name, u32 xindex)
1835 +{
1836 +       struct aa_profile *new_profile = NULL;
1837 +       struct aa_namespace *ns = profile->ns;
1838 +       u32 xtype = xindex & AA_X_TYPE_MASK;
1839 +
1840 +       switch (xtype) {
1841 +       case AA_X_NONE:
1842 +               /* fail exec unless ix || ux fallback - handled by caller */
1843 +               return NULL;
1844 +       case AA_X_NAME:
1845 +               if (xindex & AA_X_CHILD)
1846 +                       /* released by caller */
1847 +                       new_profile = find_attach(ns, &profile->base.profiles,
1848 +                                                 name);
1849 +               else
1850 +                       /* released by caller */
1851 +                       new_profile = find_attach(ns, &ns->base.profiles,
1852 +                                                 name);
1853 +               break;
1854 +       case AA_X_TABLE:
1855 +               /* released by caller */
1856 +               new_profile = x_table_lookup(profile, xindex);
1857 +               break;
1858 +       }
1859 +
1860 +       /* released by caller */
1861 +       return new_profile;
1862 +}
1863 +
1864 +/**
1865 + * apparmor_bprm_set_creds - set the new creds on the bprm struct
1866 + * @bprm: binprm for the exec  (NOT NULL)
1867 + *
1868 + * Returns: %0 or error on failure
1869 + */
1870 +int apparmor_bprm_set_creds(struct linux_binprm *bprm)
1871 +{
1872 +       struct aa_task_cxt *cxt;
1873 +       struct aa_profile *profile, *new_profile = NULL;
1874 +       struct aa_namespace *ns;
1875 +       char *buffer = NULL;
1876 +       unsigned int state;
1877 +       struct file_perms perms = {};
1878 +       struct path_cond cond = {
1879 +               bprm->file->f_path.dentry->d_inode->i_uid,
1880 +               bprm->file->f_path.dentry->d_inode->i_mode
1881 +       };
1882 +       const char *name = NULL, *target = NULL, *info = NULL;
1883 +       int error = cap_bprm_set_creds(bprm);
1884 +       if (error)
1885 +               return error;
1886 +
1887 +       if (bprm->cred_prepared)
1888 +               return 0;
1889 +
1890 +       cxt = bprm->cred->security;
1891 +       BUG_ON(!cxt);
1892 +
1893 +       profile = aa_get_profile(aa_newest_version(cxt->profile));
1894 +       /*
1895 +        * get the namespace from the replacement profile as replacement
1896 +        * can change the namespace
1897 +        */
1898 +       ns = profile->ns;
1899 +       state = profile->file.start;
1900 +
1901 +       /* buffer freed below, name is pointer into buffer */
1902 +       error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer,
1903 +                           &name);
1904 +       if (error) {
1905 +               if (profile->flags &
1906 +                   (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
1907 +                       error = 0;
1908 +               info = "Exec failed name resolution";
1909 +               name = bprm->filename;
1910 +               goto audit;
1911 +       }
1912 +
1913 +       /* Test for onexec first as onexec directives override other
1914 +        * x transitions.
1915 +        */
1916 +       if (unconfined(profile)) {
1917 +               /* unconfined task */
1918 +               if (cxt->onexec)
1919 +                       /* change_profile on exec already been granted */
1920 +                       new_profile = aa_get_profile(cxt->onexec);
1921 +               else
1922 +                       new_profile = find_attach(ns, &ns->base.profiles, name);
1923 +               if (!new_profile)
1924 +                       goto cleanup;
1925 +               goto apply;
1926 +       }
1927 +
1928 +       /* find exec permissions for name */
1929 +       state = aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
1930 +       if (cxt->onexec) {
1931 +               struct file_perms cp;
1932 +               info = "change_profile onexec";
1933 +               if (!(perms.allow & AA_MAY_ONEXEC))
1934 +                       goto audit;
1935 +
1936 +               /* test if this exec can be paired with change_profile onexec.
1937 +                * onexec permission is linked to exec with a standard pairing
1938 +                * exec\0change_profile
1939 +                */
1940 +               state = aa_dfa_null_transition(profile->file.dfa, state);
1941 +               cp = change_profile_perms(profile, cxt->onexec->ns, name,
1942 +                                         AA_MAY_ONEXEC, state);
1943 +
1944 +               if (!(cp.allow & AA_MAY_ONEXEC))
1945 +                       goto audit;
1946 +               new_profile = aa_get_profile(aa_newest_version(cxt->onexec));
1947 +               goto apply;
1948 +       }
1949 +
1950 +       if (perms.allow & MAY_EXEC) {
1951 +               /* exec permission determine how to transition */
1952 +               new_profile = x_to_profile(profile, name, perms.xindex);
1953 +               if (!new_profile) {
1954 +                       if (perms.xindex & AA_X_INHERIT) {
1955 +                               /* (p|c|n)ix - don't change profile but do
1956 +                                * use the newest version, which was picked
1957 +                                * up above when getting profile
1958 +                                */
1959 +                               info = "ix fallback";
1960 +                               new_profile = aa_get_profile(profile);
1961 +                               goto x_clear;
1962 +                       } else if (perms.xindex & AA_X_UNCONFINED) {
1963 +                               new_profile = aa_get_profile(ns->unconfined);
1964 +                               info = "ux fallback";
1965 +                       } else {
1966 +                               error = -ENOENT;
1967 +                               info = "profile not found";
1968 +                       }
1969 +               }
1970 +       } else if (COMPLAIN_MODE(profile)) {
1971 +               /* no exec permission - are we in learning mode */
1972 +               new_profile = aa_new_null_profile(profile, 0);
1973 +               if (!new_profile) {
1974 +                       error = -ENOMEM;
1975 +                       info = "could not create null profile";
1976 +               } else {
1977 +                       error = -EACCES;
1978 +                       target = new_profile->base.hname;
1979 +               }
1980 +               perms.xindex |= AA_X_UNSAFE;
1981 +       } else
1982 +               /* fail exec */
1983 +               error = -EACCES;
1984 +
1985 +       if (!new_profile)
1986 +               goto audit;
1987 +
1988 +       if (bprm->unsafe & LSM_UNSAFE_SHARE) {
1989 +               /* FIXME: currently don't mediate shared state */
1990 +               ;
1991 +       }
1992 +
1993 +       if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
1994 +               error = may_change_ptraced_domain(current, new_profile);
1995 +               if (error) {
1996 +                       aa_put_profile(new_profile);
1997 +                       goto audit;
1998 +               }
1999 +       }
2000 +
2001 +       /* Determine if secure exec is needed.
2002 +        * Can be at this point for the following reasons:
2003 +        * 1. unconfined switching to confined
2004 +        * 2. confined switching to different confinement
2005 +        * 3. confined switching to unconfined
2006 +        *
2007 +        * Cases 2 and 3 are marked as requiring secure exec
2008 +        * (unless policy specified "unsafe exec")
2009 +        *
2010 +        * bprm->unsafe is used to cache the AA_X_UNSAFE permission
2011 +        * to avoid having to recompute in secureexec
2012 +        */
2013 +       if (!(perms.xindex & AA_X_UNSAFE)) {
2014 +               AA_DEBUG("scrubbing environment variables for %s profile=%s\n",
2015 +                        name, new_profile->base.hname);
2016 +               bprm->unsafe |= AA_SECURE_X_NEEDED;
2017 +       }
2018 +apply:
2019 +       target = new_profile->base.hname;
2020 +       /* when transitioning profiles clear unsafe personality bits */
2021 +       bprm->per_clear |= PER_CLEAR_ON_SETID;
2022 +
2023 +x_clear:
2024 +       aa_put_profile(cxt->profile);
2025 +       /* transfer new profile reference will be released when cxt is freed */
2026 +       cxt->profile = new_profile;
2027 +
2028 +       /* clear out all temporary/transitional state from the context */
2029 +       aa_put_profile(cxt->previous);
2030 +       aa_put_profile(cxt->onexec);
2031 +       cxt->previous = NULL;
2032 +       cxt->onexec = NULL;
2033 +       cxt->token = 0;
2034 +
2035 +audit:
2036 +       error = aa_audit_file(profile, &perms, GFP_KERNEL, OP_EXEC, MAY_EXEC,
2037 +                             name, target, cond.uid, info, error);
2038 +
2039 +cleanup:
2040 +       aa_put_profile(profile);
2041 +       kfree(buffer);
2042 +
2043 +       return error;
2044 +}
2045 +
2046 +/**
2047 + * apparmor_bprm_secureexec - determine if secureexec is needed
2048 + * @bprm: binprm for exec  (NOT NULL)
2049 + *
2050 + * Returns: %1 if secureexec is needed else %0
2051 + */
2052 +int apparmor_bprm_secureexec(struct linux_binprm *bprm)
2053 +{
2054 +       int ret = cap_bprm_secureexec(bprm);
2055 +
2056 +       /* the decision to use secure exec is computed in set_creds
2057 +        * and stored in bprm->unsafe.
2058 +        */
2059 +       if (!ret && (bprm->unsafe & AA_SECURE_X_NEEDED))
2060 +               ret = 1;
2061 +
2062 +       return ret;
2063 +}
2064 +
2065 +/**
2066 + * apparmor_bprm_committing_creds - do task cleanup on committing new creds
2067 + * @bprm: binprm for the exec  (NOT NULL)
2068 + */
2069 +void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
2070 +{
2071 +       struct aa_profile *profile = __aa_current_profile();
2072 +       struct aa_task_cxt *new_cxt = bprm->cred->security;
2073 +
2074 +       /* bail out if unconfined or not changing profile */
2075 +       if ((new_cxt->profile == profile) ||
2076 +           (unconfined(new_cxt->profile)))
2077 +               return;
2078 +
2079 +       current->pdeath_signal = 0;
2080 +
2081 +       /* reset soft limits and set hard limits for the new profile */
2082 +       __aa_transition_rlimits(profile, new_cxt->profile);
2083 +}
2084 +
2085 +/**
2086 + * apparmor_bprm_commited_cred - do cleanup after new creds committed
2087 + * @bprm: binprm for the exec  (NOT NULL)
2088 + */
2089 +void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
2090 +{
2091 +       /* TODO: cleanup signals - ipc mediation */
2092 +       return;
2093 +}
2094 +
2095 +/*
2096 + * Functions for self directed profile change
2097 + */
2098 +
2099 +/**
2100 + * new_compound_name - create an hname with @n2 appended to @n1
2101 + * @n1: base of hname  (NOT NULL)
2102 + * @n2: name to append (NOT NULL)
2103 + *
2104 + * Returns: new name or NULL on error
2105 + */
2106 +static char *new_compound_name(const char *n1, const char *n2)
2107 +{
2108 +       char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
2109 +       if (name)
2110 +               sprintf(name, "%s//%s", n1, n2);
2111 +       return name;
2112 +}
2113 +
2114 +/**
2115 + * aa_change_hat - change hat to/from subprofile
2116 + * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0)
2117 + * @count: number of hat names in @hats
2118 + * @token: magic value to validate the hat change
2119 + * @permtest: true if this is just a permission test
2120 + *
2121 + * Change to the first profile specified in @hats that exists, and store
2122 + * the @hat_magic in the current task context.  If the count == 0 and the
2123 + * @token matches that stored in the current task context, return to the
2124 + * top level profile.
2125 + *
2126 + * Returns %0 on success, error otherwise.
2127 + */
2128 +int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
2129 +{
2130 +       const struct cred *cred;
2131 +       struct aa_task_cxt *cxt;
2132 +       struct aa_profile *profile, *previous_profile, *hat = NULL;
2133 +       char *name = NULL;
2134 +       int i;
2135 +       struct file_perms perms = {};
2136 +       const char *target = NULL, *info = NULL;
2137 +       int error = 0;
2138 +
2139 +       /* released below */
2140 +       cred = get_current_cred();
2141 +       cxt = cred->security;
2142 +       profile = aa_cred_profile(cred);
2143 +       previous_profile = cxt->previous;
2144 +
2145 +       if (unconfined(profile)) {
2146 +               info = "unconfined";
2147 +               error = -EPERM;
2148 +               goto audit;
2149 +       }
2150 +
2151 +       if (count) {
2152 +               /* attempting to change into a new hat or switch to a sibling */
2153 +               struct aa_profile *root;
2154 +               root = PROFILE_IS_HAT(profile) ? profile->parent : profile;
2155 +
2156 +               /* find first matching hat */
2157 +               for (i = 0; i < count && !hat; i++)
2158 +                       /* released below */
2159 +                       hat = aa_find_child(root, hats[i]);
2160 +               if (!hat) {
2161 +                       if (!COMPLAIN_MODE(root) || permtest) {
2162 +                               if (list_empty(&root->base.profiles))
2163 +                                       error = -ECHILD;
2164 +                               else
2165 +                                       error = -ENOENT;
2166 +                               goto out;
2167 +                       }
2168 +
2169 +                       /*
2170 +                        * In complain mode and failed to match any hats.
2171 +                        * Audit the failure is based off of the first hat
2172 +                        * supplied.  This is done due how userspace
2173 +                        * interacts with change_hat.
2174 +                        *
2175 +                        * TODO: Add logging of all failed hats
2176 +                        */
2177 +
2178 +                       /* freed below */
2179 +                       name = new_compound_name(root->base.hname, hats[0]);
2180 +                       target = name;
2181 +                       /* released below */
2182 +                       hat = aa_new_null_profile(profile, 1);
2183 +                       if (!hat) {
2184 +                               info = "failed null profile create";
2185 +                               error = -ENOMEM;
2186 +                               goto audit;
2187 +                       }
2188 +               } else {
2189 +                       target = hat->base.hname;
2190 +                       if (!PROFILE_IS_HAT(hat)) {
2191 +                               info = "target not hat";
2192 +                               error = -EPERM;
2193 +                               goto audit;
2194 +                       }
2195 +               }
2196 +
2197 +               error = may_change_ptraced_domain(current, hat);
2198 +               if (error) {
2199 +                       info = "ptraced";
2200 +                       error = -EPERM;
2201 +                       goto audit;
2202 +               }
2203 +
2204 +               if (!permtest) {
2205 +                       error = aa_set_current_hat(hat, token);
2206 +                       if (error == -EACCES)
2207 +                               /* kill task in case of brute force attacks */
2208 +                               perms.kill = AA_MAY_CHANGEHAT;
2209 +                       else if (name && !error)
2210 +                               /* reset error for learning of new hats */
2211 +                               error = -ENOENT;
2212 +               }
2213 +       } else if (previous_profile) {
2214 +               /* Return to saved profile.  Kill task if restore fails
2215 +                * to avoid brute force attacks
2216 +                */
2217 +               target = previous_profile->base.hname;
2218 +               error = aa_restore_previous_profile(token);
2219 +               perms.kill = AA_MAY_CHANGEHAT;
2220 +       } else
2221 +               /* ignore restores when there is no saved profile */
2222 +               goto out;
2223 +
2224 +audit:
2225 +       if (!permtest)
2226 +               error = aa_audit_file(profile, &perms, GFP_KERNEL,
2227 +                                     OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL,
2228 +                                     target, 0, info, error);
2229 +
2230 +out:
2231 +       aa_put_profile(hat);
2232 +       kfree(name);
2233 +       put_cred(cred);
2234 +
2235 +       return error;
2236 +}
2237 +
2238 +/**
2239 + * aa_change_profile - perform a one-way profile transition
2240 + * @ns_name: name of the profile namespace to change to (MAYBE NULL)
2241 + * @hname: name of profile to change to (MAYBE NULL)
2242 + * @onexec: whether this transition is to take place immediately or at exec
2243 + * @permtest: true if this is just a permission test
2244 + *
2245 + * Change to new profile @name.  Unlike with hats, there is no way
2246 + * to change back.  If @name isn't specified the current profile name is
2247 + * used.
2248 + * If @onexec then the transition is delayed until
2249 + * the next exec.
2250 + *
2251 + * Returns %0 on success, error otherwise.
2252 + */
2253 +int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
2254 +                     bool permtest)
2255 +{
2256 +       const struct cred *cred;
2257 +       struct aa_task_cxt *cxt;
2258 +       struct aa_profile *profile, *target = NULL;
2259 +       struct aa_namespace *ns = NULL;
2260 +       struct file_perms perms = {};
2261 +       const char *name = NULL, *info = NULL;
2262 +       int op, error = 0;
2263 +       u32 request;
2264 +
2265 +       if (!hname && !ns_name)
2266 +               return -EINVAL;
2267 +
2268 +       if (onexec) {
2269 +               request = AA_MAY_ONEXEC;
2270 +               op = OP_CHANGE_ONEXEC;
2271 +       } else {
2272 +               request = AA_MAY_CHANGE_PROFILE;
2273 +               op = OP_CHANGE_PROFILE;
2274 +       }
2275 +
2276 +       cred = get_current_cred();
2277 +       cxt = cred->security;
2278 +       profile = aa_cred_profile(cred);
2279 +
2280 +       if (ns_name) {
2281 +               /* released below */
2282 +               ns = aa_find_namespace(profile->ns, ns_name);
2283 +               if (!ns) {
2284 +                       /* we don't create new namespace in complain mode */
2285 +                       name = ns_name;
2286 +                       info = "namespace not found";
2287 +                       error = -ENOENT;
2288 +                       goto audit;
2289 +               }
2290 +       } else
2291 +               /* released below */
2292 +               ns = aa_get_namespace(profile->ns);
2293 +
2294 +       /* if the name was not specified, use the name of the current profile */
2295 +       if (!hname) {
2296 +               if (unconfined(profile))
2297 +                       hname = ns->unconfined->base.hname;
2298 +               else
2299 +                       hname = profile->base.hname;
2300 +       }
2301 +
2302 +       perms = change_profile_perms(profile, ns, hname, request,
2303 +                                    profile->file.start);
2304 +       if (!(perms.allow & request)) {
2305 +               error = -EACCES;
2306 +               goto audit;
2307 +       }
2308 +
2309 +       /* released below */
2310 +       target = aa_lookup_profile(ns, hname);
2311 +       if (!target) {
2312 +               info = "profile not found";
2313 +               error = -ENOENT;
2314 +               if (permtest || !COMPLAIN_MODE(profile))
2315 +                       goto audit;
2316 +               /* released below */
2317 +               target = aa_new_null_profile(profile, 0);
2318 +               if (!target) {
2319 +                       info = "failed null profile create";
2320 +                       error = -ENOMEM;
2321 +                       goto audit;
2322 +               }
2323 +       }
2324 +
2325 +       /* check if tracing task is allowed to trace target domain */
2326 +       error = may_change_ptraced_domain(current, target);
2327 +       if (error) {
2328 +               info = "ptrace prevents transition";
2329 +               goto audit;
2330 +       }
2331 +
2332 +       if (permtest)
2333 +               goto audit;
2334 +
2335 +       if (onexec)
2336 +               error = aa_set_current_onexec(target);
2337 +       else
2338 +               error = aa_replace_current_profile(target);
2339 +
2340 +audit:
2341 +       if (!permtest)
2342 +               error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request,
2343 +                                     name, hname, 0, info, error);
2344 +
2345 +       aa_put_namespace(ns);
2346 +       aa_put_profile(target);
2347 +       put_cred(cred);
2348 +
2349 +       return error;
2350 +}
2351 diff --git a/security/apparmor/file.c b/security/apparmor/file.c
2352 new file mode 100644
2353 index 0000000..7312db7
2354 --- /dev/null
2355 +++ b/security/apparmor/file.c
2356 @@ -0,0 +1,457 @@
2357 +/*
2358 + * AppArmor security module
2359 + *
2360 + * This file contains AppArmor mediation of files
2361 + *
2362 + * Copyright (C) 1998-2008 Novell/SUSE
2363 + * Copyright 2009-2010 Canonical Ltd.
2364 + *
2365 + * This program is free software; you can redistribute it and/or
2366 + * modify it under the terms of the GNU General Public License as
2367 + * published by the Free Software Foundation, version 2 of the
2368 + * License.
2369 + */
2370 +
2371 +#include "include/apparmor.h"
2372 +#include "include/audit.h"
2373 +#include "include/file.h"
2374 +#include "include/match.h"
2375 +#include "include/path.h"
2376 +#include "include/policy.h"
2377 +
2378 +struct file_perms nullperms;
2379 +
2380 +
2381 +/**
2382 + * audit_file_mask - convert mask to permission string
2383 + * @buffer: buffer to write string to (NOT NULL)
2384 + * @mask: permission mask to convert
2385 + */
2386 +static void audit_file_mask(struct audit_buffer *ab, u32 mask)
2387 +{
2388 +       char str[10];
2389 +
2390 +       char *m = str;
2391 +
2392 +       if (mask & AA_EXEC_MMAP)
2393 +               *m++ = 'm';
2394 +       if (mask & (MAY_READ | AA_MAY_META_READ))
2395 +               *m++ = 'r';
2396 +       if (mask & (MAY_WRITE | AA_MAY_META_WRITE | AA_MAY_CHMOD |
2397 +                   AA_MAY_CHOWN))
2398 +               *m++ = 'w';
2399 +       else if (mask & MAY_APPEND)
2400 +               *m++ = 'a';
2401 +       if (mask & AA_MAY_CREATE)
2402 +               *m++ = 'c';
2403 +       if (mask & AA_MAY_DELETE)
2404 +               *m++ = 'd';
2405 +       if (mask & AA_MAY_LINK)
2406 +               *m++ = 'l';
2407 +       if (mask & AA_MAY_LOCK)
2408 +               *m++ = 'k';
2409 +       if (mask & MAY_EXEC)
2410 +               *m++ = 'x';
2411 +       *m = '\0';
2412 +
2413 +       audit_log_string(ab, str);
2414 +}
2415 +
2416 +/**
2417 + * file_audit_cb - call back for file specific audit fields
2418 + * @ab: audit_buffer  (NOT NULL)
2419 + * @va: audit struct to audit values of  (NOT NULL)
2420 + */
2421 +static void file_audit_cb(struct audit_buffer *ab, void *va)
2422 +{
2423 +       struct common_audit_data *sa = va;
2424 +       uid_t fsuid = current_fsuid();
2425 +
2426 +       if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) {
2427 +               audit_log_format(ab, " requested_mask=");
2428 +               audit_file_mask(ab, sa->aad.fs.request);
2429 +       }
2430 +       if (sa->aad.fs.denied & AA_AUDIT_FILE_MASK) {
2431 +               audit_log_format(ab, " denied_mask=");
2432 +               audit_file_mask(ab, sa->aad.fs.denied);
2433 +       }
2434 +       if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) {
2435 +               audit_log_format(ab, " fsuid=%d", fsuid);
2436 +               audit_log_format(ab, " ouid=%d", sa->aad.fs.ouid);
2437 +       }
2438 +
2439 +       if (sa->aad.fs.target) {
2440 +               audit_log_format(ab, " target=");
2441 +               audit_log_untrustedstring(ab, sa->aad.fs.target);
2442 +       }
2443 +}
2444 +
2445 +/**
2446 + * aa_audit_file - handle the auditing of file operations
2447 + * @profile: the profile being enforced  (NOT NULL)
2448 + * @perms: the permissions computed for the request (NOT NULL)
2449 + * @gfp: allocation flags
2450 + * @op: operation being mediated
2451 + * @request: permissions requested
2452 + * @name: name of object being mediated (MAYBE NULL)
2453 + * @target: name of target (MAYBE NULL)
2454 + * @ouid: object uid
2455 + * @info: extra information message (MAYBE NULL)
2456 + * @error: 0 if operation allowed else failure error code
2457 + *
2458 + * Returns: %0 or error on failure
2459 + */
2460 +int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
2461 +                 gfp_t gfp, int op, u32 request, const char *name,
2462 +                 const char *target, uid_t ouid, const char *info, int error)
2463 +{
2464 +       int type = AUDIT_APPARMOR_AUTO;
2465 +       struct common_audit_data sa;
2466 +       COMMON_AUDIT_DATA_INIT(&sa, NONE);
2467 +       sa.aad.op = op,
2468 +       sa.aad.fs.request = request;
2469 +       sa.aad.name = name;
2470 +       sa.aad.fs.target = target;
2471 +       sa.aad.fs.ouid = ouid;
2472 +       sa.aad.info = info;
2473 +       sa.aad.error = error;
2474 +
2475 +       if (likely(!sa.aad.error)) {
2476 +               u32 mask = perms->audit;
2477 +
2478 +               if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
2479 +                       mask = 0xffff;
2480 +
2481 +               /* mask off perms that are not being force audited */
2482 +               sa.aad.fs.request &= mask;
2483 +
2484 +               if (likely(!sa.aad.fs.request))
2485 +                       return 0;
2486 +               type = AUDIT_APPARMOR_AUDIT;
2487 +       } else {
2488 +               /* only report permissions that were denied */
2489 +               sa.aad.fs.request = sa.aad.fs.request & ~perms->allow;
2490 +
2491 +               if (sa.aad.fs.request & perms->kill)
2492 +                       type = AUDIT_APPARMOR_KILL;
2493 +
2494 +               /* quiet known rejects, assumes quiet and kill do not overlap */
2495 +               if ((sa.aad.fs.request & perms->quiet) &&
2496 +                   AUDIT_MODE(profile) != AUDIT_NOQUIET &&
2497 +                   AUDIT_MODE(profile) != AUDIT_ALL)
2498 +                       sa.aad.fs.request &= ~perms->quiet;
2499 +
2500 +               if (!sa.aad.fs.request)
2501 +                       return COMPLAIN_MODE(profile) ? 0 : sa.aad.error;
2502 +       }
2503 +
2504 +       sa.aad.fs.denied = sa.aad.fs.request & ~perms->allow;
2505 +       return aa_audit(type, profile, gfp, &sa, file_audit_cb);
2506 +}
2507 +
2508 +/**
2509 + * map_old_perms - map old file perms layout to the new layout
2510 + * @old: permission set in old mapping
2511 + *
2512 + * Returns: new permission mapping
2513 + */
2514 +static u32 map_old_perms(u32 old)
2515 +{
2516 +       u32 new = old & 0xf;
2517 +       if (old & MAY_READ)
2518 +               new |= AA_MAY_META_READ;
2519 +       if (old & MAY_WRITE)
2520 +               new |= AA_MAY_META_WRITE | AA_MAY_CREATE | AA_MAY_DELETE |
2521 +                       AA_MAY_CHMOD | AA_MAY_CHOWN;
2522 +       if (old & 0x10)
2523 +               new |= AA_MAY_LINK;
2524 +       /* the old mapping lock and link_subset flags where overlaid
2525 +        * and use was determined by part of a pair that they were in
2526 +        */
2527 +       if (old & 0x20)
2528 +               new |= AA_MAY_LOCK | AA_LINK_SUBSET;
2529 +       if (old & 0x40) /* AA_EXEC_MMAP */
2530 +               new |= AA_EXEC_MMAP;
2531 +
2532 +       new |= AA_MAY_META_READ;
2533 +
2534 +       return new;
2535 +}
2536 +
2537 +/**
2538 + * compute_perms - convert dfa compressed perms to internal perms
2539 + * @dfa: dfa to compute perms for   (NOT NULL)
2540 + * @state: state in dfa
2541 + * @cond:  conditions to consider  (NOT NULL)
2542 + *
2543 + * TODO: convert from dfa + state to permission entry, do computation conversion
2544 + *       at load time.
2545 + *
2546 + * Returns: computed permission set
2547 + */
2548 +static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
2549 +                                      struct path_cond *cond)
2550 +{
2551 +       struct file_perms perms;
2552 +
2553 +       /* FIXME: change over to new dfa format
2554 +        * currently file perms are encoded in the dfa, new format
2555 +        * splits the permissions from the dfa.  This mapping can be
2556 +        * done at profile load
2557 +        */
2558 +       perms.kill = 0;
2559 +
2560 +       if (current_fsuid() == cond->uid) {
2561 +               perms.allow = map_old_perms(dfa_user_allow(dfa, state));
2562 +               perms.audit = map_old_perms(dfa_user_audit(dfa, state));
2563 +               perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
2564 +               perms.xindex = dfa_user_xindex(dfa, state);
2565 +       } else {
2566 +               perms.allow = map_old_perms(dfa_other_allow(dfa, state));
2567 +               perms.audit = map_old_perms(dfa_other_audit(dfa, state));
2568 +               perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
2569 +               perms.xindex = dfa_other_xindex(dfa, state);
2570 +       }
2571 +
2572 +       /* change_profile wasn't determined by ownership in old mapping */
2573 +       if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
2574 +               perms.allow |= AA_MAY_CHANGE_PROFILE;
2575 +
2576 +       return perms;
2577 +}
2578 +
2579 +/**
2580 + * aa_str_perms - find permission that match @name
2581 + * @dfa: to match against  (MAYBE NULL)
2582 + * @state: state to start matching in
2583 + * @name: string to match against dfa  (NOT NULL)
2584 + * @cond: conditions to consider for permission set computation  (NOT NULL)
2585 + * @perms: Returns - the permissions found when matching @name
2586 + *
2587 + * Returns: the final state in @dfa when beginning @start and walking @name
2588 + */
2589 +unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
2590 +                         const char *name, struct path_cond *cond,
2591 +                         struct file_perms *perms)
2592 +{
2593 +       unsigned int state;
2594 +       if (!dfa) {
2595 +               *perms = nullperms;
2596 +               return DFA_NOMATCH;
2597 +       }
2598 +
2599 +       state = aa_dfa_match(dfa, start, name);
2600 +       *perms = compute_perms(dfa, state, cond);
2601 +
2602 +       return state;
2603 +}
2604 +
2605 +/**
2606 + * is_deleted - test if a file has been completely unlinked
2607 + * @dentry: dentry of file to test for deletion  (NOT NULL)
2608 + *
2609 + * Returns: %1 if deleted else %0
2610 + */
2611 +static inline bool is_deleted(struct dentry *dentry)
2612 +{
2613 +       if (d_unlinked(dentry) && dentry->d_inode->i_nlink == 0)
2614 +               return 1;
2615 +       return 0;
2616 +}
2617 +
2618 +/**
2619 + * aa_path_perm - do permissions check & audit for @path
2620 + * @op: operation being checked
2621 + * @profile: profile being enforced  (NOT NULL)
2622 + * @path: path to check permissions of  (NOT NULL)
2623 + * @flags: any additional path flags beyond what the profile specifies
2624 + * @request: requested permissions
2625 + * @cond: conditional info for this request  (NOT NULL)
2626 + *
2627 + * Returns: %0 else error if access denied or other error
2628 + */
2629 +int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
2630 +                int flags, u32 request, struct path_cond *cond)
2631 +{
2632 +       char *buffer = NULL;
2633 +       struct file_perms perms = {};
2634 +       const char *name, *info = NULL;
2635 +       int error;
2636 +
2637 +       flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
2638 +       error = aa_get_name(path, flags, &buffer, &name);
2639 +       if (error) {
2640 +               if (error == -ENOENT && is_deleted(path->dentry)) {
2641 +                       /* Access to open files that are deleted are
2642 +                        * give a pass (implicit delegation)
2643 +                        */
2644 +                       error = 0;
2645 +                       perms.allow = request;
2646 +               } else if (error == -ENOENT)
2647 +                       info = "Failed name lookup - deleted entry";
2648 +               else if (error == -ESTALE)
2649 +                       info = "Failed name lookup - disconnected path";
2650 +               else if (error == -ENAMETOOLONG)
2651 +                       info = "Failed name lookup - name too long";
2652 +               else
2653 +                       info = "Failed name lookup";
2654 +       } else {
2655 +               aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
2656 +                            &perms);
2657 +               if (request & ~perms.allow)
2658 +                       error = -EACCES;
2659 +       }
2660 +       error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, name,
2661 +                             NULL, cond->uid, info, error);
2662 +       kfree(buffer);
2663 +
2664 +       return error;
2665 +}
2666 +
2667 +/**
2668 + * xindex_is_subset - helper for aa_path_link
2669 + * @link: link permission set
2670 + * @target: target permission set
2671 + *
2672 + * test target x permissions are equal OR a subset of link x permissions
2673 + * this is done as part of the subset test, where a hardlink must have
2674 + * a subset of permissions that the target has.
2675 + *
2676 + * Returns: %1 if subset else %0
2677 + */
2678 +static inline bool xindex_is_subset(u32 link, u32 target)
2679 +{
2680 +       if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
2681 +           ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
2682 +               return 0;
2683 +
2684 +       return 1;
2685 +}
2686 +
2687 +/**
2688 + * aa_path_link - Handle hard link permission check
2689 + * @profile: the profile being enforced  (NOT NULL)
2690 + * @old_dentry: the target dentry  (NOT NULL)
2691 + * @new_dir: directory the new link will be created in  (NOT NULL)
2692 + * @new_dentry: the link being created  (NOT NULL)
2693 + *
2694 + * Handle the permission test for a link & target pair.  Permission
2695 + * is encoded as a pair where the link permission is determined
2696 + * first, and if allowed, the target is tested.  The target test
2697 + * is done from the point of the link match (not start of DFA)
2698 + * making the target permission dependent on the link permission match.
2699 + *
2700 + * The subset test if required forces that permissions granted
2701 + * on link are a subset of the permission granted to target.
2702 + *
2703 + * Returns: %0 if allowed else error
2704 + */
2705 +int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
2706 +                struct path *new_dir, struct dentry *new_dentry)
2707 +{
2708 +       struct path link = { new_dir->mnt, new_dentry };
2709 +       struct path target = { new_dir->mnt, old_dentry };
2710 +       struct path_cond cond = {
2711 +               old_dentry->d_inode->i_uid,
2712 +               old_dentry->d_inode->i_mode
2713 +       };
2714 +       char *buffer = NULL, *buffer2 = NULL;
2715 +       const char *lname, *tname = NULL, *info = NULL;
2716 +       struct file_perms lperms, perms;
2717 +       u32 request = AA_MAY_LINK;
2718 +       unsigned int state;
2719 +       int error;
2720 +
2721 +       lperms = nullperms;
2722 +
2723 +       /* buffer freed below, lname is pointer in buffer */
2724 +       error = aa_get_name(&link, profile->path_flags, &buffer, &lname);
2725 +       if (error)
2726 +               goto audit;
2727 +
2728 +       /* buffer2 freed below, tname is pointer in buffer2 */
2729 +       error = aa_get_name(&target, profile->path_flags, &buffer2, &tname);
2730 +       if (error)
2731 +               goto audit;
2732 +
2733 +       error = -EACCES;
2734 +       /* aa_str_perms - handles the case of the dfa being NULL */
2735 +       state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
2736 +                            &cond, &lperms);
2737 +
2738 +       if (!(lperms.allow & AA_MAY_LINK))
2739 +               goto audit;
2740 +
2741 +       /* test to see if target can be paired with link */
2742 +       state = aa_dfa_null_transition(profile->file.dfa, state);
2743 +       aa_str_perms(profile->file.dfa, state, tname, &cond, &perms);
2744 +
2745 +       /* force audit/quiet masks for link are stored in the second entry
2746 +        * in the link pair.
2747 +        */
2748 +       lperms.audit = perms.audit;
2749 +       lperms.quiet = perms.quiet;
2750 +       lperms.kill = perms.kill;
2751 +
2752 +       if (!(perms.allow & AA_MAY_LINK)) {
2753 +               info = "target restricted";
2754 +               goto audit;
2755 +       }
2756 +
2757 +       /* done if link subset test is not required */
2758 +       if (!(perms.allow & AA_LINK_SUBSET))
2759 +               goto done_tests;
2760 +
2761 +       /* Do link perm subset test requiring allowed permission on link are a
2762 +        * subset of the allowed permissions on target.
2763 +        */
2764 +       aa_str_perms(profile->file.dfa, profile->file.start, tname, &cond,
2765 +                    &perms);
2766 +
2767 +       /* AA_MAY_LINK is not considered in the subset test */
2768 +       request = lperms.allow & ~AA_MAY_LINK;
2769 +       lperms.allow &= perms.allow | AA_MAY_LINK;
2770 +
2771 +       request |= AA_AUDIT_FILE_MASK & (lperms.allow & ~perms.allow);
2772 +       if (request & ~lperms.allow) {
2773 +               goto audit;
2774 +       } else if ((lperms.allow & MAY_EXEC) &&
2775 +                  !xindex_is_subset(lperms.xindex, perms.xindex)) {
2776 +               lperms.allow &= ~MAY_EXEC;
2777 +               request |= MAY_EXEC;
2778 +               info = "link not subset of target";
2779 +               goto audit;
2780 +       }
2781 +
2782 +done_tests:
2783 +       error = 0;
2784 +
2785 +audit:
2786 +       error = aa_audit_file(profile, &lperms, GFP_KERNEL, OP_LINK, request,
2787 +                             lname, tname, cond.uid, info, error);
2788 +       kfree(buffer);
2789 +       kfree(buffer2);
2790 +
2791 +       return error;
2792 +}
2793 +
2794 +/**
2795 + * aa_file_perm - do permission revalidation check & audit for @file
2796 + * @op: operation being checked
2797 + * @profile: profile being enforced   (NOT NULL)
2798 + * @file: file to revalidate access permissions on  (NOT NULL)
2799 + * @request: requested permissions
2800 + *
2801 + * Returns: %0 if access allowed else error
2802 + */
2803 +int aa_file_perm(int op, struct aa_profile *profile, struct file *file,
2804 +                u32 request)
2805 +{
2806 +       struct path_cond cond = {
2807 +               .uid = file->f_path.dentry->d_inode->i_uid,
2808 +               .mode = file->f_path.dentry->d_inode->i_mode
2809 +       };
2810 +
2811 +       return aa_path_perm(op, profile, &file->f_path, PATH_DELEGATE_DELETED,
2812 +                           request, &cond);
2813 +}
2814 diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
2815 new file mode 100644
2816 index 0000000..38ccaea
2817 --- /dev/null
2818 +++ b/security/apparmor/include/apparmor.h
2819 @@ -0,0 +1,92 @@
2820 +/*
2821 + * AppArmor security module
2822 + *
2823 + * This file contains AppArmor basic global and lib definitions
2824 + *
2825 + * Copyright (C) 1998-2008 Novell/SUSE
2826 + * Copyright 2009-2010 Canonical Ltd.
2827 + *
2828 + * This program is free software; you can redistribute it and/or
2829 + * modify it under the terms of the GNU General Public License as
2830 + * published by the Free Software Foundation, version 2 of the
2831 + * License.
2832 + */
2833 +
2834 +#ifndef __APPARMOR_H
2835 +#define __APPARMOR_H
2836 +
2837 +#include <linux/fs.h>
2838 +
2839 +#include "match.h"
2840 +
2841 +/* Control parameters settable through module/boot flags */
2842 +extern enum audit_mode aa_g_audit;
2843 +extern int aa_g_audit_header;
2844 +extern int aa_g_debug;
2845 +extern int aa_g_lock_policy;
2846 +extern int aa_g_logsyscall;
2847 +extern int aa_g_paranoid_load;
2848 +extern unsigned int aa_g_path_max;
2849 +
2850 +/*
2851 + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
2852 + * which is not related to profile accesses.
2853 + */
2854 +
2855 +#define AA_DEBUG(fmt, args...)                                         \
2856 +       do {                                                            \
2857 +               if (aa_g_debug && printk_ratelimit())                   \
2858 +                       printk(KERN_DEBUG "AppArmor: " fmt, ##args);    \
2859 +       } while (0)
2860 +
2861 +#define AA_ERROR(fmt, args...)                                         \
2862 +       do {                                                            \
2863 +               if (printk_ratelimit())                                 \
2864 +                       printk(KERN_ERR "AppArmor: " fmt, ##args);      \
2865 +       } while (0)
2866 +
2867 +/* Flag indicating whether initialization completed */
2868 +extern int apparmor_initialized __initdata;
2869 +
2870 +/* fn's in lib */
2871 +char *aa_split_fqname(char *args, char **ns_name);
2872 +void aa_info_message(const char *str);
2873 +void *kvmalloc(size_t size);
2874 +void kvfree(void *buffer);
2875 +
2876 +
2877 +/**
2878 + * aa_strneq - compare null terminated @str to a non null terminated substring
2879 + * @str: a null terminated string
2880 + * @sub: a substring, not necessarily null terminated
2881 + * @len: length of @sub to compare
2882 + *
2883 + * The @str string must be full consumed for this to be considered a match
2884 + */
2885 +static inline bool aa_strneq(const char *str, const char *sub, int len)
2886 +{
2887 +       return !strncmp(str, sub, len) && !str[len];
2888 +}
2889 +
2890 +/**
2891 + * aa_dfa_null_transition - step to next state after null character
2892 + * @dfa: the dfa to match against
2893 + * @start: the state of the dfa to start matching in
2894 + *
2895 + * aa_dfa_null_transition transitions to the next state after a null
2896 + * character which is not used in standard matching and is only
2897 + * used to separate pairs.
2898 + */
2899 +static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
2900 +                                                 unsigned int start)
2901 +{
2902 +       /* the null transition only needs the string's null terminator byte */
2903 +       return aa_dfa_match_len(dfa, start, "", 1);
2904 +}
2905 +
2906 +static inline bool mediated_filesystem(struct inode *inode)
2907 +{
2908 +       return !(inode->i_sb->s_flags & MS_NOUSER);
2909 +}
2910 +
2911 +#endif /* __APPARMOR_H */
2912 diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
2913 new file mode 100644
2914 index 0000000..14f955c
2915 --- /dev/null
2916 +++ b/security/apparmor/include/apparmorfs.h
2917 @@ -0,0 +1,26 @@
2918 +/*
2919 + * AppArmor security module
2920 + *
2921 + * This file contains AppArmor filesystem definitions.
2922 + *
2923 + * Copyright (C) 1998-2008 Novell/SUSE
2924 + * Copyright 2009-2010 Canonical Ltd.
2925 + *
2926 + * This program is free software; you can redistribute it and/or
2927 + * modify it under the terms of the GNU General Public License as
2928 + * published by the Free Software Foundation, version 2 of the
2929 + * License.
2930 + */
2931 +
2932 +#ifndef __AA_APPARMORFS_H
2933 +#define __AA_APPARMORFS_H
2934 +
2935 +extern void __init aa_destroy_aafs(void);
2936 +
2937 +#ifdef CONFIG_SECURITY_APPARMOR_COMPAT_24
2938 +extern const struct file_operations aa_fs_matching_fops;
2939 +extern const struct file_operations aa_fs_features_fops;
2940 +extern const struct file_operations aa_fs_profiles_fops;
2941 +#endif
2942 +
2943 +#endif /* __AA_APPARMORFS_H */
2944 diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
2945 new file mode 100644
2946 index 0000000..1951786
2947 --- /dev/null
2948 +++ b/security/apparmor/include/audit.h
2949 @@ -0,0 +1,123 @@
2950 +/*
2951 + * AppArmor security module
2952 + *
2953 + * This file contains AppArmor auditing function definitions.
2954 + *
2955 + * Copyright (C) 1998-2008 Novell/SUSE
2956 + * Copyright 2009-2010 Canonical Ltd.
2957 + *
2958 + * This program is free software; you can redistribute it and/or
2959 + * modify it under the terms of the GNU General Public License as
2960 + * published by the Free Software Foundation, version 2 of the
2961 + * License.
2962 + */
2963 +
2964 +#ifndef __AA_AUDIT_H
2965 +#define __AA_AUDIT_H
2966 +
2967 +#include <linux/audit.h>
2968 +#include <linux/fs.h>
2969 +#include <linux/lsm_audit.h>
2970 +#include <linux/sched.h>
2971 +#include <linux/slab.h>
2972 +
2973 +#include "file.h"
2974 +
2975 +struct aa_profile;
2976 +
2977 +extern const char *audit_mode_names[];
2978 +#define AUDIT_MAX_INDEX 5
2979 +
2980 +#define AUDIT_APPARMOR_AUTO 0  /* auto choose audit message type */
2981 +
2982 +enum audit_mode {
2983 +       AUDIT_NORMAL,           /* follow normal auditing of accesses */
2984 +       AUDIT_QUIET_DENIED,     /* quiet all denied access messages */
2985 +       AUDIT_QUIET,            /* quiet all messages */
2986 +       AUDIT_NOQUIET,          /* do not quiet audit messages */
2987 +       AUDIT_ALL               /* audit all accesses */
2988 +};
2989 +
2990 +enum audit_type {
2991 +       AUDIT_APPARMOR_AUDIT,
2992 +       AUDIT_APPARMOR_ALLOWED,
2993 +       AUDIT_APPARMOR_DENIED,
2994 +       AUDIT_APPARMOR_HINT,
2995 +       AUDIT_APPARMOR_STATUS,
2996 +       AUDIT_APPARMOR_ERROR,
2997 +       AUDIT_APPARMOR_KILL
2998 +};
2999 +
3000 +extern const char *op_table[];
3001 +enum aa_ops {
3002 +       OP_NULL,
3003 +
3004 +       OP_SYSCTL,
3005 +       OP_CAPABLE,
3006 +
3007 +       OP_UNLINK,
3008 +       OP_MKDIR,
3009 +       OP_RMDIR,
3010 +       OP_MKNOD,
3011 +       OP_TRUNC,
3012 +       OP_LINK,
3013 +       OP_SYMLINK,
3014 +       OP_RENAME_SRC,
3015 +       OP_RENAME_DEST,
3016 +       OP_CHMOD,
3017 +       OP_CHOWN,
3018 +       OP_GETATTR,
3019 +       OP_OPEN,
3020 +
3021 +       OP_FPERM,
3022 +       OP_FLOCK,
3023 +       OP_FMMAP,
3024 +       OP_FMPROT,
3025 +
3026 +       OP_CREATE,
3027 +       OP_POST_CREATE,
3028 +       OP_BIND,
3029 +       OP_CONNECT,
3030 +       OP_LISTEN,
3031 +       OP_ACCEPT,
3032 +       OP_SENDMSG,
3033 +       OP_RECVMSG,
3034 +       OP_GETSOCKNAME,
3035 +       OP_GETPEERNAME,
3036 +       OP_GETSOCKOPT,
3037 +       OP_SETSOCKOPT,
3038 +       OP_SOCK_SHUTDOWN,
3039 +
3040 +       OP_PTRACE,
3041 +
3042 +       OP_EXEC,
3043 +       OP_CHANGE_HAT,
3044 +       OP_CHANGE_PROFILE,
3045 +       OP_CHANGE_ONEXEC,
3046 +
3047 +       OP_SETPROCATTR,
3048 +       OP_SETRLIMIT,
3049 +
3050 +       OP_PROF_REPL,
3051 +       OP_PROF_LOAD,
3052 +       OP_PROF_RM,
3053 +};
3054 +
3055 +
3056 +/* define a short hand for apparmor_audit_data portion of common_audit_data */
3057 +#define aad apparmor_audit_data
3058 +
3059 +void aa_audit_msg(int type, struct common_audit_data *sa,
3060 +                 void (*cb) (struct audit_buffer *, void *));
3061 +int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
3062 +            struct common_audit_data *sa,
3063 +            void (*cb) (struct audit_buffer *, void *));
3064 +
3065 +static inline int complain_error(int error)
3066 +{
3067 +       if (error == -EPERM || error == -EACCES)
3068 +               return 0;
3069 +       return error;
3070 +}
3071 +
3072 +#endif /* __AA_AUDIT_H */
3073 diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
3074 new file mode 100644
3075 index 0000000..c24d295
3076 --- /dev/null
3077 +++ b/security/apparmor/include/capability.h
3078 @@ -0,0 +1,45 @@
3079 +/*
3080 + * AppArmor security module
3081 + *
3082 + * This file contains AppArmor capability mediation definitions.
3083 + *
3084 + * Copyright (C) 1998-2008 Novell/SUSE
3085 + * Copyright 2009-2010 Canonical Ltd.
3086 + *
3087 + * This program is free software; you can redistribute it and/or
3088 + * modify it under the terms of the GNU General Public License as
3089 + * published by the Free Software Foundation, version 2 of the
3090 + * License.
3091 + */
3092 +
3093 +#ifndef __AA_CAPABILITY_H
3094 +#define __AA_CAPABILITY_H
3095 +
3096 +#include <linux/sched.h>
3097 +
3098 +struct aa_profile;
3099 +
3100 +/* aa_caps - confinement data for capabilities
3101 + * @allowed: capabilities mask
3102 + * @audit: caps that are to be audited
3103 + * @quiet: caps that should not be audited
3104 + * @kill: caps that when requested will result in the task being killed
3105 + * @extended: caps that are subject finer grained mediation
3106 + */
3107 +struct aa_caps {
3108 +       kernel_cap_t allow;
3109 +       kernel_cap_t audit;
3110 +       kernel_cap_t quiet;
3111 +       kernel_cap_t kill;
3112 +       kernel_cap_t extended;
3113 +};
3114 +
3115 +int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
3116 +              int audit);
3117 +
3118 +static inline void aa_free_cap_rules(struct aa_caps *caps)
3119 +{
3120 +       /* NOP */
3121 +}
3122 +
3123 +#endif /* __AA_CAPBILITY_H */
3124 diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
3125 new file mode 100644
3126 index 0000000..a9cbee4
3127 --- /dev/null
3128 +++ b/security/apparmor/include/context.h
3129 @@ -0,0 +1,154 @@
3130 +/*
3131 + * AppArmor security module
3132 + *
3133 + * This file contains AppArmor contexts used to associate "labels" to objects.
3134 + *
3135 + * Copyright (C) 1998-2008 Novell/SUSE
3136 + * Copyright 2009-2010 Canonical Ltd.
3137 + *
3138 + * This program is free software; you can redistribute it and/or
3139 + * modify it under the terms of the GNU General Public License as
3140 + * published by the Free Software Foundation, version 2 of the
3141 + * License.
3142 + */
3143 +
3144 +#ifndef __AA_CONTEXT_H
3145 +#define __AA_CONTEXT_H
3146 +
3147 +#include <linux/cred.h>
3148 +#include <linux/slab.h>
3149 +#include <linux/sched.h>
3150 +
3151 +#include "policy.h"
3152 +
3153 +/* struct aa_file_cxt - the AppArmor context the file was opened in
3154 + * @perms: the permission the file was opened with
3155 + *
3156 + * The file_cxt could currently be directly stored in file->f_security
3157 + * as the profile reference is now stored in the f_cred.  However the
3158 + * cxt struct will expand in the future so we keep the struct.
3159 + */
3160 +struct aa_file_cxt {
3161 +       u16 allow;
3162 +};
3163 +
3164 +/**
3165 + * aa_alloc_file_context - allocate file_cxt
3166 + * @gfp: gfp flags for allocation
3167 + *
3168 + * Returns: file_cxt or NULL on failure
3169 + */
3170 +static inline struct aa_file_cxt *aa_alloc_file_context(gfp_t gfp)
3171 +{
3172 +       return kzalloc(sizeof(struct aa_file_cxt), gfp);
3173 +}
3174 +
3175 +/**
3176 + * aa_free_file_context - free a file_cxt
3177 + * @cxt: file_cxt to free  (MAYBE_NULL)
3178 + */
3179 +static inline void aa_free_file_context(struct aa_file_cxt *cxt)
3180 +{
3181 +       if (cxt)
3182 +               kzfree(cxt);
3183 +}
3184 +
3185 +/**
3186 + * struct aa_task_cxt - primary label for confined tasks
3187 + * @profile: the current profile   (NOT NULL)
3188 + * @exec: profile to transition to on next exec  (MAYBE NULL)
3189 + * @previous: profile the task may return to     (MAYBE NULL)
3190 + * @token: magic value the task must know for returning to @previous_profile
3191 + *
3192 + * Contains the task's current profile (which could change due to
3193 + * change_hat).  Plus the hat_magic needed during change_hat.
3194 + *
3195 + * TODO: make so a task can be confined by a stack of contexts
3196 + */
3197 +struct aa_task_cxt {
3198 +       struct aa_profile *profile;
3199 +       struct aa_profile *onexec;
3200 +       struct aa_profile *previous;
3201 +       u64 token;
3202 +};
3203 +
3204 +struct aa_task_cxt *aa_alloc_task_context(gfp_t flags);
3205 +void aa_free_task_context(struct aa_task_cxt *cxt);
3206 +void aa_dup_task_context(struct aa_task_cxt *new,
3207 +                        const struct aa_task_cxt *old);
3208 +int aa_replace_current_profile(struct aa_profile *profile);
3209 +int aa_set_current_onexec(struct aa_profile *profile);
3210 +int aa_set_current_hat(struct aa_profile *profile, u64 token);
3211 +int aa_restore_previous_profile(u64 cookie);
3212 +
3213 +/**
3214 + * __aa_task_is_confined - determine if @task has any confinement
3215 + * @task: task to check confinement of  (NOT NULL)
3216 + *
3217 + * If @task != current needs to be called in RCU safe critical section
3218 + */
3219 +static inline bool __aa_task_is_confined(struct task_struct *task)
3220 +{
3221 +       struct aa_task_cxt *cxt = __task_cred(task)->security;
3222 +
3223 +       BUG_ON(!cxt || !cxt->profile);
3224 +       if (unconfined(aa_newest_version(cxt->profile)))
3225 +               return 0;
3226 +
3227 +       return 1;
3228 +}
3229 +
3230 +/**
3231 + * aa_cred_profile - obtain cred's profiles
3232 + * @cred: cred to obtain profiles from  (NOT NULL)
3233 + *
3234 + * Returns: confining profile
3235 + *
3236 + * does NOT increment reference count
3237 + */
3238 +static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
3239 +{
3240 +       struct aa_task_cxt *cxt = cred->security;
3241 +       BUG_ON(!cxt || !cxt->profile);
3242 +       return aa_newest_version(cxt->profile);
3243 +}
3244 +
3245 +/**
3246 + * __aa_current_profile - find the current tasks confining profile
3247 + *
3248 + * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
3249 + *
3250 + * This fn will not update the tasks cred to the most up to date version
3251 + * of the profile so it is safe to call when inside of locks.
3252 + */
3253 +static inline struct aa_profile *__aa_current_profile(void)
3254 +{
3255 +       return aa_cred_profile(current_cred());
3256 +}
3257 +
3258 +/**
3259 + * aa_current_profile - find the current tasks confining profile and do updates
3260 + *
3261 + * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
3262 + *
3263 + * This fn will update the tasks cred structure if the profile has been
3264 + * replaced.  Not safe to call inside locks
3265 + */
3266 +static inline struct aa_profile *aa_current_profile(void)
3267 +{
3268 +       const struct aa_task_cxt *cxt = current_cred()->security;
3269 +       struct aa_profile *profile;
3270 +       BUG_ON(!cxt || !cxt->profile);
3271 +
3272 +       profile = aa_newest_version(cxt->profile);
3273 +       /*
3274 +        * Whether or not replacement succeeds, use newest profile so
3275 +        * there is no need to update it after replacement.
3276 +        */
3277 +       if (unlikely((cxt->profile != profile)))
3278 +               aa_replace_current_profile(profile);
3279 +
3280 +       return profile;
3281 +}
3282 +
3283 +#endif /* __AA_CONTEXT_H */
3284 diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
3285 new file mode 100644
3286 index 0000000..de04464
3287 --- /dev/null
3288 +++ b/security/apparmor/include/domain.h
3289 @@ -0,0 +1,36 @@
3290 +/*
3291 + * AppArmor security module
3292 + *
3293 + * This file contains AppArmor security domain transition function definitions.
3294 + *
3295 + * Copyright (C) 1998-2008 Novell/SUSE
3296 + * Copyright 2009-2010 Canonical Ltd.
3297 + *
3298 + * This program is free software; you can redistribute it and/or
3299 + * modify it under the terms of the GNU General Public License as
3300 + * published by the Free Software Foundation, version 2 of the
3301 + * License.
3302 + */
3303 +
3304 +#include <linux/binfmts.h>
3305 +#include <linux/types.h>
3306 +
3307 +#ifndef __AA_DOMAIN_H
3308 +#define __AA_DOMAIN_H
3309 +
3310 +struct aa_domain {
3311 +       int size;
3312 +       char **table;
3313 +};
3314 +
3315 +int apparmor_bprm_set_creds(struct linux_binprm *bprm);
3316 +int apparmor_bprm_secureexec(struct linux_binprm *bprm);
3317 +void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
3318 +void apparmor_bprm_committed_creds(struct linux_binprm *bprm);
3319 +
3320 +void aa_free_domain_entries(struct aa_domain *domain);
3321 +int aa_change_hat(const char *hats[], int count, u64 token, bool permtest);
3322 +int aa_change_profile(const char *ns_name, const char *name, bool onexec,
3323 +                     bool permtest);
3324 +
3325 +#endif /* __AA_DOMAIN_H */
3326 diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
3327 new file mode 100644
3328 index 0000000..be36fea
3329 --- /dev/null
3330 +++ b/security/apparmor/include/file.h
3331 @@ -0,0 +1,217 @@
3332 +/*
3333 + * AppArmor security module
3334 + *
3335 + * This file contains AppArmor file mediation function definitions.
3336 + *
3337 + * Copyright (C) 1998-2008 Novell/SUSE
3338 + * Copyright 2009-2010 Canonical Ltd.
3339 + *
3340 + * This program is free software; you can redistribute it and/or
3341 + * modify it under the terms of the GNU General Public License as
3342 + * published by the Free Software Foundation, version 2 of the
3343 + * License.
3344 + */
3345 +
3346 +#ifndef __AA_FILE_H
3347 +#define __AA_FILE_H
3348 +
3349 +#include <linux/path.h>
3350 +
3351 +#include "domain.h"
3352 +#include "match.h"
3353 +
3354 +struct aa_profile;
3355 +
3356 +/*
3357 + * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
3358 + * for profile permissions
3359 + */
3360 +#define AA_MAY_CREATE                  0x0010
3361 +#define AA_MAY_DELETE                  0x0020
3362 +#define AA_MAY_META_WRITE              0x0040
3363 +#define AA_MAY_META_READ               0x0080
3364 +
3365 +#define AA_MAY_CHMOD                   0x0100
3366 +#define AA_MAY_CHOWN                   0x0200
3367 +#define AA_MAY_LOCK                    0x0400
3368 +#define AA_EXEC_MMAP                   0x0800
3369 +
3370 +#define AA_MAY_LINK                    0x1000
3371 +#define AA_LINK_SUBSET                 AA_MAY_LOCK     /* overlaid */
3372 +#define AA_MAY_ONEXEC                  0x40000000      /* exec allows onexec */
3373 +#define AA_MAY_CHANGE_PROFILE          0x80000000
3374 +#define AA_MAY_CHANGEHAT               0x80000000      /* ctrl auditing only */
3375 +
3376 +#define AA_AUDIT_FILE_MASK     (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
3377 +                                AA_MAY_CREATE | AA_MAY_DELETE |        \
3378 +                                AA_MAY_META_READ | AA_MAY_META_WRITE | \
3379 +                                AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
3380 +                                AA_EXEC_MMAP | AA_MAY_LINK)
3381 +
3382 +/*
3383 + * The xindex is broken into 3 parts
3384 + * - index - an index into either the exec name table or the variable table
3385 + * - exec type - which determines how the executable name and index are used
3386 + * - flags - which modify how the destination name is applied
3387 + */
3388 +#define AA_X_INDEX_MASK                0x03ff
3389 +
3390 +#define AA_X_TYPE_MASK         0x0c00
3391 +#define AA_X_TYPE_SHIFT                10
3392 +#define AA_X_NONE              0x0000
3393 +#define AA_X_NAME              0x0400  /* use executable name px */
3394 +#define AA_X_TABLE             0x0800  /* use a specified name ->n# */
3395 +
3396 +#define AA_X_UNSAFE            0x1000
3397 +#define AA_X_CHILD             0x2000  /* make >AA_X_NONE apply to children */
3398 +#define AA_X_INHERIT           0x4000
3399 +#define AA_X_UNCONFINED                0x8000
3400 +
3401 +/* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */
3402 +#define AA_SECURE_X_NEEDED     0x8000
3403 +
3404 +/* need to make conditional which ones are being set */
3405 +struct path_cond {
3406 +       uid_t uid;
3407 +       umode_t mode;
3408 +};
3409 +
3410 +/* struct file_perms - file permission
3411 + * @allow: mask of permissions that are allowed
3412 + * @audit: mask of permissions to force an audit message for
3413 + * @quiet: mask of permissions to quiet audit messages for
3414 + * @kill: mask of permissions that when matched will kill the task
3415 + * @xindex: exec transition index if @allow contains MAY_EXEC
3416 + *
3417 + * The @audit and @queit mask should be mutually exclusive.
3418 + */
3419 +struct file_perms {
3420 +       u32 allow;
3421 +       u32 audit;
3422 +       u32 quiet;
3423 +       u32 kill;
3424 +       u16 xindex;
3425 +};
3426 +
3427 +extern struct file_perms nullperms;
3428 +
3429 +#define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
3430 +
3431 +/* FIXME: split perms from dfa and match this to description
3432 + *        also add delegation info.
3433 + */
3434 +static inline u16 dfa_map_xindex(u16 mask)
3435 +{
3436 +       u16 old_index = (mask >> 10) & 0xf;
3437 +       u16 index = 0;
3438 +
3439 +       if (mask & 0x100)
3440 +               index |= AA_X_UNSAFE;
3441 +       if (mask & 0x200)
3442 +               index |= AA_X_INHERIT;
3443 +       if (mask & 0x80)
3444 +               index |= AA_X_UNCONFINED;
3445 +
3446 +       if (old_index == 1) {
3447 +               index |= AA_X_UNCONFINED;
3448 +       } else if (old_index == 2) {
3449 +               index |= AA_X_NAME;
3450 +       } else if (old_index == 3) {
3451 +               index |= AA_X_NAME | AA_X_CHILD;
3452 +       } else {
3453 +               index |= AA_X_TABLE;
3454 +               index |= old_index - 4;
3455 +       }
3456 +
3457 +       return index;
3458 +}
3459 +
3460 +/*
3461 + * map old dfa inline permissions to new format
3462 + */
3463 +#define dfa_user_allow(dfa, state) (((ACCEPT_TABLE(dfa)[state]) & 0x7f) | \
3464 +                                   ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
3465 +#define dfa_user_audit(dfa, state) ((ACCEPT_TABLE2(dfa)[state]) & 0x7f)
3466 +#define dfa_user_quiet(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 7) & 0x7f)
3467 +#define dfa_user_xindex(dfa, state) \
3468 +       (dfa_map_xindex(ACCEPT_TABLE(dfa)[state] & 0x3fff))
3469 +
3470 +#define dfa_other_allow(dfa, state) ((((ACCEPT_TABLE(dfa)[state]) >> 14) & \
3471 +                                     0x7f) |                           \
3472 +                                    ((ACCEPT_TABLE(dfa)[state]) & 0x80000000))
3473 +#define dfa_other_audit(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 14) & 0x7f)
3474 +#define dfa_other_quiet(dfa, state) \
3475 +       ((((ACCEPT_TABLE2(dfa)[state]) >> 7) >> 14) & 0x7f)
3476 +#define dfa_other_xindex(dfa, state) \
3477 +       dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
3478 +
3479 +int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
3480 +                 gfp_t gfp, int op, u32 request, const char *name,
3481 +                 const char *target, uid_t ouid, const char *info, int error);
3482 +
3483 +/**
3484 + * struct aa_file_rules - components used for file rule permissions
3485 + * @dfa: dfa to match path names and conditionals against
3486 + * @perms: permission table indexed by the matched state accept entry of @dfa
3487 + * @trans: transition table for indexed by named x transitions
3488 + *
3489 + * File permission are determined by matching a path against @dfa and then
3490 + * then using the value of the accept entry for the matching state as
3491 + * an index into @perms.  If a named exec transition is required it is
3492 + * looked up in the transition table.
3493 + */
3494 +struct aa_file_rules {
3495 +       unsigned int start;
3496 +       struct aa_dfa *dfa;
3497 +       /* struct perms perms; */
3498 +       struct aa_domain trans;
3499 +       /* TODO: add delegate table */
3500 +};
3501 +
3502 +unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
3503 +                         const char *name, struct path_cond *cond,
3504 +                         struct file_perms *perms);
3505 +
3506 +int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
3507 +                int flags, u32 request, struct path_cond *cond);
3508 +
3509 +int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
3510 +                struct path *new_dir, struct dentry *new_dentry);
3511 +
3512 +int aa_file_perm(int op, struct aa_profile *profile, struct file *file,
3513 +                u32 request);
3514 +
3515 +static inline void aa_free_file_rules(struct aa_file_rules *rules)
3516 +{
3517 +       aa_put_dfa(rules->dfa);
3518 +       aa_free_domain_entries(&rules->trans);
3519 +}
3520 +
3521 +#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
3522 +
3523 +/* from namei.c */
3524 +#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
3525 +
3526 +/**
3527 + * aa_map_file_perms - map file flags to AppArmor permissions
3528 + * @file: open file to map flags to AppArmor permissions
3529 + *
3530 + * Returns: apparmor permission set for the file
3531 + */
3532 +static inline u32 aa_map_file_to_perms(struct file *file)
3533 +{
3534 +       int flags = MAP_OPEN_FLAGS(file->f_flags);
3535 +       u32 perms = ACC_FMODE(file->f_mode);
3536 +
3537 +       if ((flags & O_APPEND) && (perms & MAY_WRITE))
3538 +               perms = (perms & ~MAY_WRITE) | MAY_APPEND;
3539 +       /* trunc implies write permission */
3540 +       if (flags & O_TRUNC)
3541 +               perms |= MAY_WRITE;
3542 +       if (flags & O_CREAT)
3543 +               perms |= AA_MAY_CREATE;
3544 +
3545 +       return perms;
3546 +}
3547 +
3548 +#endif /* __AA_FILE_H */
3549 diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
3550 new file mode 100644
3551 index 0000000..aeda0fb
3552 --- /dev/null
3553 +++ b/security/apparmor/include/ipc.h
3554 @@ -0,0 +1,28 @@
3555 +/*
3556 + * AppArmor security module
3557 + *
3558 + * This file contains AppArmor ipc mediation function definitions.
3559 + *
3560 + * Copyright (C) 1998-2008 Novell/SUSE
3561 + * Copyright 2009-2010 Canonical Ltd.
3562 + *
3563 + * This program is free software; you can redistribute it and/or
3564 + * modify it under the terms of the GNU General Public License as
3565 + * published by the Free Software Foundation, version 2 of the
3566 + * License.
3567 + */
3568 +
3569 +#ifndef __AA_IPC_H
3570 +#define __AA_IPC_H
3571 +
3572 +#include <linux/sched.h>
3573 +
3574 +struct aa_profile;
3575 +
3576 +int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
3577 +                 struct aa_profile *tracee, unsigned int mode);
3578 +
3579 +int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
3580 +             unsigned int mode);
3581 +
3582 +#endif /* __AA_IPC_H */
3583 diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
3584 new file mode 100644
3585 index 0000000..734a6d3
3586 --- /dev/null
3587 +++ b/security/apparmor/include/match.h
3588 @@ -0,0 +1,132 @@
3589 +/*
3590 + * AppArmor security module
3591 + *
3592 + * This file contains AppArmor policy dfa matching engine definitions.
3593 + *
3594 + * Copyright (C) 1998-2008 Novell/SUSE
3595 + * Copyright 2009-2010 Canonical Ltd.
3596 + *
3597 + * This program is free software; you can redistribute it and/or
3598 + * modify it under the terms of the GNU General Public License as
3599 + * published by the Free Software Foundation, version 2 of the
3600 + * License.
3601 + */
3602 +
3603 +#ifndef __AA_MATCH_H
3604 +#define __AA_MATCH_H
3605 +
3606 +#include <linux/workqueue.h>
3607 +
3608 +#define DFA_NOMATCH                    0
3609 +#define DFA_START                      1
3610 +
3611 +#define DFA_VALID_PERM_MASK            0xffffffff
3612 +#define DFA_VALID_PERM2_MASK           0xffffffff
3613 +
3614 +/**
3615 + * The format used for transition tables is based on the GNU flex table
3616 + * file format (--tables-file option; see Table File Format in the flex
3617 + * info pages and the flex sources for documentation). The magic number
3618 + * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because
3619 + * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used
3620 + * slightly differently (see the apparmor-parser package).
3621 + */
3622 +
3623 +#define YYTH_MAGIC     0x1B5E783D
3624 +#define YYTH_DEF_RECURSE 0x1                   /* DEF Table is recursive */
3625 +
3626 +struct table_set_header {
3627 +       u32 th_magic;           /* YYTH_MAGIC */
3628 +       u32 th_hsize;
3629 +       u32 th_ssize;
3630 +       u16 th_flags;
3631 +       char th_version[];
3632 +};
3633 +
3634 +/* The YYTD_ID are one less than flex table mappings.  The flex id
3635 + * has 1 subtracted at table load time, this allows us to directly use the
3636 + * ID's as indexes.
3637 + */
3638 +#define        YYTD_ID_ACCEPT  0
3639 +#define YYTD_ID_BASE   1
3640 +#define YYTD_ID_CHK    2
3641 +#define YYTD_ID_DEF    3
3642 +#define YYTD_ID_EC     4
3643 +#define YYTD_ID_META   5
3644 +#define YYTD_ID_ACCEPT2 6
3645 +#define YYTD_ID_NXT    7
3646 +#define YYTD_ID_TSIZE  8
3647 +
3648 +#define YYTD_DATA8     1
3649 +#define YYTD_DATA16    2
3650 +#define YYTD_DATA32    4
3651 +#define YYTD_DATA64    8
3652 +
3653 +/* Each ACCEPT2 table gets 6 dedicated flags, YYTD_DATAX define the
3654 + * first flags
3655 + */
3656 +#define ACCEPT1_FLAGS(X) ((X) & 0x3f)
3657 +#define ACCEPT2_FLAGS(X) ACCEPT1_FLAGS((X) >> YYTD_ID_ACCEPT2)
3658 +#define TO_ACCEPT1_FLAG(X) ACCEPT1_FLAGS(X)
3659 +#define TO_ACCEPT2_FLAG(X) (ACCEPT1_FLAGS(X) << YYTD_ID_ACCEPT2)
3660 +#define DFA_FLAG_VERIFY_STATES 0x1000
3661 +
3662 +struct table_header {
3663 +       u16 td_id;
3664 +       u16 td_flags;
3665 +       u32 td_hilen;
3666 +       u32 td_lolen;
3667 +       char td_data[];
3668 +};
3669 +
3670 +#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF]->td_data))
3671 +#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE]->td_data))
3672 +#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT]->td_data))
3673 +#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK]->td_data))
3674 +#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC]->td_data))
3675 +#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT]->td_data))
3676 +#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2]->td_data))
3677 +
3678 +struct aa_dfa {
3679 +       struct kref count;
3680 +       u16 flags;
3681 +       struct table_header *tables[YYTD_ID_TSIZE];
3682 +};
3683 +
3684 +#define byte_to_byte(X) (X)
3685 +
3686 +#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
3687 +       do { \
3688 +               typeof(LEN) __i; \
3689 +               TYPE *__t = (TYPE *) TABLE; \
3690 +               TYPE *__b = (TYPE *) BLOB; \
3691 +               for (__i = 0; __i < LEN; __i++) { \
3692 +                       __t[__i] = NTOHX(__b[__i]); \
3693 +               } \
3694 +       } while (0)
3695 +
3696 +static inline size_t table_size(size_t len, size_t el_size)
3697 +{
3698 +       return ALIGN(sizeof(struct table_header) + len * el_size, 8);
3699 +}
3700 +
3701 +struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
3702 +unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
3703 +                             const char *str, int len);
3704 +unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
3705 +                         const char *str);
3706 +void aa_dfa_free_kref(struct kref *kref);
3707 +
3708 +/**
3709 + * aa_put_dfa - put a dfa refcount
3710 + * @dfa: dfa to put refcount   (MAYBE NULL)
3711 + *
3712 + * Requires: if @dfa != NULL that a valid refcount be held
3713 + */
3714 +static inline void aa_put_dfa(struct aa_dfa *dfa)
3715 +{
3716 +       if (dfa)
3717 +               kref_put(&dfa->count, aa_dfa_free_kref);
3718 +}
3719 +
3720 +#endif /* __AA_MATCH_H */
3721 diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
3722 new file mode 100644
3723 index 0000000..3c7d599
3724 --- /dev/null
3725 +++ b/security/apparmor/include/net.h
3726 @@ -0,0 +1,40 @@
3727 +/*
3728 + * AppArmor security module
3729 + *
3730 + * This file contains AppArmor network mediation definitions.
3731 + *
3732 + * Copyright (C) 1998-2008 Novell/SUSE
3733 + * Copyright 2009-2010 Canonical Ltd.
3734 + *
3735 + * This program is free software; you can redistribute it and/or
3736 + * modify it under the terms of the GNU General Public License as
3737 + * published by the Free Software Foundation, version 2 of the
3738 + * License.
3739 + */
3740 +
3741 +#ifndef __AA_NET_H
3742 +#define __AA_NET_H
3743 +
3744 +#include <net/sock.h>
3745 +
3746 +/* struct aa_net - network confinement data
3747 + * @allowed: basic network families permissions
3748 + * @audit_network: which network permissions to force audit
3749 + * @quiet_network: which network permissions to quiet rejects
3750 + */
3751 +struct aa_net {
3752 +       u16 allow[AF_MAX];
3753 +       u16 audit[AF_MAX];
3754 +       u16 quiet[AF_MAX];
3755 +};
3756 +
3757 +extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
3758 +                      int type, int protocol, struct sock *sk);
3759 +extern int aa_revalidate_sk(int op, struct sock *sk);
3760 +
3761 +static inline void aa_free_net_rules(struct aa_net *new)
3762 +{
3763 +       /* NOP */
3764 +}
3765 +
3766 +#endif /* __AA_NET_H */
3767 diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
3768 new file mode 100644
3769 index 0000000..27b327a
3770 --- /dev/null
3771 +++ b/security/apparmor/include/path.h
3772 @@ -0,0 +1,31 @@
3773 +/*
3774 + * AppArmor security module
3775 + *
3776 + * This file contains AppArmor basic path manipulation function definitions.
3777 + *
3778 + * Copyright (C) 1998-2008 Novell/SUSE
3779 + * Copyright 2009-2010 Canonical Ltd.
3780 + *
3781 + * This program is free software; you can redistribute it and/or
3782 + * modify it under the terms of the GNU General Public License as
3783 + * published by the Free Software Foundation, version 2 of the
3784 + * License.
3785 + */
3786 +
3787 +#ifndef __AA_PATH_H
3788 +#define __AA_PATH_H
3789 +
3790 +
3791 +enum path_flags {
3792 +       PATH_IS_DIR = 0x1,              /* path is a directory */
3793 +       PATH_CONNECT_PATH = 0x4,        /* connect disconnected paths to / */
3794 +       PATH_CHROOT_REL = 0x8,          /* do path lookup relative to chroot */
3795 +       PATH_CHROOT_NSCONNECT = 0x10,   /* connect paths that are at ns root */
3796 +
3797 +       PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */
3798 +       PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
3799 +};
3800 +
3801 +int aa_get_name(struct path *path, int flags, char **buffer, const char **name);
3802 +
3803 +#endif /* __AA_PATH_H */
3804 diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
3805 new file mode 100644
3806 index 0000000..6776929
3807 --- /dev/null
3808 +++ b/security/apparmor/include/policy.h
3809 @@ -0,0 +1,308 @@
3810 +/*
3811 + * AppArmor security module
3812 + *
3813 + * This file contains AppArmor policy definitions.
3814 + *
3815 + * Copyright (C) 1998-2008 Novell/SUSE
3816 + * Copyright 2009-2010 Canonical Ltd.
3817 + *
3818 + * This program is free software; you can redistribute it and/or
3819 + * modify it under the terms of the GNU General Public License as
3820 + * published by the Free Software Foundation, version 2 of the
3821 + * License.
3822 + */
3823 +
3824 +#ifndef __AA_POLICY_H
3825 +#define __AA_POLICY_H
3826 +
3827 +#include <linux/capability.h>
3828 +#include <linux/cred.h>
3829 +#include <linux/kref.h>
3830 +#include <linux/sched.h>
3831 +#include <linux/slab.h>
3832 +#include <linux/socket.h>
3833 +
3834 +#include "apparmor.h"
3835 +#include "audit.h"
3836 +#include "capability.h"
3837 +#include "domain.h"
3838 +#include "file.h"
3839 +#include "net.h"
3840 +#include "resource.h"
3841 +
3842 +extern const char *profile_mode_names[];
3843 +#define APPARMOR_NAMES_MAX_INDEX 3
3844 +
3845 +#define COMPLAIN_MODE(_profile)        \
3846 +       ((aa_g_profile_mode == APPARMOR_COMPLAIN) || \
3847 +        ((_profile)->mode == APPARMOR_COMPLAIN))
3848 +
3849 +#define KILL_MODE(_profile) \
3850 +       ((aa_g_profile_mode == APPARMOR_KILL) || \
3851 +        ((_profile)->mode == APPARMOR_KILL))
3852 +
3853 +#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
3854 +
3855 +/*
3856 + * FIXME: currently need a clean way to replace and remove profiles as a
3857 + * set.  It should be done at the namespace level.
3858 + * Either, with a set of profiles loaded at the namespace level or via
3859 + * a mark and remove marked interface.
3860 + */
3861 +enum profile_mode {
3862 +       APPARMOR_ENFORCE,       /* enforce access rules */
3863 +       APPARMOR_COMPLAIN,      /* allow and log access violations */
3864 +       APPARMOR_KILL,          /* kill task on access violation */
3865 +};
3866 +
3867 +enum profile_flags {
3868 +       PFLAG_HAT = 1,                  /* profile is a hat */
3869 +       PFLAG_UNCONFINED = 2,           /* profile is an unconfined profile */
3870 +       PFLAG_NULL = 4,                 /* profile is null learning profile */
3871 +       PFLAG_IX_ON_NAME_ERROR = 8,     /* fallback to ix on name lookup fail */
3872 +       PFLAG_IMMUTABLE = 0x10,         /* don't allow changes/replacement */
3873 +       PFLAG_USER_DEFINED = 0x20,      /* user based profile - lower privs */
3874 +       PFLAG_NO_LIST_REF = 0x40,       /* list doesn't keep profile ref */
3875 +       PFLAG_OLD_NULL_TRANS = 0x100,   /* use // as the null transition */
3876 +
3877 +       /* These flags must correspond with PATH_flags */
3878 +       PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
3879 +};
3880 +
3881 +struct aa_profile;
3882 +
3883 +/* struct aa_policy - common part of both namespaces and profiles
3884 + * @name: name of the object
3885 + * @hname - The hierarchical name
3886 + * @count: reference count of the obj
3887 + * @list: list policy object is on
3888 + * @profiles: head of the profiles list contained in the object
3889 + */
3890 +struct aa_policy {
3891 +       char *name;
3892 +       char *hname;
3893 +       struct kref count;
3894 +       struct list_head list;
3895 +       struct list_head profiles;
3896 +};
3897 +
3898 +/* struct aa_ns_acct - accounting of profiles in namespace
3899 + * @max_size: maximum space allowed for all profiles in namespace
3900 + * @max_count: maximum number of profiles that can be in this namespace
3901 + * @size: current size of profiles
3902 + * @count: current count of profiles (includes null profiles)
3903 + */
3904 +struct aa_ns_acct {
3905 +       int max_size;
3906 +       int max_count;
3907 +       int size;
3908 +       int count;
3909 +};
3910 +
3911 +/* struct aa_namespace - namespace for a set of profiles
3912 + * @base: common policy
3913 + * @parent: parent of namespace
3914 + * @lock: lock for modifying the object
3915 + * @acct: accounting for the namespace
3916 + * @unconfined: special unconfined profile for the namespace
3917 + * @sub_ns: list of namespaces under the current namespace.
3918 + *
3919 + * An aa_namespace defines the set profiles that are searched to determine
3920 + * which profile to attach to a task.  Profiles can not be shared between
3921 + * aa_namespaces and profile names within a namespace are guaranteed to be
3922 + * unique.  When profiles in separate namespaces have the same name they
3923 + * are NOT considered to be equivalent.
3924 + *
3925 + * Namespaces are hierarchical and only namespaces and profiles below the
3926 + * current namespace are visible.
3927 + *
3928 + * Namespace names must be unique and can not contain the characters :/\0
3929 + *
3930 + * FIXME TODO: add vserver support of namespaces (can it all be done in
3931 + *             userspace?)
3932 + */
3933 +struct aa_namespace {
3934 +       struct aa_policy base;
3935 +       struct aa_namespace *parent;
3936 +       rwlock_t lock;
3937 +       struct aa_ns_acct acct;
3938 +       struct aa_profile *unconfined;
3939 +       struct list_head sub_ns;
3940 +};
3941 +
3942 +/* struct aa_profile - basic confinement data
3943 + * @base - base components of the profile (name, refcount, lists, lock ...)
3944 + * @parent: parent of profile
3945 + * @ns: namespace the profile is in
3946 + * @replacedby: is set to the profile that replaced this profile
3947 + * @rename: optional profile name that this profile renamed
3948 + * @xmatch: optional extended matching for unconfined executables names
3949 + * @xmatch_len: xmatch prefix len, used to determine xmatch priority
3950 + * @sid: the unique security id number of this profile
3951 + * @audit: the auditing mode of the profile
3952 + * @mode: the enforcement mode of the profile
3953 + * @flags: flags controlling profile behavior
3954 + * @path_flags: flags controlling path generation behavior
3955 + * @size: the memory consumed by this profiles rules
3956 + * @file: The set of rules governing basic file access and domain transitions
3957 + * @caps: capabilities for the profile
3958 + * @net: network controls for the profile
3959 + * @rlimits: rlimits for the profile
3960 + *
3961 + * The AppArmor profile contains the basic confinement data.  Each profile
3962 + * has a name, and exists in a namespace.  The @name and @exec_match are
3963 + * used to determine profile attachment against unconfined tasks.  All other
3964 + * attachments are determined by profile X transition rules.
3965 + *
3966 + * The @replacedby field is write protected by the profile lock.  Reads
3967 + * are assumed to be atomic, and are done without locking.
3968 + *
3969 + * Profiles have a hierarchy where hats and children profiles keep
3970 + * a reference to their parent.
3971 + *
3972 + * Profile names can not begin with a : and can not contain the \0
3973 + * character.  If a profile name begins with / it will be considered when
3974 + * determining profile attachment on "unconfined" tasks.
3975 + */
3976 +struct aa_profile {
3977 +       struct aa_policy base;
3978 +       struct aa_profile *parent;
3979 +
3980 +       struct aa_namespace *ns;
3981 +       struct aa_profile *replacedby;
3982 +       const char *rename;
3983 +
3984 +       struct aa_dfa *xmatch;
3985 +       int xmatch_len;
3986 +       u32 sid;
3987 +       enum audit_mode audit;
3988 +       enum profile_mode mode;
3989 +       u32 flags;
3990 +       u32 path_flags;
3991 +       int size;
3992 +
3993 +       struct aa_file_rules file;
3994 +       struct aa_caps caps;
3995 +       struct aa_net net;
3996 +       struct aa_rlimit rlimits;
3997 +};
3998 +
3999 +extern struct aa_namespace *root_ns;
4000 +extern enum profile_mode aa_g_profile_mode;
4001 +
4002 +void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
4003 +
4004 +bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view);
4005 +const char *aa_ns_name(struct aa_namespace *parent, struct aa_namespace *child);
4006 +int aa_alloc_root_ns(void);
4007 +void aa_free_root_ns(void);
4008 +void aa_free_namespace_kref(struct kref *kref);
4009 +
4010 +struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
4011 +                                      const char *name);
4012 +
4013 +static inline struct aa_policy *aa_get_common(struct aa_policy *c)
4014 +{
4015 +       if (c)
4016 +               kref_get(&c->count);
4017 +
4018 +       return c;
4019 +}
4020 +
4021 +/**
4022 + * aa_get_namespace - increment references count on @ns
4023 + * @ns: namespace to increment reference count of (MAYBE NULL)
4024 + *
4025 + * Returns: pointer to @ns, if @ns is NULL returns NULL
4026 + * Requires: @ns must be held with valid refcount when called
4027 + */
4028 +static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
4029 +{
4030 +       if (ns)
4031 +               kref_get(&(ns->base.count));
4032 +
4033 +       return ns;
4034 +}
4035 +
4036 +/**
4037 + * aa_put_namespace - decrement refcount on @ns
4038 + * @ns: namespace to put reference of
4039 + *
4040 + * Decrement reference count of @ns and if no longer in use free it
4041 + */
4042 +static inline void aa_put_namespace(struct aa_namespace *ns)
4043 +{
4044 +       if (ns)
4045 +               kref_put(&ns->base.count, aa_free_namespace_kref);
4046 +}
4047 +
4048 +struct aa_profile *aa_alloc_profile(const char *name);
4049 +struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
4050 +void aa_free_profile_kref(struct kref *kref);
4051 +struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
4052 +struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
4053 +struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
4054 +
4055 +ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace);
4056 +ssize_t aa_remove_profiles(char *name, size_t size);
4057 +
4058 +#define PROF_ADD 1
4059 +#define PROF_REPLACE 0
4060 +
4061 +#define unconfined(X) ((X)->flags & PFLAG_UNCONFINED)
4062 +
4063 +/**
4064 + * aa_newest_version - find the newest version of @profile
4065 + * @profile: the profile to check for newer versions of (NOT NULL)
4066 + *
4067 + * Returns: newest version of @profile, if @profile is the newest version
4068 + *          return @profile.
4069 + *
4070 + * NOTE: the profile returned is not refcounted, The refcount on @profile
4071 + * must be held until the caller decides what to do with the returned newest
4072 + * version.
4073 + */
4074 +static inline struct aa_profile *aa_newest_version(struct aa_profile *profile)
4075 +{
4076 +       while (profile->replacedby)
4077 +               profile = profile->replacedby;
4078 +
4079 +       return profile;
4080 +}
4081 +
4082 +/**
4083 + * aa_get_profile - increment refcount on profile @p
4084 + * @p: profile  (MAYBE NULL)
4085 + *
4086 + * Returns: pointer to @p if @p is NULL will return NULL
4087 + * Requires: @p must be held with valid refcount when called
4088 + */
4089 +static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
4090 +{
4091 +       if (p)
4092 +               kref_get(&(p->base.count));
4093 +
4094 +       return p;
4095 +}
4096 +
4097 +/**
4098 + * aa_put_profile - decrement refcount on profile @p
4099 + * @p: profile  (MAYBE NULL)
4100 + */
4101 +static inline void aa_put_profile(struct aa_profile *p)
4102 +{
4103 +       if (p)
4104 +               kref_put(&p->base.count, aa_free_profile_kref);
4105 +}
4106 +
4107 +static inline int AUDIT_MODE(struct aa_profile *profile)
4108 +{
4109 +       if (aa_g_audit != AUDIT_NORMAL)
4110 +               return aa_g_audit;
4111 +
4112 +       return profile->audit;
4113 +}
4114 +
4115 +bool aa_may_manage_policy(int op);
4116 +
4117 +#endif /* __AA_POLICY_H */
4118 diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h
4119 new file mode 100644
4120 index 0000000..a2dccca
4121 --- /dev/null
4122 +++ b/security/apparmor/include/policy_unpack.h
4123 @@ -0,0 +1,20 @@
4124 +/*
4125 + * AppArmor security module
4126 + *
4127 + * This file contains AppArmor policy loading interface function definitions.
4128 + *
4129 + * Copyright (C) 1998-2008 Novell/SUSE
4130 + * Copyright 2009-2010 Canonical Ltd.
4131 + *
4132 + * This program is free software; you can redistribute it and/or
4133 + * modify it under the terms of the GNU General Public License as
4134 + * published by the Free Software Foundation, version 2 of the
4135 + * License.
4136 + */
4137 +
4138 +#ifndef __POLICY_INTERFACE_H
4139 +#define __POLICY_INTERFACE_H
4140 +
4141 +struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns);
4142 +
4143 +#endif /* __POLICY_INTERFACE_H */
4144 diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
4145 new file mode 100644
4146 index 0000000..544aa6b
4147 --- /dev/null
4148 +++ b/security/apparmor/include/procattr.h
4149 @@ -0,0 +1,26 @@
4150 +/*
4151 + * AppArmor security module
4152 + *
4153 + * This file contains AppArmor /proc/<pid>/attr/ interface function definitions.
4154 + *
4155 + * Copyright (C) 1998-2008 Novell/SUSE
4156 + * Copyright 2009-2010 Canonical Ltd.
4157 + *
4158 + * This program is free software; you can redistribute it and/or
4159 + * modify it under the terms of the GNU General Public License as
4160 + * published by the Free Software Foundation, version 2 of the
4161 + * License.
4162 + */
4163 +
4164 +#ifndef __AA_PROCATTR_H
4165 +#define __AA_PROCATTR_H
4166 +
4167 +#define AA_DO_TEST 1
4168 +#define AA_ONEXEC  1
4169 +
4170 +int aa_getprocattr(struct aa_profile *profile, char **string);
4171 +int aa_setprocattr_changehat(char *args, size_t size, int test);
4172 +int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
4173 +int aa_setprocattr_permipc(char *fqname);
4174 +
4175 +#endif /* __AA_PROCATTR_H */
4176 diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
4177 new file mode 100644
4178 index 0000000..3c88be9
4179 --- /dev/null
4180 +++ b/security/apparmor/include/resource.h
4181 @@ -0,0 +1,46 @@
4182 +/*
4183 + * AppArmor security module
4184 + *
4185 + * This file contains AppArmor resource limits function definitions.
4186 + *
4187 + * Copyright (C) 1998-2008 Novell/SUSE
4188 + * Copyright 2009-2010 Canonical Ltd.
4189 + *
4190 + * This program is free software; you can redistribute it and/or
4191 + * modify it under the terms of the GNU General Public License as
4192 + * published by the Free Software Foundation, version 2 of the
4193 + * License.
4194 + */
4195 +
4196 +#ifndef __AA_RESOURCE_H
4197 +#define __AA_RESOURCE_H
4198 +
4199 +#include <linux/resource.h>
4200 +#include <linux/sched.h>
4201 +
4202 +struct aa_profile;
4203 +
4204 +/* struct aa_rlimit - rlimit settings for the profile
4205 + * @mask: which hard limits to set
4206 + * @limits: rlimit values that override task limits
4207 + *
4208 + * AppArmor rlimits are used to set confined task rlimits.  Only the
4209 + * limits specified in @mask will be controlled by apparmor.
4210 + */
4211 +struct aa_rlimit {
4212 +       unsigned int mask;
4213 +       struct rlimit limits[RLIM_NLIMITS];
4214 +};
4215 +
4216 +int aa_map_resource(int resource);
4217 +int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
4218 +                     struct rlimit *new_rlim);
4219 +
4220 +void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new);
4221 +
4222 +static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
4223 +{
4224 +       /* NOP */
4225 +}
4226 +
4227 +#endif /* __AA_RESOURCE_H */
4228 diff --git a/security/apparmor/include/sid.h b/security/apparmor/include/sid.h
4229 new file mode 100644
4230 index 0000000..020db35
4231 --- /dev/null
4232 +++ b/security/apparmor/include/sid.h
4233 @@ -0,0 +1,24 @@
4234 +/*
4235 + * AppArmor security module
4236 + *
4237 + * This file contains AppArmor security identifier (sid) definitions
4238 + *
4239 + * Copyright 2009-2010 Canonical Ltd.
4240 + *
4241 + * This program is free software; you can redistribute it and/or
4242 + * modify it under the terms of the GNU General Public License as
4243 + * published by the Free Software Foundation, version 2 of the
4244 + * License.
4245 + */
4246 +
4247 +#ifndef __AA_SID_H
4248 +#define __AA_SID_H
4249 +
4250 +#include <linux/types.h>
4251 +
4252 +struct aa_profile;
4253 +
4254 +u32 aa_alloc_sid(void);
4255 +void aa_free_sid(u32 sid);
4256 +
4257 +#endif /* __AA_SID_H */
4258 diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
4259 new file mode 100644
4260 index 0000000..9013a78
4261 --- /dev/null
4262 +++ b/security/apparmor/ipc.c
4263 @@ -0,0 +1,114 @@
4264 +/*
4265 + * AppArmor security module
4266 + *
4267 + * This file contains AppArmor ipc mediation
4268 + *
4269 + * Copyright (C) 1998-2008 Novell/SUSE
4270 + * Copyright 2009-2010 Canonical Ltd.
4271 + *
4272 + * This program is free software; you can redistribute it and/or
4273 + * modify it under the terms of the GNU General Public License as
4274 + * published by the Free Software Foundation, version 2 of the
4275 + * License.
4276 + */
4277 +
4278 +#include <linux/gfp.h>
4279 +#include <linux/ptrace.h>
4280 +
4281 +#include "include/audit.h"
4282 +#include "include/capability.h"
4283 +#include "include/context.h"
4284 +#include "include/policy.h"
4285 +
4286 +/* call back to audit ptrace fields */
4287 +static void audit_cb(struct audit_buffer *ab, void *va)
4288 +{
4289 +       struct common_audit_data *sa = va;
4290 +       audit_log_format(ab, " target=");
4291 +       audit_log_untrustedstring(ab, sa->aad.target);
4292 +}
4293 +
4294 +/**
4295 + * aa_audit_ptrace - do auditing for ptrace
4296 + * @profile: profile being enforced  (NOT NULL)
4297 + * @target: profile being traced (NOT NULL)
4298 + * @error: error condition
4299 + *
4300 + * Returns: %0 or error code
4301 + */
4302 +static int aa_audit_ptrace(struct aa_profile *profile,
4303 +                          struct aa_profile *target, int error)
4304 +{
4305 +       struct common_audit_data sa;
4306 +       COMMON_AUDIT_DATA_INIT(&sa, NONE);
4307 +       sa.aad.op = OP_PTRACE;
4308 +       sa.aad.target = target;
4309 +       sa.aad.error = error;
4310 +
4311 +       return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa,
4312 +                       audit_cb);
4313 +}
4314 +
4315 +/**
4316 + * aa_may_ptrace - test if tracer task can trace the tracee
4317 + * @tracer_task: task who will do the tracing  (NOT NULL)
4318 + * @tracer: profile of the task doing the tracing  (NOT NULL)
4319 + * @tracee: task to be traced
4320 + * @mode: whether PTRACE_MODE_READ || PTRACE_MODE_ATTACH
4321 + *
4322 + * Returns: %0 else error code if permission denied or error
4323 + */
4324 +int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
4325 +                 struct aa_profile *tracee, unsigned int mode)
4326 +{
4327 +       /* TODO: currently only based on capability, not extended ptrace
4328 +        *       rules,
4329 +        *       Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
4330 +        */
4331 +
4332 +       if (unconfined(tracer) || tracer == tracee)
4333 +               return 0;
4334 +       /* log this capability request */
4335 +       return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1);
4336 +}
4337 +
4338 +/**
4339 + * aa_ptrace - do ptrace permission check and auditing
4340 + * @tracer: task doing the tracing (NOT NULL)
4341 + * @tracee: task being traced (NOT NULL)
4342 + * @mode: ptrace mode either PTRACE_MODE_READ || PTRACE_MODE_ATTACH
4343 + *
4344 + * Returns: %0 else error code if permission denied or error
4345 + */
4346 +int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
4347 +             unsigned int mode)
4348 +{
4349 +       /*
4350 +        * tracer can ptrace tracee when
4351 +        * - tracer is unconfined ||
4352 +        *   - tracer is in complain mode
4353 +        *   - tracer has rules allowing it to trace tracee currently this is:
4354 +        *       - confined by the same profile ||
4355 +        *       - tracer profile has CAP_SYS_PTRACE
4356 +        */
4357 +
4358 +       struct aa_profile *tracer_p;
4359 +       /* cred released below */
4360 +       const struct cred *cred = get_task_cred(tracer);
4361 +       int error = 0;
4362 +       tracer_p = aa_cred_profile(cred);
4363 +
4364 +       if (!unconfined(tracer_p)) {
4365 +               /* lcred released below */
4366 +               struct cred *lcred = get_task_cred(tracee);
4367 +               struct aa_profile *tracee_p = aa_cred_profile(lcred);
4368 +
4369 +               error = aa_may_ptrace(tracer, tracer_p, tracee_p, mode);
4370 +               error = aa_audit_ptrace(tracer_p, tracee_p, error);
4371 +
4372 +               put_cred(lcred);
4373 +       }
4374 +       put_cred(cred);
4375 +
4376 +       return error;
4377 +}
4378 diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
4379 new file mode 100644
4380 index 0000000..6e85cdb
4381 --- /dev/null
4382 +++ b/security/apparmor/lib.c
4383 @@ -0,0 +1,133 @@
4384 +/*
4385 + * AppArmor security module
4386 + *
4387 + * This file contains basic common functions used in AppArmor
4388 + *
4389 + * Copyright (C) 1998-2008 Novell/SUSE
4390 + * Copyright 2009-2010 Canonical Ltd.
4391 + *
4392 + * This program is free software; you can redistribute it and/or
4393 + * modify it under the terms of the GNU General Public License as
4394 + * published by the Free Software Foundation, version 2 of the
4395 + * License.
4396 + */
4397 +
4398 +#include <linux/slab.h>
4399 +#include <linux/string.h>
4400 +#include <linux/vmalloc.h>
4401 +
4402 +#include "include/audit.h"
4403 +
4404 +
4405 +/**
4406 + * aa_split_fqname - split a fqname into a profile and namespace name
4407 + * @fqname: a full qualified name in namespace profile format (NOT NULL)
4408 + * @ns_name: pointer to portion of the string containing the ns name (NOT NULL)
4409 + *
4410 + * Returns: profile name or NULL if one is not specified
4411 + *
4412 + * Split a namespace name from a profile name (see policy.c for naming
4413 + * description).  If a portion of the name is missing it returns NULL for
4414 + * that portion.
4415 + *
4416 + * NOTE: may modify the @fqname string.  The pointers returned point
4417 + *       into the @fqname string.
4418 + */
4419 +char *aa_split_fqname(char *fqname, char **ns_name)
4420 +{
4421 +       char *name = strim(fqname);
4422 +
4423 +       *ns_name = NULL;
4424 +       if (name[0] == ':') {
4425 +               char *split = strchr(&name[1], ':');
4426 +               if (split) {
4427 +                       /* overwrite ':' with \0 */
4428 +                       *split = 0;
4429 +                       name = skip_spaces(split + 1);
4430 +               } else
4431 +                       /* a ns name without a following profile is allowed */
4432 +                       name = NULL;
4433 +               *ns_name = &name[1];
4434 +       }
4435 +       if (name && *name == 0)
4436 +               name = NULL;
4437 +
4438 +       return name;
4439 +}
4440 +
4441 +/**
4442 + * aa_info_message - log a none profile related status message
4443 + * @str: message to log
4444 + */
4445 +void aa_info_message(const char *str)
4446 +{
4447 +       if (audit_enabled) {
4448 +               struct common_audit_data sa;
4449 +               COMMON_AUDIT_DATA_INIT(&sa, NONE);
4450 +               sa.aad.info = str;
4451 +               aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
4452 +       }
4453 +       printk(KERN_INFO "AppArmor: %s\n", str);
4454 +}
4455 +
4456 +/**
4457 + * kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
4458 + * @size: size of allocation
4459 + *
4460 + * Return: allocated buffer or NULL if failed
4461 + *
4462 + * It is possible that policy being loaded from the user is larger than
4463 + * what can be allocated by kmalloc, in those cases fall back to vmalloc.
4464 + */
4465 +void *kvmalloc(size_t size)
4466 +{
4467 +       void *buffer = NULL;
4468 +
4469 +       if (size == 0)
4470 +               return NULL;
4471 +
4472 +       /* do not attempt kmalloc if we need more than 16 pages at once */
4473 +       if (size <= (16*PAGE_SIZE))
4474 +               buffer = kmalloc(size, GFP_NOIO | __GFP_NOWARN);
4475 +       if (!buffer) {
4476 +               /* see kvfree for why size must be at least work_struct size
4477 +                * when allocated via vmalloc
4478 +                */
4479 +               if (size < sizeof(struct work_struct))
4480 +                       size = sizeof(struct work_struct);
4481 +               buffer = vmalloc(size);
4482 +       }
4483 +       return buffer;
4484 +}
4485 +
4486 +/**
4487 + * do_vfree - workqueue routine for freeing vmalloced memory
4488 + * @work: data to be freed
4489 + *
4490 + * The work_struct is overlaid to the data being freed, as at the point
4491 + * the work is scheduled the data is no longer valid, be its freeing
4492 + * needs to be delayed until safe.
4493 + */
4494 +static void do_vfree(struct work_struct *work)
4495 +{
4496 +       vfree(work);
4497 +}
4498 +
4499 +/**
4500 + * kvfree - free an allocation do by kvmalloc
4501 + * @buffer: buffer to free (MAYBE_NULL)
4502 + *
4503 + * Free a buffer allocated by kvmalloc
4504 + */
4505 +void kvfree(void *buffer)
4506 +{
4507 +       if (is_vmalloc_addr(buffer)) {
4508 +               /* Data is no longer valid so just use the allocated space
4509 +                * as the work_struct
4510 +                */
4511 +               struct work_struct *work = (struct work_struct *) buffer;
4512 +               INIT_WORK(work, do_vfree);
4513 +               schedule_work(work);
4514 +       } else
4515 +               kfree(buffer);
4516 +}
4517 diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
4518 new file mode 100644
4519 index 0000000..e8d0821
4520 --- /dev/null
4521 +++ b/security/apparmor/lsm.c
4522 @@ -0,0 +1,1051 @@
4523 +/*
4524 + * AppArmor security module
4525 + *
4526 + * This file contains AppArmor LSM hooks.
4527 + *
4528 + * Copyright (C) 1998-2008 Novell/SUSE
4529 + * Copyright 2009-2010 Canonical Ltd.
4530 + *
4531 + * This program is free software; you can redistribute it and/or
4532 + * modify it under the terms of the GNU General Public License as
4533 + * published by the Free Software Foundation, version 2 of the
4534 + * License.
4535 + */
4536 +
4537 +#include <linux/security.h>
4538 +#include <linux/moduleparam.h>
4539 +#include <linux/mm.h>
4540 +#include <linux/mman.h>
4541 +#include <linux/mount.h>
4542 +#include <linux/namei.h>
4543 +#include <linux/ptrace.h>
4544 +#include <linux/ctype.h>
4545 +#include <linux/sysctl.h>
4546 +#include <linux/audit.h>
4547 +#include <net/sock.h>
4548 +
4549 +#include "include/apparmor.h"
4550 +#include "include/apparmorfs.h"
4551 +#include "include/audit.h"
4552 +#include "include/capability.h"
4553 +#include "include/context.h"
4554 +#include "include/file.h"
4555 +#include "include/ipc.h"
4556 +#include "include/net.h"
4557 +#include "include/path.h"
4558 +#include "include/policy.h"
4559 +#include "include/procattr.h"
4560 +
4561 +/* Flag indicating whether initialization completed */
4562 +int apparmor_initialized __initdata;
4563 +
4564 +/*
4565 + * LSM hook functions
4566 + */
4567 +
4568 +/*
4569 + * free the associated aa_task_cxt and put its profiles
4570 + */
4571 +static void apparmor_cred_free(struct cred *cred)
4572 +{
4573 +       aa_free_task_context(cred->security);
4574 +       cred->security = NULL;
4575 +}
4576 +
4577 +/*
4578 + * allocate the apparmor part of blank credentials
4579 + */
4580 +static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)
4581 +{
4582 +       /* freed by apparmor_cred_free */
4583 +       struct aa_task_cxt *cxt = aa_alloc_task_context(gfp);
4584 +       if (!cxt)
4585 +               return -ENOMEM;
4586 +
4587 +       cred->security = cxt;
4588 +       return 0;
4589 +}
4590 +
4591 +/*
4592 + * prepare new aa_task_cxt for modification by prepare_cred block
4593 + */
4594 +static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
4595 +                                gfp_t gfp)
4596 +{
4597 +       /* freed by apparmor_cred_free */
4598 +       struct aa_task_cxt *cxt = aa_alloc_task_context(gfp);
4599 +       if (!cxt)
4600 +               return -ENOMEM;
4601 +
4602 +       aa_dup_task_context(cxt, old->security);
4603 +       new->security = cxt;
4604 +       return 0;
4605 +}
4606 +
4607 +/*
4608 + * transfer the apparmor data to a blank set of creds
4609 + */
4610 +static void apparmor_cred_transfer(struct cred *new, const struct cred *old)
4611 +{
4612 +       const struct aa_task_cxt *old_cxt = old->security;
4613 +       struct aa_task_cxt *new_cxt = new->security;
4614 +
4615 +       aa_dup_task_context(new_cxt, old_cxt);
4616 +}
4617 +
4618 +static int apparmor_ptrace_access_check(struct task_struct *child,
4619 +                                       unsigned int mode)
4620 +{
4621 +       int error = cap_ptrace_access_check(child, mode);
4622 +       if (error)
4623 +               return error;
4624 +
4625 +       return aa_ptrace(current, child, mode);
4626 +}
4627 +
4628 +static int apparmor_ptrace_traceme(struct task_struct *parent)
4629 +{
4630 +       int error = cap_ptrace_traceme(parent);
4631 +       if (error)
4632 +               return error;
4633 +
4634 +       return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
4635 +}
4636 +
4637 +/* Derived from security/commoncap.c:cap_capget */
4638 +static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
4639 +                          kernel_cap_t *inheritable, kernel_cap_t *permitted)
4640 +{
4641 +       struct aa_profile *profile;
4642 +       const struct cred *cred;
4643 +
4644 +       rcu_read_lock();
4645 +       cred = __task_cred(target);
4646 +       profile = aa_cred_profile(cred);
4647 +
4648 +       *effective = cred->cap_effective;
4649 +       *inheritable = cred->cap_inheritable;
4650 +       *permitted = cred->cap_permitted;
4651 +
4652 +       if (!unconfined(profile)) {
4653 +               *effective = cap_intersect(*effective, profile->caps.allow);
4654 +               *permitted = cap_intersect(*permitted, profile->caps.allow);
4655 +       }
4656 +       rcu_read_unlock();
4657 +
4658 +       return 0;
4659 +}
4660 +
4661 +static int apparmor_capable(struct task_struct *task, const struct cred *cred,
4662 +                           int cap, int audit)
4663 +{
4664 +       struct aa_profile *profile;
4665 +       /* cap_capable returns 0 on success, else -EPERM */
4666 +       int error = cap_capable(task, cred, cap, audit);
4667 +       if (!error) {
4668 +               profile = aa_cred_profile(cred);
4669 +               if (!unconfined(profile))
4670 +                       error = aa_capable(task, profile, cap, audit);
4671 +       }
4672 +       return error;
4673 +}
4674 +
4675 +/**
4676 + * common_perm - basic common permission check wrapper fn for paths
4677 + * @op: operation being checked
4678 + * @path: path to check permission of  (NOT NULL)
4679 + * @mask: requested permissions mask
4680 + * @cond: conditional info for the permission request  (NOT NULL)
4681 + *
4682 + * Returns: %0 else error code if error or permission denied
4683 + */
4684 +static int common_perm(int op, struct path *path, u32 mask,
4685 +                      struct path_cond *cond)
4686 +{
4687 +       struct aa_profile *profile;
4688 +       int error = 0;
4689 +
4690 +       profile = __aa_current_profile();
4691 +       if (!unconfined(profile))
4692 +               error = aa_path_perm(op, profile, path, 0, mask, cond);
4693 +
4694 +       return error;
4695 +}
4696 +
4697 +/**
4698 + * common_perm_dir_dentry - common permission wrapper when path is dir, dentry
4699 + * @op: operation being checked
4700 + * @dir: directory of the dentry  (NOT NULL)
4701 + * @dentry: dentry to check  (NOT NULL)
4702 + * @mask: requested permissions mask
4703 + * @cond: conditional info for the permission request  (NOT NULL)
4704 + *
4705 + * Returns: %0 else error code if error or permission denied
4706 + */
4707 +static int common_perm_dir_dentry(int op, struct path *dir,
4708 +                                 struct dentry *dentry, u32 mask,
4709 +                                 struct path_cond *cond)
4710 +{
4711 +       struct path path = { dir->mnt, dentry };
4712 +
4713 +       return common_perm(op, &path, mask, cond);
4714 +}
4715 +
4716 +/**
4717 + * common_perm_mnt_dentry - common permission wrapper when mnt, dentry
4718 + * @op: operation being checked
4719 + * @mnt: mount point of dentry (NOT NULL)
4720 + * @dentry: dentry to check  (NOT NULL)
4721 + * @mask: requested permissions mask
4722 + *
4723 + * Returns: %0 else error code if error or permission denied
4724 + */
4725 +static int common_perm_mnt_dentry(int op, struct vfsmount *mnt,
4726 +                                 struct dentry *dentry, u32 mask)
4727 +{
4728 +       struct path path = { mnt, dentry };
4729 +       struct path_cond cond = { dentry->d_inode->i_uid,
4730 +                                 dentry->d_inode->i_mode
4731 +       };
4732 +
4733 +       return common_perm(op, &path, mask, &cond);
4734 +}
4735 +
4736 +/**
4737 + * common_perm_rm - common permission wrapper for operations doing rm
4738 + * @op: operation being checked
4739 + * @dir: directory that the dentry is in  (NOT NULL)
4740 + * @dentry: dentry being rm'd  (NOT NULL)
4741 + * @mask: requested permission mask
4742 + *
4743 + * Returns: %0 else error code if error or permission denied
4744 + */
4745 +static int common_perm_rm(int op, struct path *dir,
4746 +                         struct dentry *dentry, u32 mask)
4747 +{
4748 +       struct inode *inode = dentry->d_inode;
4749 +       struct path_cond cond = { };
4750 +
4751 +       if (!inode || !dir->mnt || !mediated_filesystem(inode))
4752 +               return 0;
4753 +
4754 +       cond.uid = inode->i_uid;
4755 +       cond.mode = inode->i_mode;
4756 +
4757 +       return common_perm_dir_dentry(op, dir, dentry, mask, &cond);
4758 +}
4759 +
4760 +/**
4761 + * common_perm_create - common permission wrapper for operations doing create
4762 + * @op: operation being checked
4763 + * @dir: directory that dentry will be created in  (NOT NULL)
4764 + * @dentry: dentry to create   (NOT NULL)
4765 + * @mask: request permission mask
4766 + * @mode: created file mode
4767 + *
4768 + * Returns: %0 else error code if error or permission denied
4769 + */
4770 +static int common_perm_create(int op, struct path *dir, struct dentry *dentry,
4771 +                             u32 mask, umode_t mode)
4772 +{
4773 +       struct path_cond cond = { current_fsuid(), mode };
4774 +
4775 +       if (!dir->mnt || !mediated_filesystem(dir->dentry->d_inode))
4776 +               return 0;
4777 +
4778 +       return common_perm_dir_dentry(op, dir, dentry, mask, &cond);
4779 +}
4780 +
4781 +static int apparmor_path_unlink(struct path *dir, struct dentry *dentry)
4782 +{
4783 +       return common_perm_rm(OP_UNLINK, dir, dentry, AA_MAY_DELETE);
4784 +}
4785 +
4786 +static int apparmor_path_mkdir(struct path *dir, struct dentry *dentry,
4787 +                              int mode)
4788 +{
4789 +       return common_perm_create(OP_MKDIR, dir, dentry, AA_MAY_CREATE,
4790 +                                 S_IFDIR);
4791 +}
4792 +
4793 +static int apparmor_path_rmdir(struct path *dir, struct dentry *dentry)
4794 +{
4795 +       return common_perm_rm(OP_RMDIR, dir, dentry, AA_MAY_DELETE);
4796 +}
4797 +
4798 +static int apparmor_path_mknod(struct path *dir, struct dentry *dentry,
4799 +                              int mode, unsigned int dev)
4800 +{
4801 +       return common_perm_create(OP_MKNOD, dir, dentry, AA_MAY_CREATE, mode);
4802 +}
4803 +
4804 +static int apparmor_path_truncate(struct path *path, loff_t length,
4805 +                                 unsigned int time_attrs)
4806 +{
4807 +       struct path_cond cond = { path->dentry->d_inode->i_uid,
4808 +                                 path->dentry->d_inode->i_mode
4809 +       };
4810 +
4811 +       if (!path->mnt || !mediated_filesystem(path->dentry->d_inode))
4812 +               return 0;
4813 +
4814 +       return common_perm(OP_TRUNC, path, MAY_WRITE | AA_MAY_META_WRITE,
4815 +                          &cond);
4816 +}
4817 +
4818 +static int apparmor_path_symlink(struct path *dir, struct dentry *dentry,
4819 +                                const char *old_name)
4820 +{
4821 +       return common_perm_create(OP_SYMLINK, dir, dentry, AA_MAY_CREATE,
4822 +                                 S_IFLNK);
4823 +}
4824 +
4825 +static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir,
4826 +                             struct dentry *new_dentry)
4827 +{
4828 +       struct aa_profile *profile;
4829 +       int error = 0;
4830 +
4831 +       if (!mediated_filesystem(old_dentry->d_inode))
4832 +               return 0;
4833 +
4834 +       profile = aa_current_profile();
4835 +       if (!unconfined(profile))
4836 +               error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
4837 +       return error;
4838 +}
4839 +
4840 +static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
4841 +                               struct path *new_dir, struct dentry *new_dentry)
4842 +{
4843 +       struct aa_profile *profile;
4844 +       int error = 0;
4845 +
4846 +       if (!mediated_filesystem(old_dentry->d_inode))
4847 +               return 0;
4848 +
4849 +       profile = aa_current_profile();
4850 +       if (!unconfined(profile)) {
4851 +               struct path old_path = { old_dir->mnt, old_dentry };
4852 +               struct path new_path = { new_dir->mnt, new_dentry };
4853 +               struct path_cond cond = { old_dentry->d_inode->i_uid,
4854 +                                         old_dentry->d_inode->i_mode
4855 +               };
4856 +
4857 +               error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0,
4858 +                                    MAY_READ | AA_MAY_META_READ | MAY_WRITE |
4859 +                                    AA_MAY_META_WRITE | AA_MAY_DELETE,
4860 +                                    &cond);
4861 +               if (!error)
4862 +                       error = aa_path_perm(OP_RENAME_DEST, profile, &new_path,
4863 +                                            0, MAY_WRITE | AA_MAY_META_WRITE |
4864 +                                            AA_MAY_CREATE, &cond);
4865 +
4866 +       }
4867 +       return error;
4868 +}
4869 +
4870 +static int apparmor_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
4871 +                              mode_t mode)
4872 +{
4873 +       if (!mediated_filesystem(dentry->d_inode))
4874 +               return 0;
4875 +
4876 +       return common_perm_mnt_dentry(OP_CHMOD, mnt, dentry, AA_MAY_CHMOD);
4877 +}
4878 +
4879 +static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid)
4880 +{
4881 +       struct path_cond cond =  { path->dentry->d_inode->i_uid,
4882 +                                  path->dentry->d_inode->i_mode
4883 +       };
4884 +
4885 +       if (!mediated_filesystem(path->dentry->d_inode))
4886 +               return 0;
4887 +
4888 +       return common_perm(OP_CHOWN, path, AA_MAY_CHOWN, &cond);
4889 +}
4890 +
4891 +static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
4892 +{
4893 +       if (!mediated_filesystem(dentry->d_inode))
4894 +               return 0;
4895 +
4896 +       return common_perm_mnt_dentry(OP_GETATTR, mnt, dentry,
4897 +                                     AA_MAY_META_READ);
4898 +}
4899 +
4900 +static int apparmor_dentry_open(struct file *file, const struct cred *cred)
4901 +{
4902 +       struct aa_file_cxt *fcxt = file->f_security;
4903 +       struct aa_profile *profile;
4904 +       int error = 0;
4905 +
4906 +       if (!mediated_filesystem(file->f_path.dentry->d_inode))
4907 +               return 0;
4908 +
4909 +       /* If in exec, permission is handled by bprm hooks.
4910 +        * Cache permissions granted by the previous exec check, with
4911 +        * implicit read and executable mmap which are required to
4912 +        * actually execute the image.
4913 +        */
4914 +       if (current->in_execve) {
4915 +               fcxt->allow = MAY_EXEC | MAY_READ | AA_EXEC_MMAP;
4916 +               return 0;
4917 +       }
4918 +
4919 +       profile = aa_cred_profile(cred);
4920 +       if (!unconfined(profile)) {
4921 +               struct inode *inode = file->f_path.dentry->d_inode;
4922 +               struct path_cond cond = { inode->i_uid, inode->i_mode };
4923 +
4924 +               error = aa_path_perm(OP_OPEN, profile, &file->f_path, 0,
4925 +                                    aa_map_file_to_perms(file), &cond);
4926 +               /* todo cache full allowed permissions set and state */
4927 +               fcxt->allow = aa_map_file_to_perms(file);
4928 +       }
4929 +
4930 +       return error;
4931 +}
4932 +
4933 +static int apparmor_file_alloc_security(struct file *file)
4934 +{
4935 +       /* freed by apparmor_file_free_security */
4936 +       file->f_security = aa_alloc_file_context(GFP_KERNEL);
4937 +       if (!file->f_security)
4938 +               return -ENOMEM;
4939 +       return 0;
4940 +
4941 +}
4942 +
4943 +static void apparmor_file_free_security(struct file *file)
4944 +{
4945 +       struct aa_file_cxt *cxt = file->f_security;
4946 +
4947 +       aa_free_file_context(cxt);
4948 +}
4949 +
4950 +static int common_file_perm(int op, struct file *file, u32 mask)
4951 +{
4952 +       struct aa_file_cxt *fcxt = file->f_security;
4953 +       struct aa_profile *profile, *fprofile = aa_cred_profile(file->f_cred);
4954 +       int error = 0;
4955 +
4956 +       BUG_ON(!fprofile);
4957 +
4958 +       if (!file->f_path.mnt ||
4959 +           !mediated_filesystem(file->f_path.dentry->d_inode))
4960 +               return 0;
4961 +
4962 +       profile = __aa_current_profile();
4963 +
4964 +       /* revalidate access, if task is unconfined, or the cached cred
4965 +        * doesn't match or if the request is for more permissions than
4966 +        * was granted.
4967 +        *
4968 +        * Note: the test for !unconfined(fprofile) is to handle file
4969 +        *       delegation from unconfined tasks
4970 +        */
4971 +       if (!unconfined(profile) && !unconfined(fprofile) &&
4972 +           ((fprofile != profile) || (mask & ~fcxt->allow)))
4973 +               error = aa_file_perm(op, profile, file, mask);
4974 +
4975 +       return error;
4976 +}
4977 +
4978 +static int apparmor_file_permission(struct file *file, int mask)
4979 +{
4980 +       return common_file_perm(OP_FPERM, file, mask);
4981 +}
4982 +
4983 +static int apparmor_file_lock(struct file *file, unsigned int cmd)
4984 +{
4985 +       u32 mask = AA_MAY_LOCK;
4986 +
4987 +       if (cmd == F_WRLCK)
4988 +               mask |= MAY_WRITE;
4989 +
4990 +       return common_file_perm(OP_FLOCK, file, mask);
4991 +}
4992 +
4993 +static int common_mmap(int op, struct file *file, unsigned long prot,
4994 +                      unsigned long flags)
4995 +{
4996 +       struct dentry *dentry;
4997 +       int mask = 0;
4998 +
4999 +       if (!file || !file->f_security)
5000 +               return 0;
5001 +
5002 +       if (prot & PROT_READ)
5003 +               mask |= MAY_READ;
5004 +       /*
5005 +        * Private mappings don't require write perms since they don't
5006 +        * write back to the files
5007 +        */
5008 +       if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
5009 +               mask |= MAY_WRITE;
5010 +       if (prot & PROT_EXEC)
5011 +               mask |= AA_EXEC_MMAP;
5012 +
5013 +       dentry = file->f_path.dentry;
5014 +       return common_file_perm(op, file, mask);
5015 +}
5016 +
5017 +static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
5018 +                             unsigned long prot, unsigned long flags,
5019 +                             unsigned long addr, unsigned long addr_only)
5020 +{
5021 +       int rc = 0;
5022 +
5023 +       /* do DAC check */
5024 +       rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
5025 +       if (rc || addr_only)
5026 +               return rc;
5027 +
5028 +       return common_mmap(OP_FMMAP, file, prot, flags);
5029 +}
5030 +
5031 +static int apparmor_file_mprotect(struct vm_area_struct *vma,
5032 +                                 unsigned long reqprot, unsigned long prot)
5033 +{
5034 +       return common_mmap(OP_FMPROT, vma->vm_file, prot,
5035 +                          !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
5036 +}
5037 +
5038 +static int apparmor_getprocattr(struct task_struct *task, char *name,
5039 +                               char **value)
5040 +{
5041 +       int error = -ENOENT;
5042 +       struct aa_profile *profile;
5043 +       /* released below */
5044 +       const struct cred *cred = get_task_cred(task);
5045 +       struct aa_task_cxt *cxt = cred->security;
5046 +       profile = aa_cred_profile(cred);
5047 +
5048 +       if (strcmp(name, "current") == 0)
5049 +               error = aa_getprocattr(aa_newest_version(cxt->profile),
5050 +                                      value);
5051 +       else if (strcmp(name, "prev") == 0  && cxt->previous)
5052 +               error = aa_getprocattr(aa_newest_version(cxt->previous),
5053 +                                      value);
5054 +       else if (strcmp(name, "exec") == 0 && cxt->onexec)
5055 +               error = aa_getprocattr(aa_newest_version(cxt->onexec),
5056 +                                      value);
5057 +       else
5058 +               error = -EINVAL;
5059 +
5060 +       put_cred(cred);
5061 +
5062 +       return error;
5063 +}
5064 +
5065 +static int apparmor_setprocattr(struct task_struct *task, char *name,
5066 +                               void *value, size_t size)
5067 +{
5068 +       char *command, *args = value;
5069 +       size_t arg_size;
5070 +       int error;
5071 +
5072 +       if (size == 0)
5073 +               return -EINVAL;
5074 +       /* args points to a PAGE_SIZE buffer, AppArmor requires that
5075 +        * the buffer must be null terminated or have size <= PAGE_SIZE -1
5076 +        * so that AppArmor can null terminate them
5077 +        */
5078 +       if (args[size - 1] != '\0') {
5079 +               if (size == PAGE_SIZE)
5080 +                       return -EINVAL;
5081 +               args[size] = '\0';
5082 +       }
5083 +
5084 +       /* task can only write its own attributes */
5085 +       if (current != task)
5086 +               return -EACCES;
5087 +
5088 +       args = value;
5089 +       args = strim(args);
5090 +       command = strsep(&args, " ");
5091 +       if (!args)
5092 +               return -EINVAL;
5093 +       args = skip_spaces(args);
5094 +       if (!*args)
5095 +               return -EINVAL;
5096 +
5097 +       arg_size = size - (args - (char *) value);
5098 +       if (strcmp(name, "current") == 0) {
5099 +               if (strcmp(command, "changehat") == 0) {
5100 +                       error = aa_setprocattr_changehat(args, arg_size,
5101 +                                                        !AA_DO_TEST);
5102 +               } else if (strcmp(command, "permhat") == 0) {
5103 +                       error = aa_setprocattr_changehat(args, arg_size,
5104 +                                                        AA_DO_TEST);
5105 +               } else if (strcmp(command, "changeprofile") == 0) {
5106 +                       error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
5107 +                                                            !AA_DO_TEST);
5108 +               } else if (strcmp(command, "permprofile") == 0) {
5109 +                       error = aa_setprocattr_changeprofile(args, !AA_ONEXEC,
5110 +                                                            AA_DO_TEST);
5111 +               } else if (strcmp(command, "permipc") == 0) {
5112 +                       error = aa_setprocattr_permipc(args);
5113 +               } else {
5114 +                       struct common_audit_data sa;
5115 +                       COMMON_AUDIT_DATA_INIT(&sa, NONE);
5116 +                       sa.aad.op = OP_SETPROCATTR;
5117 +                       sa.aad.info = name;
5118 +                       sa.aad.error = -EINVAL;
5119 +                       return aa_audit(AUDIT_APPARMOR_DENIED, NULL, GFP_KERNEL,
5120 +                                       &sa, NULL);
5121 +               }
5122 +       } else if (strcmp(name, "exec") == 0) {
5123 +               error = aa_setprocattr_changeprofile(args, AA_ONEXEC,
5124 +                                                    !AA_DO_TEST);
5125 +       } else {
5126 +               /* only support the "current" and "exec" process attributes */
5127 +               return -EINVAL;
5128 +       }
5129 +       if (!error)
5130 +               error = size;
5131 +       return error;
5132 +}
5133 +
5134 +static int apparmor_task_setrlimit(unsigned int resource,
5135 +                                  struct rlimit *new_rlim)
5136 +{
5137 +       struct aa_profile *profile = aa_current_profile();
5138 +       int error = 0;
5139 +
5140 +       if (!unconfined(profile))
5141 +               error = aa_task_setrlimit(profile, resource, new_rlim);
5142 +
5143 +       return error;
5144 +}
5145 +
5146 +static int apparmor_socket_create(int family, int type, int protocol, int kern)
5147 +{
5148 +       struct aa_profile *profile;
5149 +       int error = 0;
5150 +
5151 +       if (kern)
5152 +               return 0;
5153 +
5154 +       profile = __aa_current_profile();
5155 +       if (!unconfined(profile))
5156 +               error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
5157 +                                   NULL);
5158 +       return error;
5159 +}
5160 +
5161 +static int apparmor_socket_bind(struct socket *sock,
5162 +                               struct sockaddr *address, int addrlen)
5163 +{
5164 +       struct sock *sk = sock->sk;
5165 +
5166 +       return aa_revalidate_sk(OP_BIND, sk);
5167 +}
5168 +
5169 +static int apparmor_socket_connect(struct socket *sock,
5170 +                                  struct sockaddr *address, int addrlen)
5171 +{
5172 +       struct sock *sk = sock->sk;
5173 +
5174 +       return aa_revalidate_sk(OP_CONNECT, sk);
5175 +}
5176 +
5177 +static int apparmor_socket_listen(struct socket *sock, int backlog)
5178 +{
5179 +       struct sock *sk = sock->sk;
5180 +
5181 +       return aa_revalidate_sk(OP_LISTEN, sk);
5182 +}
5183 +
5184 +static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
5185 +{
5186 +       struct sock *sk = sock->sk;
5187 +
5188 +       return aa_revalidate_sk(OP_ACCEPT, sk);
5189 +}
5190 +
5191 +static int apparmor_socket_sendmsg(struct socket *sock,
5192 +                                  struct msghdr *msg, int size)
5193 +{
5194 +       struct sock *sk = sock->sk;
5195 +
5196 +       return aa_revalidate_sk(OP_SENDMSG, sk);
5197 +}
5198 +
5199 +static int apparmor_socket_recvmsg(struct socket *sock,
5200 +                                  struct msghdr *msg, int size, int flags)
5201 +{
5202 +       struct sock *sk = sock->sk;
5203 +
5204 +       return aa_revalidate_sk(OP_RECVMSG, sk);
5205 +}
5206 +
5207 +static int apparmor_socket_getsockname(struct socket *sock)
5208 +{
5209 +       struct sock *sk = sock->sk;
5210 +
5211 +       return aa_revalidate_sk(OP_GETSOCKNAME, sk);
5212 +}
5213 +
5214 +static int apparmor_socket_getpeername(struct socket *sock)
5215 +{
5216 +       struct sock *sk = sock->sk;
5217 +
5218 +       return aa_revalidate_sk(OP_GETPEERNAME, sk);
5219 +}
5220 +
5221 +static int apparmor_socket_getsockopt(struct socket *sock, int level,
5222 +                                     int optname)
5223 +{
5224 +       struct sock *sk = sock->sk;
5225 +
5226 +       return aa_revalidate_sk(OP_GETSOCKOPT, sk);
5227 +}
5228 +
5229 +static int apparmor_socket_setsockopt(struct socket *sock, int level,
5230 +                                     int optname)
5231 +{
5232 +       struct sock *sk = sock->sk;
5233 +
5234 +       return aa_revalidate_sk(OP_SETSOCKOPT, sk);
5235 +}
5236 +
5237 +static int apparmor_socket_shutdown(struct socket *sock, int how)
5238 +{
5239 +       struct sock *sk = sock->sk;
5240 +
5241 +       return aa_revalidate_sk(OP_SOCK_SHUTDOWN, sk);
5242 +}
5243 +
5244 +static struct security_operations apparmor_ops = {
5245 +       .name =                         "apparmor",
5246 +
5247 +       .ptrace_access_check =          apparmor_ptrace_access_check,
5248 +       .ptrace_traceme =               apparmor_ptrace_traceme,
5249 +       .capget =                       apparmor_capget,
5250 +       .capable =                      apparmor_capable,
5251 +
5252 +       .path_link =                    apparmor_path_link,
5253 +       .path_unlink =                  apparmor_path_unlink,
5254 +       .path_symlink =                 apparmor_path_symlink,
5255 +       .path_mkdir =                   apparmor_path_mkdir,
5256 +       .path_rmdir =                   apparmor_path_rmdir,
5257 +       .path_mknod =                   apparmor_path_mknod,
5258 +       .path_rename =                  apparmor_path_rename,
5259 +       .path_chmod =                   apparmor_path_chmod,
5260 +       .path_chown =                   apparmor_path_chown,
5261 +       .path_truncate =                apparmor_path_truncate,
5262 +       .dentry_open =                  apparmor_dentry_open,
5263 +       .inode_getattr =                apparmor_inode_getattr,
5264 +
5265 +       .file_permission =              apparmor_file_permission,
5266 +       .file_alloc_security =          apparmor_file_alloc_security,
5267 +       .file_free_security =           apparmor_file_free_security,
5268 +       .file_mmap =                    apparmor_file_mmap,
5269 +       .file_mprotect =                apparmor_file_mprotect,
5270 +       .file_lock =                    apparmor_file_lock,
5271 +
5272 +       .getprocattr =                  apparmor_getprocattr,
5273 +       .setprocattr =                  apparmor_setprocattr,
5274 +
5275 +       .socket_create =                apparmor_socket_create,
5276 +       .socket_bind =                  apparmor_socket_bind,
5277 +       .socket_connect =               apparmor_socket_connect,
5278 +       .socket_listen =                apparmor_socket_listen,
5279 +       .socket_accept =                apparmor_socket_accept,
5280 +       .socket_sendmsg =               apparmor_socket_sendmsg,
5281 +       .socket_recvmsg =               apparmor_socket_recvmsg,
5282 +       .socket_getsockname =           apparmor_socket_getsockname,
5283 +       .socket_getpeername =           apparmor_socket_getpeername,
5284 +       .socket_getsockopt =            apparmor_socket_getsockopt,
5285 +       .socket_setsockopt =            apparmor_socket_setsockopt,
5286 +       .socket_shutdown =              apparmor_socket_shutdown,
5287 +
5288 +       .cred_alloc_blank =             apparmor_cred_alloc_blank,
5289 +       .cred_free =                    apparmor_cred_free,
5290 +       .cred_prepare =                 apparmor_cred_prepare,
5291 +       .cred_transfer =                apparmor_cred_transfer,
5292 +
5293 +       .bprm_set_creds =               apparmor_bprm_set_creds,
5294 +       .bprm_committing_creds =        apparmor_bprm_committing_creds,
5295 +       .bprm_committed_creds =         apparmor_bprm_committed_creds,
5296 +       .bprm_secureexec =              apparmor_bprm_secureexec,
5297 +
5298 +       .task_setrlimit =               apparmor_task_setrlimit,
5299 +};
5300 +
5301 +/*
5302 + * AppArmor sysfs module parameters
5303 + */
5304 +
5305 +static int param_set_aabool(const char *val, struct kernel_param *kp);
5306 +static int param_get_aabool(char *buffer, struct kernel_param *kp);
5307 +#define param_check_aabool(name, p) __param_check(name, p, int)
5308 +
5309 +static int param_set_aauint(const char *val, struct kernel_param *kp);
5310 +static int param_get_aauint(char *buffer, struct kernel_param *kp);
5311 +#define param_check_aauint(name, p) __param_check(name, p, int)
5312 +
5313 +static int param_set_aalockpolicy(const char *val, struct kernel_param *kp);
5314 +static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp);
5315 +#define param_check_aalockpolicy(name, p) __param_check(name, p, int)
5316 +
5317 +static int param_set_audit(const char *val, struct kernel_param *kp);
5318 +static int param_get_audit(char *buffer, struct kernel_param *kp);
5319 +#define param_check_audit(name, p) __param_check(name, p, int)
5320 +
5321 +static int param_set_mode(const char *val, struct kernel_param *kp);
5322 +static int param_get_mode(char *buffer, struct kernel_param *kp);
5323 +#define param_check_mode(name, p) __param_check(name, p, int)
5324 +
5325 +/* Flag values, also controllable via /sys/module/apparmor/parameters
5326 + * We define special types as we want to do additional mediation.
5327 + */
5328 +
5329 +/* AppArmor global enforcement switch - complain, enforce, kill */
5330 +enum profile_mode aa_g_profile_mode = APPARMOR_ENFORCE;
5331 +module_param_call(mode, param_set_mode, param_get_mode,
5332 +                 &aa_g_profile_mode, S_IRUSR | S_IWUSR);
5333 +
5334 +/* Debug mode */
5335 +int aa_g_debug;
5336 +module_param_named(debug, aa_g_debug, aabool, S_IRUSR | S_IWUSR);
5337 +
5338 +/* Audit mode */
5339 +enum audit_mode aa_g_audit;
5340 +module_param_call(audit, param_set_audit, param_get_audit,
5341 +                 &aa_g_audit, S_IRUSR | S_IWUSR);
5342 +
5343 +/* Determines if audit header is included in audited messages.  This
5344 + * provides more context if the audit daemon is not running
5345 + */
5346 +int aa_g_audit_header = 1;
5347 +module_param_named(audit_header, aa_g_audit_header, aabool,
5348 +                  S_IRUSR | S_IWUSR);
5349 +
5350 +/* lock out loading/removal of policy
5351 + * TODO: add in at boot loading of policy, which is the only way to
5352 + *       load policy, if lock_policy is set
5353 + */
5354 +int aa_g_lock_policy;
5355 +module_param_named(lock_policy, aa_g_lock_policy, aalockpolicy,
5356 +                  S_IRUSR | S_IWUSR);
5357 +
5358 +/* Syscall logging mode */
5359 +int aa_g_logsyscall;
5360 +module_param_named(logsyscall, aa_g_logsyscall, aabool, S_IRUSR | S_IWUSR);
5361 +
5362 +/* Maximum pathname length before accesses will start getting rejected */
5363 +unsigned int aa_g_path_max = 2 * PATH_MAX;
5364 +module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR | S_IWUSR);
5365 +
5366 +/* Determines how paranoid loading of policy is and how much verification
5367 + * on the loaded policy is done.
5368 + */
5369 +int aa_g_paranoid_load = 1;
5370 +module_param_named(paranoid_load, aa_g_paranoid_load, aabool,
5371 +                  S_IRUSR | S_IWUSR);
5372 +
5373 +/* Boot time disable flag */
5374 +static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
5375 +module_param_named(enabled, apparmor_enabled, aabool, S_IRUSR);
5376 +
5377 +static int __init apparmor_enabled_setup(char *str)
5378 +{
5379 +       unsigned long enabled;
5380 +       int error = strict_strtoul(str, 0, &enabled);
5381 +       if (!error)
5382 +               apparmor_enabled = enabled ? 1 : 0;
5383 +       return 1;
5384 +}
5385 +
5386 +__setup("apparmor=", apparmor_enabled_setup);
5387 +
5388 +/* set global flag turning off the ability to load policy */
5389 +static int param_set_aalockpolicy(const char *val, struct kernel_param *kp)
5390 +{
5391 +       if (!capable(CAP_MAC_ADMIN))
5392 +               return -EPERM;
5393 +       if (aa_g_lock_policy)
5394 +               return -EACCES;
5395 +       return param_set_bool(val, kp);
5396 +}
5397 +
5398 +static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp)
5399 +{
5400 +       if (!capable(CAP_MAC_ADMIN))
5401 +               return -EPERM;
5402 +       return param_get_bool(buffer, kp);
5403 +}
5404 +
5405 +static int param_set_aabool(const char *val, struct kernel_param *kp)
5406 +{
5407 +       if (!capable(CAP_MAC_ADMIN))
5408 +               return -EPERM;
5409 +       return param_set_bool(val, kp);
5410 +}
5411 +
5412 +static int param_get_aabool(char *buffer, struct kernel_param *kp)
5413 +{
5414 +       if (!capable(CAP_MAC_ADMIN))
5415 +               return -EPERM;
5416 +       return param_get_bool(buffer, kp);
5417 +}
5418 +
5419 +static int param_set_aauint(const char *val, struct kernel_param *kp)
5420 +{
5421 +       if (!capable(CAP_MAC_ADMIN))
5422 +               return -EPERM;
5423 +       return param_set_uint(val, kp);
5424 +}
5425 +
5426 +static int param_get_aauint(char *buffer, struct kernel_param *kp)
5427 +{
5428 +       if (!capable(CAP_MAC_ADMIN))
5429 +               return -EPERM;
5430 +       return param_get_uint(buffer, kp);
5431 +}
5432 +
5433 +static int param_get_audit(char *buffer, struct kernel_param *kp)
5434 +{
5435 +       if (!capable(CAP_MAC_ADMIN))
5436 +               return -EPERM;
5437 +
5438 +       if (!apparmor_enabled)
5439 +               return -EINVAL;
5440 +
5441 +       return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]);
5442 +}
5443 +
5444 +static int param_set_audit(const char *val, struct kernel_param *kp)
5445 +{
5446 +       int i;
5447 +       if (!capable(CAP_MAC_ADMIN))
5448 +               return -EPERM;
5449 +
5450 +       if (!apparmor_enabled)
5451 +               return -EINVAL;
5452 +
5453 +       if (!val)
5454 +               return -EINVAL;
5455 +
5456 +       for (i = 0; i < AUDIT_MAX_INDEX; i++) {
5457 +               if (strcmp(val, audit_mode_names[i]) == 0) {
5458 +                       aa_g_audit = i;
5459 +                       return 0;
5460 +               }
5461 +       }
5462 +
5463 +       return -EINVAL;
5464 +}
5465 +
5466 +static int param_get_mode(char *buffer, struct kernel_param *kp)
5467 +{
5468 +       if (!capable(CAP_MAC_ADMIN))
5469 +               return -EPERM;
5470 +
5471 +       if (!apparmor_enabled)
5472 +               return -EINVAL;
5473 +
5474 +       return sprintf(buffer, "%s", profile_mode_names[aa_g_profile_mode]);
5475 +}
5476 +
5477 +static int param_set_mode(const char *val, struct kernel_param *kp)
5478 +{
5479 +       int i;
5480 +       if (!capable(CAP_MAC_ADMIN))
5481 +               return -EPERM;
5482 +
5483 +       if (!apparmor_enabled)
5484 +               return -EINVAL;
5485 +
5486 +       if (!val)
5487 +               return -EINVAL;
5488 +
5489 +       for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) {
5490 +               if (strcmp(val, profile_mode_names[i]) == 0) {
5491 +                       aa_g_profile_mode = i;
5492 +                       return 0;
5493 +               }
5494 +       }
5495 +
5496 +       return -EINVAL;
5497 +}
5498 +
5499 +/*
5500 + * AppArmor init functions
5501 + */
5502 +
5503 +/**
5504 + * set_init_cxt - set a task context and profile on the first task.
5505 + *
5506 + * TODO: allow setting an alternate profile than unconfined
5507 + */
5508 +static int __init set_init_cxt(void)
5509 +{
5510 +       struct cred *cred = (struct cred *)current->real_cred;
5511 +       struct aa_task_cxt *cxt;
5512 +
5513 +       cxt = aa_alloc_task_context(GFP_KERNEL);
5514 +       if (!cxt)
5515 +               return -ENOMEM;
5516 +
5517 +       cxt->profile = aa_get_profile(root_ns->unconfined);
5518 +       cred->security = cxt;
5519 +
5520 +       return 0;
5521 +}
5522 +
5523 +static int __init apparmor_init(void)
5524 +{
5525 +       int error;
5526 +
5527 +       if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
5528 +               aa_info_message("AppArmor disabled by boot time parameter");
5529 +               apparmor_enabled = 0;
5530 +               return 0;
5531 +       }
5532 +
5533 +       error = aa_alloc_root_ns();
5534 +       if (error) {
5535 +               AA_ERROR("Unable to allocate default profile namespace\n");
5536 +               goto alloc_out;
5537 +       }
5538 +
5539 +       error = set_init_cxt();
5540 +       if (error) {
5541 +               AA_ERROR("Failed to set context on init task\n");
5542 +               goto register_security_out;
5543 +       }
5544 +
5545 +       error = register_security(&apparmor_ops);
5546 +       if (error) {
5547 +               AA_ERROR("Unable to register AppArmor\n");
5548 +               goto register_security_out;
5549 +       }
5550 +
5551 +       /* Report that AppArmor successfully initialized */
5552 +       apparmor_initialized = 1;
5553 +       if (aa_g_profile_mode == APPARMOR_COMPLAIN)
5554 +               aa_info_message("AppArmor initialized: complain mode enabled");
5555 +       else if (aa_g_profile_mode == APPARMOR_KILL)
5556 +               aa_info_message("AppArmor initialized: kill mode enabled");
5557 +       else
5558 +               aa_info_message("AppArmor initialized");
5559 +
5560 +       return error;
5561 +
5562 +register_security_out:
5563 +       aa_free_root_ns();
5564 +
5565 +alloc_out:
5566 +       aa_destroy_aafs();
5567 +
5568 +       apparmor_enabled = 0;
5569 +       return error;
5570 +
5571 +}
5572 +
5573 +security_initcall(apparmor_init);
5574 diff --git a/security/apparmor/match.c b/security/apparmor/match.c
5575 new file mode 100644
5576 index 0000000..0248bb3
5577 --- /dev/null
5578 +++ b/security/apparmor/match.c
5579 @@ -0,0 +1,370 @@
5580 +/*
5581 + * AppArmor security module
5582 + *
5583 + * This file contains AppArmor dfa based regular expression matching engine
5584 + *
5585 + * Copyright (C) 1998-2008 Novell/SUSE
5586 + * Copyright 2009-2010 Canonical Ltd.
5587 + *
5588 + * This program is free software; you can redistribute it and/or
5589 + * modify it under the terms of the GNU General Public License as
5590 + * published by the Free Software Foundation, version 2 of the
5591 + * License.
5592 + */
5593 +
5594 +#include <linux/errno.h>
5595 +#include <linux/kernel.h>
5596 +#include <linux/mm.h>
5597 +#include <linux/slab.h>
5598 +#include <linux/vmalloc.h>
5599 +#include <linux/err.h>
5600 +#include <linux/kref.h>
5601 +
5602 +#include "include/apparmor.h"
5603 +#include "include/match.h"
5604 +
5605 +/**
5606 + * unpack_table - unpack a dfa table (one of accept, default, base, next check)
5607 + * @blob: data to unpack (NOT NULL)
5608 + * @bsize: size of blob
5609 + *
5610 + * Returns: pointer to table else NULL on failure
5611 + *
5612 + * NOTE: must be freed by kvfree (not kmalloc)
5613 + */
5614 +static struct table_header *unpack_table(char *blob, size_t bsize)
5615 +{
5616 +       struct table_header *table = NULL;
5617 +       struct table_header th;
5618 +       size_t tsize;
5619 +
5620 +       if (bsize < sizeof(struct table_header))
5621 +               goto out;
5622 +
5623 +       /* loaded td_id's start at 1, subtract 1 now to avoid doing
5624 +        * it every time we use td_id as an index
5625 +        */
5626 +       th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1;
5627 +       th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
5628 +       th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
5629 +       blob += sizeof(struct table_header);
5630 +
5631 +       if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
5632 +             th.td_flags == YYTD_DATA8))
5633 +               goto out;
5634 +
5635 +       tsize = table_size(th.td_lolen, th.td_flags);
5636 +       if (bsize < tsize)
5637 +               goto out;
5638 +
5639 +       /* Pad table allocation for next/check by 256 entries to remain
5640 +        * backwards compatible with old (buggy) tools and remain safe without
5641 +        * run time checks
5642 +        */
5643 +       if (th.td_id == YYTD_ID_NXT || th.td_id == YYTD_ID_CHK)
5644 +               tsize += 256 * th.td_flags;
5645 +
5646 +       table = kvmalloc(tsize);
5647 +       if (table) {
5648 +               /* ensure the pad is clear, else there will be errors */
5649 +               memset(table, 0, tsize);
5650 +               *table = th;
5651 +               if (th.td_flags == YYTD_DATA8)
5652 +                       UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
5653 +                                    u8, byte_to_byte);
5654 +               else if (th.td_flags == YYTD_DATA16)
5655 +                       UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
5656 +                                    u16, be16_to_cpu);
5657 +               else if (th.td_flags == YYTD_DATA32)
5658 +                       UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
5659 +                                    u32, be32_to_cpu);
5660 +               else
5661 +                       goto fail;
5662 +       }
5663 +
5664 +out:
5665 +       /* if table was vmalloced make sure the page tables are synced
5666 +        * before it is used, as it goes live to all cpus.
5667 +        */
5668 +       if (is_vmalloc_addr(table))
5669 +               vm_unmap_aliases();
5670 +       return table;
5671 +fail:
5672 +       kvfree(table);
5673 +       return NULL;
5674 +}
5675 +
5676 +/**
5677 + * verify_dfa - verify that transitions and states in the tables are in bounds.
5678 + * @dfa: dfa to test  (NOT NULL)
5679 + * @flags: flags controlling what type of accept table are acceptable
5680 + *
5681 + * Assumes dfa has gone through the first pass verification done by unpacking
5682 + * NOTE: this does not valid accept table values
5683 + *
5684 + * Returns: %0 else error code on failure to verify
5685 + */
5686 +static int verify_dfa(struct aa_dfa *dfa, int flags)
5687 +{
5688 +       size_t i, state_count, trans_count;
5689 +       int error = -EPROTO;
5690 +
5691 +       /* check that required tables exist */
5692 +       if (!(dfa->tables[YYTD_ID_DEF] &&
5693 +             dfa->tables[YYTD_ID_BASE] &&
5694 +             dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK]))
5695 +               goto out;
5696 +
5697 +       /* accept.size == default.size == base.size */
5698 +       state_count = dfa->tables[YYTD_ID_BASE]->td_lolen;
5699 +       if (ACCEPT1_FLAGS(flags)) {
5700 +               if (!dfa->tables[YYTD_ID_ACCEPT])
5701 +                       goto out;
5702 +               if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen)
5703 +                       goto out;
5704 +       }
5705 +       if (ACCEPT2_FLAGS(flags)) {
5706 +               if (!dfa->tables[YYTD_ID_ACCEPT2])
5707 +                       goto out;
5708 +               if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen)
5709 +                       goto out;
5710 +       }
5711 +       if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen)
5712 +               goto out;
5713 +
5714 +       /* next.size == chk.size */
5715 +       trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen;
5716 +       if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen)
5717 +               goto out;
5718 +
5719 +       /* if equivalence classes then its table size must be 256 */
5720 +       if (dfa->tables[YYTD_ID_EC] &&
5721 +           dfa->tables[YYTD_ID_EC]->td_lolen != 256)
5722 +               goto out;
5723 +
5724 +       if (flags & DFA_FLAG_VERIFY_STATES) {
5725 +               int warning = 0;
5726 +               for (i = 0; i < state_count; i++) {
5727 +                       if (DEFAULT_TABLE(dfa)[i] >= state_count)
5728 +                               goto out;
5729 +                       /* TODO: do check that DEF state recursion terminates */
5730 +                       if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
5731 +                               if (warning)
5732 +                                       continue;
5733 +                               printk(KERN_WARNING "AppArmor DFA next/check "
5734 +                                      "upper bounds error fixed, upgrade "
5735 +                                      "user space tools \n");
5736 +                               warning = 1;
5737 +                       } else if (BASE_TABLE(dfa)[i] >= trans_count) {
5738 +                               printk(KERN_ERR "AppArmor DFA next/check upper "
5739 +                                      "bounds error\n");
5740 +                               goto out;
5741 +                       }
5742 +               }
5743 +
5744 +               for (i = 0; i < trans_count; i++) {
5745 +                       if (NEXT_TABLE(dfa)[i] >= state_count)
5746 +                               goto out;
5747 +                       if (CHECK_TABLE(dfa)[i] >= state_count)
5748 +                               goto out;
5749 +               }
5750 +       }
5751 +
5752 +       error = 0;
5753 +out:
5754 +       return error;
5755 +}
5756 +
5757 +/**
5758 + * dfa_free - free a dfa allocated by aa_dfa_unpack
5759 + * @dfa: the dfa to free  (MAYBE NULL)
5760 + *
5761 + * Requires: reference count to dfa == 0
5762 + */
5763 +static void dfa_free(struct aa_dfa *dfa)
5764 +{
5765 +       if (dfa) {
5766 +               int i;
5767 +
5768 +               for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
5769 +                       kvfree(dfa->tables[i]);
5770 +                       dfa->tables[i] = NULL;
5771 +               }
5772 +               kfree(dfa);
5773 +       }
5774 +}
5775 +
5776 +/**
5777 + * aa_dfa_free_kref - free aa_dfa by kref (called by aa_put_dfa)
5778 + * @kr: kref callback for freeing of a dfa  (NOT NULL)
5779 + */
5780 +void aa_dfa_free_kref(struct kref *kref)
5781 +{
5782 +       struct aa_dfa *dfa = container_of(kref, struct aa_dfa, count);
5783 +       dfa_free(dfa);
5784 +}
5785 +
5786 +/**
5787 + * aa_dfa_unpack - unpack the binary tables of a serialized dfa
5788 + * @blob: aligned serialized stream of data to unpack  (NOT NULL)
5789 + * @size: size of data to unpack
5790 + * @flags: flags controlling what type of accept tables are acceptable
5791 + *
5792 + * Unpack a dfa that has been serialized.  To find information on the dfa
5793 + * format look in Documentation/apparmor.txt
5794 + * Assumes the dfa @blob stream has been aligned on a 8 byte boundry
5795 + *
5796 + * Returns: an unpacked dfa ready for matching or ERR_PTR on failure
5797 + */
5798 +struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
5799 +{
5800 +       int hsize;
5801 +       int error = -ENOMEM;
5802 +       char *data = blob;
5803 +       struct table_header *table = NULL;
5804 +       struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
5805 +       if (!dfa)
5806 +               goto fail;
5807 +
5808 +       kref_init(&dfa->count);
5809 +
5810 +       error = -EPROTO;
5811 +
5812 +       /* get dfa table set header */
5813 +       if (size < sizeof(struct table_set_header))
5814 +               goto fail;
5815 +
5816 +       if (ntohl(*(u32 *) data) != YYTH_MAGIC)
5817 +               goto fail;
5818 +
5819 +       hsize = ntohl(*(u32 *) (data + 4));
5820 +       if (size < hsize)
5821 +               goto fail;
5822 +
5823 +       dfa->flags = ntohs(*(u16 *) (data + 12));
5824 +       data += hsize;
5825 +       size -= hsize;
5826 +
5827 +       while (size > 0) {
5828 +               table = unpack_table(data, size);
5829 +               if (!table)
5830 +                       goto fail;
5831 +
5832 +               switch (table->td_id) {
5833 +               case YYTD_ID_ACCEPT:
5834 +                       if (!(table->td_flags & ACCEPT1_FLAGS(flags)))
5835 +                               goto fail;
5836 +                       break;
5837 +               case YYTD_ID_ACCEPT2:
5838 +                       if (!(table->td_flags & ACCEPT2_FLAGS(flags)))
5839 +                               goto fail;
5840 +                       break;
5841 +               case YYTD_ID_BASE:
5842 +                       if (table->td_flags != YYTD_DATA32)
5843 +                               goto fail;
5844 +                       break;
5845 +               case YYTD_ID_DEF:
5846 +               case YYTD_ID_NXT:
5847 +               case YYTD_ID_CHK:
5848 +                       if (table->td_flags != YYTD_DATA16)
5849 +                               goto fail;
5850 +                       break;
5851 +               case YYTD_ID_EC:
5852 +                       if (table->td_flags != YYTD_DATA8)
5853 +                               goto fail;
5854 +                       break;
5855 +               default:
5856 +                       goto fail;
5857 +               }
5858 +               /* check for duplicate table entry */
5859 +               if (dfa->tables[table->td_id])
5860 +                       goto fail;
5861 +               dfa->tables[table->td_id] = table;
5862 +               data += table_size(table->td_lolen, table->td_flags);
5863 +               size -= table_size(table->td_lolen, table->td_flags);
5864 +               table = NULL;
5865 +       }
5866 +
5867 +       error = verify_dfa(dfa, flags);
5868 +       if (error)
5869 +               goto fail;
5870 +
5871 +       return dfa;
5872 +
5873 +fail:
5874 +       kvfree(table);
5875 +       dfa_free(dfa);
5876 +       return ERR_PTR(error);
5877 +}
5878 +
5879 +/**
5880 + * aa_dfa_match_len - traverse @dfa to find state @str stops at
5881 + * @dfa: the dfa to match @str against  (NOT NULL)
5882 + * @start: the state of the dfa to start matching in
5883 + * @str: the string of bytes to match against the dfa  (NOT NULL)
5884 + * @len: length of the string of bytes to match
5885 + *
5886 + * aa_dfa_match_len will match @str against the dfa and return the state it
5887 + * finished matching in. The final state can be used to look up the accepting
5888 + * label, or as the start state of a continuing match.
5889 + *
5890 + * This function will happily match again the 0 byte and only finishes
5891 + * when @len input is consumed.
5892 + *
5893 + * Returns: final state reached after input is consumed
5894 + */
5895 +unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
5896 +                             const char *str, int len)
5897 +{
5898 +       u16 *def = DEFAULT_TABLE(dfa);
5899 +       u32 *base = BASE_TABLE(dfa);
5900 +       u16 *next = NEXT_TABLE(dfa);
5901 +       u16 *check = CHECK_TABLE(dfa);
5902 +       unsigned int state = start, pos;
5903 +
5904 +       if (state == 0)
5905 +               return 0;
5906 +
5907 +       /* current state is <state>, matching character *str */
5908 +       if (dfa->tables[YYTD_ID_EC]) {
5909 +               /* Equivalence class table defined */
5910 +               u8 *equiv = EQUIV_TABLE(dfa);
5911 +               /* default is direct to next state */
5912 +               for (; len; len--) {
5913 +                       pos = base[state] + equiv[(u8) *str++];
5914 +                       if (check[pos] == state)
5915 +                               state = next[pos];
5916 +                       else
5917 +                               state = def[state];
5918 +               }
5919 +       } else {
5920 +               /* default is direct to next state */
5921 +               for (; len; len--) {
5922 +                       pos = base[state] + (u8) *str++;
5923 +                       if (check[pos] == state)
5924 +                               state = next[pos];
5925 +                       else
5926 +                               state = def[state];
5927 +               }
5928 +       }
5929 +
5930 +       return state;
5931 +}
5932 +
5933 +/**
5934 + * aa_dfa_next_state - traverse @dfa to find state @str stops at
5935 + * @dfa: the dfa to match @str against  (NOT NULL)
5936 + * @start: the state of the dfa to start matching in
5937 + * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
5938 + *
5939 + * aa_dfa_next_state will match @str against the dfa and return the state it
5940 + * finished matching in. The final state can be used to look up the accepting
5941 + * label, or as the start state of a continuing match.
5942 + *
5943 + * Returns: final state reached after input is consumed
5944 + */
5945 +unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
5946 +                         const char *str)
5947 +{
5948 +       return aa_dfa_match_len(dfa, start, str, strlen(str));
5949 +}
5950 diff --git a/security/apparmor/net.c b/security/apparmor/net.c
5951 new file mode 100644
5952 index 0000000..7c36e82
5953 --- /dev/null
5954 +++ b/security/apparmor/net.c
5955 @@ -0,0 +1,169 @@
5956 +/*
5957 + * AppArmor security module
5958 + *
5959 + * This file contains AppArmor network mediation
5960 + *
5961 + * Copyright (C) 1998-2008 Novell/SUSE
5962 + * Copyright 2009-2010 Canonical Ltd.
5963 + *
5964 + * This program is free software; you can redistribute it and/or
5965 + * modify it under the terms of the GNU General Public License as
5966 + * published by the Free Software Foundation, version 2 of the
5967 + * License.
5968 + */
5969 +
5970 +#include "include/apparmor.h"
5971 +#include "include/audit.h"
5972 +#include "include/context.h"
5973 +#include "include/net.h"
5974 +#include "include/policy.h"
5975 +
5976 +#include "af_names.h"
5977 +
5978 +static const char *sock_type_names[] = {
5979 +       "unknown(0)",
5980 +       "stream",
5981 +       "dgram",
5982 +       "raw",
5983 +       "rdm",
5984 +       "seqpacket",
5985 +       "dccp",
5986 +       "unknown(7)",
5987 +       "unknown(8)",
5988 +       "unknown(9)",
5989 +       "packet",
5990 +};
5991 +
5992 +/* audit callback for net specific fields */
5993 +static void audit_cb(struct audit_buffer *ab, void *va)
5994 +{
5995 +       struct common_audit_data *sa = va;
5996 +
5997 +       audit_log_format(ab, " family=");
5998 +       if (address_family_names[sa->u.net.family]) {
5999 +               audit_log_string(ab, address_family_names[sa->u.net.family]);
6000 +       } else {
6001 +               audit_log_format(ab, " \"unknown(%d)\"", sa->u.net.family);
6002 +       }
6003 +
6004 +       audit_log_format(ab, " sock_type=");
6005 +       if (sock_type_names[sa->aad.net.type]) {
6006 +               audit_log_string(ab, sock_type_names[sa->aad.net.type]);
6007 +       } else {
6008 +               audit_log_format(ab, "\"unknown(%d)\"", sa->aad.net.type);
6009 +       }
6010 +
6011 +       audit_log_format(ab, " protocol=%d", sa->aad.net.protocol);
6012 +}
6013 +
6014 +/**
6015 + * audit_net - audit network access
6016 + * @profile: profile being enforced  (NOT NULL)
6017 + * @op: operation being checked
6018 + * @family: network family
6019 + * @type:   network type
6020 + * @protocol: network protocol
6021 + * @sk: socket auditing is being applied to
6022 + * @error: error code for failure else 0
6023 + *
6024 + * Returns: %0 or sa->error else other errorcode on failure
6025 + */
6026 +static int audit_net(struct aa_profile *profile, int op, u16 family, int type,
6027 +                    int protocol, struct sock *sk, int error)
6028 +{
6029 +       int audit_type = AUDIT_APPARMOR_AUTO;
6030 +       struct common_audit_data sa;
6031 +       if (sk) {
6032 +               COMMON_AUDIT_DATA_INIT(&sa, NET);
6033 +       } else {
6034 +               COMMON_AUDIT_DATA_INIT(&sa, NONE);
6035 +       }
6036 +       /* todo fill in socket addr info */
6037 +
6038 +       sa.aad.op = op,
6039 +       sa.u.net.family = family;
6040 +       sa.u.net.sk = sk;
6041 +       sa.aad.net.type = type;
6042 +       sa.aad.net.protocol = protocol;
6043 +
6044 +       if (likely(!sa.aad.error)) {
6045 +               u16 audit_mask = profile->net.audit[sa.u.net.family];
6046 +               if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
6047 +                          !(1 << sa.aad.net.type & audit_mask)))
6048 +                       return 0;
6049 +               audit_type = AUDIT_APPARMOR_AUDIT;
6050 +       } else {
6051 +               u16 quiet_mask = profile->net.quiet[sa.u.net.family];
6052 +               u16 kill_mask = 0;
6053 +               u16 denied = (1 << sa.aad.net.type) & ~quiet_mask;
6054 +
6055 +               if (denied & kill_mask)
6056 +                       audit_type = AUDIT_APPARMOR_KILL;
6057 +
6058 +               if ((denied & quiet_mask) &&
6059 +                   AUDIT_MODE(profile) != AUDIT_NOQUIET &&
6060 +                   AUDIT_MODE(profile) != AUDIT_ALL)
6061 +                       return COMPLAIN_MODE(profile) ? 0 : sa.aad.error;
6062 +       }
6063 +
6064 +       return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb);
6065 +}
6066 +
6067 +/**
6068 + * aa_net_perm - very course network access check
6069 + * @op: operation being checked
6070 + * @profile: profile being enforced  (NOT NULL)
6071 + * @family: network family
6072 + * @type:   network type
6073 + * @protocol: network protocol
6074 + *
6075 + * Returns: %0 else error if permission denied
6076 + */
6077 +int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type,
6078 +               int protocol, struct sock *sk)
6079 +{
6080 +       u16 family_mask;
6081 +       int error;
6082 +
6083 +       if ((family < 0) || (family >= AF_MAX))
6084 +               return -EINVAL;
6085 +
6086 +       if ((type < 0) || (type >= SOCK_MAX))
6087 +               return -EINVAL;
6088 +
6089 +       /* unix domain and netlink sockets are handled by ipc */
6090 +       if (family == AF_UNIX || family == AF_NETLINK)
6091 +               return 0;
6092 +
6093 +       family_mask = profile->net.allow[family];
6094 +
6095 +       error = (family_mask & (1 << type)) ? 0 : -EACCES;
6096 +
6097 +       return audit_net(profile, op, family, type, protocol, sk, error);
6098 +}
6099 +
6100 +/**
6101 + * aa_revalidate_sk - Revalidate access to a sock
6102 + * @op: operation being checked
6103 + * @sk: sock being revalidated  (NOT NULL)
6104 + *
6105 + * Returns: %0 else error if permission denied
6106 + */
6107 +int aa_revalidate_sk(int op, struct sock *sk)
6108 +{
6109 +       struct aa_profile *profile;
6110 +       int error = 0;
6111 +
6112 +       /* aa_revalidate_sk should not be called from interrupt context
6113 +        * don't mediate these calls as they are not task related
6114 +        */
6115 +       if (in_interrupt())
6116 +               return 0;
6117 +
6118 +       profile = __aa_current_profile();
6119 +       if (!unconfined(profile))
6120 +               error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type,
6121 +                                   sk->sk_protocol, sk);
6122 +
6123 +       return error;
6124 +}
6125 diff --git a/security/apparmor/path.c b/security/apparmor/path.c
6126 new file mode 100644
6127 index 0000000..96bab94
6128 --- /dev/null
6129 +++ b/security/apparmor/path.c
6130 @@ -0,0 +1,235 @@
6131 +/*
6132 + * AppArmor security module
6133 + *
6134 + * This file contains AppArmor function for pathnames
6135 + *
6136 + * Copyright (C) 1998-2008 Novell/SUSE
6137 + * Copyright 2009-2010 Canonical Ltd.
6138 + *
6139 + * This program is free software; you can redistribute it and/or
6140 + * modify it under the terms of the GNU General Public License as
6141 + * published by the Free Software Foundation, version 2 of the
6142 + * License.
6143 + */
6144 +
6145 +#include <linux/magic.h>
6146 +#include <linux/mnt_namespace.h>
6147 +#include <linux/mount.h>
6148 +#include <linux/namei.h>
6149 +#include <linux/nsproxy.h>
6150 +#include <linux/path.h>
6151 +#include <linux/sched.h>
6152 +#include <linux/slab.h>
6153 +#include <linux/fs_struct.h>
6154 +
6155 +#include "include/apparmor.h"
6156 +#include "include/path.h"
6157 +#include "include/policy.h"
6158 +
6159 +
6160 +/* modified from dcache.c */
6161 +static int prepend(char **buffer, int buflen, const char *str, int namelen)
6162 +{
6163 +       buflen -= namelen;
6164 +       if (buflen < 0)
6165 +               return -ENAMETOOLONG;
6166 +       *buffer -= namelen;
6167 +       memcpy(*buffer, str, namelen);
6168 +       return 0;
6169 +}
6170 +
6171 +#define CHROOT_NSCONNECT (PATH_CHROOT_REL | PATH_CHROOT_NSCONNECT)
6172 +
6173 +/**
6174 + * d_namespace_path - lookup a name associated with a given path
6175 + * @path: path to lookup  (NOT NULL)
6176 + * @buf:  buffer to store path to  (NOT NULL)
6177 + * @buflen: length of @buf
6178 + * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
6179 + * @flags: flags controlling path lookup
6180 + *
6181 + * Handle path name lookup.
6182 + *
6183 + * Returns: %0 else error code if path lookup fails
6184 + *          When no error the path name is returned in @name which points to
6185 + *          to a position in @buf
6186 + */
6187 +static int d_namespace_path(struct path *path, char *buf, int buflen,
6188 +                           char **name, int flags)
6189 +{
6190 +       struct path root, tmp;
6191 +       char *res;
6192 +       int deleted, connected;
6193 +       int error = 0;
6194 +
6195 +       /* Get the root we want to resolve too */
6196 +       if (flags & PATH_CHROOT_REL) {
6197 +               /* resolve paths relative to chroot */
6198 +               read_lock(&current->fs->lock);
6199 +               root = current->fs->root;
6200 +               /* released below */
6201 +               path_get(&root);
6202 +               read_unlock(&current->fs->lock);
6203 +       } else {
6204 +               /* resolve paths relative to namespace */
6205 +               root.mnt = current->nsproxy->mnt_ns->root;
6206 +               root.dentry = root.mnt->mnt_root;
6207 +               /* released below */
6208 +               path_get(&root);
6209 +       }
6210 +
6211 +       spin_lock(&dcache_lock);
6212 +       /* There is a race window between path lookup here and the
6213 +        * need to strip the " (deleted) string that __d_path applies
6214 +        * Detect the race and relookup the path
6215 +        *
6216 +        * The stripping of (deleted) is a hack that could be removed
6217 +        * with an updated __d_path
6218 +        */
6219 +       do {
6220 +               tmp = root;
6221 +               deleted = d_unlinked(path->dentry);
6222 +               res = __d_path(path, &tmp, buf, buflen);
6223 +
6224 +       } while (deleted != d_unlinked(path->dentry));
6225 +       spin_unlock(&dcache_lock);
6226 +
6227 +       *name = res;
6228 +       /* handle error conditions - and still allow a partial path to
6229 +        * be returned.
6230 +        */
6231 +       if (IS_ERR(res)) {
6232 +               error = PTR_ERR(res);
6233 +               *name = buf;
6234 +               goto out;
6235 +       }
6236 +       if (deleted) {
6237 +               /* On some filesystems, newly allocated dentries appear to the
6238 +                * security_path hooks as a deleted dentry except without an
6239 +                * inode allocated.
6240 +                *
6241 +                * Remove the appended deleted text and return as string for
6242 +                * normal mediation, or auditing.  The (deleted) string is
6243 +                * guaranteed to be added in this case, so just strip it.
6244 +                */
6245 +               buf[buflen - 11] = 0;   /* - (len(" (deleted)") +\0) */
6246 +
6247 +               if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) {
6248 +                       error = -ENOENT;
6249 +                       goto out;
6250 +               }
6251 +       }
6252 +
6253 +       /* Determine if the path is connected to the expected root */
6254 +       connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt;
6255 +
6256 +       /* If the path is not connected,
6257 +        * check if it is a sysctl and handle specially else remove any
6258 +        * leading / that __d_path may have returned.
6259 +        * Unless
6260 +        *     specifically directed to connect the path,
6261 +        * OR
6262 +        *     if in a chroot and doing chroot relative paths and the path
6263 +        *     resolves to the namespace root (would be connected outside
6264 +        *     of chroot) and specifically directed to connect paths to
6265 +        *     namespace root.
6266 +        */
6267 +       if (!connected) {
6268 +               /* is the disconnect path a sysctl? */
6269 +               if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC &&
6270 +                   strncmp(*name, "/sys/", 5) == 0) {
6271 +                       /* TODO: convert over to using a per namespace
6272 +                        * control instead of hard coded /proc
6273 +                        */
6274 +                       error = prepend(name, *name - buf, "/proc", 5);
6275 +               } else if (!(flags & PATH_CONNECT_PATH) &&
6276 +                          !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) &&
6277 +                            (tmp.mnt == current->nsproxy->mnt_ns->root &&
6278 +                             tmp.dentry == tmp.mnt->mnt_root))) {
6279 +                       /* disconnected path, don't return pathname starting
6280 +                        * with '/'
6281 +                        */
6282 +                       error = -ESTALE;
6283 +                       if (*res == '/')
6284 +                               *name = res + 1;
6285 +               }
6286 +       }
6287 +
6288 +out:
6289 +       path_put(&root);
6290 +
6291 +       return error;
6292 +}
6293 +
6294 +/**
6295 + * get_name_to_buffer - get the pathname to a buffer ensure dir / is appended
6296 + * @path: path to get name for  (NOT NULL)
6297 + * @flags: flags controlling path lookup
6298 + * @buffer: buffer to put name in  (NOT NULL)
6299 + * @size: size of buffer
6300 + * @name: Returns - contains position of path name in @buffer (NOT NULL)
6301 + *
6302 + * Returns: %0 else error on failure
6303 + */
6304 +static int get_name_to_buffer(struct path *path, int flags, char *buffer,
6305 +                             int size, char **name)
6306 +{
6307 +       int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
6308 +       int error = d_namespace_path(path, buffer, size - adjust, name, flags);
6309 +
6310 +       if (!error && (flags & PATH_IS_DIR) && (*name)[1] != '\0')
6311 +               /*
6312 +                * Append "/" to the pathname.  The root directory is a special
6313 +                * case; it already ends in slash.
6314 +                */
6315 +               strcpy(&buffer[size - 2], "/");
6316 +
6317 +       return error;
6318 +}
6319 +
6320 +/**
6321 + * aa_get_name - compute the pathname of a file
6322 + * @path: path the file  (NOT NULL)
6323 + * @flags: flags controlling path name generation
6324 + * @buffer: buffer that aa_get_name() allocated  (NOT NULL)
6325 + * @name: Returns - the generated path name if !error (NOT NULL)
6326 + *
6327 + * @name is a pointer to the beginning of the pathname (which usually differs
6328 + * from the beginning of the buffer), or NULL.  If there is an error @name
6329 + * may contain a partial or invalid name that can be used for audit purposes,
6330 + * but it can not be used for mediation.
6331 + *
6332 + * We need PATH_IS_DIR to indicate whether the file is a directory or not
6333 + * because the file may not yet exist, and so we cannot check the inode's
6334 + * file type.
6335 + *
6336 + * Returns: %0 else error code if could retrieve name
6337 + */
6338 +int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
6339 +{
6340 +       char *buf, *str = NULL;
6341 +       int size = 256;
6342 +       int error;
6343 +
6344 +       *name = NULL;
6345 +       *buffer = NULL;
6346 +       for (;;) {
6347 +               /* freed by caller */
6348 +               buf = kmalloc(size, GFP_KERNEL);
6349 +               if (!buf)
6350 +                       return -ENOMEM;
6351 +
6352 +               error = get_name_to_buffer(path, flags, buf, size, &str);
6353 +               if (error != -ENAMETOOLONG)
6354 +                       break;
6355 +
6356 +               kfree(buf);
6357 +               size <<= 1;
6358 +               if (size > aa_g_path_max)
6359 +                       return -ENAMETOOLONG;
6360 +       }
6361 +       *buffer = buf;
6362 +       *name = str;
6363 +
6364 +       return error;
6365 +}
6366 diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
6367 new file mode 100644
6368 index 0000000..e3020ed
6369 --- /dev/null
6370 +++ b/security/apparmor/policy.c
6371 @@ -0,0 +1,1185 @@
6372 +/*
6373 + * AppArmor security module
6374 + *
6375 + * This file contains AppArmor policy manipulation functions
6376 + *
6377 + * Copyright (C) 1998-2008 Novell/SUSE
6378 + * Copyright 2009-2010 Canonical Ltd.
6379 + *
6380 + * This program is free software; you can redistribute it and/or
6381 + * modify it under the terms of the GNU General Public License as
6382 + * published by the Free Software Foundation, version 2 of the
6383 + * License.
6384 + *
6385 + *
6386 + * AppArmor policy is based around profiles, which contain the rules a
6387 + * task is confined by.  Every task in the system has a profile attached
6388 + * to it determined either by matching "unconfined" tasks against the
6389 + * visible set of profiles or by following a profiles attachment rules.
6390 + *
6391 + * Each profile exists in a profile namespace which is a container of
6392 + * visible profiles.  Each namespace contains a special "unconfined" profile,
6393 + * which doesn't enforce any confinement on a task beyond DAC.
6394 + *
6395 + * Namespace and profile names can be written together in either
6396 + * of two syntaxes.
6397 + *     :namespace:profile - used by kernel interfaces for easy detection
6398 + *     namespace://profile - used by policy
6399 + *
6400 + * Profile names can not start with : or @ or ^ and may not contain \0
6401 + *
6402 + * Reserved profile names
6403 + *     unconfined - special automatically generated unconfined profile
6404 + *     inherit - special name to indicate profile inheritance
6405 + *     null-XXXX-YYYY - special automatically generated learning profiles
6406 + *
6407 + * Namespace names may not start with / or @ and may not contain \0 or :
6408 + * Reserved namespace names
6409 + *     user-XXXX - user defined profiles
6410 + *
6411 + * a // in a profile or namespace name indicates a hierarchical name with the
6412 + * name before the // being the parent and the name after the child.
6413 + *
6414 + * Profile and namespace hierarchies serve two different but similar purposes.
6415 + * The namespace contains the set of visible profiles that are considered
6416 + * for attachment.  The hierarchy of namespaces allows for virtualizing
6417 + * the namespace so that for example a chroot can have its own set of profiles
6418 + * which may define some local user namespaces.
6419 + * The profile hierarchy severs two distinct purposes,
6420 + * -  it allows for sub profiles or hats, which allows an application to run
6421 + *    subprograms under its own profile with different restriction than it
6422 + *    self, and not have it use the system profile.
6423 + *    eg. if a mail program starts an editor, the policy might make the
6424 + *        restrictions tighter on the editor tighter than the mail program,
6425 + *        and definitely different than general editor restrictions
6426 + * - it allows for binary hierarchy of profiles, so that execution history
6427 + *   is preserved.  This feature isn't exploited by AppArmor reference policy
6428 + *   but is allowed.  NOTE: this is currently suboptimal because profile
6429 + *   aliasing is not currently implemented so that a profile for each
6430 + *   level must be defined.
6431 + *   eg. /bin/bash///bin/ls as a name would indicate /bin/ls was started
6432 + *       from /bin/bash
6433 + *
6434 + *   A profile or namespace name that can contain one or more // separators
6435 + *   is referred to as an hname (hierarchical).
6436 + *   eg.  /bin/bash//bin/ls
6437 + *
6438 + *   An fqname is a name that may contain both namespace and profile hnames.
6439 + *   eg. :ns:/bin/bash//bin/ls
6440 + *
6441 + * NOTES:
6442 + *   - locking of profile lists is currently fairly coarse.  All profile
6443 + *     lists within a namespace use the namespace lock.
6444 + * FIXME: move profile lists to using rcu_lists
6445 + */
6446 +
6447 +#include <linux/slab.h>
6448 +#include <linux/spinlock.h>
6449 +#include <linux/string.h>
6450 +
6451 +#include "include/apparmor.h"
6452 +#include "include/capability.h"
6453 +#include "include/context.h"
6454 +#include "include/file.h"
6455 +#include "include/ipc.h"
6456 +#include "include/match.h"
6457 +#include "include/path.h"
6458 +#include "include/policy.h"
6459 +#include "include/policy_unpack.h"
6460 +#include "include/resource.h"
6461 +#include "include/sid.h"
6462 +
6463 +
6464 +/* root profile namespace */
6465 +struct aa_namespace *root_ns;
6466 +
6467 +const char *profile_mode_names[] = {
6468 +       "enforce",
6469 +       "complain",
6470 +       "kill",
6471 +};
6472 +
6473 +/**
6474 + * hname_tail - find the last component of an hname
6475 + * @name: hname to find the base profile name component of  (NOT NULL)
6476 + *
6477 + * Returns: the tail (base profile name) name component of an hname
6478 + */
6479 +static const char *hname_tail(const char *hname)
6480 +{
6481 +       char *split;
6482 +       hname = strim((char *)hname);
6483 +       for (split = strstr(hname, "//"); split; split = strstr(hname, "//"))
6484 +               hname = split + 2;
6485 +
6486 +       return hname;
6487 +}
6488 +
6489 +/**
6490 + * policy_init - initialize a policy structure
6491 + * @policy: policy to initialize  (NOT NULL)
6492 + * @prefix: prefix name if any is required.  (MAYBE NULL)
6493 + * @name: name of the policy, init will make a copy of it  (NOT NULL)
6494 + *
6495 + * Note: this fn creates a copy of strings passed in
6496 + *
6497 + * Returns: true if policy init successful
6498 + */
6499 +static bool policy_init(struct aa_policy *policy, const char *prefix,
6500 +                       const char *name)
6501 +{
6502 +       /* freed by policy_free */
6503 +       if (prefix) {
6504 +               policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
6505 +                                       GFP_KERNEL);
6506 +               if (policy->hname)
6507 +                       sprintf(policy->hname, "%s//%s", prefix, name);
6508 +       } else
6509 +               policy->hname = kstrdup(name, GFP_KERNEL);
6510 +       if (!policy->hname)
6511 +               return 0;
6512 +       /* base.name is a substring of fqname */
6513 +       policy->name = (char *)hname_tail(policy->hname);
6514 +       INIT_LIST_HEAD(&policy->list);
6515 +       INIT_LIST_HEAD(&policy->profiles);
6516 +       kref_init(&policy->count);
6517 +
6518 +       return 1;
6519 +}
6520 +
6521 +/**
6522 + * policy_destroy - free the elements referenced by @policy
6523 + * @policy: policy that is to have its elements freed  (NOT NULL)
6524 + */
6525 +static void policy_destroy(struct aa_policy *policy)
6526 +{
6527 +       /* still contains profiles -- invalid */
6528 +       if (!list_empty(&policy->profiles)) {
6529 +               AA_ERROR("%s: internal error, "
6530 +                        "policy '%s' still contains profiles\n",
6531 +                        __func__, policy->name);
6532 +               BUG();
6533 +       }
6534 +       if (!list_empty(&policy->list)) {
6535 +               AA_ERROR("%s: internal error, policy '%s' still on list\n",
6536 +                        __func__, policy->name);
6537 +               BUG();
6538 +       }
6539 +
6540 +       /* don't free name as its a subset of hname */
6541 +       kzfree(policy->hname);
6542 +}
6543 +
6544 +/**
6545 + * __policy_find - find a policy by @name on a policy list
6546 + * @head: list to search  (NOT NULL)
6547 + * @name: name to search for  (NOT NULL)
6548 + *
6549 + * Requires: correct locks for the @head list be held
6550 + *
6551 + * Returns: unrefcounted policy that match @name or NULL if not found
6552 + */
6553 +static struct aa_policy *__policy_find(struct list_head *head, const char *name)
6554 +{
6555 +       struct aa_policy *policy;
6556 +
6557 +       list_for_each_entry(policy, head, list) {
6558 +               if (!strcmp(policy->name, name))
6559 +                       return policy;
6560 +       }
6561 +       return NULL;
6562 +}
6563 +
6564 +/**
6565 + * __policy_strn_find - find a policy that's name matches @len chars of @str
6566 + * @head: list to search  (NOT NULL)
6567 + * @str: string to search for  (NOT NULL)
6568 + * @len: length of match required
6569 + *
6570 + * Requires: correct locks for the @head list be held
6571 + *
6572 + * Returns: unrefcounted policy that match @str or NULL if not found
6573 + *
6574 + * if @len == strlen(@strlen) then this is equiv to __policy_find
6575 + * other wise it allows searching for policy by a partial match of name
6576 + */
6577 +static struct aa_policy *__policy_strn_find(struct list_head *head,
6578 +                                           const char *str, int len)
6579 +{
6580 +       struct aa_policy *policy;
6581 +
6582 +       list_for_each_entry(policy, head, list) {
6583 +               if (aa_strneq(policy->name, str, len))
6584 +                       return policy;
6585 +       }
6586 +
6587 +       return NULL;
6588 +}
6589 +
6590 +/*
6591 + * Routines for AppArmor namespaces
6592 + */
6593 +
6594 +static const char *hidden_ns_name = "---";
6595 +/**
6596 + * aa_ns_visible - test if @view is visible from @curr
6597 + * @curr: namespace to treat as the parent (NOT NULL)
6598 + * @view:  namespace to test if visible from @curr (NOT NULL)
6599 + *
6600 + * Returns: true if @view is visible from @curr else false
6601 + */
6602 +bool aa_ns_visible(struct aa_namespace *curr, struct aa_namespace *view)
6603 +{
6604 +       if (curr == view)
6605 +               return true;
6606 +
6607 +       for ( ; view; view = view->parent) {
6608 +               if (view->parent == curr)
6609 +                       return true;
6610 +       }
6611 +       return false;
6612 +}
6613 +
6614 +/**
6615 + * aa_na_name - Find the ns name to display for @view from @curr
6616 + * @curr - current namespace (NOT NULL)
6617 + * @view - namespace attempting to view (NOT NULL)
6618 + *
6619 + * Returns: name of @view visible from @curr
6620 + */
6621 +const char *aa_ns_name(struct aa_namespace *curr, struct aa_namespace *view)
6622 +{
6623 +       /* if view == curr then the namespace name isn't displayed */
6624 +       if (curr == view)
6625 +               return "";
6626 +
6627 +       if (aa_ns_visible(curr, view)) {
6628 +               /* at this point if a ns is visible it is in a view ns
6629 +                * thus the curr ns.hname is a prefix of its name.
6630 +                * Only output the virtualized portion of the name
6631 +                * Add + 2 to skip over // separating curr hname prefix
6632 +                * from the visible tail of the views hname
6633 +                */
6634 +               return view->base.hname + strlen(curr->base.hname) + 2;
6635 +       } else
6636 +               return hidden_ns_name;
6637 +}
6638 +
6639 +/**
6640 + * alloc_namespace - allocate, initialize and return a new namespace
6641 + * @prefix: parent namespace name (MAYBE NULL)
6642 + * @name: a preallocated name  (NOT NULL)
6643 + *
6644 + * Returns: refcounted namespace or NULL on failure.
6645 + */
6646 +static struct aa_namespace *alloc_namespace(const char *prefix,
6647 +                                           const char *name)
6648 +{
6649 +       struct aa_namespace *ns;
6650 +
6651 +       ns = kzalloc(sizeof(*ns), GFP_KERNEL);
6652 +       AA_DEBUG("%s(%p)\n", __func__, ns);
6653 +       if (!ns)
6654 +               return NULL;
6655 +       if (!policy_init(&ns->base, prefix, name))
6656 +               goto fail_ns;
6657 +
6658 +       INIT_LIST_HEAD(&ns->sub_ns);
6659 +       rwlock_init(&ns->lock);
6660 +
6661 +       /* released by free_namespace */
6662 +       ns->unconfined = aa_alloc_profile("unconfined");
6663 +       if (!ns->unconfined)
6664 +               goto fail_unconfined;
6665 +
6666 +       ns->unconfined->sid = aa_alloc_sid();
6667 +       ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
6668 +           PFLAG_IMMUTABLE;
6669 +
6670 +       /*
6671 +        * released by free_namespace, however __remove_namespace breaks
6672 +        * the cyclic references (ns->unconfined, and unconfined->ns) and
6673 +        * replaces with refs to parent namespace unconfined
6674 +        */
6675 +       ns->unconfined->ns = aa_get_namespace(ns);
6676 +
6677 +       return ns;
6678 +
6679 +fail_unconfined:
6680 +       kzfree(ns->base.name);
6681 +fail_ns:
6682 +       kzfree(ns);
6683 +       return NULL;
6684 +}
6685 +
6686 +/**
6687 + * free_namespace - free a profile namespace
6688 + * @ns: the namespace to free  (MAYBE NULL)
6689 + *
6690 + * Requires: All references to the namespace must have been put, if the
6691 + *           namespace was referenced by a profile confining a task,
6692 + */
6693 +static void free_namespace(struct aa_namespace *ns)
6694 +{
6695 +       if (!ns)
6696 +               return;
6697 +
6698 +       policy_destroy(&ns->base);
6699 +       aa_put_namespace(ns->parent);
6700 +
6701 +       if (ns->unconfined && ns->unconfined->ns == ns)
6702 +               ns->unconfined->ns = NULL;
6703 +
6704 +       aa_put_profile(ns->unconfined);
6705 +       kzfree(ns);
6706 +}
6707 +
6708 +/**
6709 + * aa_free_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
6710 + * @kr: kref callback for freeing of a namespace  (NOT NULL)
6711 + */
6712 +void aa_free_namespace_kref(struct kref *kref)
6713 +{
6714 +       free_namespace(container_of(kref, struct aa_namespace, base.count));
6715 +}
6716 +
6717 +/**
6718 + * __aa_find_namespace - find a namespace on a list by @name
6719 + * @head: list to search for namespace on  (NOT NULL)
6720 + * @name: name of namespace to look for  (NOT NULL)
6721 + *
6722 + * Returns: unrefcounted namespace
6723 + *
6724 + * Requires: ns lock be held
6725 + */
6726 +static struct aa_namespace *__aa_find_namespace(struct list_head *head,
6727 +                                               const char *name)
6728 +{
6729 +       return (struct aa_namespace *)__policy_find(head, name);
6730 +}
6731 +
6732 +/**
6733 + * aa_find_namespace  -  look up a profile namespace on the namespace list
6734 + * @root: namespace to search in  (NOT NULL)
6735 + * @name: name of namespace to find  (NOT NULL)
6736 + *
6737 + * Returns: a refcounted namespace on the list, or NULL if no namespace
6738 + *          called @name exists.
6739 + *
6740 + * refcount released by caller
6741 + */
6742 +struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
6743 +                                      const char *name)
6744 +{
6745 +       struct aa_namespace *ns = NULL;
6746 +
6747 +       read_lock(&root->lock);
6748 +       ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
6749 +       read_unlock(&root->lock);
6750 +
6751 +       return ns;
6752 +}
6753 +
6754 +/**
6755 + * aa_prepare_namespace - find an existing or create a new namespace of @name
6756 + * @name: the namespace to find or add  (MAYBE NULL)
6757 + *
6758 + * Returns: refcounted namespace or NULL if failed to create one
6759 + */
6760 +static struct aa_namespace *aa_prepare_namespace(const char *name)
6761 +{
6762 +       struct aa_namespace *ns, *root;
6763 +
6764 +       root = aa_current_profile()->ns;
6765 +
6766 +       write_lock(&root->lock);
6767 +
6768 +       /* if name isn't specified the profile is loaded to the current ns */
6769 +       if (!name) {
6770 +               /* released by caller */
6771 +               ns = aa_get_namespace(root);
6772 +               goto out;
6773 +       }
6774 +
6775 +       /* try and find the specified ns and if it doesn't exist create it */
6776 +       /* released by caller */
6777 +       ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
6778 +       if (!ns) {
6779 +               /* namespace not found */
6780 +               struct aa_namespace *new_ns;
6781 +               write_unlock(&root->lock);
6782 +               new_ns = alloc_namespace(root->base.hname, name);
6783 +               if (!new_ns)
6784 +                       return NULL;
6785 +               write_lock(&root->lock);
6786 +               /* test for race when new_ns was allocated */
6787 +               ns = __aa_find_namespace(&root->sub_ns, name);
6788 +               if (!ns) {
6789 +                       /* add parent ref */
6790 +                       new_ns->parent = aa_get_namespace(root);
6791 +
6792 +                       list_add(&new_ns->base.list, &root->sub_ns);
6793 +                       /* add list ref */
6794 +                       ns = aa_get_namespace(new_ns);
6795 +               } else {
6796 +                       /* raced so free the new one */
6797 +                       free_namespace(new_ns);
6798 +                       /* get reference on namespace */
6799 +                       aa_get_namespace(ns);
6800 +               }
6801 +       }
6802 +out:
6803 +       write_unlock(&root->lock);
6804 +
6805 +       /* return ref */
6806 +       return ns;
6807 +}
6808 +
6809 +/**
6810 + * __list_add_profile - add a profile to a list
6811 + * @list: list to add it to  (NOT NULL)
6812 + * @profile: the profile to add  (NOT NULL)
6813 + *
6814 + * refcount @profile, should be put by __list_remove_profile
6815 + *
6816 + * Requires: namespace lock be held, or list not be shared
6817 + */
6818 +static void __list_add_profile(struct list_head *list,
6819 +                              struct aa_profile *profile)
6820 +{
6821 +       list_add(&profile->base.list, list);
6822 +       /* get list reference */
6823 +       aa_get_profile(profile);
6824 +}
6825 +
6826 +/**
6827 + * __list_remove_profile - remove a profile from the list it is on
6828 + * @profile: the profile to remove  (NOT NULL)
6829 + *
6830 + * remove a profile from the list, warning generally removal should
6831 + * be done with __replace_profile as most profile removals are
6832 + * replacements to the unconfined profile.
6833 + *
6834 + * put @profile list refcount
6835 + *
6836 + * Requires: namespace lock be held, or list not have been live
6837 + */
6838 +static void __list_remove_profile(struct aa_profile *profile)
6839 +{
6840 +       list_del_init(&profile->base.list);
6841 +       if (!(profile->flags & PFLAG_NO_LIST_REF))
6842 +               /* release list reference */
6843 +               aa_put_profile(profile);
6844 +}
6845 +
6846 +/**
6847 + * __replace_profile - replace @old with @new on a list
6848 + * @old: profile to be replaced  (NOT NULL)
6849 + * @new: profile to replace @old with  (NOT NULL)
6850 + *
6851 + * Will duplicate and refcount elements that @new inherits from @old
6852 + * and will inherit @old children.
6853 + *
6854 + * refcount @new for list, put @old list refcount
6855 + *
6856 + * Requires: namespace list lock be held, or list not be shared
6857 + */
6858 +static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
6859 +{
6860 +       struct aa_policy *policy;
6861 +       struct aa_profile *child, *tmp;
6862 +
6863 +       if (old->parent)
6864 +               policy = &old->parent->base;
6865 +       else
6866 +               policy = &old->ns->base;
6867 +
6868 +       /* released when @new is freed */
6869 +       new->parent = aa_get_profile(old->parent);
6870 +       new->ns = aa_get_namespace(old->ns);
6871 +       new->sid = old->sid;
6872 +       __list_add_profile(&policy->profiles, new);
6873 +       /* inherit children */
6874 +       list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {
6875 +               aa_put_profile(child->parent);
6876 +               child->parent = aa_get_profile(new);
6877 +               /* list refcount transferred to @new*/
6878 +               list_move(&child->base.list, &new->base.profiles);
6879 +       }
6880 +
6881 +       /* released by free_profile */
6882 +       old->replacedby = aa_get_profile(new);
6883 +       __list_remove_profile(old);
6884 +}
6885 +
6886 +static void __profile_list_release(struct list_head *head);
6887 +
6888 +/**
6889 + * __remove_profile - remove old profile, and children
6890 + * @profile: profile to be replaced  (NOT NULL)
6891 + *
6892 + * Requires: namespace list lock be held, or list not be shared
6893 + */
6894 +static void __remove_profile(struct aa_profile *profile)
6895 +{
6896 +       /* release any children lists first */
6897 +       __profile_list_release(&profile->base.profiles);
6898 +       /* released by free_profile */
6899 +       profile->replacedby = aa_get_profile(profile->ns->unconfined);
6900 +       __list_remove_profile(profile);
6901 +}
6902 +
6903 +/**
6904 + * __profile_list_release - remove all profiles on the list and put refs
6905 + * @head: list of profiles  (NOT NULL)
6906 + *
6907 + * Requires: namespace lock be held
6908 + */
6909 +static void __profile_list_release(struct list_head *head)
6910 +{
6911 +       struct aa_profile *profile, *tmp;
6912 +       list_for_each_entry_safe(profile, tmp, head, base.list)
6913 +               __remove_profile(profile);
6914 +}
6915 +
6916 +static void __ns_list_release(struct list_head *head);
6917 +
6918 +/**
6919 + * destroy_namespace - remove everything contained by @ns
6920 + * @ns: namespace to have it contents removed  (NOT NULL)
6921 + */
6922 +static void destroy_namespace(struct aa_namespace *ns)
6923 +{
6924 +       if (!ns)
6925 +               return;
6926 +
6927 +       write_lock(&ns->lock);
6928 +       /* release all profiles in this namespace */
6929 +       __profile_list_release(&ns->base.profiles);
6930 +
6931 +       /* release all sub namespaces */
6932 +       __ns_list_release(&ns->sub_ns);
6933 +
6934 +       write_unlock(&ns->lock);
6935 +}
6936 +
6937 +/**
6938 + * __remove_namespace - remove a namespace and all its children
6939 + * @ns: namespace to be removed  (NOT NULL)
6940 + *
6941 + * Requires: ns->parent->lock be held and ns removed from parent.
6942 + */
6943 +static void __remove_namespace(struct aa_namespace *ns)
6944 +{
6945 +       struct aa_profile *unconfined = ns->unconfined;
6946 +
6947 +       /* remove ns from namespace list */
6948 +       list_del_init(&ns->base.list);
6949 +
6950 +       /*
6951 +        * break the ns, unconfined profile cyclic reference and forward
6952 +        * all new unconfined profiles requests to the parent namespace
6953 +        * This will result in all confined tasks that have a profile
6954 +        * being removed, inheriting the parent->unconfined profile.
6955 +        */
6956 +       if (ns->parent)
6957 +               ns->unconfined = aa_get_profile(ns->parent->unconfined);
6958 +
6959 +       destroy_namespace(ns);
6960 +
6961 +       /* release original ns->unconfined ref */
6962 +       aa_put_profile(unconfined);
6963 +       /* release ns->base.list ref, from removal above */
6964 +       aa_put_namespace(ns);
6965 +}
6966 +
6967 +/**
6968 + * __ns_list_release - remove all profile namespaces on the list put refs
6969 + * @head: list of profile namespaces  (NOT NULL)
6970 + *
6971 + * Requires: namespace lock be held
6972 + */
6973 +static void __ns_list_release(struct list_head *head)
6974 +{
6975 +       struct aa_namespace *ns, *tmp;
6976 +       list_for_each_entry_safe(ns, tmp, head, base.list)
6977 +               __remove_namespace(ns);
6978 +
6979 +}
6980 +
6981 +/**
6982 + * aa_alloc_root_ns - allocate the root profile namespace
6983 + *
6984 + * Returns: %0 on success else error
6985 + *
6986 + */
6987 +int __init aa_alloc_root_ns(void)
6988 +{
6989 +       /* released by aa_free_root_ns - used as list ref*/
6990 +       root_ns = alloc_namespace(NULL, "root");
6991 +       if (!root_ns)
6992 +               return -ENOMEM;
6993 +
6994 +       return 0;
6995 +}
6996 +
6997 + /**
6998 +  * aa_free_root_ns - free the root profile namespace
6999 +  */
7000 +void __init aa_free_root_ns(void)
7001 + {
7002 +        struct aa_namespace *ns = root_ns;
7003 +        root_ns = NULL;
7004 +
7005 +        destroy_namespace(ns);
7006 +        aa_put_namespace(ns);
7007 +}
7008 +
7009 +/**
7010 + * aa_alloc_profile - allocate, initialize and return a new profile
7011 + * @hname: name of the profile  (NOT NULL)
7012 + *
7013 + * Returns: refcount profile or NULL on failure
7014 + */
7015 +struct aa_profile *aa_alloc_profile(const char *hname)
7016 +{
7017 +       struct aa_profile *profile;
7018 +
7019 +       /* freed by free_profile - usually through aa_put_profile */
7020 +       profile = kzalloc(sizeof(*profile), GFP_KERNEL);
7021 +       if (!profile)
7022 +               return NULL;
7023 +
7024 +       if (!policy_init(&profile->base, NULL, hname)) {
7025 +               kzfree(profile);
7026 +               return NULL;
7027 +       }
7028 +
7029 +       /* refcount released by caller */
7030 +       return profile;
7031 +}
7032 +
7033 +/**
7034 + * aa_new_null_profile - create a new null-X learning profile
7035 + * @parent: profile that caused this profile to be created (NOT NULL)
7036 + * @hat: true if the null- learning profile is a hat
7037 + *
7038 + * Create a null- complain mode profile used in learning mode.  The name of
7039 + * the profile is unique and follows the format of parent//null-sid.
7040 + *
7041 + * null profiles are added to the profile list but the list does not
7042 + * hold a count on them so that they are automatically released when
7043 + * not in use.
7044 + *
7045 + * Returns: new refcounted profile else NULL on failure
7046 + */
7047 +struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
7048 +{
7049 +       struct aa_profile *profile = NULL;
7050 +       char *name;
7051 +       u32 sid = aa_alloc_sid();
7052 +
7053 +       /* freed below */
7054 +       name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, GFP_KERNEL);
7055 +       if (!name)
7056 +               goto fail;
7057 +       sprintf(name, "%s//null-%x", parent->base.hname, sid);
7058 +
7059 +       profile = aa_alloc_profile(name);
7060 +       kfree(name);
7061 +       if (!profile)
7062 +               goto fail;
7063 +
7064 +       profile->sid = sid;
7065 +       profile->mode = APPARMOR_COMPLAIN;
7066 +       profile->flags = PFLAG_NULL;
7067 +       if (hat)
7068 +               profile->flags |= PFLAG_HAT;
7069 +
7070 +       /* released on free_profile */
7071 +       profile->parent = aa_get_profile(parent);
7072 +       profile->ns = aa_get_namespace(parent->ns);
7073 +
7074 +       write_lock(&profile->ns->lock);
7075 +       __list_add_profile(&parent->base.profiles, profile);
7076 +       write_unlock(&profile->ns->lock);
7077 +
7078 +       /* refcount released by caller */
7079 +       return profile;
7080 +
7081 +fail:
7082 +       aa_free_sid(sid);
7083 +       return NULL;
7084 +}
7085 +
7086 +/**
7087 + * free_profile - free a profile
7088 + * @profile: the profile to free  (MAYBE NULL)
7089 + *
7090 + * Free a profile, its hats and null_profile. All references to the profile,
7091 + * its hats and null_profile must have been put.
7092 + *
7093 + * If the profile was referenced from a task context, free_profile() will
7094 + * be called from an rcu callback routine, so we must not sleep here.
7095 + */
7096 +static void free_profile(struct aa_profile *profile)
7097 +{
7098 +       AA_DEBUG("%s(%p)\n", __func__, profile);
7099 +
7100 +       if (!profile)
7101 +               return;
7102 +
7103 +       if (!list_empty(&profile->base.list)) {
7104 +               AA_ERROR("%s: internal error, "
7105 +                        "profile '%s' still on ns list\n",
7106 +                        __func__, profile->base.name);
7107 +               BUG();
7108 +       }
7109 +
7110 +       /* free children profiles */
7111 +       policy_destroy(&profile->base);
7112 +       aa_put_profile(profile->parent);
7113 +
7114 +       aa_put_namespace(profile->ns);
7115 +       kzfree(profile->rename);
7116 +
7117 +       aa_free_file_rules(&profile->file);
7118 +       aa_free_cap_rules(&profile->caps);
7119 +       aa_free_net_rules(&profile->net);
7120 +       aa_free_rlimit_rules(&profile->rlimits);
7121 +
7122 +       aa_free_sid(profile->sid);
7123 +       aa_put_dfa(profile->xmatch);
7124 +
7125 +       aa_put_profile(profile->replacedby);
7126 +
7127 +       kzfree(profile);
7128 +}
7129 +
7130 +/**
7131 + * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)
7132 + * @kr: kref callback for freeing of a profile  (NOT NULL)
7133 + */
7134 +void aa_free_profile_kref(struct kref *kref)
7135 +{
7136 +       struct aa_profile *p = container_of(kref, struct aa_profile,
7137 +                                           base.count);
7138 +
7139 +       free_profile(p);
7140 +}
7141 +
7142 +/* TODO: profile accounting - setup in remove */
7143 +
7144 +/**
7145 + * __find_child - find a profile on @head list with a name matching @name
7146 + * @head: list to search  (NOT NULL)
7147 + * @name: name of profile (NOT NULL)
7148 + *
7149 + * Requires: ns lock protecting list be held
7150 + *
7151 + * Returns: unrefcounted profile ptr, or NULL if not found
7152 + */
7153 +static struct aa_profile *__find_child(struct list_head *head, const char *name)
7154 +{
7155 +       return (struct aa_profile *)__policy_find(head, name);
7156 +}
7157 +
7158 +/**
7159 + * __strn_find_child - find a profile on @head list using substring of @name
7160 + * @head: list to search  (NOT NULL)
7161 + * @name: name of profile (NOT NULL)
7162 + * @len: length of @name substring to match
7163 + *
7164 + * Requires: ns lock protecting list be held
7165 + *
7166 + * Returns: unrefcounted profile ptr, or NULL if not found
7167 + */
7168 +static struct aa_profile *__strn_find_child(struct list_head *head,
7169 +                                           const char *name, int len)
7170 +{
7171 +       return (struct aa_profile *)__policy_strn_find(head, name, len);
7172 +}
7173 +
7174 +/**
7175 + * aa_find_child - find a profile by @name in @parent
7176 + * @parent: profile to search  (NOT NULL)
7177 + * @name: profile name to search for  (NOT NULL)
7178 + *
7179 + * Returns: a refcounted profile or NULL if not found
7180 + */
7181 +struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
7182 +{
7183 +       struct aa_profile *profile;
7184 +
7185 +       read_lock(&parent->ns->lock);
7186 +       profile = aa_get_profile(__find_child(&parent->base.profiles, name));
7187 +       read_unlock(&parent->ns->lock);
7188 +
7189 +       /* refcount released by caller */
7190 +       return profile;
7191 +}
7192 +
7193 +/**
7194 + * __lookup_parent - lookup the parent of a profile of name @hname
7195 + * @ns: namespace to lookup profile in  (NOT NULL)
7196 + * @hname: hierarchical profile name to find parent of  (NOT NULL)
7197 + *
7198 + * Lookups up the parent of a fully qualified profile name, the profile
7199 + * that matches hname does not need to exist, in general this
7200 + * is used to load a new profile.
7201 + *
7202 + * Requires: ns->lock be held
7203 + *
7204 + * Returns: unrefcounted policy or NULL if not found
7205 + */
7206 +static struct aa_policy *__lookup_parent(struct aa_namespace *ns,
7207 +                                        const char *hname)
7208 +{
7209 +       struct aa_policy *policy;
7210 +       struct aa_profile *profile = NULL;
7211 +       char *split;
7212 +
7213 +       policy = &ns->base;
7214 +
7215 +       for (split = strstr(hname, "//"); split;) {
7216 +               profile = __strn_find_child(&policy->profiles, hname,
7217 +                                           split - hname);
7218 +               if (!profile)
7219 +                       return NULL;
7220 +               policy = &profile->base;
7221 +               hname = split + 2;
7222 +               split = strstr(hname, "//");
7223 +       }
7224 +       if (!profile)
7225 +               return &ns->base;
7226 +       return &profile->base;
7227 +}
7228 +
7229 +/**
7230 + * __lookup_profile - lookup the profile matching @hname
7231 + * @base: base list to start looking up profile name from  (NOT NULL)
7232 + * @hname: hierarchical profile name  (NOT NULL)
7233 + *
7234 + * Requires: ns->lock be held
7235 + *
7236 + * Returns: unrefcounted profile pointer or NULL if not found
7237 + *
7238 + * Do a relative name lookup, recursing through profile tree.
7239 + */
7240 +static struct aa_profile *__lookup_profile(struct aa_policy *base,
7241 +                                          const char *hname)
7242 +{
7243 +       struct aa_profile *profile = NULL;
7244 +       char *split;
7245 +
7246 +       for (split = strstr(hname, "//"); split;) {
7247 +               profile = __strn_find_child(&base->profiles, hname,
7248 +                                           split - hname);
7249 +               if (!profile)
7250 +                       return NULL;
7251 +
7252 +               base = &profile->base;
7253 +               hname = split + 2;
7254 +               split = strstr(hname, "//");
7255 +       }
7256 +
7257 +       profile = __find_child(&base->profiles, hname);
7258 +
7259 +       return profile;
7260 +}
7261 +
7262 +/**
7263 + * aa_lookup_profile - find a profile by its full or partial name
7264 + * @ns: the namespace to start from (NOT NULL)
7265 + * @hname: name to do lookup on.  Does not contain namespace prefix (NOT NULL)
7266 + *
7267 + * Returns: refcounted profile or NULL if not found
7268 + */
7269 +struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname)
7270 +{
7271 +       struct aa_profile *profile;
7272 +
7273 +       read_lock(&ns->lock);
7274 +       profile = aa_get_profile(__lookup_profile(&ns->base, hname));
7275 +       read_unlock(&ns->lock);
7276 +
7277 +       /* refcount released by caller */
7278 +       return profile;
7279 +}
7280 +
7281 +/**
7282 + * replacement_allowed - test to see if replacement is allowed
7283 + * @profile: profile to test if it can be replaced  (MAYBE NULL)
7284 + * @noreplace: true if replacement shouldn't be allowed but addition is okay
7285 + * @info: Returns - info about why replacement failed (NOT NULL)
7286 + *
7287 + * Returns: %0 if replacement allowed else error code
7288 + */
7289 +static int replacement_allowed(struct aa_profile *profile, int noreplace,
7290 +                              const char **info)
7291 +{
7292 +       if (profile) {
7293 +               if (profile->flags & PFLAG_IMMUTABLE) {
7294 +                       *info = "cannot replace immutible profile";
7295 +                       return -EPERM;
7296 +               } else if (noreplace) {
7297 +                       *info = "profile already exists";
7298 +                       return -EEXIST;
7299 +               }
7300 +       }
7301 +       return 0;
7302 +}
7303 +
7304 +/**
7305 + * __add_new_profile - simple wrapper around __list_add_profile
7306 + * @ns: namespace that profile is being added to  (NOT NULL)
7307 + * @policy: the policy container to add the profile to  (NOT NULL)
7308 + * @profile: profile to add  (NOT NULL)
7309 + *
7310 + * add a profile to a list and do other required basic allocations
7311 + */
7312 +static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
7313 +                             struct aa_profile *profile)
7314 +{
7315 +       if (policy != &ns->base)
7316 +               /* released on profile replacement or free_profile */
7317 +               profile->parent = aa_get_profile((struct aa_profile *) policy);
7318 +       __list_add_profile(&policy->profiles, profile);
7319 +       /* released on free_profile */
7320 +       profile->sid = aa_alloc_sid();
7321 +       profile->ns = aa_get_namespace(ns);
7322 +}
7323 +
7324 +/**
7325 + * aa_audit_policy - Do auditing of policy changes
7326 + * @op: policy operation being performed
7327 + * @gfp: memory allocation flags
7328 + * @name: name of profile being manipulated (NOT NULL)
7329 + * @info: any extra information to be audited (MAYBE NULL)
7330 + * @error: error code
7331 + *
7332 + * Returns: the error to be returned after audit is done
7333 + */
7334 +static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
7335 +                       int error)
7336 +{
7337 +       struct common_audit_data sa;
7338 +       COMMON_AUDIT_DATA_INIT(&sa, NONE);
7339 +       sa.aad.op = op;
7340 +       sa.aad.name = name;
7341 +       sa.aad.info = info;
7342 +       sa.aad.error = error;
7343 +
7344 +       return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp,
7345 +                       &sa, NULL);
7346 +}
7347 +
7348 +/**
7349 + * aa_may_manage_policy - can the current task manage policy
7350 + * @op: the policy manipulation operation being done
7351 + *
7352 + * Returns: true if the task is allowed to manipulate policy
7353 + */
7354 +bool aa_may_manage_policy(int op)
7355 +{
7356 +       /* check if loading policy is locked out */
7357 +       if (aa_g_lock_policy) {
7358 +               audit_policy(op, GFP_KERNEL, NULL, "policy_locked", -EACCES);
7359 +               return 0;
7360 +       }
7361 +
7362 +       if (!capable(CAP_MAC_ADMIN)) {
7363 +               audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
7364 +               return 0;
7365 +       }
7366 +
7367 +       return 1;
7368 +}
7369 +
7370 +/**
7371 + * aa_replace_profiles - replace profile(s) on the profile list
7372 + * @udata: serialized data stream  (NOT NULL)
7373 + * @size: size of the serialized data stream
7374 + * @noreplace: true if only doing addition, no replacement allowed
7375 + *
7376 + * unpack and replace a profile on the profile list and uses of that profile
7377 + * by any aa_task_cxt.  If the profile does not exist on the profile list
7378 + * it is added.
7379 + *
7380 + * Returns: size of data consumed else error code on failure.
7381 + */
7382 +ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
7383 +{
7384 +       struct aa_policy *policy;
7385 +       struct aa_profile *old_profile = NULL, *new_profile = NULL;
7386 +       struct aa_profile *rename_profile = NULL;
7387 +       struct aa_namespace *ns = NULL;
7388 +       const char *ns_name, *name = NULL, *info = NULL;
7389 +       int op = OP_PROF_REPL;
7390 +       ssize_t error;
7391 +
7392 +       /* released below */
7393 +       new_profile = aa_unpack(udata, size, &ns_name);
7394 +       if (IS_ERR(new_profile)) {
7395 +               error = PTR_ERR(new_profile);
7396 +               new_profile = NULL;
7397 +               goto fail;
7398 +       }
7399 +
7400 +       /* released below */
7401 +       ns = aa_prepare_namespace(ns_name);
7402 +       if (!ns) {
7403 +               info = "failed to prepare namespace";
7404 +               error = -ENOMEM;
7405 +               name = ns_name;
7406 +               goto fail;
7407 +       }
7408 +
7409 +       name = new_profile->base.hname;
7410 +
7411 +       write_lock(&ns->lock);
7412 +       /* no ref on policy only use inside lock */
7413 +       policy = __lookup_parent(ns, new_profile->base.hname);
7414 +
7415 +       if (!policy) {
7416 +               info = "parent does not exist";
7417 +               error = -ENOENT;
7418 +               goto audit;
7419 +       }
7420 +
7421 +       old_profile = __find_child(&policy->profiles, new_profile->base.name);
7422 +       /* released below */
7423 +       aa_get_profile(old_profile);
7424 +
7425 +       if (new_profile->rename) {
7426 +               rename_profile = __lookup_profile(&ns->base,
7427 +                                                 new_profile->rename);
7428 +               /* released below */
7429 +               aa_get_profile(rename_profile);
7430 +
7431 +               if (!rename_profile) {
7432 +                       info = "profile to rename does not exist";
7433 +                       name = new_profile->rename;
7434 +                       error = -ENOENT;
7435 +                       goto audit;
7436 +               }
7437 +       }
7438 +
7439 +       error = replacement_allowed(old_profile, noreplace, &info);
7440 +       if (error)
7441 +               goto audit;
7442 +
7443 +       error = replacement_allowed(rename_profile, noreplace, &info);
7444 +       if (error)
7445 +               goto audit;
7446 +
7447 +audit:
7448 +       if (!old_profile && !rename_profile)
7449 +               op = OP_PROF_LOAD;
7450 +
7451 +       error = audit_policy(op, GFP_ATOMIC, name, info, error);
7452 +
7453 +       if (!error) {
7454 +               if (rename_profile)
7455 +                       __replace_profile(rename_profile, new_profile);
7456 +               if (old_profile) {
7457 +                       /* when there are both rename and old profiles
7458 +                        * inherit old profiles sid
7459 +                        */
7460 +                       if (rename_profile)
7461 +                               aa_free_sid(new_profile->sid);
7462 +                       __replace_profile(old_profile, new_profile);
7463 +               }
7464 +               if (!(old_profile || rename_profile))
7465 +                       __add_new_profile(ns, policy, new_profile);
7466 +       }
7467 +       write_unlock(&ns->lock);
7468 +
7469 +out:
7470 +       aa_put_namespace(ns);
7471 +       aa_put_profile(rename_profile);
7472 +       aa_put_profile(old_profile);
7473 +       aa_put_profile(new_profile);
7474 +       if (error)
7475 +               return error;
7476 +       return size;
7477 +
7478 +fail:
7479 +       error = audit_policy(op, GFP_KERNEL, name, info, error);
7480 +       goto out;
7481 +}
7482 +
7483 +/**
7484 + * aa_remove_profiles - remove profile(s) from the system
7485 + * @fqname: name of the profile or namespace to remove  (NOT NULL)
7486 + * @size: size of the name
7487 + *
7488 + * Remove a profile or sub namespace from the current namespace, so that
7489 + * they can not be found anymore and mark them as replaced by unconfined
7490 + *
7491 + * NOTE: removing confinement does not restore rlimits to preconfinemnet values
7492 + *
7493 + * Returns: size of data consume else error code if fails
7494 + */
7495 +ssize_t aa_remove_profiles(char *fqname, size_t size)
7496 +{
7497 +       struct aa_namespace *root, *ns = NULL;
7498 +       struct aa_profile *profile = NULL;
7499 +       const char *name = fqname, *info = NULL;
7500 +       ssize_t error = 0;
7501 +
7502 +       if (*fqname == 0) {
7503 +               info = "no profile specified";
7504 +               error = -ENOENT;
7505 +               goto fail;
7506 +       }
7507 +
7508 +       root = aa_current_profile()->ns;
7509 +
7510 +       if (fqname[0] == ':') {
7511 +               char *ns_name;
7512 +               name = aa_split_fqname(fqname, &ns_name);
7513 +               if (ns_name) {
7514 +                       /* released below */
7515 +                       ns = aa_find_namespace(root, ns_name);
7516 +                       if (!ns) {
7517 +                               info = "namespace does not exist";
7518 +                               error = -ENOENT;
7519 +                               goto fail;
7520 +                       }
7521 +               }
7522 +       } else
7523 +               /* released below */
7524 +               ns = aa_get_namespace(root);
7525 +
7526 +       write_lock(&ns->lock);
7527 +       if (!name) {
7528 +               /* remove namespace - can only happen if fqname[0] == ':' */
7529 +               __remove_namespace(ns);
7530 +       } else {
7531 +               /* remove profile */
7532 +               profile = aa_get_profile(__lookup_profile(&ns->base, name));
7533 +               if (!profile) {
7534 +                       error = -ENOENT;
7535 +                       info = "profile does not exist";
7536 +                       goto fail_ns_lock;
7537 +               }
7538 +               name = profile->base.hname;
7539 +               __remove_profile(profile);
7540 +       }
7541 +       write_unlock(&ns->lock);
7542 +
7543 +       /* don't fail removal if audit fails */
7544 +       (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);
7545 +       aa_put_namespace(ns);
7546 +       aa_put_profile(profile);
7547 +       return size;
7548 +
7549 +fail_ns_lock:
7550 +       write_unlock(&ns->lock);
7551 +       aa_put_namespace(ns);
7552 +
7553 +fail:
7554 +       (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error);
7555 +       return error;
7556 +}
7557 diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
7558 new file mode 100644
7559 index 0000000..6b0637b
7560 --- /dev/null
7561 +++ b/security/apparmor/policy_unpack.c
7562 @@ -0,0 +1,740 @@
7563 +/*
7564 + * AppArmor security module
7565 + *
7566 + * This file contains AppArmor functions for unpacking policy loaded from
7567 + * userspace.
7568 + *
7569 + * Copyright (C) 1998-2008 Novell/SUSE
7570 + * Copyright 2009-2010 Canonical Ltd.
7571 + *
7572 + * This program is free software; you can redistribute it and/or
7573 + * modify it under the terms of the GNU General Public License as
7574 + * published by the Free Software Foundation, version 2 of the
7575 + * License.
7576 + *
7577 + * AppArmor uses a serialized binary format for loading policy.
7578 + * To find policy format documentation look in Documentation/apparmor.txt
7579 + * All policy is validated before it is used.
7580 + */
7581 +
7582 +#include <asm/unaligned.h>
7583 +#include <linux/ctype.h>
7584 +#include <linux/errno.h>
7585 +
7586 +#include "include/apparmor.h"
7587 +#include "include/audit.h"
7588 +#include "include/context.h"
7589 +#include "include/match.h"
7590 +#include "include/policy.h"
7591 +#include "include/policy_unpack.h"
7592 +#include "include/sid.h"
7593 +
7594 +/*
7595 + * The AppArmor interface treats data as a type byte followed by the
7596 + * actual data.  The interface has the notion of a a named entry
7597 + * which has a name (AA_NAME typecode followed by name string) followed by
7598 + * the entries typecode and data.  Named types allow for optional
7599 + * elements and extensions to be added and tested for without breaking
7600 + * backwards compatibility.
7601 + */
7602 +
7603 +enum aa_code {
7604 +       AA_U8,
7605 +       AA_U16,
7606 +       AA_U32,
7607 +       AA_U64,
7608 +       AA_NAME,                /* same as string except it is items name */
7609 +       AA_STRING,
7610 +       AA_BLOB,
7611 +       AA_STRUCT,
7612 +       AA_STRUCTEND,
7613 +       AA_LIST,
7614 +       AA_LISTEND,
7615 +       AA_ARRAY,
7616 +       AA_ARRAYEND,
7617 +};
7618 +
7619 +/*
7620 + * aa_ext is the read of the buffer containing the serialized profile.  The
7621 + * data is copied into a kernel buffer in apparmorfs and then handed off to
7622 + * the unpack routines.
7623 + */
7624 +struct aa_ext {
7625 +       void *start;
7626 +       void *end;
7627 +       void *pos;              /* pointer to current position in the buffer */
7628 +       u32 version;
7629 +};
7630 +
7631 +/* audit callback for unpack fields */
7632 +static void audit_cb(struct audit_buffer *ab, void *va)
7633 +{
7634 +       struct common_audit_data *sa = va;
7635 +       if (sa->aad.iface.target) {
7636 +               struct aa_profile *name = sa->aad.iface.target;
7637 +               audit_log_format(ab, " name=");
7638 +               audit_log_untrustedstring(ab, name->base.hname);
7639 +       }
7640 +       if (sa->aad.iface.pos)
7641 +               audit_log_format(ab, " offset=%ld", sa->aad.iface.pos);
7642 +}
7643 +
7644 +/**
7645 + * audit_iface - do audit message for policy unpacking/load/replace/remove
7646 + * @new: profile if it has been allocated (MAYBE NULL)
7647 + * @name: name of the profile being manipulated (MAYBE NULL)
7648 + * @info: any extra info about the failure (MAYBE NULL)
7649 + * @e: buffer position info (NOT NULL)
7650 + * @error: error code
7651 + *
7652 + * Returns: %0 or error
7653 + */
7654 +static int audit_iface(struct aa_profile *new, const char *name,
7655 +                      const char *info, struct aa_ext *e, int error)
7656 +{
7657 +       struct aa_profile *profile = __aa_current_profile();
7658 +       struct common_audit_data sa;
7659 +       COMMON_AUDIT_DATA_INIT(&sa, NONE);
7660 +       sa.aad.iface.pos = e->pos - e->start;
7661 +       sa.aad.iface.target = new;
7662 +       sa.aad.name = name;
7663 +       sa.aad.info = info;
7664 +       sa.aad.error = error;
7665 +
7666 +       return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa,
7667 +                       audit_cb);
7668 +}
7669 +
7670 +/* test if read will be in packed data bounds */
7671 +static bool inbounds(struct aa_ext *e, size_t size)
7672 +{
7673 +       return (size <= e->end - e->pos);
7674 +}
7675 +
7676 +/**
7677 + * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
7678 + * @e: serialized data read head (NOT NULL)
7679 + * @chunk: start address for chunk of data (NOT NULL)
7680 + *
7681 + * Returns: the size of chunk found with the read head at the end of the chunk.
7682 + */
7683 +static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
7684 +{
7685 +       size_t size = 0;
7686 +
7687 +       if (!inbounds(e, sizeof(u16)))
7688 +               return 0;
7689 +       size = le16_to_cpu(get_unaligned((u16 *) e->pos));
7690 +       e->pos += sizeof(u16);
7691 +       if (!inbounds(e, size))
7692 +               return 0;
7693 +       *chunk = e->pos;
7694 +       e->pos += size;
7695 +       return size;
7696 +}
7697 +
7698 +/* unpack control byte */
7699 +static bool unpack_X(struct aa_ext *e, enum aa_code code)
7700 +{
7701 +       if (!inbounds(e, 1))
7702 +               return 0;
7703 +       if (*(u8 *) e->pos != code)
7704 +               return 0;
7705 +       e->pos++;
7706 +       return 1;
7707 +}
7708 +
7709 +/**
7710 + * unpack_nameX - check is the next element is of type X with a name of @name
7711 + * @e: serialized data extent information  (NOT NULL)
7712 + * @code: type code
7713 + * @name: name to match to the serialized element.  (MAYBE NULL)
7714 + *
7715 + * check that the next serialized data element is of type X and has a tag
7716 + * name @name.  If @name is specified then there must be a matching
7717 + * name element in the stream.  If @name is NULL any name element will be
7718 + * skipped and only the typecode will be tested.
7719 + *
7720 + * Returns 1 on success (both type code and name tests match) and the read
7721 + * head is advanced past the headers
7722 + *
7723 + * Returns: 0 if either match fails, the read head does not move
7724 + */
7725 +static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
7726 +{
7727 +       /*
7728 +        * May need to reset pos if name or type doesn't match
7729 +        */
7730 +       void *pos = e->pos;
7731 +       /*
7732 +        * Check for presence of a tagname, and if present name size
7733 +        * AA_NAME tag value is a u16.
7734 +        */
7735 +       if (unpack_X(e, AA_NAME)) {
7736 +               char *tag = NULL;
7737 +               size_t size = unpack_u16_chunk(e, &tag);
7738 +               /* if a name is specified it must match. otherwise skip tag */
7739 +               if (name && (!size || strcmp(name, tag)))
7740 +                       goto fail;
7741 +       } else if (name) {
7742 +               /* if a name is specified and there is no name tag fail */
7743 +               goto fail;
7744 +       }
7745 +
7746 +       /* now check if type code matches */
7747 +       if (unpack_X(e, code))
7748 +               return 1;
7749 +
7750 +fail:
7751 +       e->pos = pos;
7752 +       return 0;
7753 +}
7754 +
7755 +static bool unpack_u16(struct aa_ext *e, u16 *data, const char *name)
7756 +{
7757 +       if (unpack_nameX(e, AA_U16, name)) {
7758 +               if (!inbounds(e, sizeof(u16)))
7759 +                       return 0;
7760 +               if (data)
7761 +                       *data = le16_to_cpu(get_unaligned((u16 *) e->pos));
7762 +               e->pos += sizeof(u16);
7763 +               return 1;
7764 +       }
7765 +       return 0;
7766 +}
7767 +
7768 +static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
7769 +{
7770 +       if (unpack_nameX(e, AA_U32, name)) {
7771 +               if (!inbounds(e, sizeof(u32)))
7772 +                       return 0;
7773 +               if (data)
7774 +                       *data = le32_to_cpu(get_unaligned((u32 *) e->pos));
7775 +               e->pos += sizeof(u32);
7776 +               return 1;
7777 +       }
7778 +       return 0;
7779 +}
7780 +
7781 +static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
7782 +{
7783 +       if (unpack_nameX(e, AA_U64, name)) {
7784 +               if (!inbounds(e, sizeof(u64)))
7785 +                       return 0;
7786 +               if (data)
7787 +                       *data = le64_to_cpu(get_unaligned((u64 *) e->pos));
7788 +               e->pos += sizeof(u64);
7789 +               return 1;
7790 +       }
7791 +       return 0;
7792 +}
7793 +
7794 +static size_t unpack_array(struct aa_ext *e, const char *name)
7795 +{
7796 +       if (unpack_nameX(e, AA_ARRAY, name)) {
7797 +               int size;
7798 +               if (!inbounds(e, sizeof(u16)))
7799 +                       return 0;
7800 +               size = (int)le16_to_cpu(get_unaligned((u16 *) e->pos));
7801 +               e->pos += sizeof(u16);
7802 +               return size;
7803 +       }
7804 +       return 0;
7805 +}
7806 +
7807 +static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
7808 +{
7809 +       if (unpack_nameX(e, AA_BLOB, name)) {
7810 +               u32 size;
7811 +               if (!inbounds(e, sizeof(u32)))
7812 +                       return 0;
7813 +               size = le32_to_cpu(get_unaligned((u32 *) e->pos));
7814 +               e->pos += sizeof(u32);
7815 +               if (inbounds(e, (size_t) size)) {
7816 +                       *blob = e->pos;
7817 +                       e->pos += size;
7818 +                       return size;
7819 +               }
7820 +       }
7821 +       return 0;
7822 +}
7823 +
7824 +static int unpack_str(struct aa_ext *e, const char **string, const char *name)
7825 +{
7826 +       char *src_str;
7827 +       size_t size = 0;
7828 +       void *pos = e->pos;
7829 +       *string = NULL;
7830 +       if (unpack_nameX(e, AA_STRING, name)) {
7831 +               size = unpack_u16_chunk(e, &src_str);
7832 +               if (size) {
7833 +                       /* strings are null terminated, length is size - 1 */
7834 +                       if (src_str[size - 1] != 0)
7835 +                               goto fail;
7836 +                       *string = src_str;
7837 +               }
7838 +       }
7839 +       return size;
7840 +
7841 +fail:
7842 +       e->pos = pos;
7843 +       return 0;
7844 +}
7845 +
7846 +static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
7847 +{
7848 +       const char *tmp;
7849 +       void *pos = e->pos;
7850 +       int res = unpack_str(e, &tmp, name);
7851 +       *string = NULL;
7852 +
7853 +       if (!res)
7854 +               return 0;
7855 +
7856 +       *string = kmemdup(tmp, res, GFP_KERNEL);
7857 +       if (!*string) {
7858 +               e->pos = pos;
7859 +               return 0;
7860 +       }
7861 +
7862 +       return res;
7863 +}
7864 +
7865 +/**
7866 + * verify_accept - verify the accept tables of a dfa
7867 + * @dfa: dfa to verify accept tables of (NOT NULL)
7868 + * @flags: flags governing dfa
7869 + *
7870 + * Returns: 1 if valid accept tables else 0 if error
7871 + */
7872 +static bool verify_accept(struct aa_dfa *dfa, int flags)
7873 +{
7874 +       int i;
7875 +
7876 +       /* verify accept permissions */
7877 +       for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
7878 +               int mode = ACCEPT_TABLE(dfa)[i];
7879 +
7880 +               if (mode & ~DFA_VALID_PERM_MASK)
7881 +                       return 0;
7882 +
7883 +               if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
7884 +                       return 0;
7885 +       }
7886 +       return 1;
7887 +}
7888 +
7889 +/**
7890 + * unpack_dfa - unpack a file rule dfa
7891 + * @e: serialized data extent information (NOT NULL)
7892 + *
7893 + * returns dfa or ERR_PTR or NULL if no dfa
7894 + */
7895 +static struct aa_dfa *unpack_dfa(struct aa_ext *e)
7896 +{
7897 +       char *blob = NULL;
7898 +       size_t size;
7899 +       struct aa_dfa *dfa = NULL;
7900 +
7901 +       size = unpack_blob(e, &blob, "aadfa");
7902 +       if (size) {
7903 +               /*
7904 +                * The dfa is aligned with in the blob to 8 bytes
7905 +                * from the beginning of the stream.
7906 +                */
7907 +               size_t sz = blob - (char *)e->start;
7908 +               size_t pad = ALIGN(sz, 8) - sz;
7909 +               int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
7910 +                       TO_ACCEPT2_FLAG(YYTD_DATA32);
7911 +
7912 +
7913 +               if (aa_g_paranoid_load)
7914 +                       flags |= DFA_FLAG_VERIFY_STATES;
7915 +
7916 +               dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
7917 +
7918 +               if (IS_ERR(dfa))
7919 +                       return dfa;
7920 +
7921 +               if (!verify_accept(dfa, flags))
7922 +                       goto fail;
7923 +       }
7924 +
7925 +       return dfa;
7926 +
7927 +fail:
7928 +       aa_put_dfa(dfa);
7929 +       return ERR_PTR(-EPROTO);
7930 +}
7931 +
7932 +/**
7933 + * unpack_trans_table - unpack a profile transition table
7934 + * @e: serialized data extent information  (NOT NULL)
7935 + * @profile: profile to add the accept table to (NOT NULL)
7936 + *
7937 + * Returns: 1 if table succesfully unpacked
7938 + */
7939 +static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
7940 +{
7941 +       void *pos = e->pos;
7942 +
7943 +       /* exec table is optional */
7944 +       if (unpack_nameX(e, AA_STRUCT, "xtable")) {
7945 +               int i, size;
7946 +
7947 +               size = unpack_array(e, NULL);
7948 +               /* currently 4 exec bits and entries 0-3 are reserved iupcx */
7949 +               if (size > 16 - 4)
7950 +                       goto fail;
7951 +               profile->file.trans.table = kzalloc(sizeof(char *) * size,
7952 +                                                   GFP_KERNEL);
7953 +               if (!profile->file.trans.table)
7954 +                       goto fail;
7955 +
7956 +               profile->file.trans.size = size;
7957 +               for (i = 0; i < size; i++) {
7958 +                       char *str;
7959 +                       int c, j, size = unpack_strdup(e, &str, NULL);
7960 +                       /* unpack_strdup verifies that the last character is
7961 +                        * null termination byte.
7962 +                        */
7963 +                       if (!size)
7964 +                               goto fail;
7965 +                       profile->file.trans.table[i] = str;
7966 +                       /* verify that name doesn't start with space */
7967 +                       if (isspace(*str))
7968 +                               goto fail;
7969 +
7970 +                       /* count internal #  of internal \0 */
7971 +                       for (c = j = 0; j < size - 2; j++) {
7972 +                               if (!str[j])
7973 +                                       c++;
7974 +                       }
7975 +                       if (*str == ':') {
7976 +                               /* beginning with : requires an embedded \0,
7977 +                                * verify that exactly 1 internal \0 exists
7978 +                                * trailing \0 already verified by unpack_strdup
7979 +                                */
7980 +                               if (c != 1)
7981 +                                       goto fail;
7982 +                               /* first character after : must be valid */
7983 +                               if (!str[1])
7984 +                                       goto fail;
7985 +                       } else if (c)
7986 +                               /* fail - all other cases with embedded \0 */
7987 +                               goto fail;
7988 +               }
7989 +               if (!unpack_nameX(e, AA_ARRAYEND, NULL))
7990 +                       goto fail;
7991 +               if (!unpack_nameX(e, AA_STRUCTEND, NULL))
7992 +                       goto fail;
7993 +       }
7994 +       return 1;
7995 +
7996 +fail:
7997 +       aa_free_domain_entries(&profile->file.trans);
7998 +       e->pos = pos;
7999 +       return 0;
8000 +}
8001 +
8002 +static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
8003 +{
8004 +       void *pos = e->pos;
8005 +
8006 +       /* rlimits are optional */
8007 +       if (unpack_nameX(e, AA_STRUCT, "rlimits")) {
8008 +               int i, size;
8009 +               u32 tmp = 0;
8010 +               if (!unpack_u32(e, &tmp, NULL))
8011 +                       goto fail;
8012 +               profile->rlimits.mask = tmp;
8013 +
8014 +               size = unpack_array(e, NULL);
8015 +               if (size > RLIM_NLIMITS)
8016 +                       goto fail;
8017 +               for (i = 0; i < size; i++) {
8018 +                       u64 tmp = 0;
8019 +                       int a = aa_map_resource(i);
8020 +                       if (!unpack_u64(e, &tmp, NULL))
8021 +                               goto fail;
8022 +                       profile->rlimits.limits[a].rlim_max = tmp;
8023 +               }
8024 +               if (!unpack_nameX(e, AA_ARRAYEND, NULL))
8025 +                       goto fail;
8026 +               if (!unpack_nameX(e, AA_STRUCTEND, NULL))
8027 +                       goto fail;
8028 +       }
8029 +       return 1;
8030 +
8031 +fail:
8032 +       e->pos = pos;
8033 +       return 0;
8034 +}
8035 +
8036 +/**
8037 + * unpack_profile - unpack a serialized profile
8038 + * @e: serialized data extent information (NOT NULL)
8039 + *
8040 + * NOTE: unpack profile sets audit struct if there is a failure
8041 + */
8042 +static struct aa_profile *unpack_profile(struct aa_ext *e)
8043 +{
8044 +       struct aa_profile *profile = NULL;
8045 +       const char *name = NULL;
8046 +       size_t size = 0;
8047 +       int i, error = -EPROTO;
8048 +       kernel_cap_t tmpcap;
8049 +       u32 tmp;
8050 +
8051 +       /* check that we have the right struct being passed */
8052 +       if (!unpack_nameX(e, AA_STRUCT, "profile"))
8053 +               goto fail;
8054 +       if (!unpack_str(e, &name, NULL))
8055 +               goto fail;
8056 +
8057 +       profile = aa_alloc_profile(name);
8058 +       if (!profile)
8059 +               return ERR_PTR(-ENOMEM);
8060 +
8061 +       /* profile renaming is optional */
8062 +       (void) unpack_str(e, &profile->rename, "rename");
8063 +
8064 +       /* xmatch is optional and may be NULL */
8065 +       profile->xmatch = unpack_dfa(e);
8066 +       if (IS_ERR(profile->xmatch)) {
8067 +               error = PTR_ERR(profile->xmatch);
8068 +               profile->xmatch = NULL;
8069 +               goto fail;
8070 +       }
8071 +       /* xmatch_len is not optional if xmatch is set */
8072 +       if (profile->xmatch) {
8073 +               if (!unpack_u32(e, &tmp, NULL))
8074 +                       goto fail;
8075 +               profile->xmatch_len = tmp;
8076 +       }
8077 +
8078 +       /* per profile debug flags (complain, audit) */
8079 +       if (!unpack_nameX(e, AA_STRUCT, "flags"))
8080 +               goto fail;
8081 +       if (!unpack_u32(e, &tmp, NULL))
8082 +               goto fail;
8083 +       if (tmp)
8084 +               profile->flags |= PFLAG_HAT;
8085 +       if (!unpack_u32(e, &tmp, NULL))
8086 +               goto fail;
8087 +       if (tmp)
8088 +               profile->mode = APPARMOR_COMPLAIN;
8089 +       if (!unpack_u32(e, &tmp, NULL))
8090 +               goto fail;
8091 +       if (tmp)
8092 +               profile->audit = AUDIT_ALL;
8093 +
8094 +       if (!unpack_nameX(e, AA_STRUCTEND, NULL))
8095 +               goto fail;
8096 +
8097 +       /* path_flags is optional */
8098 +       if (unpack_u32(e, &profile->path_flags, "path_flags"))
8099 +               profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
8100 +       else
8101 +               /* set a default value if path_flags field is not present */
8102 +               profile->path_flags = PFLAG_MEDIATE_DELETED;
8103 +
8104 +       if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
8105 +               goto fail;
8106 +       if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
8107 +               goto fail;
8108 +       if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL))
8109 +               goto fail;
8110 +       if (!unpack_u32(e, &tmpcap.cap[0], NULL))
8111 +               goto fail;
8112 +
8113 +       if (unpack_nameX(e, AA_STRUCT, "caps64")) {
8114 +               /* optional upper half of 64 bit caps */
8115 +               if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
8116 +                       goto fail;
8117 +               if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL))
8118 +                       goto fail;
8119 +               if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL))
8120 +                       goto fail;
8121 +               if (!unpack_u32(e, &(tmpcap.cap[1]), NULL))
8122 +                       goto fail;
8123 +               if (!unpack_nameX(e, AA_STRUCTEND, NULL))
8124 +                       goto fail;
8125 +       }
8126 +
8127 +       if (unpack_nameX(e, AA_STRUCT, "capsx")) {
8128 +               /* optional extended caps mediation mask */
8129 +               if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
8130 +                       goto fail;
8131 +               if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
8132 +                       goto fail;
8133 +       }
8134 +
8135 +       if (!unpack_rlimits(e, profile))
8136 +               goto fail;
8137 +
8138 +       size = unpack_array(e, "net_allowed_af");
8139 +       if (size) {
8140 +               if (size > AF_MAX)
8141 +                       goto fail;
8142 +
8143 +               for (i = 0; i < size; i++) {
8144 +                       if (!unpack_u16(e, &profile->net.allow[i], NULL))
8145 +                               goto fail;
8146 +                       if (!unpack_u16(e, &profile->net.audit[i], NULL))
8147 +                               goto fail;
8148 +                       if (!unpack_u16(e, &profile->net.quiet[i], NULL))
8149 +                               goto fail;
8150 +               }
8151 +               if (!unpack_nameX(e, AA_ARRAYEND, NULL))
8152 +                       goto fail;
8153 +               /*
8154 +                * allow unix domain and netlink sockets they are handled
8155 +                * by IPC
8156 +                */
8157 +       }
8158 +       profile->net.allow[AF_UNIX] = 0xffff;
8159 +       profile->net.allow[AF_NETLINK] = 0xffff;
8160 +
8161 +       /* get file rules */
8162 +       profile->file.dfa = unpack_dfa(e);
8163 +       if (IS_ERR(profile->file.dfa)) {
8164 +               error = PTR_ERR(profile->file.dfa);
8165 +               profile->file.dfa = NULL;
8166 +               goto fail;
8167 +       }
8168 +
8169 +       if (!unpack_u32(e, &profile->file.start, "dfa_start"))
8170 +               /* default start state */
8171 +               profile->file.start = DFA_START;
8172 +
8173 +       if (!unpack_trans_table(e, profile))
8174 +               goto fail;
8175 +
8176 +       if (!unpack_nameX(e, AA_STRUCTEND, NULL))
8177 +               goto fail;
8178 +
8179 +       return profile;
8180 +
8181 +fail:
8182 +       if (profile)
8183 +               name = NULL;
8184 +       else if (!name)
8185 +               name = "unknown";
8186 +       audit_iface(profile, name, "failed to unpack profile", e, error);
8187 +       aa_put_profile(profile);
8188 +
8189 +       return ERR_PTR(error);
8190 +}
8191 +
8192 +/**
8193 + * verify_head - unpack serialized stream header
8194 + * @e: serialized data read head (NOT NULL)
8195 + * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
8196 + *
8197 + * Returns: error or 0 if header is good
8198 + */
8199 +static int verify_header(struct aa_ext *e, const char **ns)
8200 +{
8201 +       int error = -EPROTONOSUPPORT;
8202 +       /* get the interface version */
8203 +       if (!unpack_u32(e, &e->version, "version")) {
8204 +               audit_iface(NULL, NULL, "invalid profile format", e, error);
8205 +               return error;
8206 +       }
8207 +
8208 +       /* check that the interface version is currently supported */
8209 +       if (e->version != 5) {
8210 +               audit_iface(NULL, NULL, "unsupported interface version", e,
8211 +                           error);
8212 +               return error;
8213 +       }
8214 +
8215 +       /* read the namespace if present */
8216 +       if (!unpack_str(e, ns, "namespace"))
8217 +               *ns = NULL;
8218 +
8219 +       return 0;
8220 +}
8221 +
8222 +static bool verify_xindex(int xindex, int table_size)
8223 +{
8224 +       int index, xtype;
8225 +       xtype = xindex & AA_X_TYPE_MASK;
8226 +       index = xindex & AA_X_INDEX_MASK;
8227 +       if (xtype == AA_X_TABLE && index > table_size)
8228 +               return 0;
8229 +       return 1;
8230 +}
8231 +
8232 +/* verify dfa xindexes are in range of transition tables */
8233 +static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
8234 +{
8235 +       int i;
8236 +       for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
8237 +               if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
8238 +                       return 0;
8239 +               if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
8240 +                       return 0;
8241 +       }
8242 +       return 1;
8243 +}
8244 +
8245 +/**
8246 + * verify_profile - Do post unpack analysis to verify profile consistency
8247 + * @profile: profile to verify (NOT NULL)
8248 + *
8249 + * Returns: 0 if passes verification else error
8250 + */
8251 +static int verify_profile(struct aa_profile *profile)
8252 +{
8253 +       if (aa_g_paranoid_load) {
8254 +               if (profile->file.dfa &&
8255 +                   !verify_dfa_xindex(profile->file.dfa,
8256 +                                      profile->file.trans.size)) {
8257 +                       audit_iface(profile, NULL, "Invalid named transition",
8258 +                                   NULL, -EPROTO);
8259 +                       return -EPROTO;
8260 +               }
8261 +       }
8262 +
8263 +       return 0;
8264 +}
8265 +
8266 +/**
8267 + * aa_unpack - unpack packed binary profile data loaded from user space
8268 + * @udata: user data copied to kmem  (NOT NULL)
8269 + * @size: the size of the user data
8270 + * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
8271 + *
8272 + * Unpack user data and return refcounted allocated profile or ERR_PTR
8273 + *
8274 + * Returns: profile else error pointer if fails to unpack
8275 + */
8276 +struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns)
8277 +{
8278 +       struct aa_profile *profile = NULL;
8279 +       int error;
8280 +       struct aa_ext e = {
8281 +               .start = udata,
8282 +               .end = udata + size,
8283 +               .pos = udata,
8284 +       };
8285 +
8286 +       error = verify_header(&e, ns);
8287 +       if (error)
8288 +               return ERR_PTR(error);
8289 +
8290 +       profile = unpack_profile(&e);
8291 +       if (IS_ERR(profile))
8292 +               return profile;
8293 +
8294 +       error = verify_profile(profile);
8295 +       if (error) {
8296 +               aa_put_profile(profile);
8297 +               profile = ERR_PTR(error);
8298 +       }
8299 +
8300 +       /* return refcount */
8301 +       return profile;
8302 +}
8303 diff --git a/security/apparmor/policy_unpack.c.rej b/security/apparmor/policy_unpack.c.rej
8304 new file mode 100644
8305 index 0000000..5bddfd6
8306 --- /dev/null
8307 +++ b/security/apparmor/policy_unpack.c.rej
8308 @@ -0,0 +1,11 @@
8309 +diff a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c   (rejected hunks)
8310 +@@ -473,7 +473,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
8311 + {
8312 +       struct aa_profile *profile = NULL;
8313 +       const char *name = NULL, *info = NULL;
8314 +-      int error = -EPROTO;
8315 ++      size_t size = 0;
8316 ++      int i, error = -EPROTO;
8317 +       kernel_cap_t tmpcap;
8318 +       u32 tmp;
8319 +       u64 tmp64;
8320 diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
8321 new file mode 100644
8322 index 0000000..04a2cf8
8323 --- /dev/null
8324 +++ b/security/apparmor/procattr.c
8325 @@ -0,0 +1,170 @@
8326 +/*
8327 + * AppArmor security module
8328 + *
8329 + * This file contains AppArmor /proc/<pid>/attr/ interface functions
8330 + *
8331 + * Copyright (C) 1998-2008 Novell/SUSE
8332 + * Copyright 2009-2010 Canonical Ltd.
8333 + *
8334 + * This program is free software; you can redistribute it and/or
8335 + * modify it under the terms of the GNU General Public License as
8336 + * published by the Free Software Foundation, version 2 of the
8337 + * License.
8338 + */
8339 +
8340 +#include "include/apparmor.h"
8341 +#include "include/context.h"
8342 +#include "include/policy.h"
8343 +#include "include/domain.h"
8344 +
8345 +
8346 +/**
8347 + * aa_getprocattr - Return the profile information for @profile
8348 + * @profile: the profile to print profile info about  (NOT NULL)
8349 + * @string: Returns - string containing the profile info (NOT NULL)
8350 + *
8351 + * Returns: length of @string on success else error on failure
8352 + *
8353 + * Requires: profile != NULL
8354 + *
8355 + * Creates a string containing the namespace_name://profile_name for
8356 + * @profile.
8357 + *
8358 + * Returns: size of string placed in @string else error code on failure
8359 + */
8360 +int aa_getprocattr(struct aa_profile *profile, char **string)
8361 +{
8362 +       char *str;
8363 +       int len = 0, mode_len = 0, ns_len = 0, name_len;
8364 +       const char *mode_str = profile_mode_names[profile->mode];
8365 +       const char *ns_name = NULL;
8366 +       struct aa_namespace *ns = profile->ns;
8367 +       struct aa_namespace *current_ns = __aa_current_profile()->ns;
8368 +       char *s;
8369 +
8370 +       if (!aa_ns_visible(current_ns, ns))
8371 +               return -EACCES;
8372 +
8373 +       ns_name = aa_ns_name(current_ns, ns);
8374 +       ns_len = strlen(ns_name);
8375 +
8376 +       /* if the visible ns_name is > 0 increase size for : :// seperator */
8377 +       if (ns_len)
8378 +               ns_len += 4;
8379 +
8380 +       /* unconfined profiles don't have a mode string appended */
8381 +       if (!unconfined(profile))
8382 +               mode_len = strlen(mode_str) + 3;        /* + 3 for _() */
8383 +
8384 +       name_len = strlen(profile->base.hname);
8385 +       len = mode_len + ns_len + name_len + 1;     /* + 1 for \n */
8386 +       s = str = kmalloc(len + 1, GFP_KERNEL);     /* + 1 \0 */
8387 +       if (!str)
8388 +               return -ENOMEM;
8389 +
8390 +       if (ns_len) {
8391 +               /* skip over prefix current_ns->base.hname and separating // */
8392 +               sprintf(s, ":%s://", ns_name);
8393 +               s += ns_len;
8394 +       }
8395 +       if (unconfined(profile))
8396 +               /* mode string not being appended */
8397 +               sprintf(s, "%s\n", profile->base.hname);
8398 +       else
8399 +               sprintf(s, "%s (%s)\n", profile->base.hname, mode_str);
8400 +       *string = str;
8401 +
8402 +       /* NOTE: len does not include \0 of string, not saved as part of file */
8403 +       return len;
8404 +}
8405 +
8406 +/**
8407 + * split_token_from_name - separate a string of form  <token>^<name>
8408 + * @op: operation being checked
8409 + * @args: string to parse  (NOT NULL)
8410 + * @token: stores returned parsed token value  (NOT NULL)
8411 + *
8412 + * Returns: start position of name after token else NULL on failure
8413 + */
8414 +static char *split_token_from_name(int op, char *args, u64 * token)
8415 +{
8416 +       char *name;
8417 +
8418 +       *token = simple_strtoull(args, &name, 16);
8419 +       if ((name == args) || *name != '^') {
8420 +               AA_ERROR("%s: Invalid input '%s'", op_table[op], args);
8421 +               return ERR_PTR(-EINVAL);
8422 +       }
8423 +
8424 +       name++;                 /* skip ^ */
8425 +       if (!*name)
8426 +               name = NULL;
8427 +       return name;
8428 +}
8429 +
8430 +/**
8431 + * aa_setprocattr_chagnehat - handle procattr interface to change_hat
8432 + * @args: args received from writing to /proc/<pid>/attr/current (NOT NULL)
8433 + * @size: size of the args
8434 + * @test: true if this is a test of change_hat permissions
8435 + *
8436 + * Returns: %0 or error code if change_hat fails
8437 + */
8438 +int aa_setprocattr_changehat(char *args, size_t size, int test)
8439 +{
8440 +       char *hat;
8441 +       u64 token;
8442 +       const char *hats[16];           /* current hard limit on # of names */
8443 +       int count = 0;
8444 +
8445 +       hat = split_token_from_name(OP_CHANGE_HAT, args, &token);
8446 +       if (IS_ERR(hat))
8447 +               return PTR_ERR(hat);
8448 +
8449 +       if (!hat && !token) {
8450 +               AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
8451 +               return -EINVAL;
8452 +       }
8453 +
8454 +       if (hat) {
8455 +               /* set up hat name vector, args guaranteed null terminated
8456 +                * at args[size] by setprocattr.
8457 +                *
8458 +                * If there are multiple hat names in the buffer each is
8459 +                * separated by a \0.  Ie. userspace writes them pre tokenized
8460 +                */
8461 +               char *end = args + size;
8462 +               for (count = 0; (hat < end) && count < 16; ++count) {
8463 +                       char *next = hat + strlen(hat) + 1;
8464 +                       hats[count] = hat;
8465 +                       hat = next;
8466 +               }
8467 +       }
8468 +
8469 +       AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
8470 +                __func__, token, hat ? hat : NULL);
8471 +
8472 +       return aa_change_hat(hats, count, token, test);
8473 +}
8474 +
8475 +/**
8476 + * aa_setprocattr_changeprofile - handle procattr interface to changeprofile
8477 + * @fqname: args received from writting to /proc/<pid>/attr/current (NOT NULL)
8478 + * @onexec: true if change_profile should be delayed until exec
8479 + * @test: true if this is a test of change_profile permissions
8480 + *
8481 + * Returns: %0 or error code if change_profile fails
8482 + */
8483 +int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test)
8484 +{
8485 +       char *name, *ns_name;
8486 +
8487 +       name = aa_split_fqname(fqname, &ns_name);
8488 +       return aa_change_profile(ns_name, name, onexec, test);
8489 +}
8490 +
8491 +int aa_setprocattr_permipc(char *fqname)
8492 +{
8493 +       /* TODO: add ipc permission querying */
8494 +       return -ENOTSUPP;
8495 +}
8496 diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
8497 new file mode 100644
8498 index 0000000..4a368f1
8499 --- /dev/null
8500 +++ b/security/apparmor/resource.c
8501 @@ -0,0 +1,134 @@
8502 +/*
8503 + * AppArmor security module
8504 + *
8505 + * This file contains AppArmor resource mediation and attachment
8506 + *
8507 + * Copyright (C) 1998-2008 Novell/SUSE
8508 + * Copyright 2009-2010 Canonical Ltd.
8509 + *
8510 + * This program is free software; you can redistribute it and/or
8511 + * modify it under the terms of the GNU General Public License as
8512 + * published by the Free Software Foundation, version 2 of the
8513 + * License.
8514 + */
8515 +
8516 +#include <linux/audit.h>
8517 +
8518 +#include "include/audit.h"
8519 +#include "include/resource.h"
8520 +#include "include/policy.h"
8521 +
8522 +/*
8523 + * Table of rlimit names: we generate it from resource.h.
8524 + */
8525 +#include "rlim_names.h"
8526 +
8527 +/* audit callback for resource specific fields */
8528 +static void audit_cb(struct audit_buffer *ab, void *va)
8529 +{
8530 +       struct common_audit_data *sa = va;
8531 +
8532 +       audit_log_format(ab, " rlimit=%s value=%lu",
8533 +                        rlim_names[sa->aad.rlim.rlim], sa->aad.rlim.max);
8534 +}
8535 +
8536 +/**
8537 + * audit_resource - audit setting resource limit
8538 + * @profile: profile being enforced  (NOT NULL)
8539 + * @resoure: rlimit being auditing
8540 + * @value: value being set
8541 + * @error: error value
8542 + *
8543 + * Returns: 0 or sa->error else other error code on failure
8544 + */
8545 +static int audit_resource(struct aa_profile *profile, unsigned int resource,
8546 +                         unsigned long value, int error)
8547 +{
8548 +       struct common_audit_data sa;
8549 +
8550 +       COMMON_AUDIT_DATA_INIT(&sa, NONE);
8551 +       sa.aad.op = OP_SETRLIMIT,
8552 +       sa.aad.rlim.rlim = resource;
8553 +       sa.aad.rlim.max = value;
8554 +       sa.aad.error = error;
8555 +       return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa,
8556 +                       audit_cb);
8557 +}
8558 +
8559 +/**
8560 + * aa_map_resouce - map compiled policy resource to internal #
8561 + * @resource: flattened policy resource number
8562 + *
8563 + * Returns: resource # for the current architecture.
8564 + *
8565 + * rlimit resource can vary based on architecture, map the compiled policy
8566 + * resource # to the internal representation for the architecture.
8567 + */
8568 +int aa_map_resource(int resource)
8569 +{
8570 +       return rlim_map[resource];
8571 +}
8572 +
8573 +/**
8574 + * aa_task_setrlimit - test permission to set an rlimit
8575 + * @profile - profile confining the task  (NOT NULL)
8576 + * @resource - the resource being set
8577 + * @new_rlim - the new resource limit  (NOT NULL)
8578 + *
8579 + * Control raising the processes hard limit.
8580 + *
8581 + * Returns: 0 or error code if setting resource failed
8582 + */
8583 +int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
8584 +                     struct rlimit *new_rlim)
8585 +{
8586 +       int error = 0;
8587 +
8588 +       if (profile->rlimits.mask & (1 << resource) &&
8589 +           new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)
8590 +
8591 +               error = audit_resource(profile, resource, new_rlim->rlim_max,
8592 +                       -EACCES);
8593 +
8594 +       return error;
8595 +}
8596 +
8597 +/**
8598 + * __aa_transition_rlimits - apply new profile rlimits
8599 + * @old: old profile on task  (NOT NULL)
8600 + * @new: new profile with rlimits to apply  (NOT NULL)
8601 + */
8602 +void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new)
8603 +{
8604 +       unsigned int mask = 0;
8605 +       struct rlimit *rlim, *initrlim;
8606 +       int i;
8607 +
8608 +       /* for any rlimits the profile controlled reset the soft limit
8609 +        * to the less of the tasks hard limit and the init tasks soft limit
8610 +        */
8611 +       if (old->rlimits.mask) {
8612 +               for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) {
8613 +                       if (old->rlimits.mask & mask) {
8614 +                               rlim = current->signal->rlim + i;
8615 +                               initrlim = init_task.signal->rlim + i;
8616 +                               rlim->rlim_cur = min(rlim->rlim_max,
8617 +                                                    initrlim->rlim_cur);
8618 +                       }
8619 +               }
8620 +       }
8621 +
8622 +       /* set any new hard limits as dictated by the new profile */
8623 +       if (!new->rlimits.mask)
8624 +               return;
8625 +       for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<= 1) {
8626 +               if (!(new->rlimits.mask & mask))
8627 +                       continue;
8628 +
8629 +               rlim = current->signal->rlim + i;
8630 +               rlim->rlim_max = min(rlim->rlim_max,
8631 +                                    new->rlimits.limits[i].rlim_max);
8632 +               /* soft limit should not exceed hard limit */
8633 +               rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
8634 +       }
8635 +}
8636 diff --git a/security/apparmor/sid.c b/security/apparmor/sid.c
8637 new file mode 100644
8638 index 0000000..f0b34f7
8639 --- /dev/null
8640 +++ b/security/apparmor/sid.c
8641 @@ -0,0 +1,55 @@
8642 +/*
8643 + * AppArmor security module
8644 + *
8645 + * This file contains AppArmor security identifier (sid) manipulation fns
8646 + *
8647 + * Copyright 2009-2010 Canonical Ltd.
8648 + *
8649 + * This program is free software; you can redistribute it and/or
8650 + * modify it under the terms of the GNU General Public License as
8651 + * published by the Free Software Foundation, version 2 of the
8652 + * License.
8653 + *
8654 + *
8655 + * AppArmor allocates a unique sid for every profile loaded.  If a profile
8656 + * is replaced it receives the sid of the profile it is replacing.
8657 + *
8658 + * The sid value of 0 is invalid.
8659 + */
8660 +
8661 +#include <linux/spinlock.h>
8662 +#include <linux/errno.h>
8663 +#include <linux/err.h>
8664 +
8665 +#include "include/sid.h"
8666 +
8667 +/* global counter from which sids are allocated */
8668 +static u32 global_sid;
8669 +static DEFINE_SPINLOCK(sid_lock);
8670 +
8671 +/* TODO FIXME: add sid to profile mapping, and sid recycling */
8672 +
8673 +/**
8674 + * aa_alloc_sid - allocate a new sid for a profile
8675 + */
8676 +u32 aa_alloc_sid(void)
8677 +{
8678 +       u32 sid;
8679 +
8680 +       /*
8681 +        * TODO FIXME: sid recycling - part of profile mapping table
8682 +        */
8683 +       spin_lock(&sid_lock);
8684 +       sid = (++global_sid);
8685 +       spin_unlock(&sid_lock);
8686 +       return sid;
8687 +}
8688 +
8689 +/**
8690 + * aa_free_sid - free a sid
8691 + * @sid: sid to free
8692 + */
8693 +void aa_free_sid(u32 sid)
8694 +{
8695 +       ;                       /* NOP ATM */
8696 +}
8697 -- 
8698 1.7.1
8699
This page took 0.74967 seconds and 3 git commands to generate.