aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-11-26 17:32:55 -0500
committerPaul Moore <pmoore@redhat.com>2013-11-26 17:32:55 -0500
commitdd0a11815a339d6deeea8357574f8126a8404c92 (patch)
treec3c743ac6323e1caf9e987d6946cc4b2333a8256 /security
parent42d64e1add3a1ce8a787116036163b8724362145 (diff)
parent5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff)
Merge tag 'v3.12'
Linux 3.12
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/Kconfig12
-rw-r--r--security/apparmor/Makefile7
-rw-r--r--security/apparmor/apparmorfs.c634
-rw-r--r--security/apparmor/capability.c5
-rw-r--r--security/apparmor/context.c16
-rw-r--r--security/apparmor/crypto.c95
-rw-r--r--security/apparmor/domain.c24
-rw-r--r--security/apparmor/include/apparmor.h6
-rw-r--r--security/apparmor/include/apparmorfs.h40
-rw-r--r--security/apparmor/include/audit.h1
-rw-r--r--security/apparmor/include/capability.h4
-rw-r--r--security/apparmor/include/context.h15
-rw-r--r--security/apparmor/include/crypto.h36
-rw-r--r--security/apparmor/include/policy.h220
-rw-r--r--security/apparmor/include/policy_unpack.h21
-rw-r--r--security/apparmor/lib.c5
-rw-r--r--security/apparmor/lsm.c24
-rw-r--r--security/apparmor/policy.c611
-rw-r--r--security/apparmor/policy_unpack.c135
-rw-r--r--security/apparmor/procattr.c2
-rw-r--r--security/capability.c2
-rw-r--r--security/commoncap.c10
-rw-r--r--security/device_cgroup.c65
-rw-r--r--security/integrity/evm/evm_main.c2
-rw-r--r--security/security.c8
-rw-r--r--security/selinux/avc.c9
-rw-r--r--security/selinux/hooks.c32
-rw-r--r--security/selinux/include/avc.h18
-rw-r--r--security/selinux/include/xfrm.h7
-rw-r--r--security/smack/smack.h13
-rw-r--r--security/smack/smack_access.c29
-rw-r--r--security/smack/smack_lsm.c51
-rw-r--r--security/smack/smackfs.c180
33 files changed, 1720 insertions, 619 deletions
diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
index 9b9013b2e321..d49c53960b60 100644
--- a/security/apparmor/Kconfig
+++ b/security/apparmor/Kconfig
@@ -29,3 +29,15 @@ config SECURITY_APPARMOR_BOOTPARAM_VALUE
29 boot. 29 boot.
30 30
31 If you are unsure how to answer this question, answer 1. 31 If you are unsure how to answer this question, answer 1.
32
33config SECURITY_APPARMOR_HASH
34 bool "SHA1 hash of loaded profiles"
35 depends on SECURITY_APPARMOR
36 depends on CRYPTO
37 select CRYPTO_SHA1
38 default y
39
40 help
41 This option selects whether sha1 hashing is done against loaded
42 profiles and exported for inspection to user space via the apparmor
43 filesystem.
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 5706b74c857f..d693df874818 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ 5apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ 6 path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
7 resource.o sid.o file.o 7 resource.o sid.o file.o
8apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
8 9
9clean-files := capability_names.h rlim_names.h 10clean-files := capability_names.h rlim_names.h
10 11
@@ -18,7 +19,11 @@ quiet_cmd_make-caps = GEN $@
18cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\ 19cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
19 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \ 20 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
20 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\ 21 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
21 echo "};" >> $@ 22 echo "};" >> $@ ;\
23 echo -n '\#define AA_FS_CAPS_MASK "' >> $@ ;\
24 sed $< -r -n -e '/CAP_FS_MASK/d' \
25 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
26 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
22 27
23 28
24# Build a lower case string table of rlimit names. 29# Build a lower case string table of rlimit names.
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 16c15ec6f670..7db9954f1af2 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -12,6 +12,7 @@
12 * License. 12 * License.
13 */ 13 */
14 14
15#include <linux/ctype.h>
15#include <linux/security.h> 16#include <linux/security.h>
16#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
17#include <linux/module.h> 18#include <linux/module.h>
@@ -19,15 +20,56 @@
19#include <linux/uaccess.h> 20#include <linux/uaccess.h>
20#include <linux/namei.h> 21#include <linux/namei.h>
21#include <linux/capability.h> 22#include <linux/capability.h>
23#include <linux/rcupdate.h>
22 24
23#include "include/apparmor.h" 25#include "include/apparmor.h"
24#include "include/apparmorfs.h" 26#include "include/apparmorfs.h"
25#include "include/audit.h" 27#include "include/audit.h"
26#include "include/context.h" 28#include "include/context.h"
29#include "include/crypto.h"
27#include "include/policy.h" 30#include "include/policy.h"
28#include "include/resource.h" 31#include "include/resource.h"
29 32
30/** 33/**
34 * aa_mangle_name - mangle a profile name to std profile layout form
35 * @name: profile name to mangle (NOT NULL)
36 * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
37 *
38 * Returns: length of mangled name
39 */
40static int mangle_name(char *name, char *target)
41{
42 char *t = target;
43
44 while (*name == '/' || *name == '.')
45 name++;
46
47 if (target) {
48 for (; *name; name++) {
49 if (*name == '/')
50 *(t)++ = '.';
51 else if (isspace(*name))
52 *(t)++ = '_';
53 else if (isalnum(*name) || strchr("._-", *name))
54 *(t)++ = *name;
55 }
56
57 *t = 0;
58 } else {
59 int len = 0;
60 for (; *name; name++) {
61 if (isalnum(*name) || isspace(*name) ||
62 strchr("/._-", *name))
63 len++;
64 }
65
66 return len;
67 }
68
69 return t - target;
70}
71
72/**
31 * aa_simple_write_to_buffer - common routine for getting policy from user 73 * aa_simple_write_to_buffer - common routine for getting policy from user
32 * @op: operation doing the user buffer copy 74 * @op: operation doing the user buffer copy
33 * @userbuf: user buffer to copy data from (NOT NULL) 75 * @userbuf: user buffer to copy data from (NOT NULL)
@@ -182,8 +224,565 @@ const struct file_operations aa_fs_seq_file_ops = {
182 .release = single_release, 224 .release = single_release,
183}; 225};
184 226
185/** Base file system setup **/ 227static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
228 int (*show)(struct seq_file *, void *))
229{
230 struct aa_replacedby *r = aa_get_replacedby(inode->i_private);
231 int error = single_open(file, show, r);
232
233 if (error) {
234 file->private_data = NULL;
235 aa_put_replacedby(r);
236 }
237
238 return error;
239}
240
241static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
242{
243 struct seq_file *seq = (struct seq_file *) file->private_data;
244 if (seq)
245 aa_put_replacedby(seq->private);
246 return single_release(inode, file);
247}
248
249static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
250{
251 struct aa_replacedby *r = seq->private;
252 struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
253 seq_printf(seq, "%s\n", profile->base.name);
254 aa_put_profile(profile);
255
256 return 0;
257}
258
259static int aa_fs_seq_profname_open(struct inode *inode, struct file *file)
260{
261 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profname_show);
262}
263
264static const struct file_operations aa_fs_profname_fops = {
265 .owner = THIS_MODULE,
266 .open = aa_fs_seq_profname_open,
267 .read = seq_read,
268 .llseek = seq_lseek,
269 .release = aa_fs_seq_profile_release,
270};
271
272static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
273{
274 struct aa_replacedby *r = seq->private;
275 struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
276 seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
277 aa_put_profile(profile);
278
279 return 0;
280}
281
282static int aa_fs_seq_profmode_open(struct inode *inode, struct file *file)
283{
284 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profmode_show);
285}
286
287static const struct file_operations aa_fs_profmode_fops = {
288 .owner = THIS_MODULE,
289 .open = aa_fs_seq_profmode_open,
290 .read = seq_read,
291 .llseek = seq_lseek,
292 .release = aa_fs_seq_profile_release,
293};
294
295static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
296{
297 struct aa_replacedby *r = seq->private;
298 struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
299 if (profile->attach)
300 seq_printf(seq, "%s\n", profile->attach);
301 else if (profile->xmatch)
302 seq_puts(seq, "<unknown>\n");
303 else
304 seq_printf(seq, "%s\n", profile->base.name);
305 aa_put_profile(profile);
306
307 return 0;
308}
309
310static int aa_fs_seq_profattach_open(struct inode *inode, struct file *file)
311{
312 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profattach_show);
313}
314
315static const struct file_operations aa_fs_profattach_fops = {
316 .owner = THIS_MODULE,
317 .open = aa_fs_seq_profattach_open,
318 .read = seq_read,
319 .llseek = seq_lseek,
320 .release = aa_fs_seq_profile_release,
321};
322
323static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
324{
325 struct aa_replacedby *r = seq->private;
326 struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
327 unsigned int i, size = aa_hash_size();
328
329 if (profile->hash) {
330 for (i = 0; i < size; i++)
331 seq_printf(seq, "%.2x", profile->hash[i]);
332 seq_puts(seq, "\n");
333 }
334
335 return 0;
336}
337
338static int aa_fs_seq_hash_open(struct inode *inode, struct file *file)
339{
340 return single_open(file, aa_fs_seq_hash_show, inode->i_private);
341}
342
343static const struct file_operations aa_fs_seq_hash_fops = {
344 .owner = THIS_MODULE,
345 .open = aa_fs_seq_hash_open,
346 .read = seq_read,
347 .llseek = seq_lseek,
348 .release = single_release,
349};
350
351/** fns to setup dynamic per profile/namespace files **/
352void __aa_fs_profile_rmdir(struct aa_profile *profile)
353{
354 struct aa_profile *child;
355 int i;
356
357 if (!profile)
358 return;
359
360 list_for_each_entry(child, &profile->base.profiles, base.list)
361 __aa_fs_profile_rmdir(child);
362
363 for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
364 struct aa_replacedby *r;
365 if (!profile->dents[i])
366 continue;
367
368 r = profile->dents[i]->d_inode->i_private;
369 securityfs_remove(profile->dents[i]);
370 aa_put_replacedby(r);
371 profile->dents[i] = NULL;
372 }
373}
374
375void __aa_fs_profile_migrate_dents(struct aa_profile *old,
376 struct aa_profile *new)
377{
378 int i;
379
380 for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
381 new->dents[i] = old->dents[i];
382 old->dents[i] = NULL;
383 }
384}
385
386static struct dentry *create_profile_file(struct dentry *dir, const char *name,
387 struct aa_profile *profile,
388 const struct file_operations *fops)
389{
390 struct aa_replacedby *r = aa_get_replacedby(profile->replacedby);
391 struct dentry *dent;
392
393 dent = securityfs_create_file(name, S_IFREG | 0444, dir, r, fops);
394 if (IS_ERR(dent))
395 aa_put_replacedby(r);
396
397 return dent;
398}
399
400/* requires lock be held */
401int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
402{
403 struct aa_profile *child;
404 struct dentry *dent = NULL, *dir;
405 int error;
406
407 if (!parent) {
408 struct aa_profile *p;
409 p = aa_deref_parent(profile);
410 dent = prof_dir(p);
411 /* adding to parent that previously didn't have children */
412 dent = securityfs_create_dir("profiles", dent);
413 if (IS_ERR(dent))
414 goto fail;
415 prof_child_dir(p) = parent = dent;
416 }
417
418 if (!profile->dirname) {
419 int len, id_len;
420 len = mangle_name(profile->base.name, NULL);
421 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
422
423 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
424 if (!profile->dirname)
425 goto fail;
426
427 mangle_name(profile->base.name, profile->dirname);
428 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
429 }
430
431 dent = securityfs_create_dir(profile->dirname, parent);
432 if (IS_ERR(dent))
433 goto fail;
434 prof_dir(profile) = dir = dent;
435
436 dent = create_profile_file(dir, "name", profile, &aa_fs_profname_fops);
437 if (IS_ERR(dent))
438 goto fail;
439 profile->dents[AAFS_PROF_NAME] = dent;
440
441 dent = create_profile_file(dir, "mode", profile, &aa_fs_profmode_fops);
442 if (IS_ERR(dent))
443 goto fail;
444 profile->dents[AAFS_PROF_MODE] = dent;
445
446 dent = create_profile_file(dir, "attach", profile,
447 &aa_fs_profattach_fops);
448 if (IS_ERR(dent))
449 goto fail;
450 profile->dents[AAFS_PROF_ATTACH] = dent;
451
452 if (profile->hash) {
453 dent = create_profile_file(dir, "sha1", profile,
454 &aa_fs_seq_hash_fops);
455 if (IS_ERR(dent))
456 goto fail;
457 profile->dents[AAFS_PROF_HASH] = dent;
458 }
459
460 list_for_each_entry(child, &profile->base.profiles, base.list) {
461 error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
462 if (error)
463 goto fail2;
464 }
465
466 return 0;
467
468fail:
469 error = PTR_ERR(dent);
470
471fail2:
472 __aa_fs_profile_rmdir(profile);
473
474 return error;
475}
476
477void __aa_fs_namespace_rmdir(struct aa_namespace *ns)
478{
479 struct aa_namespace *sub;
480 struct aa_profile *child;
481 int i;
482
483 if (!ns)
484 return;
485
486 list_for_each_entry(child, &ns->base.profiles, base.list)
487 __aa_fs_profile_rmdir(child);
488
489 list_for_each_entry(sub, &ns->sub_ns, base.list) {
490 mutex_lock(&sub->lock);
491 __aa_fs_namespace_rmdir(sub);
492 mutex_unlock(&sub->lock);
493 }
186 494
495 for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
496 securityfs_remove(ns->dents[i]);
497 ns->dents[i] = NULL;
498 }
499}
500
501int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent,
502 const char *name)
503{
504 struct aa_namespace *sub;
505 struct aa_profile *child;
506 struct dentry *dent, *dir;
507 int error;
508
509 if (!name)
510 name = ns->base.name;
511
512 dent = securityfs_create_dir(name, parent);
513 if (IS_ERR(dent))
514 goto fail;
515 ns_dir(ns) = dir = dent;
516
517 dent = securityfs_create_dir("profiles", dir);
518 if (IS_ERR(dent))
519 goto fail;
520 ns_subprofs_dir(ns) = dent;
521
522 dent = securityfs_create_dir("namespaces", dir);
523 if (IS_ERR(dent))
524 goto fail;
525 ns_subns_dir(ns) = dent;
526
527 list_for_each_entry(child, &ns->base.profiles, base.list) {
528 error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns));
529 if (error)
530 goto fail2;
531 }
532
533 list_for_each_entry(sub, &ns->sub_ns, base.list) {
534 mutex_lock(&sub->lock);
535 error = __aa_fs_namespace_mkdir(sub, ns_subns_dir(ns), NULL);
536 mutex_unlock(&sub->lock);
537 if (error)
538 goto fail2;
539 }
540
541 return 0;
542
543fail:
544 error = PTR_ERR(dent);
545
546fail2:
547 __aa_fs_namespace_rmdir(ns);
548
549 return error;
550}
551
552
553#define list_entry_next(pos, member) \
554 list_entry(pos->member.next, typeof(*pos), member)
555#define list_entry_is_head(pos, head, member) (&pos->member == (head))
556
557/**
558 * __next_namespace - find the next namespace to list
559 * @root: root namespace to stop search at (NOT NULL)
560 * @ns: current ns position (NOT NULL)
561 *
562 * Find the next namespace from @ns under @root and handle all locking needed
563 * while switching current namespace.
564 *
565 * Returns: next namespace or NULL if at last namespace under @root
566 * Requires: ns->parent->lock to be held
567 * NOTE: will not unlock root->lock
568 */
569static struct aa_namespace *__next_namespace(struct aa_namespace *root,
570 struct aa_namespace *ns)
571{
572 struct aa_namespace *parent, *next;
573
574 /* is next namespace a child */
575 if (!list_empty(&ns->sub_ns)) {
576 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
577 mutex_lock(&next->lock);
578 return next;
579 }
580
581 /* check if the next ns is a sibling, parent, gp, .. */
582 parent = ns->parent;
583 while (ns != root) {
584 mutex_unlock(&ns->lock);
585 next = list_entry_next(ns, base.list);
586 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
587 mutex_lock(&next->lock);
588 return next;
589 }
590 ns = parent;
591 parent = parent->parent;
592 }
593
594 return NULL;
595}
596
597/**
598 * __first_profile - find the first profile in a namespace
599 * @root: namespace that is root of profiles being displayed (NOT NULL)
600 * @ns: namespace to start in (NOT NULL)
601 *
602 * Returns: unrefcounted profile or NULL if no profile
603 * Requires: profile->ns.lock to be held
604 */
605static struct aa_profile *__first_profile(struct aa_namespace *root,
606 struct aa_namespace *ns)
607{
608 for (; ns; ns = __next_namespace(root, ns)) {
609 if (!list_empty(&ns->base.profiles))
610 return list_first_entry(&ns->base.profiles,
611 struct aa_profile, base.list);
612 }
613 return NULL;
614}
615
616/**
617 * __next_profile - step to the next profile in a profile tree
618 * @profile: current profile in tree (NOT NULL)
619 *
620 * Perform a depth first traversal on the profile tree in a namespace
621 *
622 * Returns: next profile or NULL if done
623 * Requires: profile->ns.lock to be held
624 */
625static struct aa_profile *__next_profile(struct aa_profile *p)
626{
627 struct aa_profile *parent;
628 struct aa_namespace *ns = p->ns;
629
630 /* is next profile a child */
631 if (!list_empty(&p->base.profiles))
632 return list_first_entry(&p->base.profiles, typeof(*p),
633 base.list);
634
635 /* is next profile a sibling, parent sibling, gp, sibling, .. */
636 parent = rcu_dereference_protected(p->parent,
637 mutex_is_locked(&p->ns->lock));
638 while (parent) {
639 p = list_entry_next(p, base.list);
640 if (!list_entry_is_head(p, &parent->base.profiles, base.list))
641 return p;
642 p = parent;
643 parent = rcu_dereference_protected(parent->parent,
644 mutex_is_locked(&parent->ns->lock));
645 }
646
647 /* is next another profile in the namespace */
648 p = list_entry_next(p, base.list);
649 if (!list_entry_is_head(p, &ns->base.profiles, base.list))
650 return p;
651
652 return NULL;
653}
654
655/**
656 * next_profile - step to the next profile in where ever it may be
657 * @root: root namespace (NOT NULL)
658 * @profile: current profile (NOT NULL)
659 *
660 * Returns: next profile or NULL if there isn't one
661 */
662static struct aa_profile *next_profile(struct aa_namespace *root,
663 struct aa_profile *profile)
664{
665 struct aa_profile *next = __next_profile(profile);
666 if (next)
667 return next;
668
669 /* finished all profiles in namespace move to next namespace */
670 return __first_profile(root, __next_namespace(root, profile->ns));
671}
672
673/**
674 * p_start - start a depth first traversal of profile tree
675 * @f: seq_file to fill
676 * @pos: current position
677 *
678 * Returns: first profile under current namespace or NULL if none found
679 *
680 * acquires first ns->lock
681 */
682static void *p_start(struct seq_file *f, loff_t *pos)
683{
684 struct aa_profile *profile = NULL;
685 struct aa_namespace *root = aa_current_profile()->ns;
686 loff_t l = *pos;
687 f->private = aa_get_namespace(root);
688
689
690 /* find the first profile */
691 mutex_lock(&root->lock);
692 profile = __first_profile(root, root);
693
694 /* skip to position */
695 for (; profile && l > 0; l--)
696 profile = next_profile(root, profile);
697
698 return profile;
699}
700
701/**
702 * p_next - read the next profile entry
703 * @f: seq_file to fill
704 * @p: profile previously returned
705 * @pos: current position
706 *
707 * Returns: next profile after @p or NULL if none
708 *
709 * may acquire/release locks in namespace tree as necessary
710 */
711static void *p_next(struct seq_file *f, void *p, loff_t *pos)
712{
713 struct aa_profile *profile = p;
714 struct aa_namespace *ns = f->private;
715 (*pos)++;
716
717 return next_profile(ns, profile);
718}
719
720/**
721 * p_stop - stop depth first traversal
722 * @f: seq_file we are filling
723 * @p: the last profile writen
724 *
725 * Release all locking done by p_start/p_next on namespace tree
726 */
727static void p_stop(struct seq_file *f, void *p)
728{
729 struct aa_profile *profile = p;
730 struct aa_namespace *root = f->private, *ns;
731
732 if (profile) {
733 for (ns = profile->ns; ns && ns != root; ns = ns->parent)
734 mutex_unlock(&ns->lock);
735 }
736 mutex_unlock(&root->lock);
737 aa_put_namespace(root);
738}
739
740/**
741 * seq_show_profile - show a profile entry
742 * @f: seq_file to file
743 * @p: current position (profile) (NOT NULL)
744 *
745 * Returns: error on failure
746 */
747static int seq_show_profile(struct seq_file *f, void *p)
748{
749 struct aa_profile *profile = (struct aa_profile *)p;
750 struct aa_namespace *root = f->private;
751
752 if (profile->ns != root)
753 seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
754 seq_printf(f, "%s (%s)\n", profile->base.hname,
755 aa_profile_mode_names[profile->mode]);
756
757 return 0;
758}
759
760static const struct seq_operations aa_fs_profiles_op = {
761 .start = p_start,
762 .next = p_next,
763 .stop = p_stop,
764 .show = seq_show_profile,
765};
766
767static int profiles_open(struct inode *inode, struct file *file)
768{
769 return seq_open(file, &aa_fs_profiles_op);
770}
771
772static int profiles_release(struct inode *inode, struct file *file)
773{
774 return seq_release(inode, file);
775}
776
777static const struct file_operations aa_fs_profiles_fops = {
778 .open = profiles_open,
779 .read = seq_read,
780 .llseek = seq_lseek,
781 .release = profiles_release,
782};
783
784
785/** Base file system setup **/
187static struct aa_fs_entry aa_fs_entry_file[] = { 786static struct aa_fs_entry aa_fs_entry_file[] = {
188 AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \ 787 AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
189 "link lock"), 788 "link lock"),
@@ -198,11 +797,18 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
198 { } 797 { }
199}; 798};
200 799
800static struct aa_fs_entry aa_fs_entry_policy[] = {
801 AA_FS_FILE_BOOLEAN("set_load", 1),
802 {}
803};
804
201static struct aa_fs_entry aa_fs_entry_features[] = { 805static struct aa_fs_entry aa_fs_entry_features[] = {
806 AA_FS_DIR("policy", aa_fs_entry_policy),
202 AA_FS_DIR("domain", aa_fs_entry_domain), 807 AA_FS_DIR("domain", aa_fs_entry_domain),
203 AA_FS_DIR("file", aa_fs_entry_file), 808 AA_FS_DIR("file", aa_fs_entry_file),
204 AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), 809 AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
205 AA_FS_DIR("rlimit", aa_fs_entry_rlimit), 810 AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
811 AA_FS_DIR("caps", aa_fs_entry_caps),
206 { } 812 { }
207}; 813};
208 814
@@ -210,6 +816,7 @@ static struct aa_fs_entry aa_fs_entry_apparmor[] = {
210 AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load), 816 AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
211 AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace), 817 AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
212 AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove), 818 AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
819 AA_FS_FILE_FOPS("profiles", 0640, &aa_fs_profiles_fops),
213 AA_FS_DIR("features", aa_fs_entry_features), 820 AA_FS_DIR("features", aa_fs_entry_features),
214 { } 821 { }
215}; 822};
@@ -240,6 +847,7 @@ static int __init aafs_create_file(struct aa_fs_entry *fs_file,
240 return error; 847 return error;
241} 848}
242 849
850static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir);
243/** 851/**
244 * aafs_create_dir - recursively create a directory entry in the securityfs 852 * aafs_create_dir - recursively create a directory entry in the securityfs
245 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL) 853 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
@@ -250,17 +858,16 @@ static int __init aafs_create_file(struct aa_fs_entry *fs_file,
250static int __init aafs_create_dir(struct aa_fs_entry *fs_dir, 858static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
251 struct dentry *parent) 859 struct dentry *parent)
252{ 860{
253 int error;
254 struct aa_fs_entry *fs_file; 861 struct aa_fs_entry *fs_file;
862 struct dentry *dir;
863 int error;
255 864
256 fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent); 865 dir = securityfs_create_dir(fs_dir->name, parent);
257 if (IS_ERR(fs_dir->dentry)) { 866 if (IS_ERR(dir))
258 error = PTR_ERR(fs_dir->dentry); 867 return PTR_ERR(dir);
259 fs_dir->dentry = NULL; 868 fs_dir->dentry = dir;
260 goto failed;
261 }
262 869
263 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) { 870 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
264 if (fs_file->v_type == AA_FS_TYPE_DIR) 871 if (fs_file->v_type == AA_FS_TYPE_DIR)
265 error = aafs_create_dir(fs_file, fs_dir->dentry); 872 error = aafs_create_dir(fs_file, fs_dir->dentry);
266 else 873 else
@@ -272,6 +879,8 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
272 return 0; 879 return 0;
273 880
274failed: 881failed:
882 aafs_remove_dir(fs_dir);
883
275 return error; 884 return error;
276} 885}
277 886
@@ -296,7 +905,7 @@ static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
296{ 905{
297 struct aa_fs_entry *fs_file; 906 struct aa_fs_entry *fs_file;
298 907
299 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) { 908 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
300 if (fs_file->v_type == AA_FS_TYPE_DIR) 909 if (fs_file->v_type == AA_FS_TYPE_DIR)
301 aafs_remove_dir(fs_file); 910 aafs_remove_dir(fs_file);
302 else 911 else
@@ -340,6 +949,11 @@ static int __init aa_create_aafs(void)
340 if (error) 949 if (error)
341 goto error; 950 goto error;
342 951
952 error = __aa_fs_namespace_mkdir(root_ns, aa_fs_entry.dentry,
953 "policy");
954 if (error)
955 goto error;
956
343 /* TODO: add support for apparmorfs_null and apparmorfs_mnt */ 957 /* TODO: add support for apparmorfs_null and apparmorfs_mnt */
344 958
345 /* Report that AppArmor fs is enabled */ 959 /* Report that AppArmor fs is enabled */
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index 887a5e948945..84d1f5f53877 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -27,6 +27,11 @@
27 */ 27 */
28#include "capability_names.h" 28#include "capability_names.h"
29 29
30struct aa_fs_entry aa_fs_entry_caps[] = {
31 AA_FS_FILE_STRING("mask", AA_FS_CAPS_MASK),
32 { }
33};
34
30struct audit_cache { 35struct audit_cache {
31 struct aa_profile *profile; 36 struct aa_profile *profile;
32 kernel_cap_t caps; 37 kernel_cap_t caps;
diff --git a/security/apparmor/context.c b/security/apparmor/context.c
index d5af1d15f26d..3064c6ced87c 100644
--- a/security/apparmor/context.c
+++ b/security/apparmor/context.c
@@ -112,9 +112,9 @@ int aa_replace_current_profile(struct aa_profile *profile)
112 aa_clear_task_cxt_trans(cxt); 112 aa_clear_task_cxt_trans(cxt);
113 113
114 /* be careful switching cxt->profile, when racing replacement it 114 /* be careful switching cxt->profile, when racing replacement it
115 * is possible that cxt->profile->replacedby is the reference keeping 115 * is possible that cxt->profile->replacedby->profile is the reference
116 * @profile valid, so make sure to get its reference before dropping 116 * keeping @profile valid, so make sure to get its reference before
117 * the reference on cxt->profile */ 117 * dropping the reference on cxt->profile */
118 aa_get_profile(profile); 118 aa_get_profile(profile);
119 aa_put_profile(cxt->profile); 119 aa_put_profile(cxt->profile);
120 cxt->profile = profile; 120 cxt->profile = profile;
@@ -175,7 +175,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
175 abort_creds(new); 175 abort_creds(new);
176 return -EACCES; 176 return -EACCES;
177 } 177 }
178 cxt->profile = aa_get_profile(aa_newest_version(profile)); 178 cxt->profile = aa_get_newest_profile(profile);
179 /* clear exec on switching context */ 179 /* clear exec on switching context */
180 aa_put_profile(cxt->onexec); 180 aa_put_profile(cxt->onexec);
181 cxt->onexec = NULL; 181 cxt->onexec = NULL;
@@ -212,14 +212,8 @@ int aa_restore_previous_profile(u64 token)
212 } 212 }
213 213
214 aa_put_profile(cxt->profile); 214 aa_put_profile(cxt->profile);
215 cxt->profile = aa_newest_version(cxt->previous); 215 cxt->profile = aa_get_newest_profile(cxt->previous);
216 BUG_ON(!cxt->profile); 216 BUG_ON(!cxt->profile);
217 if (unlikely(cxt->profile != cxt->previous)) {
218 aa_get_profile(cxt->profile);
219 aa_put_profile(cxt->previous);
220 }
221 /* ref has been transfered so avoid putting ref in clear_task_cxt */
222 cxt->previous = NULL;
223 /* clear exec && prev information when restoring to previous context */ 217 /* clear exec && prev information when restoring to previous context */
224 aa_clear_task_cxt_trans(cxt); 218 aa_clear_task_cxt_trans(cxt);
225 219
diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c
new file mode 100644
index 000000000000..532471d0b3a0
--- /dev/null
+++ b/security/apparmor/crypto.c
@@ -0,0 +1,95 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor policy loading interface function definitions.
5 *
6 * Copyright 2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the
11 * License.
12 *
13 * Fns to provide a checksum of policy that has been loaded this can be
14 * compared to userspace policy compiles to check loaded policy is what
15 * it should be.
16 */
17
18#include <crypto/hash.h>
19
20#include "include/apparmor.h"
21#include "include/crypto.h"
22
23static unsigned int apparmor_hash_size;
24
25static struct crypto_shash *apparmor_tfm;
26
27unsigned int aa_hash_size(void)
28{
29 return apparmor_hash_size;
30}
31
32int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
33 size_t len)
34{
35 struct {
36 struct shash_desc shash;
37 char ctx[crypto_shash_descsize(apparmor_tfm)];
38 } desc;
39 int error = -ENOMEM;
40 u32 le32_version = cpu_to_le32(version);
41
42 if (!apparmor_tfm)
43 return 0;
44
45 profile->hash = kzalloc(apparmor_hash_size, GFP_KERNEL);
46 if (!profile->hash)
47 goto fail;
48
49 desc.shash.tfm = apparmor_tfm;
50 desc.shash.flags = 0;
51
52 error = crypto_shash_init(&desc.shash);
53 if (error)
54 goto fail;
55 error = crypto_shash_update(&desc.shash, (u8 *) &le32_version, 4);
56 if (error)
57 goto fail;
58 error = crypto_shash_update(&desc.shash, (u8 *) start, len);
59 if (error)
60 goto fail;
61 error = crypto_shash_final(&desc.shash, profile->hash);
62 if (error)
63 goto fail;
64
65 return 0;
66
67fail:
68 kfree(profile->hash);
69 profile->hash = NULL;
70
71 return error;
72}
73
74static int __init init_profile_hash(void)
75{
76 struct crypto_shash *tfm;
77
78 if (!apparmor_initialized)
79 return 0;
80
81 tfm = crypto_alloc_shash("sha1", 0, CRYPTO_ALG_ASYNC);
82 if (IS_ERR(tfm)) {
83 int error = PTR_ERR(tfm);
84 AA_ERROR("failed to setup profile sha1 hashing: %d\n", error);
85 return error;
86 }
87 apparmor_tfm = tfm;
88 apparmor_hash_size = crypto_shash_digestsize(apparmor_tfm);
89
90 aa_info_message("AppArmor sha1 policy hashing enabled");
91
92 return 0;
93}
94
95late_initcall(init_profile_hash);
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 01b7bd669a88..26c607c971f5 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -144,7 +144,7 @@ static struct aa_profile *__attach_match(const char *name,
144 int len = 0; 144 int len = 0;
145 struct aa_profile *profile, *candidate = NULL; 145 struct aa_profile *profile, *candidate = NULL;
146 146
147 list_for_each_entry(profile, head, base.list) { 147 list_for_each_entry_rcu(profile, head, base.list) {
148 if (profile->flags & PFLAG_NULL) 148 if (profile->flags & PFLAG_NULL)
149 continue; 149 continue;
150 if (profile->xmatch && profile->xmatch_len > len) { 150 if (profile->xmatch && profile->xmatch_len > len) {
@@ -177,9 +177,9 @@ static struct aa_profile *find_attach(struct aa_namespace *ns,
177{ 177{
178 struct aa_profile *profile; 178 struct aa_profile *profile;
179 179
180 read_lock(&ns->lock); 180 rcu_read_lock();
181 profile = aa_get_profile(__attach_match(name, list)); 181 profile = aa_get_profile(__attach_match(name, list));
182 read_unlock(&ns->lock); 182 rcu_read_unlock();
183 183
184 return profile; 184 return profile;
185} 185}
@@ -359,7 +359,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
359 cxt = cred_cxt(bprm->cred); 359 cxt = cred_cxt(bprm->cred);
360 BUG_ON(!cxt); 360 BUG_ON(!cxt);
361 361
362 profile = aa_get_profile(aa_newest_version(cxt->profile)); 362 profile = aa_get_newest_profile(cxt->profile);
363 /* 363 /*
364 * get the namespace from the replacement profile as replacement 364 * get the namespace from the replacement profile as replacement
365 * can change the namespace 365 * can change the namespace
@@ -371,8 +371,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
371 error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer, 371 error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
372 &name, &info); 372 &name, &info);
373 if (error) { 373 if (error) {
374 if (profile->flags & 374 if (unconfined(profile) ||
375 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED)) 375 (profile->flags & PFLAG_IX_ON_NAME_ERROR))
376 error = 0; 376 error = 0;
377 name = bprm->filename; 377 name = bprm->filename;
378 goto audit; 378 goto audit;
@@ -417,7 +417,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
417 417
418 if (!(cp.allow & AA_MAY_ONEXEC)) 418 if (!(cp.allow & AA_MAY_ONEXEC))
419 goto audit; 419 goto audit;
420 new_profile = aa_get_profile(aa_newest_version(cxt->onexec)); 420 new_profile = aa_get_newest_profile(cxt->onexec);
421 goto apply; 421 goto apply;
422 } 422 }
423 423
@@ -434,7 +434,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
434 new_profile = aa_get_profile(profile); 434 new_profile = aa_get_profile(profile);
435 goto x_clear; 435 goto x_clear;
436 } else if (perms.xindex & AA_X_UNCONFINED) { 436 } else if (perms.xindex & AA_X_UNCONFINED) {
437 new_profile = aa_get_profile(ns->unconfined); 437 new_profile = aa_get_newest_profile(ns->unconfined);
438 info = "ux fallback"; 438 info = "ux fallback";
439 } else { 439 } else {
440 error = -ENOENT; 440 error = -ENOENT;
@@ -641,7 +641,10 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
641 if (count) { 641 if (count) {
642 /* attempting to change into a new hat or switch to a sibling */ 642 /* attempting to change into a new hat or switch to a sibling */
643 struct aa_profile *root; 643 struct aa_profile *root;
644 root = PROFILE_IS_HAT(profile) ? profile->parent : profile; 644 if (PROFILE_IS_HAT(profile))
645 root = aa_get_profile_rcu(&profile->parent);
646 else
647 root = aa_get_profile(profile);
645 648
646 /* find first matching hat */ 649 /* find first matching hat */
647 for (i = 0; i < count && !hat; i++) 650 for (i = 0; i < count && !hat; i++)
@@ -653,6 +656,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
653 error = -ECHILD; 656 error = -ECHILD;
654 else 657 else
655 error = -ENOENT; 658 error = -ENOENT;
659 aa_put_profile(root);
656 goto out; 660 goto out;
657 } 661 }
658 662
@@ -667,6 +671,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
667 671
668 /* freed below */ 672 /* freed below */
669 name = new_compound_name(root->base.hname, hats[0]); 673 name = new_compound_name(root->base.hname, hats[0]);
674 aa_put_profile(root);
670 target = name; 675 target = name;
671 /* released below */ 676 /* released below */
672 hat = aa_new_null_profile(profile, 1); 677 hat = aa_new_null_profile(profile, 1);
@@ -676,6 +681,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
676 goto audit; 681 goto audit;
677 } 682 }
678 } else { 683 } else {
684 aa_put_profile(root);
679 target = hat->base.hname; 685 target = hat->base.hname;
680 if (!PROFILE_IS_HAT(hat)) { 686 if (!PROFILE_IS_HAT(hat)) {
681 info = "target not hat"; 687 info = "target not hat";
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 1ba2ca56a6ef..8fb1488a3cd4 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -78,6 +78,12 @@ static inline void *kvzalloc(size_t size)
78 return __aa_kvmalloc(size, __GFP_ZERO); 78 return __aa_kvmalloc(size, __GFP_ZERO);
79} 79}
80 80
81/* returns 0 if kref not incremented */
82static inline int kref_get_not0(struct kref *kref)
83{
84 return atomic_inc_not_zero(&kref->refcount);
85}
86
81/** 87/**
82 * aa_strneq - compare null terminated @str to a non null terminated substring 88 * aa_strneq - compare null terminated @str to a non null terminated substring
83 * @str: a null terminated string 89 * @str: a null terminated string
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index 7ea4769fab3f..414e56878dd0 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -61,4 +61,44 @@ extern const struct file_operations aa_fs_seq_file_ops;
61 61
62extern void __init aa_destroy_aafs(void); 62extern void __init aa_destroy_aafs(void);
63 63
64struct aa_profile;
65struct aa_namespace;
66
67enum aafs_ns_type {
68 AAFS_NS_DIR,
69 AAFS_NS_PROFS,
70 AAFS_NS_NS,
71 AAFS_NS_COUNT,
72 AAFS_NS_MAX_COUNT,
73 AAFS_NS_SIZE,
74 AAFS_NS_MAX_SIZE,
75 AAFS_NS_OWNER,
76 AAFS_NS_SIZEOF,
77};
78
79enum aafs_prof_type {
80 AAFS_PROF_DIR,
81 AAFS_PROF_PROFS,
82 AAFS_PROF_NAME,
83 AAFS_PROF_MODE,
84 AAFS_PROF_ATTACH,
85 AAFS_PROF_HASH,
86 AAFS_PROF_SIZEOF,
87};
88
89#define ns_dir(X) ((X)->dents[AAFS_NS_DIR])
90#define ns_subns_dir(X) ((X)->dents[AAFS_NS_NS])
91#define ns_subprofs_dir(X) ((X)->dents[AAFS_NS_PROFS])
92
93#define prof_dir(X) ((X)->dents[AAFS_PROF_DIR])
94#define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
95
96void __aa_fs_profile_rmdir(struct aa_profile *profile);
97void __aa_fs_profile_migrate_dents(struct aa_profile *old,
98 struct aa_profile *new);
99int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
100void __aa_fs_namespace_rmdir(struct aa_namespace *ns);
101int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent,
102 const char *name);
103
64#endif /* __AA_APPARMORFS_H */ 104#endif /* __AA_APPARMORFS_H */
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 69d8cae634e7..30e8d7687259 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -27,7 +27,6 @@ struct aa_profile;
27 27
28extern const char *const audit_mode_names[]; 28extern const char *const audit_mode_names[];
29#define AUDIT_MAX_INDEX 5 29#define AUDIT_MAX_INDEX 5
30
31enum audit_mode { 30enum audit_mode {
32 AUDIT_NORMAL, /* follow normal auditing of accesses */ 31 AUDIT_NORMAL, /* follow normal auditing of accesses */
33 AUDIT_QUIET_DENIED, /* quiet all denied access messages */ 32 AUDIT_QUIET_DENIED, /* quiet all denied access messages */
diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
index c24d2959ea02..2e7c9d6a2f3b 100644
--- a/security/apparmor/include/capability.h
+++ b/security/apparmor/include/capability.h
@@ -17,6 +17,8 @@
17 17
18#include <linux/sched.h> 18#include <linux/sched.h>
19 19
20#include "apparmorfs.h"
21
20struct aa_profile; 22struct aa_profile;
21 23
22/* aa_caps - confinement data for capabilities 24/* aa_caps - confinement data for capabilities
@@ -34,6 +36,8 @@ struct aa_caps {
34 kernel_cap_t extended; 36 kernel_cap_t extended;
35}; 37};
36 38
39extern struct aa_fs_entry aa_fs_entry_caps[];
40
37int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap, 41int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
38 int audit); 42 int audit);
39 43
diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
index d44ba5802e3d..6bf65798e5d1 100644
--- a/security/apparmor/include/context.h
+++ b/security/apparmor/include/context.h
@@ -98,7 +98,7 @@ static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
98{ 98{
99 struct aa_task_cxt *cxt = cred_cxt(cred); 99 struct aa_task_cxt *cxt = cred_cxt(cred);
100 BUG_ON(!cxt || !cxt->profile); 100 BUG_ON(!cxt || !cxt->profile);
101 return aa_newest_version(cxt->profile); 101 return cxt->profile;
102} 102}
103 103
104/** 104/**
@@ -152,15 +152,14 @@ static inline struct aa_profile *aa_current_profile(void)
152 struct aa_profile *profile; 152 struct aa_profile *profile;
153 BUG_ON(!cxt || !cxt->profile); 153 BUG_ON(!cxt || !cxt->profile);
154 154
155 profile = aa_newest_version(cxt->profile); 155 if (PROFILE_INVALID(cxt->profile)) {
156 /* 156 profile = aa_get_newest_profile(cxt->profile);
157 * Whether or not replacement succeeds, use newest profile so
158 * there is no need to update it after replacement.
159 */
160 if (unlikely((cxt->profile != profile)))
161 aa_replace_current_profile(profile); 157 aa_replace_current_profile(profile);
158 aa_put_profile(profile);
159 cxt = current_cxt();
160 }
162 161
163 return profile; 162 return cxt->profile;
164} 163}
165 164
166/** 165/**
diff --git a/security/apparmor/include/crypto.h b/security/apparmor/include/crypto.h
new file mode 100644
index 000000000000..dc418e5024d9
--- /dev/null
+++ b/security/apparmor/include/crypto.h
@@ -0,0 +1,36 @@
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor policy loading interface function definitions.
5 *
6 * Copyright 2013 Canonical Ltd.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2 of the
11 * License.
12 */
13
14#ifndef __APPARMOR_CRYPTO_H
15#define __APPARMOR_CRYPTO_H
16
17#include "policy.h"
18
19#ifdef CONFIG_SECURITY_APPARMOR_HASH
20unsigned int aa_hash_size(void);
21int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start,
22 size_t len);
23#else
24static inline int aa_calc_profile_hash(struct aa_profile *profile, u32 version,
25 void *start, size_t len)
26{
27 return 0;
28}
29
30static inline unsigned int aa_hash_size(void)
31{
32 return 0;
33}
34#endif
35
36#endif /* __APPARMOR_CRYPTO_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index b25491a3046a..c28b0f20ab53 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -29,8 +29,8 @@
29#include "file.h" 29#include "file.h"
30#include "resource.h" 30#include "resource.h"
31 31
32extern const char *const profile_mode_names[]; 32extern const char *const aa_profile_mode_names[];
33#define APPARMOR_NAMES_MAX_INDEX 3 33#define APPARMOR_MODE_NAMES_MAX_INDEX 4
34 34
35#define PROFILE_MODE(_profile, _mode) \ 35#define PROFILE_MODE(_profile, _mode) \
36 ((aa_g_profile_mode == (_mode)) || \ 36 ((aa_g_profile_mode == (_mode)) || \
@@ -42,6 +42,10 @@ extern const char *const profile_mode_names[];
42 42
43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) 43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
44 44
45#define PROFILE_INVALID(_profile) ((_profile)->flags & PFLAG_INVALID)
46
47#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
48
45/* 49/*
46 * FIXME: currently need a clean way to replace and remove profiles as a 50 * FIXME: currently need a clean way to replace and remove profiles as a
47 * set. It should be done at the namespace level. 51 * set. It should be done at the namespace level.
@@ -52,17 +56,19 @@ enum profile_mode {
52 APPARMOR_ENFORCE, /* enforce access rules */ 56 APPARMOR_ENFORCE, /* enforce access rules */
53 APPARMOR_COMPLAIN, /* allow and log access violations */ 57 APPARMOR_COMPLAIN, /* allow and log access violations */
54 APPARMOR_KILL, /* kill task on access violation */ 58 APPARMOR_KILL, /* kill task on access violation */
59 APPARMOR_UNCONFINED, /* profile set to unconfined */
55}; 60};
56 61
57enum profile_flags { 62enum profile_flags {
58 PFLAG_HAT = 1, /* profile is a hat */ 63 PFLAG_HAT = 1, /* profile is a hat */
59 PFLAG_UNCONFINED = 2, /* profile is an unconfined profile */
60 PFLAG_NULL = 4, /* profile is null learning profile */ 64 PFLAG_NULL = 4, /* profile is null learning profile */
61 PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */ 65 PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
62 PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */ 66 PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */
63 PFLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */ 67 PFLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */
64 PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */ 68 PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
65 PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */ 69 PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */
70 PFLAG_INVALID = 0x200, /* profile replaced/removed */
71 PFLAG_NS_COUNT = 0x400, /* carries NS ref count */
66 72
67 /* These flags must correspond with PATH_flags */ 73 /* These flags must correspond with PATH_flags */
68 PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */ 74 PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
@@ -73,14 +79,12 @@ struct aa_profile;
73/* struct aa_policy - common part of both namespaces and profiles 79/* struct aa_policy - common part of both namespaces and profiles
74 * @name: name of the object 80 * @name: name of the object
75 * @hname - The hierarchical name 81 * @hname - The hierarchical name
76 * @count: reference count of the obj
77 * @list: list policy object is on 82 * @list: list policy object is on
78 * @profiles: head of the profiles list contained in the object 83 * @profiles: head of the profiles list contained in the object
79 */ 84 */
80struct aa_policy { 85struct aa_policy {
81 char *name; 86 char *name;
82 char *hname; 87 char *hname;
83 struct kref count;
84 struct list_head list; 88 struct list_head list;
85 struct list_head profiles; 89 struct list_head profiles;
86}; 90};
@@ -106,6 +110,8 @@ struct aa_ns_acct {
106 * @unconfined: special unconfined profile for the namespace 110 * @unconfined: special unconfined profile for the namespace
107 * @sub_ns: list of namespaces under the current namespace. 111 * @sub_ns: list of namespaces under the current namespace.
108 * @uniq_null: uniq value used for null learning profiles 112 * @uniq_null: uniq value used for null learning profiles
113 * @uniq_id: a unique id count for the profiles in the namespace
114 * @dents: dentries for the namespaces file entries in apparmorfs
109 * 115 *
110 * An aa_namespace defines the set profiles that are searched to determine 116 * An aa_namespace defines the set profiles that are searched to determine
111 * which profile to attach to a task. Profiles can not be shared between 117 * which profile to attach to a task. Profiles can not be shared between
@@ -124,11 +130,14 @@ struct aa_ns_acct {
124struct aa_namespace { 130struct aa_namespace {
125 struct aa_policy base; 131 struct aa_policy base;
126 struct aa_namespace *parent; 132 struct aa_namespace *parent;
127 rwlock_t lock; 133 struct mutex lock;
128 struct aa_ns_acct acct; 134 struct aa_ns_acct acct;
129 struct aa_profile *unconfined; 135 struct aa_profile *unconfined;
130 struct list_head sub_ns; 136 struct list_head sub_ns;
131 atomic_t uniq_null; 137 atomic_t uniq_null;
138 long uniq_id;
139
140 struct dentry *dents[AAFS_NS_SIZEOF];
132}; 141};
133 142
134/* struct aa_policydb - match engine for a policy 143/* struct aa_policydb - match engine for a policy
@@ -142,12 +151,21 @@ struct aa_policydb {
142 151
143}; 152};
144 153
154struct aa_replacedby {
155 struct kref count;
156 struct aa_profile __rcu *profile;
157};
158
159
145/* struct aa_profile - basic confinement data 160/* struct aa_profile - basic confinement data
146 * @base - base components of the profile (name, refcount, lists, lock ...) 161 * @base - base components of the profile (name, refcount, lists, lock ...)
162 * @count: reference count of the obj
163 * @rcu: rcu head used when removing from @list
147 * @parent: parent of profile 164 * @parent: parent of profile
148 * @ns: namespace the profile is in 165 * @ns: namespace the profile is in
149 * @replacedby: is set to the profile that replaced this profile 166 * @replacedby: is set to the profile that replaced this profile
150 * @rename: optional profile name that this profile renamed 167 * @rename: optional profile name that this profile renamed
168 * @attach: human readable attachment string
151 * @xmatch: optional extended matching for unconfined executables names 169 * @xmatch: optional extended matching for unconfined executables names
152 * @xmatch_len: xmatch prefix len, used to determine xmatch priority 170 * @xmatch_len: xmatch prefix len, used to determine xmatch priority
153 * @audit: the auditing mode of the profile 171 * @audit: the auditing mode of the profile
@@ -160,13 +178,15 @@ struct aa_policydb {
160 * @caps: capabilities for the profile 178 * @caps: capabilities for the profile
161 * @rlimits: rlimits for the profile 179 * @rlimits: rlimits for the profile
162 * 180 *
181 * @dents: dentries for the profiles file entries in apparmorfs
182 * @dirname: name of the profile dir in apparmorfs
183 *
163 * The AppArmor profile contains the basic confinement data. Each profile 184 * The AppArmor profile contains the basic confinement data. Each profile
164 * has a name, and exists in a namespace. The @name and @exec_match are 185 * has a name, and exists in a namespace. The @name and @exec_match are
165 * used to determine profile attachment against unconfined tasks. All other 186 * used to determine profile attachment against unconfined tasks. All other
166 * attachments are determined by profile X transition rules. 187 * attachments are determined by profile X transition rules.
167 * 188 *
168 * The @replacedby field is write protected by the profile lock. Reads 189 * The @replacedby struct is write protected by the profile lock.
169 * are assumed to be atomic, and are done without locking.
170 * 190 *
171 * Profiles have a hierarchy where hats and children profiles keep 191 * Profiles have a hierarchy where hats and children profiles keep
172 * a reference to their parent. 192 * a reference to their parent.
@@ -177,17 +197,20 @@ struct aa_policydb {
177 */ 197 */
178struct aa_profile { 198struct aa_profile {
179 struct aa_policy base; 199 struct aa_policy base;
180 struct aa_profile *parent; 200 struct kref count;
201 struct rcu_head rcu;
202 struct aa_profile __rcu *parent;
181 203
182 struct aa_namespace *ns; 204 struct aa_namespace *ns;
183 struct aa_profile *replacedby; 205 struct aa_replacedby *replacedby;
184 const char *rename; 206 const char *rename;
185 207
208 const char *attach;
186 struct aa_dfa *xmatch; 209 struct aa_dfa *xmatch;
187 int xmatch_len; 210 int xmatch_len;
188 enum audit_mode audit; 211 enum audit_mode audit;
189 enum profile_mode mode; 212 long mode;
190 u32 flags; 213 long flags;
191 u32 path_flags; 214 u32 path_flags;
192 int size; 215 int size;
193 216
@@ -195,6 +218,10 @@ struct aa_profile {
195 struct aa_file_rules file; 218 struct aa_file_rules file;
196 struct aa_caps caps; 219 struct aa_caps caps;
197 struct aa_rlimit rlimits; 220 struct aa_rlimit rlimits;
221
222 unsigned char *hash;
223 char *dirname;
224 struct dentry *dents[AAFS_PROF_SIZEOF];
198}; 225};
199 226
200extern struct aa_namespace *root_ns; 227extern struct aa_namespace *root_ns;
@@ -211,43 +238,11 @@ void aa_free_namespace_kref(struct kref *kref);
211struct aa_namespace *aa_find_namespace(struct aa_namespace *root, 238struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
212 const char *name); 239 const char *name);
213 240
214static inline struct aa_policy *aa_get_common(struct aa_policy *c)
215{
216 if (c)
217 kref_get(&c->count);
218
219 return c;
220}
221
222/**
223 * aa_get_namespace - increment references count on @ns
224 * @ns: namespace to increment reference count of (MAYBE NULL)
225 *
226 * Returns: pointer to @ns, if @ns is NULL returns NULL
227 * Requires: @ns must be held with valid refcount when called
228 */
229static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
230{
231 if (ns)
232 kref_get(&(ns->base.count));
233
234 return ns;
235}
236
237/**
238 * aa_put_namespace - decrement refcount on @ns
239 * @ns: namespace to put reference of
240 *
241 * Decrement reference count of @ns and if no longer in use free it
242 */
243static inline void aa_put_namespace(struct aa_namespace *ns)
244{
245 if (ns)
246 kref_put(&ns->base.count, aa_free_namespace_kref);
247}
248 241
242void aa_free_replacedby_kref(struct kref *kref);
249struct aa_profile *aa_alloc_profile(const char *name); 243struct aa_profile *aa_alloc_profile(const char *name);
250struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat); 244struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat);
245void aa_free_profile(struct aa_profile *profile);
251void aa_free_profile_kref(struct kref *kref); 246void aa_free_profile_kref(struct kref *kref);
252struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name); 247struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
253struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name); 248struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *name);
@@ -259,25 +254,13 @@ ssize_t aa_remove_profiles(char *name, size_t size);
259#define PROF_ADD 1 254#define PROF_ADD 1
260#define PROF_REPLACE 0 255#define PROF_REPLACE 0
261 256
262#define unconfined(X) ((X)->flags & PFLAG_UNCONFINED) 257#define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
263 258
264/**
265 * aa_newest_version - find the newest version of @profile
266 * @profile: the profile to check for newer versions of (NOT NULL)
267 *
268 * Returns: newest version of @profile, if @profile is the newest version
269 * return @profile.
270 *
271 * NOTE: the profile returned is not refcounted, The refcount on @profile
272 * must be held until the caller decides what to do with the returned newest
273 * version.
274 */
275static inline struct aa_profile *aa_newest_version(struct aa_profile *profile)
276{
277 while (profile->replacedby)
278 profile = profile->replacedby;
279 259
280 return profile; 260static inline struct aa_profile *aa_deref_parent(struct aa_profile *p)
261{
262 return rcu_dereference_protected(p->parent,
263 mutex_is_locked(&p->ns->lock));
281} 264}
282 265
283/** 266/**
@@ -290,19 +273,126 @@ static inline struct aa_profile *aa_newest_version(struct aa_profile *profile)
290static inline struct aa_profile *aa_get_profile(struct aa_profile *p) 273static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
291{ 274{
292 if (p) 275 if (p)
293 kref_get(&(p->base.count)); 276 kref_get(&(p->count));
294 277
295 return p; 278 return p;
296} 279}
297 280
298/** 281/**
282 * aa_get_profile_not0 - increment refcount on profile @p found via lookup
283 * @p: profile (MAYBE NULL)
284 *
285 * Returns: pointer to @p if @p is NULL will return NULL
286 * Requires: @p must be held with valid refcount when called
287 */
288static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
289{
290 if (p && kref_get_not0(&p->count))
291 return p;
292
293 return NULL;
294}
295
296/**
297 * aa_get_profile_rcu - increment a refcount profile that can be replaced
298 * @p: pointer to profile that can be replaced (NOT NULL)
299 *
300 * Returns: pointer to a refcounted profile.
301 * else NULL if no profile
302 */
303static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
304{
305 struct aa_profile *c;
306
307 rcu_read_lock();
308 do {
309 c = rcu_dereference(*p);
310 } while (c && !kref_get_not0(&c->count));
311 rcu_read_unlock();
312
313 return c;
314}
315
316/**
317 * aa_get_newest_profile - find the newest version of @profile
318 * @profile: the profile to check for newer versions of
319 *
320 * Returns: refcounted newest version of @profile taking into account
321 * replacement, renames and removals
322 * return @profile.
323 */
324static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
325{
326 if (!p)
327 return NULL;
328
329 if (PROFILE_INVALID(p))
330 return aa_get_profile_rcu(&p->replacedby->profile);
331
332 return aa_get_profile(p);
333}
334
335/**
299 * aa_put_profile - decrement refcount on profile @p 336 * aa_put_profile - decrement refcount on profile @p
300 * @p: profile (MAYBE NULL) 337 * @p: profile (MAYBE NULL)
301 */ 338 */
302static inline void aa_put_profile(struct aa_profile *p) 339static inline void aa_put_profile(struct aa_profile *p)
303{ 340{
304 if (p) 341 if (p)
305 kref_put(&p->base.count, aa_free_profile_kref); 342 kref_put(&p->count, aa_free_profile_kref);
343}
344
345static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
346{
347 if (p)
348 kref_get(&(p->count));
349
350 return p;
351}
352
353static inline void aa_put_replacedby(struct aa_replacedby *p)
354{
355 if (p)
356 kref_put(&p->count, aa_free_replacedby_kref);
357}
358
359/* requires profile list write lock held */
360static inline void __aa_update_replacedby(struct aa_profile *orig,
361 struct aa_profile *new)
362{
363 struct aa_profile *tmp;
364 tmp = rcu_dereference_protected(orig->replacedby->profile,
365 mutex_is_locked(&orig->ns->lock));
366 rcu_assign_pointer(orig->replacedby->profile, aa_get_profile(new));
367 orig->flags |= PFLAG_INVALID;
368 aa_put_profile(tmp);
369}
370
371/**
372 * aa_get_namespace - increment references count on @ns
373 * @ns: namespace to increment reference count of (MAYBE NULL)
374 *
375 * Returns: pointer to @ns, if @ns is NULL returns NULL
376 * Requires: @ns must be held with valid refcount when called
377 */
378static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
379{
380 if (ns)
381 aa_get_profile(ns->unconfined);
382
383 return ns;
384}
385
386/**
387 * aa_put_namespace - decrement refcount on @ns
388 * @ns: namespace to put reference of
389 *
390 * Decrement reference count of @ns and if no longer in use free it
391 */
392static inline void aa_put_namespace(struct aa_namespace *ns)
393{
394 if (ns)
395 aa_put_profile(ns->unconfined);
306} 396}
307 397
308static inline int AUDIT_MODE(struct aa_profile *profile) 398static inline int AUDIT_MODE(struct aa_profile *profile)
diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h
index a2dcccac45aa..c214fb88b1bc 100644
--- a/security/apparmor/include/policy_unpack.h
+++ b/security/apparmor/include/policy_unpack.h
@@ -15,6 +15,25 @@
15#ifndef __POLICY_INTERFACE_H 15#ifndef __POLICY_INTERFACE_H
16#define __POLICY_INTERFACE_H 16#define __POLICY_INTERFACE_H
17 17
18struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns); 18#include <linux/list.h>
19
20struct aa_load_ent {
21 struct list_head list;
22 struct aa_profile *new;
23 struct aa_profile *old;
24 struct aa_profile *rename;
25};
26
27void aa_load_ent_free(struct aa_load_ent *ent);
28struct aa_load_ent *aa_load_ent_alloc(void);
29
30#define PACKED_FLAG_HAT 1
31
32#define PACKED_MODE_ENFORCE 0
33#define PACKED_MODE_COMPLAIN 1
34#define PACKED_MODE_KILL 2
35#define PACKED_MODE_UNCONFINED 3
36
37int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns);
19 38
20#endif /* __POLICY_INTERFACE_H */ 39#endif /* __POLICY_INTERFACE_H */
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index fcfe0233574c..69689922c491 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -97,11 +97,6 @@ void *__aa_kvmalloc(size_t size, gfp_t flags)
97 if (size <= (16*PAGE_SIZE)) 97 if (size <= (16*PAGE_SIZE))
98 buffer = kmalloc(size, flags | GFP_NOIO | __GFP_NOWARN); 98 buffer = kmalloc(size, flags | GFP_NOIO | __GFP_NOWARN);
99 if (!buffer) { 99 if (!buffer) {
100 /* see kvfree for why size must be at least work_struct size
101 * when allocated via vmalloc
102 */
103 if (size < sizeof(struct work_struct))
104 size = sizeof(struct work_struct);
105 if (flags & __GFP_ZERO) 100 if (flags & __GFP_ZERO)
106 buffer = vzalloc(size); 101 buffer = vzalloc(size);
107 else 102 else
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 2e2a0dd4a73f..fb99e18123b4 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -508,19 +508,21 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
508 /* released below */ 508 /* released below */
509 const struct cred *cred = get_task_cred(task); 509 const struct cred *cred = get_task_cred(task);
510 struct aa_task_cxt *cxt = cred_cxt(cred); 510 struct aa_task_cxt *cxt = cred_cxt(cred);
511 struct aa_profile *profile = NULL;
511 512
512 if (strcmp(name, "current") == 0) 513 if (strcmp(name, "current") == 0)
513 error = aa_getprocattr(aa_newest_version(cxt->profile), 514 profile = aa_get_newest_profile(cxt->profile);
514 value);
515 else if (strcmp(name, "prev") == 0 && cxt->previous) 515 else if (strcmp(name, "prev") == 0 && cxt->previous)
516 error = aa_getprocattr(aa_newest_version(cxt->previous), 516 profile = aa_get_newest_profile(cxt->previous);
517 value);
518 else if (strcmp(name, "exec") == 0 && cxt->onexec) 517 else if (strcmp(name, "exec") == 0 && cxt->onexec)
519 error = aa_getprocattr(aa_newest_version(cxt->onexec), 518 profile = aa_get_newest_profile(cxt->onexec);
520 value);
521 else 519 else
522 error = -EINVAL; 520 error = -EINVAL;
523 521
522 if (profile)
523 error = aa_getprocattr(profile, value);
524
525 aa_put_profile(profile);
524 put_cred(cred); 526 put_cred(cred);
525 527
526 return error; 528 return error;
@@ -666,6 +668,7 @@ static int param_set_aabool(const char *val, const struct kernel_param *kp);
666static int param_get_aabool(char *buffer, const struct kernel_param *kp); 668static int param_get_aabool(char *buffer, const struct kernel_param *kp);
667#define param_check_aabool param_check_bool 669#define param_check_aabool param_check_bool
668static struct kernel_param_ops param_ops_aabool = { 670static struct kernel_param_ops param_ops_aabool = {
671 .flags = KERNEL_PARAM_FL_NOARG,
669 .set = param_set_aabool, 672 .set = param_set_aabool,
670 .get = param_get_aabool 673 .get = param_get_aabool
671}; 674};
@@ -682,6 +685,7 @@ static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp
682static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); 685static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
683#define param_check_aalockpolicy param_check_bool 686#define param_check_aalockpolicy param_check_bool
684static struct kernel_param_ops param_ops_aalockpolicy = { 687static struct kernel_param_ops param_ops_aalockpolicy = {
688 .flags = KERNEL_PARAM_FL_NOARG,
685 .set = param_set_aalockpolicy, 689 .set = param_set_aalockpolicy,
686 .get = param_get_aalockpolicy 690 .get = param_get_aalockpolicy
687}; 691};
@@ -742,7 +746,7 @@ module_param_named(paranoid_load, aa_g_paranoid_load, aabool,
742 746
743/* Boot time disable flag */ 747/* Boot time disable flag */
744static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; 748static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
745module_param_named(enabled, apparmor_enabled, aabool, S_IRUSR); 749module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
746 750
747static int __init apparmor_enabled_setup(char *str) 751static int __init apparmor_enabled_setup(char *str)
748{ 752{
@@ -841,7 +845,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
841 if (!apparmor_enabled) 845 if (!apparmor_enabled)
842 return -EINVAL; 846 return -EINVAL;
843 847
844 return sprintf(buffer, "%s", profile_mode_names[aa_g_profile_mode]); 848 return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]);
845} 849}
846 850
847static int param_set_mode(const char *val, struct kernel_param *kp) 851static int param_set_mode(const char *val, struct kernel_param *kp)
@@ -856,8 +860,8 @@ static int param_set_mode(const char *val, struct kernel_param *kp)
856 if (!val) 860 if (!val)
857 return -EINVAL; 861 return -EINVAL;
858 862
859 for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) { 863 for (i = 0; i < APPARMOR_MODE_NAMES_MAX_INDEX; i++) {
860 if (strcmp(val, profile_mode_names[i]) == 0) { 864 if (strcmp(val, aa_profile_mode_names[i]) == 0) {
861 aa_g_profile_mode = i; 865 aa_g_profile_mode = i;
862 return 0; 866 return 0;
863 } 867 }
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 0f345c4dee5f..705c2879d3a9 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -92,10 +92,11 @@
92/* root profile namespace */ 92/* root profile namespace */
93struct aa_namespace *root_ns; 93struct aa_namespace *root_ns;
94 94
95const char *const profile_mode_names[] = { 95const char *const aa_profile_mode_names[] = {
96 "enforce", 96 "enforce",
97 "complain", 97 "complain",
98 "kill", 98 "kill",
99 "unconfined",
99}; 100};
100 101
101/** 102/**
@@ -141,7 +142,6 @@ static bool policy_init(struct aa_policy *policy, const char *prefix,
141 policy->name = (char *)hname_tail(policy->hname); 142 policy->name = (char *)hname_tail(policy->hname);
142 INIT_LIST_HEAD(&policy->list); 143 INIT_LIST_HEAD(&policy->list);
143 INIT_LIST_HEAD(&policy->profiles); 144 INIT_LIST_HEAD(&policy->profiles);
144 kref_init(&policy->count);
145 145
146 return 1; 146 return 1;
147} 147}
@@ -153,13 +153,13 @@ static bool policy_init(struct aa_policy *policy, const char *prefix,
153static void policy_destroy(struct aa_policy *policy) 153static void policy_destroy(struct aa_policy *policy)
154{ 154{
155 /* still contains profiles -- invalid */ 155 /* still contains profiles -- invalid */
156 if (!list_empty(&policy->profiles)) { 156 if (on_list_rcu(&policy->profiles)) {
157 AA_ERROR("%s: internal error, " 157 AA_ERROR("%s: internal error, "
158 "policy '%s' still contains profiles\n", 158 "policy '%s' still contains profiles\n",
159 __func__, policy->name); 159 __func__, policy->name);
160 BUG(); 160 BUG();
161 } 161 }
162 if (!list_empty(&policy->list)) { 162 if (on_list_rcu(&policy->list)) {
163 AA_ERROR("%s: internal error, policy '%s' still on list\n", 163 AA_ERROR("%s: internal error, policy '%s' still on list\n",
164 __func__, policy->name); 164 __func__, policy->name);
165 BUG(); 165 BUG();
@@ -174,7 +174,7 @@ static void policy_destroy(struct aa_policy *policy)
174 * @head: list to search (NOT NULL) 174 * @head: list to search (NOT NULL)
175 * @name: name to search for (NOT NULL) 175 * @name: name to search for (NOT NULL)
176 * 176 *
177 * Requires: correct locks for the @head list be held 177 * Requires: rcu_read_lock be held
178 * 178 *
179 * Returns: unrefcounted policy that match @name or NULL if not found 179 * Returns: unrefcounted policy that match @name or NULL if not found
180 */ 180 */
@@ -182,7 +182,7 @@ static struct aa_policy *__policy_find(struct list_head *head, const char *name)
182{ 182{
183 struct aa_policy *policy; 183 struct aa_policy *policy;
184 184
185 list_for_each_entry(policy, head, list) { 185 list_for_each_entry_rcu(policy, head, list) {
186 if (!strcmp(policy->name, name)) 186 if (!strcmp(policy->name, name))
187 return policy; 187 return policy;
188 } 188 }
@@ -195,7 +195,7 @@ static struct aa_policy *__policy_find(struct list_head *head, const char *name)
195 * @str: string to search for (NOT NULL) 195 * @str: string to search for (NOT NULL)
196 * @len: length of match required 196 * @len: length of match required
197 * 197 *
198 * Requires: correct locks for the @head list be held 198 * Requires: rcu_read_lock be held
199 * 199 *
200 * Returns: unrefcounted policy that match @str or NULL if not found 200 * Returns: unrefcounted policy that match @str or NULL if not found
201 * 201 *
@@ -207,7 +207,7 @@ static struct aa_policy *__policy_strn_find(struct list_head *head,
207{ 207{
208 struct aa_policy *policy; 208 struct aa_policy *policy;
209 209
210 list_for_each_entry(policy, head, list) { 210 list_for_each_entry_rcu(policy, head, list) {
211 if (aa_strneq(policy->name, str, len)) 211 if (aa_strneq(policy->name, str, len))
212 return policy; 212 return policy;
213 } 213 }
@@ -284,22 +284,19 @@ static struct aa_namespace *alloc_namespace(const char *prefix,
284 goto fail_ns; 284 goto fail_ns;
285 285
286 INIT_LIST_HEAD(&ns->sub_ns); 286 INIT_LIST_HEAD(&ns->sub_ns);
287 rwlock_init(&ns->lock); 287 mutex_init(&ns->lock);
288 288
289 /* released by free_namespace */ 289 /* released by free_namespace */
290 ns->unconfined = aa_alloc_profile("unconfined"); 290 ns->unconfined = aa_alloc_profile("unconfined");
291 if (!ns->unconfined) 291 if (!ns->unconfined)
292 goto fail_unconfined; 292 goto fail_unconfined;
293 293
294 ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR | 294 ns->unconfined->flags = PFLAG_IX_ON_NAME_ERROR |
295 PFLAG_IMMUTABLE; 295 PFLAG_IMMUTABLE | PFLAG_NS_COUNT;
296 ns->unconfined->mode = APPARMOR_UNCONFINED;
296 297
297 /* 298 /* ns and ns->unconfined share ns->unconfined refcount */
298 * released by free_namespace, however __remove_namespace breaks 299 ns->unconfined->ns = ns;
299 * the cyclic references (ns->unconfined, and unconfined->ns) and
300 * replaces with refs to parent namespace unconfined
301 */
302 ns->unconfined->ns = aa_get_namespace(ns);
303 300
304 atomic_set(&ns->uniq_null, 0); 301 atomic_set(&ns->uniq_null, 0);
305 302
@@ -327,30 +324,19 @@ static void free_namespace(struct aa_namespace *ns)
327 policy_destroy(&ns->base); 324 policy_destroy(&ns->base);
328 aa_put_namespace(ns->parent); 325 aa_put_namespace(ns->parent);
329 326
330 if (ns->unconfined && ns->unconfined->ns == ns) 327 ns->unconfined->ns = NULL;
331 ns->unconfined->ns = NULL; 328 aa_free_profile(ns->unconfined);
332
333 aa_put_profile(ns->unconfined);
334 kzfree(ns); 329 kzfree(ns);
335} 330}
336 331
337/** 332/**
338 * aa_free_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
339 * @kr: kref callback for freeing of a namespace (NOT NULL)
340 */
341void aa_free_namespace_kref(struct kref *kref)
342{
343 free_namespace(container_of(kref, struct aa_namespace, base.count));
344}
345
346/**
347 * __aa_find_namespace - find a namespace on a list by @name 333 * __aa_find_namespace - find a namespace on a list by @name
348 * @head: list to search for namespace on (NOT NULL) 334 * @head: list to search for namespace on (NOT NULL)
349 * @name: name of namespace to look for (NOT NULL) 335 * @name: name of namespace to look for (NOT NULL)
350 * 336 *
351 * Returns: unrefcounted namespace 337 * Returns: unrefcounted namespace
352 * 338 *
353 * Requires: ns lock be held 339 * Requires: rcu_read_lock be held
354 */ 340 */
355static struct aa_namespace *__aa_find_namespace(struct list_head *head, 341static struct aa_namespace *__aa_find_namespace(struct list_head *head,
356 const char *name) 342 const char *name)
@@ -373,9 +359,9 @@ struct aa_namespace *aa_find_namespace(struct aa_namespace *root,
373{ 359{
374 struct aa_namespace *ns = NULL; 360 struct aa_namespace *ns = NULL;
375 361
376 read_lock(&root->lock); 362 rcu_read_lock();
377 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name)); 363 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
378 read_unlock(&root->lock); 364 rcu_read_unlock();
379 365
380 return ns; 366 return ns;
381} 367}
@@ -392,7 +378,7 @@ static struct aa_namespace *aa_prepare_namespace(const char *name)
392 378
393 root = aa_current_profile()->ns; 379 root = aa_current_profile()->ns;
394 380
395 write_lock(&root->lock); 381 mutex_lock(&root->lock);
396 382
397 /* if name isn't specified the profile is loaded to the current ns */ 383 /* if name isn't specified the profile is loaded to the current ns */
398 if (!name) { 384 if (!name) {
@@ -405,31 +391,23 @@ static struct aa_namespace *aa_prepare_namespace(const char *name)
405 /* released by caller */ 391 /* released by caller */
406 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name)); 392 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
407 if (!ns) { 393 if (!ns) {
408 /* namespace not found */ 394 ns = alloc_namespace(root->base.hname, name);
409 struct aa_namespace *new_ns; 395 if (!ns)
410 write_unlock(&root->lock); 396 goto out;
411 new_ns = alloc_namespace(root->base.hname, name); 397 if (__aa_fs_namespace_mkdir(ns, ns_subns_dir(root), name)) {
412 if (!new_ns) 398 AA_ERROR("Failed to create interface for ns %s\n",
413 return NULL; 399 ns->base.name);
414 write_lock(&root->lock); 400 free_namespace(ns);
415 /* test for race when new_ns was allocated */ 401 ns = NULL;
416 ns = __aa_find_namespace(&root->sub_ns, name); 402 goto out;
417 if (!ns) {
418 /* add parent ref */
419 new_ns->parent = aa_get_namespace(root);
420
421 list_add(&new_ns->base.list, &root->sub_ns);
422 /* add list ref */
423 ns = aa_get_namespace(new_ns);
424 } else {
425 /* raced so free the new one */
426 free_namespace(new_ns);
427 /* get reference on namespace */
428 aa_get_namespace(ns);
429 } 403 }
404 ns->parent = aa_get_namespace(root);
405 list_add_rcu(&ns->base.list, &root->sub_ns);
406 /* add list ref */
407 aa_get_namespace(ns);
430 } 408 }
431out: 409out:
432 write_unlock(&root->lock); 410 mutex_unlock(&root->lock);
433 411
434 /* return ref */ 412 /* return ref */
435 return ns; 413 return ns;
@@ -447,7 +425,7 @@ out:
447static void __list_add_profile(struct list_head *list, 425static void __list_add_profile(struct list_head *list,
448 struct aa_profile *profile) 426 struct aa_profile *profile)
449{ 427{
450 list_add(&profile->base.list, list); 428 list_add_rcu(&profile->base.list, list);
451 /* get list reference */ 429 /* get list reference */
452 aa_get_profile(profile); 430 aa_get_profile(profile);
453} 431}
@@ -466,49 +444,8 @@ static void __list_add_profile(struct list_head *list,
466 */ 444 */
467static void __list_remove_profile(struct aa_profile *profile) 445static void __list_remove_profile(struct aa_profile *profile)
468{ 446{
469 list_del_init(&profile->base.list); 447 list_del_rcu(&profile->base.list);
470 if (!(profile->flags & PFLAG_NO_LIST_REF)) 448 aa_put_profile(profile);
471 /* release list reference */
472 aa_put_profile(profile);
473}
474
475/**
476 * __replace_profile - replace @old with @new on a list
477 * @old: profile to be replaced (NOT NULL)
478 * @new: profile to replace @old with (NOT NULL)
479 *
480 * Will duplicate and refcount elements that @new inherits from @old
481 * and will inherit @old children.
482 *
483 * refcount @new for list, put @old list refcount
484 *
485 * Requires: namespace list lock be held, or list not be shared
486 */
487static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
488{
489 struct aa_policy *policy;
490 struct aa_profile *child, *tmp;
491
492 if (old->parent)
493 policy = &old->parent->base;
494 else
495 policy = &old->ns->base;
496
497 /* released when @new is freed */
498 new->parent = aa_get_profile(old->parent);
499 new->ns = aa_get_namespace(old->ns);
500 __list_add_profile(&policy->profiles, new);
501 /* inherit children */
502 list_for_each_entry_safe(child, tmp, &old->base.profiles, base.list) {
503 aa_put_profile(child->parent);
504 child->parent = aa_get_profile(new);
505 /* list refcount transferred to @new*/
506 list_move(&child->base.list, &new->base.profiles);
507 }
508
509 /* released by free_profile */
510 old->replacedby = aa_get_profile(new);
511 __list_remove_profile(old);
512} 449}
513 450
514static void __profile_list_release(struct list_head *head); 451static void __profile_list_release(struct list_head *head);
@@ -524,7 +461,8 @@ static void __remove_profile(struct aa_profile *profile)
524 /* release any children lists first */ 461 /* release any children lists first */
525 __profile_list_release(&profile->base.profiles); 462 __profile_list_release(&profile->base.profiles);
526 /* released by free_profile */ 463 /* released by free_profile */
527 profile->replacedby = aa_get_profile(profile->ns->unconfined); 464 __aa_update_replacedby(profile, profile->ns->unconfined);
465 __aa_fs_profile_rmdir(profile);
528 __list_remove_profile(profile); 466 __list_remove_profile(profile);
529} 467}
530 468
@@ -552,14 +490,17 @@ static void destroy_namespace(struct aa_namespace *ns)
552 if (!ns) 490 if (!ns)
553 return; 491 return;
554 492
555 write_lock(&ns->lock); 493 mutex_lock(&ns->lock);
556 /* release all profiles in this namespace */ 494 /* release all profiles in this namespace */
557 __profile_list_release(&ns->base.profiles); 495 __profile_list_release(&ns->base.profiles);
558 496
559 /* release all sub namespaces */ 497 /* release all sub namespaces */
560 __ns_list_release(&ns->sub_ns); 498 __ns_list_release(&ns->sub_ns);
561 499
562 write_unlock(&ns->lock); 500 if (ns->parent)
501 __aa_update_replacedby(ns->unconfined, ns->parent->unconfined);
502 __aa_fs_namespace_rmdir(ns);
503 mutex_unlock(&ns->lock);
563} 504}
564 505
565/** 506/**
@@ -570,25 +511,9 @@ static void destroy_namespace(struct aa_namespace *ns)
570 */ 511 */
571static void __remove_namespace(struct aa_namespace *ns) 512static void __remove_namespace(struct aa_namespace *ns)
572{ 513{
573 struct aa_profile *unconfined = ns->unconfined;
574
575 /* remove ns from namespace list */ 514 /* remove ns from namespace list */
576 list_del_init(&ns->base.list); 515 list_del_rcu(&ns->base.list);
577
578 /*
579 * break the ns, unconfined profile cyclic reference and forward
580 * all new unconfined profiles requests to the parent namespace
581 * This will result in all confined tasks that have a profile
582 * being removed, inheriting the parent->unconfined profile.
583 */
584 if (ns->parent)
585 ns->unconfined = aa_get_profile(ns->parent->unconfined);
586
587 destroy_namespace(ns); 516 destroy_namespace(ns);
588
589 /* release original ns->unconfined ref */
590 aa_put_profile(unconfined);
591 /* release ns->base.list ref, from removal above */
592 aa_put_namespace(ns); 517 aa_put_namespace(ns);
593} 518}
594 519
@@ -634,8 +559,26 @@ void __init aa_free_root_ns(void)
634 aa_put_namespace(ns); 559 aa_put_namespace(ns);
635} 560}
636 561
562
563static void free_replacedby(struct aa_replacedby *r)
564{
565 if (r) {
566 /* r->profile will not be updated any more as r is dead */
567 aa_put_profile(rcu_dereference_protected(r->profile, true));
568 kzfree(r);
569 }
570}
571
572
573void aa_free_replacedby_kref(struct kref *kref)
574{
575 struct aa_replacedby *r = container_of(kref, struct aa_replacedby,
576 count);
577 free_replacedby(r);
578}
579
637/** 580/**
638 * free_profile - free a profile 581 * aa_free_profile - free a profile
639 * @profile: the profile to free (MAYBE NULL) 582 * @profile: the profile to free (MAYBE NULL)
640 * 583 *
641 * Free a profile, its hats and null_profile. All references to the profile, 584 * Free a profile, its hats and null_profile. All references to the profile,
@@ -644,25 +587,16 @@ void __init aa_free_root_ns(void)
644 * If the profile was referenced from a task context, free_profile() will 587 * If the profile was referenced from a task context, free_profile() will
645 * be called from an rcu callback routine, so we must not sleep here. 588 * be called from an rcu callback routine, so we must not sleep here.
646 */ 589 */
647static void free_profile(struct aa_profile *profile) 590void aa_free_profile(struct aa_profile *profile)
648{ 591{
649 struct aa_profile *p;
650
651 AA_DEBUG("%s(%p)\n", __func__, profile); 592 AA_DEBUG("%s(%p)\n", __func__, profile);
652 593
653 if (!profile) 594 if (!profile)
654 return; 595 return;
655 596
656 if (!list_empty(&profile->base.list)) {
657 AA_ERROR("%s: internal error, "
658 "profile '%s' still on ns list\n",
659 __func__, profile->base.name);
660 BUG();
661 }
662
663 /* free children profiles */ 597 /* free children profiles */
664 policy_destroy(&profile->base); 598 policy_destroy(&profile->base);
665 aa_put_profile(profile->parent); 599 aa_put_profile(rcu_access_pointer(profile->parent));
666 600
667 aa_put_namespace(profile->ns); 601 aa_put_namespace(profile->ns);
668 kzfree(profile->rename); 602 kzfree(profile->rename);
@@ -671,44 +605,36 @@ static void free_profile(struct aa_profile *profile)
671 aa_free_cap_rules(&profile->caps); 605 aa_free_cap_rules(&profile->caps);
672 aa_free_rlimit_rules(&profile->rlimits); 606 aa_free_rlimit_rules(&profile->rlimits);
673 607
608 kzfree(profile->dirname);
674 aa_put_dfa(profile->xmatch); 609 aa_put_dfa(profile->xmatch);
675 aa_put_dfa(profile->policy.dfa); 610 aa_put_dfa(profile->policy.dfa);
611 aa_put_replacedby(profile->replacedby);
676 612
677 /* put the profile reference for replacedby, but not via 613 kzfree(profile->hash);
678 * put_profile(kref_put).
679 * replacedby can form a long chain that can result in cascading
680 * frees that blows the stack because kref_put makes a nested fn
681 * call (it looks like recursion, with free_profile calling
682 * free_profile) for each profile in the chain lp#1056078.
683 */
684 for (p = profile->replacedby; p; ) {
685 if (atomic_dec_and_test(&p->base.count.refcount)) {
686 /* no more refs on p, grab its replacedby */
687 struct aa_profile *next = p->replacedby;
688 /* break the chain */
689 p->replacedby = NULL;
690 /* now free p, chain is broken */
691 free_profile(p);
692
693 /* follow up with next profile in the chain */
694 p = next;
695 } else
696 break;
697 }
698
699 kzfree(profile); 614 kzfree(profile);
700} 615}
701 616
702/** 617/**
618 * aa_free_profile_rcu - free aa_profile by rcu (called by aa_free_profile_kref)
619 * @head: rcu_head callback for freeing of a profile (NOT NULL)
620 */
621static void aa_free_profile_rcu(struct rcu_head *head)
622{
623 struct aa_profile *p = container_of(head, struct aa_profile, rcu);
624 if (p->flags & PFLAG_NS_COUNT)
625 free_namespace(p->ns);
626 else
627 aa_free_profile(p);
628}
629
630/**
703 * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile) 631 * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)
704 * @kr: kref callback for freeing of a profile (NOT NULL) 632 * @kr: kref callback for freeing of a profile (NOT NULL)
705 */ 633 */
706void aa_free_profile_kref(struct kref *kref) 634void aa_free_profile_kref(struct kref *kref)
707{ 635{
708 struct aa_profile *p = container_of(kref, struct aa_profile, 636 struct aa_profile *p = container_of(kref, struct aa_profile, count);
709 base.count); 637 call_rcu(&p->rcu, aa_free_profile_rcu);
710
711 free_profile(p);
712} 638}
713 639
714/** 640/**
@@ -726,13 +652,23 @@ struct aa_profile *aa_alloc_profile(const char *hname)
726 if (!profile) 652 if (!profile)
727 return NULL; 653 return NULL;
728 654
729 if (!policy_init(&profile->base, NULL, hname)) { 655 profile->replacedby = kzalloc(sizeof(struct aa_replacedby), GFP_KERNEL);
730 kzfree(profile); 656 if (!profile->replacedby)
731 return NULL; 657 goto fail;
732 } 658 kref_init(&profile->replacedby->count);
659
660 if (!policy_init(&profile->base, NULL, hname))
661 goto fail;
662 kref_init(&profile->count);
733 663
734 /* refcount released by caller */ 664 /* refcount released by caller */
735 return profile; 665 return profile;
666
667fail:
668 kzfree(profile->replacedby);
669 kzfree(profile);
670
671 return NULL;
736} 672}
737 673
738/** 674/**
@@ -772,12 +708,12 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, int hat)
772 profile->flags |= PFLAG_HAT; 708 profile->flags |= PFLAG_HAT;
773 709
774 /* released on free_profile */ 710 /* released on free_profile */
775 profile->parent = aa_get_profile(parent); 711 rcu_assign_pointer(profile->parent, aa_get_profile(parent));
776 profile->ns = aa_get_namespace(parent->ns); 712 profile->ns = aa_get_namespace(parent->ns);
777 713
778 write_lock(&profile->ns->lock); 714 mutex_lock(&profile->ns->lock);
779 __list_add_profile(&parent->base.profiles, profile); 715 __list_add_profile(&parent->base.profiles, profile);
780 write_unlock(&profile->ns->lock); 716 mutex_unlock(&profile->ns->lock);
781 717
782 /* refcount released by caller */ 718 /* refcount released by caller */
783 return profile; 719 return profile;
@@ -793,7 +729,7 @@ fail:
793 * @head: list to search (NOT NULL) 729 * @head: list to search (NOT NULL)
794 * @name: name of profile (NOT NULL) 730 * @name: name of profile (NOT NULL)
795 * 731 *
796 * Requires: ns lock protecting list be held 732 * Requires: rcu_read_lock be held
797 * 733 *
798 * Returns: unrefcounted profile ptr, or NULL if not found 734 * Returns: unrefcounted profile ptr, or NULL if not found
799 */ 735 */
@@ -808,7 +744,7 @@ static struct aa_profile *__find_child(struct list_head *head, const char *name)
808 * @name: name of profile (NOT NULL) 744 * @name: name of profile (NOT NULL)
809 * @len: length of @name substring to match 745 * @len: length of @name substring to match
810 * 746 *
811 * Requires: ns lock protecting list be held 747 * Requires: rcu_read_lock be held
812 * 748 *
813 * Returns: unrefcounted profile ptr, or NULL if not found 749 * Returns: unrefcounted profile ptr, or NULL if not found
814 */ 750 */
@@ -829,9 +765,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
829{ 765{
830 struct aa_profile *profile; 766 struct aa_profile *profile;
831 767
832 read_lock(&parent->ns->lock); 768 rcu_read_lock();
833 profile = aa_get_profile(__find_child(&parent->base.profiles, name)); 769 profile = aa_get_profile(__find_child(&parent->base.profiles, name));
834 read_unlock(&parent->ns->lock); 770 rcu_read_unlock();
835 771
836 /* refcount released by caller */ 772 /* refcount released by caller */
837 return profile; 773 return profile;
@@ -846,7 +782,7 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
846 * that matches hname does not need to exist, in general this 782 * that matches hname does not need to exist, in general this
847 * is used to load a new profile. 783 * is used to load a new profile.
848 * 784 *
849 * Requires: ns->lock be held 785 * Requires: rcu_read_lock be held
850 * 786 *
851 * Returns: unrefcounted policy or NULL if not found 787 * Returns: unrefcounted policy or NULL if not found
852 */ 788 */
@@ -878,7 +814,7 @@ static struct aa_policy *__lookup_parent(struct aa_namespace *ns,
878 * @base: base list to start looking up profile name from (NOT NULL) 814 * @base: base list to start looking up profile name from (NOT NULL)
879 * @hname: hierarchical profile name (NOT NULL) 815 * @hname: hierarchical profile name (NOT NULL)
880 * 816 *
881 * Requires: ns->lock be held 817 * Requires: rcu_read_lock be held
882 * 818 *
883 * Returns: unrefcounted profile pointer or NULL if not found 819 * Returns: unrefcounted profile pointer or NULL if not found
884 * 820 *
@@ -917,13 +853,15 @@ struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname)
917{ 853{
918 struct aa_profile *profile; 854 struct aa_profile *profile;
919 855
920 read_lock(&ns->lock); 856 rcu_read_lock();
921 profile = aa_get_profile(__lookup_profile(&ns->base, hname)); 857 do {
922 read_unlock(&ns->lock); 858 profile = __lookup_profile(&ns->base, hname);
859 } while (profile && !aa_get_profile_not0(profile));
860 rcu_read_unlock();
923 861
924 /* the unconfined profile is not in the regular profile list */ 862 /* the unconfined profile is not in the regular profile list */
925 if (!profile && strcmp(hname, "unconfined") == 0) 863 if (!profile && strcmp(hname, "unconfined") == 0)
926 profile = aa_get_profile(ns->unconfined); 864 profile = aa_get_newest_profile(ns->unconfined);
927 865
928 /* refcount released by caller */ 866 /* refcount released by caller */
929 return profile; 867 return profile;
@@ -953,25 +891,6 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace,
953} 891}
954 892
955/** 893/**
956 * __add_new_profile - simple wrapper around __list_add_profile
957 * @ns: namespace that profile is being added to (NOT NULL)
958 * @policy: the policy container to add the profile to (NOT NULL)
959 * @profile: profile to add (NOT NULL)
960 *
961 * add a profile to a list and do other required basic allocations
962 */
963static void __add_new_profile(struct aa_namespace *ns, struct aa_policy *policy,
964 struct aa_profile *profile)
965{
966 if (policy != &ns->base)
967 /* released on profile replacement or free_profile */
968 profile->parent = aa_get_profile((struct aa_profile *) policy);
969 __list_add_profile(&policy->profiles, profile);
970 /* released on free_profile */
971 profile->ns = aa_get_namespace(ns);
972}
973
974/**
975 * aa_audit_policy - Do auditing of policy changes 894 * aa_audit_policy - Do auditing of policy changes
976 * @op: policy operation being performed 895 * @op: policy operation being performed
977 * @gfp: memory allocation flags 896 * @gfp: memory allocation flags
@@ -1019,6 +938,121 @@ bool aa_may_manage_policy(int op)
1019 return 1; 938 return 1;
1020} 939}
1021 940
941static struct aa_profile *__list_lookup_parent(struct list_head *lh,
942 struct aa_profile *profile)
943{
944 const char *base = hname_tail(profile->base.hname);
945 long len = base - profile->base.hname;
946 struct aa_load_ent *ent;
947
948 /* parent won't have trailing // so remove from len */
949 if (len <= 2)
950 return NULL;
951 len -= 2;
952
953 list_for_each_entry(ent, lh, list) {
954 if (ent->new == profile)
955 continue;
956 if (strncmp(ent->new->base.hname, profile->base.hname, len) ==
957 0 && ent->new->base.hname[len] == 0)
958 return ent->new;
959 }
960
961 return NULL;
962}
963
964/**
965 * __replace_profile - replace @old with @new on a list
966 * @old: profile to be replaced (NOT NULL)
967 * @new: profile to replace @old with (NOT NULL)
968 * @share_replacedby: transfer @old->replacedby to @new
969 *
970 * Will duplicate and refcount elements that @new inherits from @old
971 * and will inherit @old children.
972 *
973 * refcount @new for list, put @old list refcount
974 *
975 * Requires: namespace list lock be held, or list not be shared
976 */
977static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
978 bool share_replacedby)
979{
980 struct aa_profile *child, *tmp;
981
982 if (!list_empty(&old->base.profiles)) {
983 LIST_HEAD(lh);
984 list_splice_init_rcu(&old->base.profiles, &lh, synchronize_rcu);
985
986 list_for_each_entry_safe(child, tmp, &lh, base.list) {
987 struct aa_profile *p;
988
989 list_del_init(&child->base.list);
990 p = __find_child(&new->base.profiles, child->base.name);
991 if (p) {
992 /* @p replaces @child */
993 __replace_profile(child, p, share_replacedby);
994 continue;
995 }
996
997 /* inherit @child and its children */
998 /* TODO: update hname of inherited children */
999 /* list refcount transferred to @new */
1000 p = aa_deref_parent(child);
1001 rcu_assign_pointer(child->parent, aa_get_profile(new));
1002 list_add_rcu(&child->base.list, &new->base.profiles);
1003 aa_put_profile(p);
1004 }
1005 }
1006
1007 if (!rcu_access_pointer(new->parent)) {
1008 struct aa_profile *parent = aa_deref_parent(old);
1009 rcu_assign_pointer(new->parent, aa_get_profile(parent));
1010 }
1011 __aa_update_replacedby(old, new);
1012 if (share_replacedby) {
1013 aa_put_replacedby(new->replacedby);
1014 new->replacedby = aa_get_replacedby(old->replacedby);
1015 } else if (!rcu_access_pointer(new->replacedby->profile))
1016 /* aafs interface uses replacedby */
1017 rcu_assign_pointer(new->replacedby->profile,
1018 aa_get_profile(new));
1019 __aa_fs_profile_migrate_dents(old, new);
1020
1021 if (list_empty(&new->base.list)) {
1022 /* new is not on a list already */
1023 list_replace_rcu(&old->base.list, &new->base.list);
1024 aa_get_profile(new);
1025 aa_put_profile(old);
1026 } else
1027 __list_remove_profile(old);
1028}
1029
1030/**
1031 * __lookup_replace - lookup replacement information for a profile
1032 * @ns - namespace the lookup occurs in
1033 * @hname - name of profile to lookup
1034 * @noreplace - true if not replacing an existing profile
1035 * @p - Returns: profile to be replaced
1036 * @info - Returns: info string on why lookup failed
1037 *
1038 * Returns: profile to replace (no ref) on success else ptr error
1039 */
1040static int __lookup_replace(struct aa_namespace *ns, const char *hname,
1041 bool noreplace, struct aa_profile **p,
1042 const char **info)
1043{
1044 *p = aa_get_profile(__lookup_profile(&ns->base, hname));
1045 if (*p) {
1046 int error = replacement_allowed(*p, noreplace, info);
1047 if (error) {
1048 *info = "profile can not be replaced";
1049 return error;
1050 }
1051 }
1052
1053 return 0;
1054}
1055
1022/** 1056/**
1023 * aa_replace_profiles - replace profile(s) on the profile list 1057 * aa_replace_profiles - replace profile(s) on the profile list
1024 * @udata: serialized data stream (NOT NULL) 1058 * @udata: serialized data stream (NOT NULL)
@@ -1033,21 +1067,17 @@ bool aa_may_manage_policy(int op)
1033 */ 1067 */
1034ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace) 1068ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
1035{ 1069{
1036 struct aa_policy *policy;
1037 struct aa_profile *old_profile = NULL, *new_profile = NULL;
1038 struct aa_profile *rename_profile = NULL;
1039 struct aa_namespace *ns = NULL;
1040 const char *ns_name, *name = NULL, *info = NULL; 1070 const char *ns_name, *name = NULL, *info = NULL;
1071 struct aa_namespace *ns = NULL;
1072 struct aa_load_ent *ent, *tmp;
1041 int op = OP_PROF_REPL; 1073 int op = OP_PROF_REPL;
1042 ssize_t error; 1074 ssize_t error;
1075 LIST_HEAD(lh);
1043 1076
1044 /* released below */ 1077 /* released below */
1045 new_profile = aa_unpack(udata, size, &ns_name); 1078 error = aa_unpack(udata, size, &lh, &ns_name);
1046 if (IS_ERR(new_profile)) { 1079 if (error)
1047 error = PTR_ERR(new_profile); 1080 goto out;
1048 new_profile = NULL;
1049 goto fail;
1050 }
1051 1081
1052 /* released below */ 1082 /* released below */
1053 ns = aa_prepare_namespace(ns_name); 1083 ns = aa_prepare_namespace(ns_name);
@@ -1058,71 +1088,140 @@ ssize_t aa_replace_profiles(void *udata, size_t size, bool noreplace)
1058 goto fail; 1088 goto fail;
1059 } 1089 }
1060 1090
1061 name = new_profile->base.hname; 1091 mutex_lock(&ns->lock);
1062 1092 /* setup parent and ns info */
1063 write_lock(&ns->lock); 1093 list_for_each_entry(ent, &lh, list) {
1064 /* no ref on policy only use inside lock */ 1094 struct aa_policy *policy;
1065 policy = __lookup_parent(ns, new_profile->base.hname); 1095
1096 name = ent->new->base.hname;
1097 error = __lookup_replace(ns, ent->new->base.hname, noreplace,
1098 &ent->old, &info);
1099 if (error)
1100 goto fail_lock;
1101
1102 if (ent->new->rename) {
1103 error = __lookup_replace(ns, ent->new->rename,
1104 noreplace, &ent->rename,
1105 &info);
1106 if (error)
1107 goto fail_lock;
1108 }
1066 1109
1067 if (!policy) { 1110 /* released when @new is freed */
1068 info = "parent does not exist"; 1111 ent->new->ns = aa_get_namespace(ns);
1069 error = -ENOENT; 1112
1070 goto audit; 1113 if (ent->old || ent->rename)
1114 continue;
1115
1116 /* no ref on policy only use inside lock */
1117 policy = __lookup_parent(ns, ent->new->base.hname);
1118 if (!policy) {
1119 struct aa_profile *p;
1120 p = __list_lookup_parent(&lh, ent->new);
1121 if (!p) {
1122 error = -ENOENT;
1123 info = "parent does not exist";
1124 name = ent->new->base.hname;
1125 goto fail_lock;
1126 }
1127 rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
1128 } else if (policy != &ns->base) {
1129 /* released on profile replacement or free_profile */
1130 struct aa_profile *p = (struct aa_profile *) policy;
1131 rcu_assign_pointer(ent->new->parent, aa_get_profile(p));
1132 }
1071 } 1133 }
1072 1134
1073 old_profile = __find_child(&policy->profiles, new_profile->base.name); 1135 /* create new fs entries for introspection if needed */
1074 /* released below */ 1136 list_for_each_entry(ent, &lh, list) {
1075 aa_get_profile(old_profile); 1137 if (ent->old) {
1138 /* inherit old interface files */
1076 1139
1077 if (new_profile->rename) { 1140 /* if (ent->rename)
1078 rename_profile = __lookup_profile(&ns->base, 1141 TODO: support rename */
1079 new_profile->rename); 1142 /* } else if (ent->rename) {
1080 /* released below */ 1143 TODO: support rename */
1081 aa_get_profile(rename_profile); 1144 } else {
1145 struct dentry *parent;
1146 if (rcu_access_pointer(ent->new->parent)) {
1147 struct aa_profile *p;
1148 p = aa_deref_parent(ent->new);
1149 parent = prof_child_dir(p);
1150 } else
1151 parent = ns_subprofs_dir(ent->new->ns);
1152 error = __aa_fs_profile_mkdir(ent->new, parent);
1153 }
1082 1154
1083 if (!rename_profile) { 1155 if (error) {
1084 info = "profile to rename does not exist"; 1156 info = "failed to create ";
1085 name = new_profile->rename; 1157 goto fail_lock;
1086 error = -ENOENT;
1087 goto audit;
1088 } 1158 }
1089 } 1159 }
1090 1160
1091 error = replacement_allowed(old_profile, noreplace, &info); 1161 /* Done with checks that may fail - do actual replacement */
1092 if (error) 1162 list_for_each_entry_safe(ent, tmp, &lh, list) {
1093 goto audit; 1163 list_del_init(&ent->list);
1094 1164 op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
1095 error = replacement_allowed(rename_profile, noreplace, &info); 1165
1096 if (error) 1166 audit_policy(op, GFP_ATOMIC, ent->new->base.name, NULL, error);
1097 goto audit; 1167
1098 1168 if (ent->old) {
1099audit: 1169 __replace_profile(ent->old, ent->new, 1);
1100 if (!old_profile && !rename_profile) 1170 if (ent->rename) {
1101 op = OP_PROF_LOAD; 1171 /* aafs interface uses replacedby */
1102 1172 struct aa_replacedby *r = ent->new->replacedby;
1103 error = audit_policy(op, GFP_ATOMIC, name, info, error); 1173 rcu_assign_pointer(r->profile,
1104 1174 aa_get_profile(ent->new));
1105 if (!error) { 1175 __replace_profile(ent->rename, ent->new, 0);
1106 if (rename_profile) 1176 }
1107 __replace_profile(rename_profile, new_profile); 1177 } else if (ent->rename) {
1108 if (old_profile) 1178 /* aafs interface uses replacedby */
1109 __replace_profile(old_profile, new_profile); 1179 rcu_assign_pointer(ent->new->replacedby->profile,
1110 if (!(old_profile || rename_profile)) 1180 aa_get_profile(ent->new));
1111 __add_new_profile(ns, policy, new_profile); 1181 __replace_profile(ent->rename, ent->new, 0);
1182 } else if (ent->new->parent) {
1183 struct aa_profile *parent, *newest;
1184 parent = aa_deref_parent(ent->new);
1185 newest = aa_get_newest_profile(parent);
1186
1187 /* parent replaced in this atomic set? */
1188 if (newest != parent) {
1189 aa_get_profile(newest);
1190 aa_put_profile(parent);
1191 rcu_assign_pointer(ent->new->parent, newest);
1192 } else
1193 aa_put_profile(newest);
1194 /* aafs interface uses replacedby */
1195 rcu_assign_pointer(ent->new->replacedby->profile,
1196 aa_get_profile(ent->new));
1197 __list_add_profile(&parent->base.profiles, ent->new);
1198 } else {
1199 /* aafs interface uses replacedby */
1200 rcu_assign_pointer(ent->new->replacedby->profile,
1201 aa_get_profile(ent->new));
1202 __list_add_profile(&ns->base.profiles, ent->new);
1203 }
1204 aa_load_ent_free(ent);
1112 } 1205 }
1113 write_unlock(&ns->lock); 1206 mutex_unlock(&ns->lock);
1114 1207
1115out: 1208out:
1116 aa_put_namespace(ns); 1209 aa_put_namespace(ns);
1117 aa_put_profile(rename_profile); 1210
1118 aa_put_profile(old_profile);
1119 aa_put_profile(new_profile);
1120 if (error) 1211 if (error)
1121 return error; 1212 return error;
1122 return size; 1213 return size;
1123 1214
1215fail_lock:
1216 mutex_unlock(&ns->lock);
1124fail: 1217fail:
1125 error = audit_policy(op, GFP_KERNEL, name, info, error); 1218 error = audit_policy(op, GFP_KERNEL, name, info, error);
1219
1220 list_for_each_entry_safe(ent, tmp, &lh, list) {
1221 list_del_init(&ent->list);
1222 aa_load_ent_free(ent);
1223 }
1224
1126 goto out; 1225 goto out;
1127} 1226}
1128 1227
@@ -1169,12 +1268,12 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
1169 1268
1170 if (!name) { 1269 if (!name) {
1171 /* remove namespace - can only happen if fqname[0] == ':' */ 1270 /* remove namespace - can only happen if fqname[0] == ':' */
1172 write_lock(&ns->parent->lock); 1271 mutex_lock(&ns->parent->lock);
1173 __remove_namespace(ns); 1272 __remove_namespace(ns);
1174 write_unlock(&ns->parent->lock); 1273 mutex_unlock(&ns->parent->lock);
1175 } else { 1274 } else {
1176 /* remove profile */ 1275 /* remove profile */
1177 write_lock(&ns->lock); 1276 mutex_lock(&ns->lock);
1178 profile = aa_get_profile(__lookup_profile(&ns->base, name)); 1277 profile = aa_get_profile(__lookup_profile(&ns->base, name));
1179 if (!profile) { 1278 if (!profile) {
1180 error = -ENOENT; 1279 error = -ENOENT;
@@ -1183,7 +1282,7 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
1183 } 1282 }
1184 name = profile->base.hname; 1283 name = profile->base.hname;
1185 __remove_profile(profile); 1284 __remove_profile(profile);
1186 write_unlock(&ns->lock); 1285 mutex_unlock(&ns->lock);
1187 } 1286 }
1188 1287
1189 /* don't fail removal if audit fails */ 1288 /* don't fail removal if audit fails */
@@ -1193,7 +1292,7 @@ ssize_t aa_remove_profiles(char *fqname, size_t size)
1193 return size; 1292 return size;
1194 1293
1195fail_ns_lock: 1294fail_ns_lock:
1196 write_unlock(&ns->lock); 1295 mutex_unlock(&ns->lock);
1197 aa_put_namespace(ns); 1296 aa_put_namespace(ns);
1198 1297
1199fail: 1298fail:
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 6dac7d77cb4d..a689f10930b5 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -24,6 +24,7 @@
24#include "include/apparmor.h" 24#include "include/apparmor.h"
25#include "include/audit.h" 25#include "include/audit.h"
26#include "include/context.h" 26#include "include/context.h"
27#include "include/crypto.h"
27#include "include/match.h" 28#include "include/match.h"
28#include "include/policy.h" 29#include "include/policy.h"
29#include "include/policy_unpack.h" 30#include "include/policy_unpack.h"
@@ -333,8 +334,10 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
333 /* 334 /*
334 * The dfa is aligned with in the blob to 8 bytes 335 * The dfa is aligned with in the blob to 8 bytes
335 * from the beginning of the stream. 336 * from the beginning of the stream.
337 * alignment adjust needed by dfa unpack
336 */ 338 */
337 size_t sz = blob - (char *)e->start; 339 size_t sz = blob - (char *) e->start -
340 ((e->pos - e->start) & 7);
338 size_t pad = ALIGN(sz, 8) - sz; 341 size_t pad = ALIGN(sz, 8) - sz;
339 int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) | 342 int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
340 TO_ACCEPT2_FLAG(YYTD_DATA32); 343 TO_ACCEPT2_FLAG(YYTD_DATA32);
@@ -490,6 +493,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
490 /* profile renaming is optional */ 493 /* profile renaming is optional */
491 (void) unpack_str(e, &profile->rename, "rename"); 494 (void) unpack_str(e, &profile->rename, "rename");
492 495
496 /* attachment string is optional */
497 (void) unpack_str(e, &profile->attach, "attach");
498
493 /* xmatch is optional and may be NULL */ 499 /* xmatch is optional and may be NULL */
494 profile->xmatch = unpack_dfa(e); 500 profile->xmatch = unpack_dfa(e);
495 if (IS_ERR(profile->xmatch)) { 501 if (IS_ERR(profile->xmatch)) {
@@ -509,12 +515,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
509 goto fail; 515 goto fail;
510 if (!unpack_u32(e, &tmp, NULL)) 516 if (!unpack_u32(e, &tmp, NULL))
511 goto fail; 517 goto fail;
512 if (tmp) 518 if (tmp & PACKED_FLAG_HAT)
513 profile->flags |= PFLAG_HAT; 519 profile->flags |= PFLAG_HAT;
514 if (!unpack_u32(e, &tmp, NULL)) 520 if (!unpack_u32(e, &tmp, NULL))
515 goto fail; 521 goto fail;
516 if (tmp) 522 if (tmp == PACKED_MODE_COMPLAIN)
517 profile->mode = APPARMOR_COMPLAIN; 523 profile->mode = APPARMOR_COMPLAIN;
524 else if (tmp == PACKED_MODE_KILL)
525 profile->mode = APPARMOR_KILL;
526 else if (tmp == PACKED_MODE_UNCONFINED)
527 profile->mode = APPARMOR_UNCONFINED;
518 if (!unpack_u32(e, &tmp, NULL)) 528 if (!unpack_u32(e, &tmp, NULL))
519 goto fail; 529 goto fail;
520 if (tmp) 530 if (tmp)
@@ -614,7 +624,7 @@ fail:
614 else if (!name) 624 else if (!name)
615 name = "unknown"; 625 name = "unknown";
616 audit_iface(profile, name, "failed to unpack profile", e, error); 626 audit_iface(profile, name, "failed to unpack profile", e, error);
617 aa_put_profile(profile); 627 aa_free_profile(profile);
618 628
619 return ERR_PTR(error); 629 return ERR_PTR(error);
620} 630}
@@ -622,29 +632,41 @@ fail:
622/** 632/**
623 * verify_head - unpack serialized stream header 633 * verify_head - unpack serialized stream header
624 * @e: serialized data read head (NOT NULL) 634 * @e: serialized data read head (NOT NULL)
635 * @required: whether the header is required or optional
625 * @ns: Returns - namespace if one is specified else NULL (NOT NULL) 636 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
626 * 637 *
627 * Returns: error or 0 if header is good 638 * Returns: error or 0 if header is good
628 */ 639 */
629static int verify_header(struct aa_ext *e, const char **ns) 640static int verify_header(struct aa_ext *e, int required, const char **ns)
630{ 641{
631 int error = -EPROTONOSUPPORT; 642 int error = -EPROTONOSUPPORT;
643 const char *name = NULL;
644 *ns = NULL;
645
632 /* get the interface version */ 646 /* get the interface version */
633 if (!unpack_u32(e, &e->version, "version")) { 647 if (!unpack_u32(e, &e->version, "version")) {
634 audit_iface(NULL, NULL, "invalid profile format", e, error); 648 if (required) {
635 return error; 649 audit_iface(NULL, NULL, "invalid profile format", e,
636 } 650 error);
651 return error;
652 }
637 653
638 /* check that the interface version is currently supported */ 654 /* check that the interface version is currently supported */
639 if (e->version != 5) { 655 if (e->version != 5) {
640 audit_iface(NULL, NULL, "unsupported interface version", e, 656 audit_iface(NULL, NULL, "unsupported interface version",
641 error); 657 e, error);
642 return error; 658 return error;
659 }
643 } 660 }
644 661
662
645 /* read the namespace if present */ 663 /* read the namespace if present */
646 if (!unpack_str(e, ns, "namespace")) 664 if (unpack_str(e, &name, "namespace")) {
647 *ns = NULL; 665 if (*ns && strcmp(*ns, name))
666 audit_iface(NULL, NULL, "invalid ns change", e, error);
667 else if (!*ns)
668 *ns = name;
669 }
648 670
649 return 0; 671 return 0;
650} 672}
@@ -693,18 +715,40 @@ static int verify_profile(struct aa_profile *profile)
693 return 0; 715 return 0;
694} 716}
695 717
718void aa_load_ent_free(struct aa_load_ent *ent)
719{
720 if (ent) {
721 aa_put_profile(ent->rename);
722 aa_put_profile(ent->old);
723 aa_put_profile(ent->new);
724 kzfree(ent);
725 }
726}
727
728struct aa_load_ent *aa_load_ent_alloc(void)
729{
730 struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL);
731 if (ent)
732 INIT_LIST_HEAD(&ent->list);
733 return ent;
734}
735
696/** 736/**
697 * aa_unpack - unpack packed binary profile data loaded from user space 737 * aa_unpack - unpack packed binary profile(s) data loaded from user space
698 * @udata: user data copied to kmem (NOT NULL) 738 * @udata: user data copied to kmem (NOT NULL)
699 * @size: the size of the user data 739 * @size: the size of the user data
740 * @lh: list to place unpacked profiles in a aa_repl_ws
700 * @ns: Returns namespace profile is in if specified else NULL (NOT NULL) 741 * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
701 * 742 *
702 * Unpack user data and return refcounted allocated profile or ERR_PTR 743 * Unpack user data and return refcounted allocated profile(s) stored in
744 * @lh in order of discovery, with the list chain stored in base.list
745 * or error
703 * 746 *
704 * Returns: profile else error pointer if fails to unpack 747 * Returns: profile(s) on @lh else error pointer if fails to unpack
705 */ 748 */
706struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns) 749int aa_unpack(void *udata, size_t size, struct list_head *lh, const char **ns)
707{ 750{
751 struct aa_load_ent *tmp, *ent;
708 struct aa_profile *profile = NULL; 752 struct aa_profile *profile = NULL;
709 int error; 753 int error;
710 struct aa_ext e = { 754 struct aa_ext e = {
@@ -713,20 +757,49 @@ struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns)
713 .pos = udata, 757 .pos = udata,
714 }; 758 };
715 759
716 error = verify_header(&e, ns); 760 *ns = NULL;
717 if (error) 761 while (e.pos < e.end) {
718 return ERR_PTR(error); 762 void *start;
763 error = verify_header(&e, e.pos == e.start, ns);
764 if (error)
765 goto fail;
766
767 start = e.pos;
768 profile = unpack_profile(&e);
769 if (IS_ERR(profile)) {
770 error = PTR_ERR(profile);
771 goto fail;
772 }
773
774 error = verify_profile(profile);
775 if (error)
776 goto fail_profile;
777
778 error = aa_calc_profile_hash(profile, e.version, start,
779 e.pos - start);
780 if (error)
781 goto fail_profile;
782
783 ent = aa_load_ent_alloc();
784 if (!ent) {
785 error = -ENOMEM;
786 goto fail_profile;
787 }
788
789 ent->new = profile;
790 list_add_tail(&ent->list, lh);
791 }
792
793 return 0;
719 794
720 profile = unpack_profile(&e); 795fail_profile:
721 if (IS_ERR(profile)) 796 aa_put_profile(profile);
722 return profile;
723 797
724 error = verify_profile(profile); 798fail:
725 if (error) { 799 list_for_each_entry_safe(ent, tmp, lh, list) {
726 aa_put_profile(profile); 800 list_del_init(&ent->list);
727 profile = ERR_PTR(error); 801 aa_load_ent_free(ent);
728 } 802 }
729 803
730 /* return refcount */ 804 return error;
731 return profile;
732} 805}
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 6c9390179b89..b125acc9aa26 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -37,7 +37,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
37{ 37{
38 char *str; 38 char *str;
39 int len = 0, mode_len = 0, ns_len = 0, name_len; 39 int len = 0, mode_len = 0, ns_len = 0, name_len;
40 const char *mode_str = profile_mode_names[profile->mode]; 40 const char *mode_str = aa_profile_mode_names[profile->mode];
41 const char *ns_name = NULL; 41 const char *ns_name = NULL;
42 struct aa_namespace *ns = profile->ns; 42 struct aa_namespace *ns = profile->ns;
43 struct aa_namespace *current_ns = __aa_current_profile()->ns; 43 struct aa_namespace *current_ns = __aa_current_profile()->ns;
diff --git a/security/capability.c b/security/capability.c
index b6d779b6aa25..8b4f24ae4338 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -129,7 +129,7 @@ static void cap_inode_free_security(struct inode *inode)
129} 129}
130 130
131static int cap_inode_init_security(struct inode *inode, struct inode *dir, 131static int cap_inode_init_security(struct inode *inode, struct inode *dir,
132 const struct qstr *qstr, char **name, 132 const struct qstr *qstr, const char **name,
133 void **value, size_t *len) 133 void **value, size_t *len)
134{ 134{
135 return -EOPNOTSUPP; 135 return -EOPNOTSUPP;
diff --git a/security/commoncap.c b/security/commoncap.c
index c44b6fe6648e..b9d613e0ef14 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -768,16 +768,16 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
768 */ 768 */
769static int cap_safe_nice(struct task_struct *p) 769static int cap_safe_nice(struct task_struct *p)
770{ 770{
771 int is_subset; 771 int is_subset, ret = 0;
772 772
773 rcu_read_lock(); 773 rcu_read_lock();
774 is_subset = cap_issubset(__task_cred(p)->cap_permitted, 774 is_subset = cap_issubset(__task_cred(p)->cap_permitted,
775 current_cred()->cap_permitted); 775 current_cred()->cap_permitted);
776 if (!is_subset && !ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE))
777 ret = -EPERM;
776 rcu_read_unlock(); 778 rcu_read_unlock();
777 779
778 if (!is_subset && !capable(CAP_SYS_NICE)) 780 return ret;
779 return -EPERM;
780 return 0;
781} 781}
782 782
783/** 783/**
@@ -824,7 +824,7 @@ int cap_task_setnice(struct task_struct *p, int nice)
824 */ 824 */
825static long cap_prctl_drop(struct cred *new, unsigned long cap) 825static long cap_prctl_drop(struct cred *new, unsigned long cap)
826{ 826{
827 if (!capable(CAP_SETPCAP)) 827 if (!ns_capable(current_user_ns(), CAP_SETPCAP))
828 return -EPERM; 828 return -EPERM;
829 if (!cap_valid(cap)) 829 if (!cap_valid(cap))
830 return -EINVAL; 830 return -EINVAL;
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index e8aad69f0d69..c123628d3f84 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -53,22 +53,17 @@ struct dev_cgroup {
53 53
54static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) 54static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
55{ 55{
56 return container_of(s, struct dev_cgroup, css); 56 return s ? container_of(s, struct dev_cgroup, css) : NULL;
57}
58
59static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup)
60{
61 return css_to_devcgroup(cgroup_subsys_state(cgroup, devices_subsys_id));
62} 57}
63 58
64static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) 59static inline struct dev_cgroup *task_devcgroup(struct task_struct *task)
65{ 60{
66 return css_to_devcgroup(task_subsys_state(task, devices_subsys_id)); 61 return css_to_devcgroup(task_css(task, devices_subsys_id));
67} 62}
68 63
69struct cgroup_subsys devices_subsys; 64struct cgroup_subsys devices_subsys;
70 65
71static int devcgroup_can_attach(struct cgroup *new_cgrp, 66static int devcgroup_can_attach(struct cgroup_subsys_state *new_css,
72 struct cgroup_taskset *set) 67 struct cgroup_taskset *set)
73{ 68{
74 struct task_struct *task = cgroup_taskset_first(set); 69 struct task_struct *task = cgroup_taskset_first(set);
@@ -193,18 +188,16 @@ static inline bool is_devcg_online(const struct dev_cgroup *devcg)
193/** 188/**
194 * devcgroup_online - initializes devcgroup's behavior and exceptions based on 189 * devcgroup_online - initializes devcgroup's behavior and exceptions based on
195 * parent's 190 * parent's
196 * @cgroup: cgroup getting online 191 * @css: css getting online
197 * returns 0 in case of success, error code otherwise 192 * returns 0 in case of success, error code otherwise
198 */ 193 */
199static int devcgroup_online(struct cgroup *cgroup) 194static int devcgroup_online(struct cgroup_subsys_state *css)
200{ 195{
201 struct dev_cgroup *dev_cgroup, *parent_dev_cgroup = NULL; 196 struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
197 struct dev_cgroup *parent_dev_cgroup = css_to_devcgroup(css_parent(css));
202 int ret = 0; 198 int ret = 0;
203 199
204 mutex_lock(&devcgroup_mutex); 200 mutex_lock(&devcgroup_mutex);
205 dev_cgroup = cgroup_to_devcgroup(cgroup);
206 if (cgroup->parent)
207 parent_dev_cgroup = cgroup_to_devcgroup(cgroup->parent);
208 201
209 if (parent_dev_cgroup == NULL) 202 if (parent_dev_cgroup == NULL)
210 dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; 203 dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW;
@@ -219,9 +212,9 @@ static int devcgroup_online(struct cgroup *cgroup)
219 return ret; 212 return ret;
220} 213}
221 214
222static void devcgroup_offline(struct cgroup *cgroup) 215static void devcgroup_offline(struct cgroup_subsys_state *css)
223{ 216{
224 struct dev_cgroup *dev_cgroup = cgroup_to_devcgroup(cgroup); 217 struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
225 218
226 mutex_lock(&devcgroup_mutex); 219 mutex_lock(&devcgroup_mutex);
227 dev_cgroup->behavior = DEVCG_DEFAULT_NONE; 220 dev_cgroup->behavior = DEVCG_DEFAULT_NONE;
@@ -231,7 +224,8 @@ static void devcgroup_offline(struct cgroup *cgroup)
231/* 224/*
232 * called from kernel/cgroup.c with cgroup_lock() held. 225 * called from kernel/cgroup.c with cgroup_lock() held.
233 */ 226 */
234static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) 227static struct cgroup_subsys_state *
228devcgroup_css_alloc(struct cgroup_subsys_state *parent_css)
235{ 229{
236 struct dev_cgroup *dev_cgroup; 230 struct dev_cgroup *dev_cgroup;
237 231
@@ -244,11 +238,10 @@ static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup)
244 return &dev_cgroup->css; 238 return &dev_cgroup->css;
245} 239}
246 240
247static void devcgroup_css_free(struct cgroup *cgroup) 241static void devcgroup_css_free(struct cgroup_subsys_state *css)
248{ 242{
249 struct dev_cgroup *dev_cgroup; 243 struct dev_cgroup *dev_cgroup = css_to_devcgroup(css);
250 244
251 dev_cgroup = cgroup_to_devcgroup(cgroup);
252 __dev_exception_clean(dev_cgroup); 245 __dev_exception_clean(dev_cgroup);
253 kfree(dev_cgroup); 246 kfree(dev_cgroup);
254} 247}
@@ -291,10 +284,10 @@ static void set_majmin(char *str, unsigned m)
291 sprintf(str, "%u", m); 284 sprintf(str, "%u", m);
292} 285}
293 286
294static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, 287static int devcgroup_seq_read(struct cgroup_subsys_state *css,
295 struct seq_file *m) 288 struct cftype *cft, struct seq_file *m)
296{ 289{
297 struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); 290 struct dev_cgroup *devcgroup = css_to_devcgroup(css);
298 struct dev_exception_item *ex; 291 struct dev_exception_item *ex;
299 char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; 292 char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
300 293
@@ -394,12 +387,10 @@ static bool may_access(struct dev_cgroup *dev_cgroup,
394static int parent_has_perm(struct dev_cgroup *childcg, 387static int parent_has_perm(struct dev_cgroup *childcg,
395 struct dev_exception_item *ex) 388 struct dev_exception_item *ex)
396{ 389{
397 struct cgroup *pcg = childcg->css.cgroup->parent; 390 struct dev_cgroup *parent = css_to_devcgroup(css_parent(&childcg->css));
398 struct dev_cgroup *parent;
399 391
400 if (!pcg) 392 if (!parent)
401 return 1; 393 return 1;
402 parent = cgroup_to_devcgroup(pcg);
403 return may_access(parent, ex, childcg->behavior); 394 return may_access(parent, ex, childcg->behavior);
404} 395}
405 396
@@ -451,13 +442,13 @@ static void revalidate_active_exceptions(struct dev_cgroup *devcg)
451static int propagate_exception(struct dev_cgroup *devcg_root, 442static int propagate_exception(struct dev_cgroup *devcg_root,
452 struct dev_exception_item *ex) 443 struct dev_exception_item *ex)
453{ 444{
454 struct cgroup *root = devcg_root->css.cgroup, *pos; 445 struct cgroup_subsys_state *pos;
455 int rc = 0; 446 int rc = 0;
456 447
457 rcu_read_lock(); 448 rcu_read_lock();
458 449
459 cgroup_for_each_descendant_pre(pos, root) { 450 css_for_each_descendant_pre(pos, &devcg_root->css) {
460 struct dev_cgroup *devcg = cgroup_to_devcgroup(pos); 451 struct dev_cgroup *devcg = css_to_devcgroup(pos);
461 452
462 /* 453 /*
463 * Because devcgroup_mutex is held, no devcg will become 454 * Because devcgroup_mutex is held, no devcg will become
@@ -465,7 +456,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root,
465 * methods), and online ones are safe to access outside RCU 456 * methods), and online ones are safe to access outside RCU
466 * read lock without bumping refcnt. 457 * read lock without bumping refcnt.
467 */ 458 */
468 if (!is_devcg_online(devcg)) 459 if (pos == &devcg_root->css || !is_devcg_online(devcg))
469 continue; 460 continue;
470 461
471 rcu_read_unlock(); 462 rcu_read_unlock();
@@ -524,15 +515,11 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
524 char temp[12]; /* 11 + 1 characters needed for a u32 */ 515 char temp[12]; /* 11 + 1 characters needed for a u32 */
525 int count, rc = 0; 516 int count, rc = 0;
526 struct dev_exception_item ex; 517 struct dev_exception_item ex;
527 struct cgroup *p = devcgroup->css.cgroup; 518 struct dev_cgroup *parent = css_to_devcgroup(css_parent(&devcgroup->css));
528 struct dev_cgroup *parent = NULL;
529 519
530 if (!capable(CAP_SYS_ADMIN)) 520 if (!capable(CAP_SYS_ADMIN))
531 return -EPERM; 521 return -EPERM;
532 522
533 if (p->parent)
534 parent = cgroup_to_devcgroup(p->parent);
535
536 memset(&ex, 0, sizeof(ex)); 523 memset(&ex, 0, sizeof(ex));
537 b = buffer; 524 b = buffer;
538 525
@@ -677,13 +664,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
677 return rc; 664 return rc;
678} 665}
679 666
680static int devcgroup_access_write(struct cgroup *cgrp, struct cftype *cft, 667static int devcgroup_access_write(struct cgroup_subsys_state *css,
681 const char *buffer) 668 struct cftype *cft, const char *buffer)
682{ 669{
683 int retval; 670 int retval;
684 671
685 mutex_lock(&devcgroup_mutex); 672 mutex_lock(&devcgroup_mutex);
686 retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp), 673 retval = devcgroup_update_access(css_to_devcgroup(css),
687 cft->private, buffer); 674 cft->private, buffer);
688 mutex_unlock(&devcgroup_mutex); 675 mutex_unlock(&devcgroup_mutex);
689 return retval; 676 return retval;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index df0fa451a871..af9b6852f4e1 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -418,7 +418,7 @@ int evm_inode_init_security(struct inode *inode,
418 418
419 evm_xattr->value = xattr_data; 419 evm_xattr->value = xattr_data;
420 evm_xattr->value_len = sizeof(*xattr_data); 420 evm_xattr->value_len = sizeof(*xattr_data);
421 evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS); 421 evm_xattr->name = XATTR_EVM_SUFFIX;
422 return 0; 422 return 0;
423out: 423out:
424 kfree(xattr_data); 424 kfree(xattr_data);
diff --git a/security/security.c b/security/security.c
index 94048028bdd1..15b6928592ef 100644
--- a/security/security.c
+++ b/security/security.c
@@ -348,10 +348,10 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
348 if (unlikely(IS_PRIVATE(inode))) 348 if (unlikely(IS_PRIVATE(inode)))
349 return 0; 349 return 0;
350 350
351 memset(new_xattrs, 0, sizeof new_xattrs);
352 if (!initxattrs) 351 if (!initxattrs)
353 return security_ops->inode_init_security(inode, dir, qstr, 352 return security_ops->inode_init_security(inode, dir, qstr,
354 NULL, NULL, NULL); 353 NULL, NULL, NULL);
354 memset(new_xattrs, 0, sizeof(new_xattrs));
355 lsm_xattr = new_xattrs; 355 lsm_xattr = new_xattrs;
356 ret = security_ops->inode_init_security(inode, dir, qstr, 356 ret = security_ops->inode_init_security(inode, dir, qstr,
357 &lsm_xattr->name, 357 &lsm_xattr->name,
@@ -366,16 +366,14 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
366 goto out; 366 goto out;
367 ret = initxattrs(inode, new_xattrs, fs_data); 367 ret = initxattrs(inode, new_xattrs, fs_data);
368out: 368out:
369 for (xattr = new_xattrs; xattr->name != NULL; xattr++) { 369 for (xattr = new_xattrs; xattr->value != NULL; xattr++)
370 kfree(xattr->name);
371 kfree(xattr->value); 370 kfree(xattr->value);
372 }
373 return (ret == -EOPNOTSUPP) ? 0 : ret; 371 return (ret == -EOPNOTSUPP) ? 0 : ret;
374} 372}
375EXPORT_SYMBOL(security_inode_init_security); 373EXPORT_SYMBOL(security_inode_init_security);
376 374
377int security_old_inode_init_security(struct inode *inode, struct inode *dir, 375int security_old_inode_init_security(struct inode *inode, struct inode *dir,
378 const struct qstr *qstr, char **name, 376 const struct qstr *qstr, const char **name,
379 void **value, size_t *len) 377 void **value, size_t *len)
380{ 378{
381 if (unlikely(IS_PRIVATE(inode))) 379 if (unlikely(IS_PRIVATE(inode)))
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index dad36a6ab45f..fc3e6628a864 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -746,7 +746,6 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
746 * @tclass: target security class 746 * @tclass: target security class
747 * @requested: requested permissions, interpreted based on @tclass 747 * @requested: requested permissions, interpreted based on @tclass
748 * @auditdata: auxiliary audit data 748 * @auditdata: auxiliary audit data
749 * @flags: VFS walk flags
750 * 749 *
751 * Check the AVC to determine whether the @requested permissions are granted 750 * Check the AVC to determine whether the @requested permissions are granted
752 * for the SID pair (@ssid, @tsid), interpreting the permissions 751 * for the SID pair (@ssid, @tsid), interpreting the permissions
@@ -756,17 +755,15 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
756 * permissions are granted, -%EACCES if any permissions are denied, or 755 * permissions are granted, -%EACCES if any permissions are denied, or
757 * another -errno upon other errors. 756 * another -errno upon other errors.
758 */ 757 */
759int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass, 758int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
760 u32 requested, struct common_audit_data *auditdata, 759 u32 requested, struct common_audit_data *auditdata)
761 unsigned flags)
762{ 760{
763 struct av_decision avd; 761 struct av_decision avd;
764 int rc, rc2; 762 int rc, rc2;
765 763
766 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); 764 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
767 765
768 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata, 766 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
769 flags);
770 if (rc2) 767 if (rc2)
771 return rc2; 768 return rc2;
772 return rc; 769 return rc;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c09211a4d7da..777ee98273d1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1539,7 +1539,7 @@ static int cred_has_capability(const struct cred *cred,
1539 1539
1540 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1540 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
1541 if (audit == SECURITY_CAP_AUDIT) { 1541 if (audit == SECURITY_CAP_AUDIT) {
1542 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0); 1542 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad);
1543 if (rc2) 1543 if (rc2)
1544 return rc2; 1544 return rc2;
1545 } 1545 }
@@ -1562,8 +1562,7 @@ static int task_has_system(struct task_struct *tsk,
1562static int inode_has_perm(const struct cred *cred, 1562static int inode_has_perm(const struct cred *cred,
1563 struct inode *inode, 1563 struct inode *inode,
1564 u32 perms, 1564 u32 perms,
1565 struct common_audit_data *adp, 1565 struct common_audit_data *adp)
1566 unsigned flags)
1567{ 1566{
1568 struct inode_security_struct *isec; 1567 struct inode_security_struct *isec;
1569 u32 sid; 1568 u32 sid;
@@ -1576,7 +1575,7 @@ static int inode_has_perm(const struct cred *cred,
1576 sid = cred_sid(cred); 1575 sid = cred_sid(cred);
1577 isec = inode->i_security; 1576 isec = inode->i_security;
1578 1577
1579 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1578 return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
1580} 1579}
1581 1580
1582/* Same as inode_has_perm, but pass explicit audit data containing 1581/* Same as inode_has_perm, but pass explicit audit data containing
@@ -1591,7 +1590,7 @@ static inline int dentry_has_perm(const struct cred *cred,
1591 1590
1592 ad.type = LSM_AUDIT_DATA_DENTRY; 1591 ad.type = LSM_AUDIT_DATA_DENTRY;
1593 ad.u.dentry = dentry; 1592 ad.u.dentry = dentry;
1594 return inode_has_perm(cred, inode, av, &ad, 0); 1593 return inode_has_perm(cred, inode, av, &ad);
1595} 1594}
1596 1595
1597/* Same as inode_has_perm, but pass explicit audit data containing 1596/* Same as inode_has_perm, but pass explicit audit data containing
@@ -1606,7 +1605,7 @@ static inline int path_has_perm(const struct cred *cred,
1606 1605
1607 ad.type = LSM_AUDIT_DATA_PATH; 1606 ad.type = LSM_AUDIT_DATA_PATH;
1608 ad.u.path = *path; 1607 ad.u.path = *path;
1609 return inode_has_perm(cred, inode, av, &ad, 0); 1608 return inode_has_perm(cred, inode, av, &ad);
1610} 1609}
1611 1610
1612/* Same as path_has_perm, but uses the inode from the file struct. */ 1611/* Same as path_has_perm, but uses the inode from the file struct. */
@@ -1618,7 +1617,7 @@ static inline int file_path_has_perm(const struct cred *cred,
1618 1617
1619 ad.type = LSM_AUDIT_DATA_PATH; 1618 ad.type = LSM_AUDIT_DATA_PATH;
1620 ad.u.path = file->f_path; 1619 ad.u.path = file->f_path;
1621 return inode_has_perm(cred, file_inode(file), av, &ad, 0); 1620 return inode_has_perm(cred, file_inode(file), av, &ad);
1622} 1621}
1623 1622
1624/* Check whether a task can use an open file descriptor to 1623/* Check whether a task can use an open file descriptor to
@@ -1654,7 +1653,7 @@ static int file_has_perm(const struct cred *cred,
1654 /* av is zero if only checking access to the descriptor. */ 1653 /* av is zero if only checking access to the descriptor. */
1655 rc = 0; 1654 rc = 0;
1656 if (av) 1655 if (av)
1657 rc = inode_has_perm(cred, inode, av, &ad, 0); 1656 rc = inode_has_perm(cred, inode, av, &ad);
1658 1657
1659out: 1658out:
1660 return rc; 1659 return rc;
@@ -2624,7 +2623,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2624} 2623}
2625 2624
2626static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2625static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2627 const struct qstr *qstr, char **name, 2626 const struct qstr *qstr,
2627 const char **name,
2628 void **value, size_t *len) 2628 void **value, size_t *len)
2629{ 2629{
2630 const struct task_security_struct *tsec = current_security(); 2630 const struct task_security_struct *tsec = current_security();
@@ -2632,7 +2632,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2632 struct superblock_security_struct *sbsec; 2632 struct superblock_security_struct *sbsec;
2633 u32 sid, newsid, clen; 2633 u32 sid, newsid, clen;
2634 int rc; 2634 int rc;
2635 char *namep = NULL, *context; 2635 char *context;
2636 2636
2637 dsec = dir->i_security; 2637 dsec = dir->i_security;
2638 sbsec = dir->i_sb->s_security; 2638 sbsec = dir->i_sb->s_security;
@@ -2668,19 +2668,13 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2668 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT)) 2668 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
2669 return -EOPNOTSUPP; 2669 return -EOPNOTSUPP;
2670 2670
2671 if (name) { 2671 if (name)
2672 namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_NOFS); 2672 *name = XATTR_SELINUX_SUFFIX;
2673 if (!namep)
2674 return -ENOMEM;
2675 *name = namep;
2676 }
2677 2673
2678 if (value && len) { 2674 if (value && len) {
2679 rc = security_sid_to_context_force(newsid, &context, &clen); 2675 rc = security_sid_to_context_force(newsid, &context, &clen);
2680 if (rc) { 2676 if (rc)
2681 kfree(namep);
2682 return rc; 2677 return rc;
2683 }
2684 *value = context; 2678 *value = context;
2685 *len = clen; 2679 *len = clen;
2686 } 2680 }
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 92d0ab561db8..f53ee3c58d0f 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -130,7 +130,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
130 u16 tclass, u32 requested, 130 u16 tclass, u32 requested,
131 struct av_decision *avd, 131 struct av_decision *avd,
132 int result, 132 int result,
133 struct common_audit_data *a, unsigned flags) 133 struct common_audit_data *a)
134{ 134{
135 u32 audited, denied; 135 u32 audited, denied;
136 audited = avc_audit_required(requested, avd, result, 0, &denied); 136 audited = avc_audit_required(requested, avd, result, 0, &denied);
@@ -138,7 +138,7 @@ static inline int avc_audit(u32 ssid, u32 tsid,
138 return 0; 138 return 0;
139 return slow_avc_audit(ssid, tsid, tclass, 139 return slow_avc_audit(ssid, tsid, tclass,
140 requested, audited, denied, 140 requested, audited, denied,
141 a, flags); 141 a, 0);
142} 142}
143 143
144#define AVC_STRICT 1 /* Ignore permissive mode. */ 144#define AVC_STRICT 1 /* Ignore permissive mode. */
@@ -147,17 +147,9 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
147 unsigned flags, 147 unsigned flags,
148 struct av_decision *avd); 148 struct av_decision *avd);
149 149
150int avc_has_perm_flags(u32 ssid, u32 tsid, 150int avc_has_perm(u32 ssid, u32 tsid,
151 u16 tclass, u32 requested, 151 u16 tclass, u32 requested,
152 struct common_audit_data *auditdata, 152 struct common_audit_data *auditdata);
153 unsigned);
154
155static inline int avc_has_perm(u32 ssid, u32 tsid,
156 u16 tclass, u32 requested,
157 struct common_audit_data *auditdata)
158{
159 return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0);
160}
161 153
162u32 avc_policy_seqno(void); 154u32 avc_policy_seqno(void);
163 155
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 7605251936f5..0dec76c64cf5 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -42,8 +42,13 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
42 42
43static inline void selinux_xfrm_notify_policyload(void) 43static inline void selinux_xfrm_notify_policyload(void)
44{ 44{
45 struct net *net;
46
45 atomic_inc(&flow_cache_genid); 47 atomic_inc(&flow_cache_genid);
46 rt_genid_bump(&init_net); 48 rtnl_lock();
49 for_each_net(net)
50 rt_genid_bump_all(net);
51 rtnl_unlock();
47} 52}
48#else 53#else
49static inline int selinux_xfrm_enabled(void) 54static inline int selinux_xfrm_enabled(void)
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 339614c76e63..076b8e8a51ab 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -53,6 +53,7 @@
53 */ 53 */
54struct smack_known { 54struct smack_known {
55 struct list_head list; 55 struct list_head list;
56 struct hlist_node smk_hashed;
56 char *smk_known; 57 char *smk_known;
57 u32 smk_secid; 58 u32 smk_secid;
58 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ 59 struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
@@ -167,9 +168,13 @@ struct smk_port_label {
167#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */ 168#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */
168#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ 169#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */
169#define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */ 170#define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */
170#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */
171#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ 171#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */
172#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ 172/*
173 * CIPSO 2.2 standard is 239, but Smack wants to use the
174 * categories in a structured way that limits the value to
175 * the bits in 23 bytes, hence the unusual number.
176 */
177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
173 178
174/* 179/*
175 * Flag for transmute access 180 * Flag for transmute access
@@ -222,6 +227,7 @@ char *smk_parse_smack(const char *string, int len);
222int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); 227int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
223char *smk_import(const char *, int); 228char *smk_import(const char *, int);
224struct smack_known *smk_import_entry(const char *, int); 229struct smack_known *smk_import_entry(const char *, int);
230void smk_insert_entry(struct smack_known *skp);
225struct smack_known *smk_find_entry(const char *); 231struct smack_known *smk_find_entry(const char *);
226u32 smack_to_secid(const char *); 232u32 smack_to_secid(const char *);
227 233
@@ -247,6 +253,9 @@ extern struct list_head smk_netlbladdr_list;
247 253
248extern struct security_operations smack_ops; 254extern struct security_operations smack_ops;
249 255
256#define SMACK_HASH_SLOTS 16
257extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
258
250/* 259/*
251 * Is the directory transmuting? 260 * Is the directory transmuting?
252 */ 261 */
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 6a0377f38620..b3b59b1e93d6 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -325,6 +325,25 @@ void smack_log(char *subject_label, char *object_label, int request,
325 325
326DEFINE_MUTEX(smack_known_lock); 326DEFINE_MUTEX(smack_known_lock);
327 327
328struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
329
330/**
331 * smk_insert_entry - insert a smack label into a hash map,
332 *
333 * this function must be called under smack_known_lock
334 */
335void smk_insert_entry(struct smack_known *skp)
336{
337 unsigned int hash;
338 struct hlist_head *head;
339
340 hash = full_name_hash(skp->smk_known, strlen(skp->smk_known));
341 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
342
343 hlist_add_head_rcu(&skp->smk_hashed, head);
344 list_add_rcu(&skp->list, &smack_known_list);
345}
346
328/** 347/**
329 * smk_find_entry - find a label on the list, return the list entry 348 * smk_find_entry - find a label on the list, return the list entry
330 * @string: a text string that might be a Smack label 349 * @string: a text string that might be a Smack label
@@ -334,12 +353,16 @@ DEFINE_MUTEX(smack_known_lock);
334 */ 353 */
335struct smack_known *smk_find_entry(const char *string) 354struct smack_known *smk_find_entry(const char *string)
336{ 355{
356 unsigned int hash;
357 struct hlist_head *head;
337 struct smack_known *skp; 358 struct smack_known *skp;
338 359
339 list_for_each_entry_rcu(skp, &smack_known_list, list) { 360 hash = full_name_hash(string, strlen(string));
361 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)];
362
363 hlist_for_each_entry_rcu(skp, head, smk_hashed)
340 if (strcmp(skp->smk_known, string) == 0) 364 if (strcmp(skp->smk_known, string) == 0)
341 return skp; 365 return skp;
342 }
343 366
344 return NULL; 367 return NULL;
345} 368}
@@ -475,7 +498,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
475 * Make sure that the entry is actually 498 * Make sure that the entry is actually
476 * filled before putting it on the list. 499 * filled before putting it on the list.
477 */ 500 */
478 list_add_rcu(&skp->list, &smack_known_list); 501 smk_insert_entry(skp);
479 goto unlockout; 502 goto unlockout;
480 } 503 }
481 /* 504 /*
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index eefbd10e408f..8825375cc031 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -582,7 +582,7 @@ static void smack_inode_free_security(struct inode *inode)
582 * Returns 0 if it all works out, -ENOMEM if there's no memory 582 * Returns 0 if it all works out, -ENOMEM if there's no memory
583 */ 583 */
584static int smack_inode_init_security(struct inode *inode, struct inode *dir, 584static int smack_inode_init_security(struct inode *inode, struct inode *dir,
585 const struct qstr *qstr, char **name, 585 const struct qstr *qstr, const char **name,
586 void **value, size_t *len) 586 void **value, size_t *len)
587{ 587{
588 struct inode_smack *issp = inode->i_security; 588 struct inode_smack *issp = inode->i_security;
@@ -591,11 +591,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
591 char *dsp = smk_of_inode(dir); 591 char *dsp = smk_of_inode(dir);
592 int may; 592 int may;
593 593
594 if (name) { 594 if (name)
595 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS); 595 *name = XATTR_SMACK_SUFFIX;
596 if (*name == NULL)
597 return -ENOMEM;
598 }
599 596
600 if (value) { 597 if (value) {
601 rcu_read_lock(); 598 rcu_read_lock();
@@ -3065,6 +3062,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3065{ 3062{
3066 struct smack_known *skp; 3063 struct smack_known *skp;
3067 int found = 0; 3064 int found = 0;
3065 int acat;
3066 int kcat;
3068 3067
3069 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 3068 if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
3070 /* 3069 /*
@@ -3081,12 +3080,28 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3081 list_for_each_entry(skp, &smack_known_list, list) { 3080 list_for_each_entry(skp, &smack_known_list, list) {
3082 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl) 3081 if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
3083 continue; 3082 continue;
3084 if (memcmp(sap->attr.mls.cat, 3083 /*
3085 skp->smk_netlabel.attr.mls.cat, 3084 * Compare the catsets. Use the netlbl APIs.
3086 SMK_CIPSOLEN) != 0) 3085 */
3087 continue; 3086 if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
3088 found = 1; 3087 if ((skp->smk_netlabel.flags &
3089 break; 3088 NETLBL_SECATTR_MLS_CAT) == 0)
3089 found = 1;
3090 break;
3091 }
3092 for (acat = -1, kcat = -1; acat == kcat; ) {
3093 acat = netlbl_secattr_catmap_walk(
3094 sap->attr.mls.cat, acat + 1);
3095 kcat = netlbl_secattr_catmap_walk(
3096 skp->smk_netlabel.attr.mls.cat,
3097 kcat + 1);
3098 if (acat < 0 || kcat < 0)
3099 break;
3100 }
3101 if (acat == kcat) {
3102 found = 1;
3103 break;
3104 }
3090 } 3105 }
3091 rcu_read_unlock(); 3106 rcu_read_unlock();
3092 3107
@@ -3877,12 +3892,12 @@ static __init void init_smack_known_list(void)
3877 /* 3892 /*
3878 * Create the known labels list 3893 * Create the known labels list
3879 */ 3894 */
3880 list_add(&smack_known_huh.list, &smack_known_list); 3895 smk_insert_entry(&smack_known_huh);
3881 list_add(&smack_known_hat.list, &smack_known_list); 3896 smk_insert_entry(&smack_known_hat);
3882 list_add(&smack_known_star.list, &smack_known_list); 3897 smk_insert_entry(&smack_known_star);
3883 list_add(&smack_known_floor.list, &smack_known_list); 3898 smk_insert_entry(&smack_known_floor);
3884 list_add(&smack_known_invalid.list, &smack_known_list); 3899 smk_insert_entry(&smack_known_invalid);
3885 list_add(&smack_known_web.list, &smack_known_list); 3900 smk_insert_entry(&smack_known_web);
3886} 3901}
3887 3902
3888/** 3903/**
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index ab167037b2dd..80f4b4a45725 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -368,56 +368,43 @@ static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule,
368 * @data: string to be parsed, null terminated 368 * @data: string to be parsed, null terminated
369 * @rule: Will be filled with Smack parsed rule 369 * @rule: Will be filled with Smack parsed rule
370 * @import: if non-zero, import labels 370 * @import: if non-zero, import labels
371 * @change: if non-zero, data is from /smack/change-rule 371 * @tokens: numer of substrings expected in data
372 * 372 *
373 * Returns 0 on success, -1 on failure 373 * Returns number of processed bytes on success, -1 on failure.
374 */ 374 */
375static int smk_parse_long_rule(const char *data, struct smack_parsed_rule *rule, 375static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
376 int import, int change) 376 int import, int tokens)
377{ 377{
378 char *subject; 378 ssize_t cnt = 0;
379 char *object; 379 char *tok[4];
380 char *access1; 380 int i;
381 char *access2;
382 int datalen;
383 int rc = -1;
384 381
385 /* This is inefficient */ 382 /*
386 datalen = strlen(data); 383 * Parsing the rule in-place, filling all white-spaces with '\0'
384 */
385 for (i = 0; i < tokens; ++i) {
386 while (isspace(data[cnt]))
387 data[cnt++] = '\0';
387 388
388 /* Our first element can be 64 + \0 with no spaces */ 389 if (data[cnt] == '\0')
389 subject = kzalloc(datalen + 1, GFP_KERNEL); 390 /* Unexpected end of data */
390 if (subject == NULL) 391 return -1;
391 return -1; 392
392 object = kzalloc(datalen, GFP_KERNEL); 393 tok[i] = data + cnt;
393 if (object == NULL) 394
394 goto free_out_s; 395 while (data[cnt] && !isspace(data[cnt]))
395 access1 = kzalloc(datalen, GFP_KERNEL); 396 ++cnt;
396 if (access1 == NULL)
397 goto free_out_o;
398 access2 = kzalloc(datalen, GFP_KERNEL);
399 if (access2 == NULL)
400 goto free_out_a;
401
402 if (change) {
403 if (sscanf(data, "%s %s %s %s",
404 subject, object, access1, access2) == 4)
405 rc = smk_fill_rule(subject, object, access1, access2,
406 rule, import, 0);
407 } else {
408 if (sscanf(data, "%s %s %s", subject, object, access1) == 3)
409 rc = smk_fill_rule(subject, object, access1, NULL,
410 rule, import, 0);
411 } 397 }
398 while (isspace(data[cnt]))
399 data[cnt++] = '\0';
412 400
413 kfree(access2); 401 while (i < 4)
414free_out_a: 402 tok[i++] = NULL;
415 kfree(access1); 403
416free_out_o: 404 if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0))
417 kfree(object); 405 return -1;
418free_out_s: 406
419 kfree(subject); 407 return cnt;
420 return rc;
421} 408}
422 409
423#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ 410#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
@@ -447,11 +434,12 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
447 struct list_head *rule_list, 434 struct list_head *rule_list,
448 struct mutex *rule_lock, int format) 435 struct mutex *rule_lock, int format)
449{ 436{
450 struct smack_parsed_rule *rule; 437 struct smack_parsed_rule rule;
451 char *data; 438 char *data;
452 int datalen; 439 int rc;
453 int rc = -EINVAL; 440 int trunc = 0;
454 int load = 0; 441 int tokens;
442 ssize_t cnt = 0;
455 443
456 /* 444 /*
457 * No partial writes. 445 * No partial writes.
@@ -466,11 +454,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
466 */ 454 */
467 if (count != SMK_OLOADLEN && count != SMK_LOADLEN) 455 if (count != SMK_OLOADLEN && count != SMK_LOADLEN)
468 return -EINVAL; 456 return -EINVAL;
469 datalen = SMK_LOADLEN; 457 } else {
470 } else 458 if (count >= PAGE_SIZE) {
471 datalen = count + 1; 459 count = PAGE_SIZE - 1;
460 trunc = 1;
461 }
462 }
472 463
473 data = kzalloc(datalen, GFP_KERNEL); 464 data = kmalloc(count + 1, GFP_KERNEL);
474 if (data == NULL) 465 if (data == NULL)
475 return -ENOMEM; 466 return -ENOMEM;
476 467
@@ -479,47 +470,49 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
479 goto out; 470 goto out;
480 } 471 }
481 472
482 rule = kzalloc(sizeof(*rule), GFP_KERNEL); 473 /*
483 if (rule == NULL) { 474 * In case of parsing only part of user buf,
484 rc = -ENOMEM; 475 * avoid having partial rule at the data buffer
485 goto out; 476 */
477 if (trunc) {
478 while (count > 0 && (data[count - 1] != '\n'))
479 --count;
480 if (count == 0) {
481 rc = -EINVAL;
482 goto out;
483 }
486 } 484 }
487 485
488 if (format == SMK_LONG_FMT) { 486 data[count] = '\0';
489 /* 487 tokens = (format == SMK_CHANGE_FMT ? 4 : 3);
490 * Be sure the data string is terminated. 488 while (cnt < count) {
491 */ 489 if (format == SMK_FIXED24_FMT) {
492 data[count] = '\0'; 490 rc = smk_parse_rule(data, &rule, 1);
493 if (smk_parse_long_rule(data, rule, 1, 0)) 491 if (rc != 0) {
494 goto out_free_rule; 492 rc = -EINVAL;
495 } else if (format == SMK_CHANGE_FMT) { 493 goto out;
496 data[count] = '\0'; 494 }
497 if (smk_parse_long_rule(data, rule, 1, 1)) 495 cnt = count;
498 goto out_free_rule; 496 } else {
499 } else { 497 rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens);
500 /* 498 if (rc <= 0) {
501 * More on the minor hack for backward compatibility 499 rc = -EINVAL;
502 */ 500 goto out;
503 if (count == (SMK_OLOADLEN)) 501 }
504 data[SMK_OLOADLEN] = '-'; 502 cnt += rc;
505 if (smk_parse_rule(data, rule, 1)) 503 }
506 goto out_free_rule;
507 }
508 504
509 if (rule_list == NULL) { 505 if (rule_list == NULL)
510 load = 1; 506 rc = smk_set_access(&rule, &rule.smk_subject->smk_rules,
511 rule_list = &rule->smk_subject->smk_rules; 507 &rule.smk_subject->smk_rules_lock, 1);
512 rule_lock = &rule->smk_subject->smk_rules_lock; 508 else
513 } 509 rc = smk_set_access(&rule, rule_list, rule_lock, 0);
514 510
515 rc = smk_set_access(rule, rule_list, rule_lock, load); 511 if (rc)
516 if (rc == 0) { 512 goto out;
517 rc = count;
518 goto out;
519 } 513 }
520 514
521out_free_rule: 515 rc = cnt;
522 kfree(rule);
523out: 516out:
524 kfree(data); 517 kfree(data);
525 return rc; 518 return rc;
@@ -901,7 +894,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
901 for (i = 0; i < catlen; i++) { 894 for (i = 0; i < catlen; i++) {
902 rule += SMK_DIGITLEN; 895 rule += SMK_DIGITLEN;
903 ret = sscanf(rule, "%u", &cat); 896 ret = sscanf(rule, "%u", &cat);
904 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) 897 if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM)
905 goto out; 898 goto out;
906 899
907 smack_catset_bit(cat, mapcatset); 900 smack_catset_bit(cat, mapcatset);
@@ -1840,7 +1833,6 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1840{ 1833{
1841 struct smack_parsed_rule rule; 1834 struct smack_parsed_rule rule;
1842 char *data; 1835 char *data;
1843 char *cod;
1844 int res; 1836 int res;
1845 1837
1846 data = simple_transaction_get(file, buf, count); 1838 data = simple_transaction_get(file, buf, count);
@@ -1853,18 +1845,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1853 res = smk_parse_rule(data, &rule, 0); 1845 res = smk_parse_rule(data, &rule, 0);
1854 } else { 1846 } else {
1855 /* 1847 /*
1856 * Copy the data to make sure the string is terminated. 1848 * simple_transaction_get() returns null-terminated data
1857 */ 1849 */
1858 cod = kzalloc(count + 1, GFP_KERNEL); 1850 res = smk_parse_long_rule(data, &rule, 0, 3);
1859 if (cod == NULL)
1860 return -ENOMEM;
1861 memcpy(cod, data, count);
1862 cod[count] = '\0';
1863 res = smk_parse_long_rule(cod, &rule, 0, 0);
1864 kfree(cod);
1865 } 1851 }
1866 1852
1867 if (res) 1853 if (res < 0)
1868 return -EINVAL; 1854 return -EINVAL;
1869 1855
1870 res = smk_access(rule.smk_subject, rule.smk_object, 1856 res = smk_access(rule.smk_subject, rule.smk_object,