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