aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 16:25:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 16:25:04 -0400
commit3556485f1595e3964ba539e39ea682acbb835cee (patch)
tree7f5ee254f425b1427ac0059b5f347a307f8538a1
parentb8716614a7cc2fc15ea2a518edd04755fb08d922 (diff)
parent09f61cdbb32a9d812c618d3922db533542736bb0 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates for 3.4 from James Morris: "The main addition here is the new Yama security module from Kees Cook, which was discussed at the Linux Security Summit last year. Its purpose is to collect miscellaneous DAC security enhancements in one place. This also marks a departure in policy for LSM modules, which were previously limited to being standalone access control systems. Chromium OS is using Yama, and I believe there are plans for Ubuntu, at least. This patchset also includes maintenance updates for AppArmor, TOMOYO and others." Fix trivial conflict in <net/sock.h> due to the jumo_label->static_key rename. * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (38 commits) AppArmor: Fix location of const qualifier on generated string tables TOMOYO: Return error if fails to delete a domain AppArmor: add const qualifiers to string arrays AppArmor: Add ability to load extended policy TOMOYO: Return appropriate value to poll(). AppArmor: Move path failure information into aa_get_name and rename AppArmor: Update dfa matching routines. AppArmor: Minor cleanup of d_namespace_path to consolidate error handling AppArmor: Retrieve the dentry_path for error reporting when path lookup fails AppArmor: Add const qualifiers to generated string tables AppArmor: Fix oops in policy unpack auditing AppArmor: Fix error returned when a path lookup is disconnected KEYS: testing wrong bit for KEY_FLAG_REVOKED TOMOYO: Fix mount flags checking order. security: fix ima kconfig warning AppArmor: Fix the error case for chroot relative path name lookup AppArmor: fix mapping of META_READ to audit and quiet flags AppArmor: Fix underflow in xindex calculation AppArmor: Fix dropping of allowed operations that are force audited AppArmor: Add mising end of structure test to caps unpacking ...
-rw-r--r--Documentation/networking/dns_resolver.txt4
-rw-r--r--Documentation/security/00-INDEX2
-rw-r--r--Documentation/security/Yama.txt65
-rw-r--r--Documentation/security/keys.txt4
-rw-r--r--drivers/char/tpm/Kconfig1
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tpm/tpm.h2
-rw-r--r--drivers/char/tpm/tpm_tis.c17
-rw-r--r--drivers/net/macvtap.c1
-rw-r--r--drivers/target/iscsi/iscsi_target.c1
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c1
-rw-r--r--fs/cifs/cifsacl.c1
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/idmap.c1
-rw-r--r--fs/proc/proc_sysctl.c2
-rw-r--r--fs/quota/dquot.c1
-rw-r--r--fs/super.c1
-rw-r--r--include/linux/key.h1
-rw-r--r--include/linux/prctl.h7
-rw-r--r--include/linux/security.h80
-rw-r--r--include/net/sock.h2
-rw-r--r--ipc/msgutil.c2
-rw-r--r--kernel/cred.c1
-rw-r--r--kernel/exit.c1
-rw-r--r--kernel/fork.c3
-rw-r--r--kernel/sched/core.c1
-rw-r--r--kernel/sysctl.c1
-rw-r--r--mm/mmap.c17
-rw-r--r--mm/mprotect.c2
-rw-r--r--mm/mremap.c2
-rw-r--r--mm/shmem.c4
-rw-r--r--mm/swapfile.c4
-rw-r--r--net/dns_resolver/dns_key.c1
-rw-r--r--security/Kconfig6
-rw-r--r--security/Makefile2
-rw-r--r--security/apparmor/Makefile27
-rw-r--r--security/apparmor/apparmorfs.c195
-rw-r--r--security/apparmor/audit.c7
-rw-r--r--security/apparmor/domain.c5
-rw-r--r--security/apparmor/file.c21
-rw-r--r--security/apparmor/include/apparmor.h15
-rw-r--r--security/apparmor/include/apparmorfs.h44
-rw-r--r--security/apparmor/include/audit.h9
-rw-r--r--security/apparmor/include/file.h2
-rw-r--r--security/apparmor/include/match.h3
-rw-r--r--security/apparmor/include/path.h3
-rw-r--r--security/apparmor/include/policy.h15
-rw-r--r--security/apparmor/include/resource.h4
-rw-r--r--security/apparmor/match.c80
-rw-r--r--security/apparmor/path.c56
-rw-r--r--security/apparmor/policy.c3
-rw-r--r--security/apparmor/policy_unpack.c31
-rw-r--r--security/apparmor/resource.c5
-rw-r--r--security/capability.c5
-rw-r--r--security/commoncap.c1
-rw-r--r--security/integrity/ima/Kconfig4
-rw-r--r--security/integrity/ima/ima_audit.c2
-rw-r--r--security/integrity/ima/ima_policy.c3
-rw-r--r--security/keys/keyctl.c15
-rw-r--r--security/keys/process_keys.c3
-rw-r--r--security/security.c21
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/smack/smack_lsm.c3
-rw-r--r--security/tomoyo/audit.c4
-rw-r--r--security/tomoyo/common.c63
-rw-r--r--security/tomoyo/common.h6
-rw-r--r--security/tomoyo/mount.c38
-rw-r--r--security/tomoyo/securityfs_if.c5
-rw-r--r--security/yama/Kconfig13
-rw-r--r--security/yama/Makefile3
-rw-r--r--security/yama/yama_lsm.c323
71 files changed, 1034 insertions, 250 deletions
diff --git a/Documentation/networking/dns_resolver.txt b/Documentation/networking/dns_resolver.txt
index 7f531ad83285..d86adcdae420 100644
--- a/Documentation/networking/dns_resolver.txt
+++ b/Documentation/networking/dns_resolver.txt
@@ -102,6 +102,10 @@ implemented in the module can be called after doing:
102 If _expiry is non-NULL, the expiry time (TTL) of the result will be 102 If _expiry is non-NULL, the expiry time (TTL) of the result will be
103 returned also. 103 returned also.
104 104
105The kernel maintains an internal keyring in which it caches looked up keys.
106This can be cleared by any process that has the CAP_SYS_ADMIN capability by
107the use of KEYCTL_KEYRING_CLEAR on the keyring ID.
108
105 109
106=============================== 110===============================
107READING DNS KEYS FROM USERSPACE 111READING DNS KEYS FROM USERSPACE
diff --git a/Documentation/security/00-INDEX b/Documentation/security/00-INDEX
index 99b85d39751c..eeed1de546d4 100644
--- a/Documentation/security/00-INDEX
+++ b/Documentation/security/00-INDEX
@@ -6,6 +6,8 @@ SELinux.txt
6 - how to get started with the SELinux security enhancement. 6 - how to get started with the SELinux security enhancement.
7Smack.txt 7Smack.txt
8 - documentation on the Smack Linux Security Module. 8 - documentation on the Smack Linux Security Module.
9Yama.txt
10 - documentation on the Yama Linux Security Module.
9apparmor.txt 11apparmor.txt
10 - documentation on the AppArmor security extension. 12 - documentation on the AppArmor security extension.
11credentials.txt 13credentials.txt
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt
new file mode 100644
index 000000000000..a9511f179069
--- /dev/null
+++ b/Documentation/security/Yama.txt
@@ -0,0 +1,65 @@
1Yama is a Linux Security Module that collects a number of system-wide DAC
2security protections that are not handled by the core kernel itself. To
3select it at boot time, specify "security=yama" (though this will disable
4any other LSM).
5
6Yama is controlled through sysctl in /proc/sys/kernel/yama:
7
8- ptrace_scope
9
10==============================================================
11
12ptrace_scope:
13
14As Linux grows in popularity, it will become a larger target for
15malware. One particularly troubling weakness of the Linux process
16interfaces is that a single user is able to examine the memory and
17running state of any of their processes. For example, if one application
18(e.g. Pidgin) was compromised, it would be possible for an attacker to
19attach to other running processes (e.g. Firefox, SSH sessions, GPG agent,
20etc) to extract additional credentials and continue to expand the scope
21of their attack without resorting to user-assisted phishing.
22
23This is not a theoretical problem. SSH session hijacking
24(http://www.storm.net.nz/projects/7) and arbitrary code injection
25(http://c-skills.blogspot.com/2007/05/injectso.html) attacks already
26exist and remain possible if ptrace is allowed to operate as before.
27Since ptrace is not commonly used by non-developers and non-admins, system
28builders should be allowed the option to disable this debugging system.
29
30For a solution, some applications use prctl(PR_SET_DUMPABLE, ...) to
31specifically disallow such ptrace attachment (e.g. ssh-agent), but many
32do not. A more general solution is to only allow ptrace directly from a
33parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still
34work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID"
35still work as root).
36
37For software that has defined application-specific relationships
38between a debugging process and its inferior (crash handlers, etc),
39prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which
40other process (and its descendents) are allowed to call PTRACE_ATTACH
41against it. Only one such declared debugging process can exists for
42each inferior at a time. For example, this is used by KDE, Chromium, and
43Firefox's crash handlers, and by Wine for allowing only Wine processes
44to ptrace each other. If a process wishes to entirely disable these ptrace
45restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
46so that any otherwise allowed process (even those in external pid namespaces)
47may attach.
48
49The sysctl settings are:
50
510 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
52 process running under the same uid, as long as it is dumpable (i.e.
53 did not transition uids, start privileged, or have called
54 prctl(PR_SET_DUMPABLE...) already).
55
561 - restricted ptrace: a process must have a predefined relationship
57 with the inferior it wants to call PTRACE_ATTACH on. By default,
58 this relationship is that of only its descendants when the above
59 classic criteria is also met. To change the relationship, an
60 inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
61 an allowed debugger PID to call PTRACE_ATTACH on the inferior.
62
63The original children-only logic was based on the restrictions in grsecurity.
64
65==============================================================
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index fcbe7a703405..787717091421 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -554,6 +554,10 @@ The keyctl syscall functions are:
554 process must have write permission on the keyring, and it must be a 554 process must have write permission on the keyring, and it must be a
555 keyring (or else error ENOTDIR will result). 555 keyring (or else error ENOTDIR will result).
556 556
557 This function can also be used to clear special kernel keyrings if they
558 are appropriately marked if the user has CAP_SYS_ADMIN capability. The
559 DNS resolver cache keyring is an example of this.
560
557 561
558 (*) Link a key into a keyring: 562 (*) Link a key into a keyring:
559 563
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 7fc75e47e6d0..a048199ce866 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -5,7 +5,6 @@
5menuconfig TCG_TPM 5menuconfig TCG_TPM
6 tristate "TPM Hardware Support" 6 tristate "TPM Hardware Support"
7 depends on HAS_IOMEM 7 depends on HAS_IOMEM
8 depends on EXPERIMENTAL
9 select SECURITYFS 8 select SECURITYFS
10 ---help--- 9 ---help---
11 If you have a TPM security chip in your system, which 10 If you have a TPM security chip in your system, which
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 32362cf35b8d..ad7c7320dd1b 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1221,12 +1221,13 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1221 ret_size = atomic_read(&chip->data_pending); 1221 ret_size = atomic_read(&chip->data_pending);
1222 atomic_set(&chip->data_pending, 0); 1222 atomic_set(&chip->data_pending, 0);
1223 if (ret_size > 0) { /* relay data */ 1223 if (ret_size > 0) { /* relay data */
1224 ssize_t orig_ret_size = ret_size;
1224 if (size < ret_size) 1225 if (size < ret_size)
1225 ret_size = size; 1226 ret_size = size;
1226 1227
1227 mutex_lock(&chip->buffer_mutex); 1228 mutex_lock(&chip->buffer_mutex);
1228 rc = copy_to_user(buf, chip->data_buffer, ret_size); 1229 rc = copy_to_user(buf, chip->data_buffer, ret_size);
1229 memset(chip->data_buffer, 0, ret_size); 1230 memset(chip->data_buffer, 0, orig_ret_size);
1230 if (rc) 1231 if (rc)
1231 ret_size = -EFAULT; 1232 ret_size = -EFAULT;
1232 1233
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 010547138281..b1c5280ac159 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -99,6 +99,8 @@ struct tpm_vendor_specific {
99 wait_queue_head_t int_queue; 99 wait_queue_head_t int_queue;
100}; 100};
101 101
102#define TPM_VID_INTEL 0x8086
103
102struct tpm_chip { 104struct tpm_chip {
103 struct device *dev; /* Device stuff */ 105 struct device *dev; /* Device stuff */
104 106
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 70fac9abb0e2..d2a70cae76df 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -367,7 +367,12 @@ static int probe_itpm(struct tpm_chip *chip)
367 0x00, 0x00, 0x00, 0xf1 367 0x00, 0x00, 0x00, 0xf1
368 }; 368 };
369 size_t len = sizeof(cmd_getticks); 369 size_t len = sizeof(cmd_getticks);
370 int rem_itpm = itpm; 370 bool rem_itpm = itpm;
371 u16 vendor = ioread16(chip->vendor.iobase + TPM_DID_VID(0));
372
373 /* probe only iTPMS */
374 if (vendor != TPM_VID_INTEL)
375 return 0;
371 376
372 itpm = 0; 377 itpm = 0;
373 378
@@ -390,9 +395,6 @@ static int probe_itpm(struct tpm_chip *chip)
390out: 395out:
391 itpm = rem_itpm; 396 itpm = rem_itpm;
392 tpm_tis_ready(chip); 397 tpm_tis_ready(chip);
393 /* some TPMs need a break here otherwise they will not work
394 * correctly on the immediately subsequent command */
395 msleep(chip->vendor.timeout_b);
396 release_locality(chip, chip->vendor.locality, 0); 398 release_locality(chip, chip->vendor.locality, 0);
397 399
398 return rc; 400 return rc;
@@ -508,7 +510,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
508 resource_size_t len, unsigned int irq) 510 resource_size_t len, unsigned int irq)
509{ 511{
510 u32 vendor, intfcaps, intmask; 512 u32 vendor, intfcaps, intmask;
511 int rc, i, irq_s, irq_e; 513 int rc, i, irq_s, irq_e, probe;
512 struct tpm_chip *chip; 514 struct tpm_chip *chip;
513 515
514 if (!(chip = tpm_register_hardware(dev, &tpm_tis))) 516 if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
@@ -538,11 +540,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
538 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); 540 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
539 541
540 if (!itpm) { 542 if (!itpm) {
541 itpm = probe_itpm(chip); 543 probe = probe_itpm(chip);
542 if (itpm < 0) { 544 if (probe < 0) {
543 rc = -ENODEV; 545 rc = -ENODEV;
544 goto out_err; 546 goto out_err;
545 } 547 }
548 itpm = (probe == 0) ? 0 : 1;
546 } 549 }
547 550
548 if (itpm) 551 if (itpm)
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 58dc117a8d78..0427c6561c84 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/wait.h> 14#include <linux/wait.h>
15#include <linux/cdev.h> 15#include <linux/cdev.h>
16#include <linux/idr.h>
16#include <linux/fs.h> 17#include <linux/fs.h>
17 18
18#include <net/net_namespace.h> 19#include <net/net_namespace.h>
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 501b27c18145..1c6f700f5faa 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -23,6 +23,7 @@
23#include <linux/crypto.h> 23#include <linux/crypto.h>
24#include <linux/completion.h> 24#include <linux/completion.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/idr.h>
26#include <asm/unaligned.h> 27#include <asm/unaligned.h>
27#include <scsi/scsi_device.h> 28#include <scsi/scsi_device.h>
28#include <scsi/iscsi_proto.h> 29#include <scsi/iscsi_proto.h>
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 38cb7ce8469e..1ee33a8c3fab 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/kthread.h> 22#include <linux/kthread.h>
23#include <linux/crypto.h> 23#include <linux/crypto.h>
24#include <linux/idr.h>
24#include <scsi/iscsi_proto.h> 25#include <scsi/iscsi_proto.h>
25#include <target/target_core_base.h> 26#include <target/target_core_base.h>
26#include <target/target_core_fabric.h> 27#include <target/target_core_fabric.h>
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c1b254487388..3cc1b251ca08 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -556,6 +556,7 @@ init_cifs_idmap(void)
556 556
557 /* instruct request_key() to use this special keyring as a cache for 557 /* instruct request_key() to use this special keyring as a cache for
558 * the results it looks up */ 558 * the results it looks up */
559 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
559 cred->thread_keyring = keyring; 560 cred->thread_keyring = keyring;
560 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 561 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
561 root_cred = cred; 562 root_cred = cred;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 31778f74357d..d4f772ebd1ef 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -36,6 +36,7 @@
36#include <linux/inet.h> 36#include <linux/inet.h>
37#include <linux/in6.h> 37#include <linux/in6.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/idr.h>
39#include <net/ipv6.h> 40#include <net/ipv6.h>
40#include <linux/nfs_xdr.h> 41#include <linux/nfs_xdr.h>
41#include <linux/sunrpc/bc_xprt.h> 42#include <linux/sunrpc/bc_xprt.h>
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 2c05f1991e1e..a1bbf7780dfc 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -198,6 +198,7 @@ int nfs_idmap_init(void)
198 if (ret < 0) 198 if (ret < 0)
199 goto failed_put_key; 199 goto failed_put_key;
200 200
201 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
201 cred->thread_keyring = keyring; 202 cred->thread_keyring = keyring;
202 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 203 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
203 id_resolver_cache = cred; 204 id_resolver_cache = cred;
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index a6b62173d4c3..67bbf6e4e197 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -6,7 +6,9 @@
6#include <linux/poll.h> 6#include <linux/poll.h>
7#include <linux/proc_fs.h> 7#include <linux/proc_fs.h>
8#include <linux/security.h> 8#include <linux/security.h>
9#include <linux/sched.h>
9#include <linux/namei.h> 10#include <linux/namei.h>
11#include <linux/mm.h>
10#include "internal.h" 12#include "internal.h"
11 13
12static const struct dentry_operations proc_sys_dentry_operations; 14static const struct dentry_operations proc_sys_dentry_operations;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 46741970371b..8b4f12b33f57 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -71,6 +71,7 @@
71#include <linux/module.h> 71#include <linux/module.h>
72#include <linux/proc_fs.h> 72#include <linux/proc_fs.h>
73#include <linux/security.h> 73#include <linux/security.h>
74#include <linux/sched.h>
74#include <linux/kmod.h> 75#include <linux/kmod.h>
75#include <linux/namei.h> 76#include <linux/namei.h>
76#include <linux/capability.h> 77#include <linux/capability.h>
diff --git a/fs/super.c b/fs/super.c
index 6277ec6cb60a..d90e900a8a0e 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -32,6 +32,7 @@
32#include <linux/backing-dev.h> 32#include <linux/backing-dev.h>
33#include <linux/rculist_bl.h> 33#include <linux/rculist_bl.h>
34#include <linux/cleancache.h> 34#include <linux/cleancache.h>
35#include <linux/fsnotify.h>
35#include "internal.h" 36#include "internal.h"
36 37
37 38
diff --git a/include/linux/key.h b/include/linux/key.h
index 5253471cd2ea..1600ebf717a7 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -155,6 +155,7 @@ struct key {
155#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ 155#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */
156#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ 156#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */
157#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ 157#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
158#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
158 159
159 /* the description string 160 /* the description string
160 * - this is used to match a key against search criteria 161 * - this is used to match a key against search criteria
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index 7ddc7f1b480f..a0413ac3abe8 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -114,4 +114,11 @@
114# define PR_SET_MM_START_BRK 6 114# define PR_SET_MM_START_BRK 6
115# define PR_SET_MM_BRK 7 115# define PR_SET_MM_BRK 7
116 116
117/*
118 * Set specific pid that is allowed to ptrace the current task.
119 * A value of 0 mean "no process".
120 */
121#define PR_SET_PTRACER 0x59616d61
122# define PR_SET_PTRACER_ANY ((unsigned long)-1)
123
117#endif /* _LINUX_PRCTL_H */ 124#endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index c8949385e56e..673afbb8238a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -22,22 +22,36 @@
22#ifndef __LINUX_SECURITY_H 22#ifndef __LINUX_SECURITY_H
23#define __LINUX_SECURITY_H 23#define __LINUX_SECURITY_H
24 24
25#include <linux/fs.h>
26#include <linux/fsnotify.h>
27#include <linux/binfmts.h>
28#include <linux/dcache.h>
29#include <linux/signal.h>
30#include <linux/resource.h>
31#include <linux/sem.h>
32#include <linux/shm.h>
33#include <linux/mm.h> /* PAGE_ALIGN */
34#include <linux/msg.h>
35#include <linux/sched.h>
36#include <linux/key.h> 25#include <linux/key.h>
37#include <linux/xfrm.h> 26#include <linux/capability.h>
38#include <linux/slab.h> 27#include <linux/slab.h>
39#include <linux/xattr.h> 28#include <linux/err.h>
40#include <net/flow.h> 29
30struct linux_binprm;
31struct cred;
32struct rlimit;
33struct siginfo;
34struct sem_array;
35struct sembuf;
36struct kern_ipc_perm;
37struct audit_context;
38struct super_block;
39struct inode;
40struct dentry;
41struct file;
42struct vfsmount;
43struct path;
44struct qstr;
45struct nameidata;
46struct iattr;
47struct fown_struct;
48struct file_operations;
49struct shmid_kernel;
50struct msg_msg;
51struct msg_queue;
52struct xattr;
53struct xfrm_sec_ctx;
54struct mm_struct;
41 55
42/* Maximum number of letters for an LSM name string */ 56/* Maximum number of letters for an LSM name string */
43#define SECURITY_NAME_MAX 10 57#define SECURITY_NAME_MAX 10
@@ -49,6 +63,7 @@
49struct ctl_table; 63struct ctl_table;
50struct audit_krule; 64struct audit_krule;
51struct user_namespace; 65struct user_namespace;
66struct timezone;
52 67
53/* 68/*
54 * These functions are in security/capability.c and are used 69 * These functions are in security/capability.c and are used
@@ -131,18 +146,6 @@ struct request_sock;
131#define LSM_UNSAFE_PTRACE_CAP 4 146#define LSM_UNSAFE_PTRACE_CAP 4
132 147
133#ifdef CONFIG_MMU 148#ifdef CONFIG_MMU
134/*
135 * If a hint addr is less than mmap_min_addr change hint to be as
136 * low as possible but still greater than mmap_min_addr
137 */
138static inline unsigned long round_hint_to_min(unsigned long hint)
139{
140 hint &= PAGE_MASK;
141 if (((void *)hint != NULL) &&
142 (hint < mmap_min_addr))
143 return PAGE_ALIGN(mmap_min_addr);
144 return hint;
145}
146extern int mmap_min_addr_handler(struct ctl_table *table, int write, 149extern int mmap_min_addr_handler(struct ctl_table *table, int write,
147 void __user *buffer, size_t *lenp, loff_t *ppos); 150 void __user *buffer, size_t *lenp, loff_t *ppos);
148#endif 151#endif
@@ -651,6 +654,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
651 * manual page for definitions of the @clone_flags. 654 * manual page for definitions of the @clone_flags.
652 * @clone_flags contains the flags indicating what should be shared. 655 * @clone_flags contains the flags indicating what should be shared.
653 * Return 0 if permission is granted. 656 * Return 0 if permission is granted.
657 * @task_free:
658 * @task task being freed
659 * Handle release of task-related resources. (Note that this can be called
660 * from interrupt context.)
654 * @cred_alloc_blank: 661 * @cred_alloc_blank:
655 * @cred points to the credentials. 662 * @cred points to the credentials.
656 * @gfp indicates the atomicity of any memory allocations. 663 * @gfp indicates the atomicity of any memory allocations.
@@ -1493,6 +1500,7 @@ struct security_operations {
1493 int (*dentry_open) (struct file *file, const struct cred *cred); 1500 int (*dentry_open) (struct file *file, const struct cred *cred);
1494 1501
1495 int (*task_create) (unsigned long clone_flags); 1502 int (*task_create) (unsigned long clone_flags);
1503 void (*task_free) (struct task_struct *task);
1496 int (*cred_alloc_blank) (struct cred *cred, gfp_t gfp); 1504 int (*cred_alloc_blank) (struct cred *cred, gfp_t gfp);
1497 void (*cred_free) (struct cred *cred); 1505 void (*cred_free) (struct cred *cred);
1498 int (*cred_prepare)(struct cred *new, const struct cred *old, 1506 int (*cred_prepare)(struct cred *new, const struct cred *old,
@@ -1674,9 +1682,7 @@ int security_quotactl(int cmds, int type, int id, struct super_block *sb);
1674int security_quota_on(struct dentry *dentry); 1682int security_quota_on(struct dentry *dentry);
1675int security_syslog(int type); 1683int security_syslog(int type);
1676int security_settime(const struct timespec *ts, const struct timezone *tz); 1684int security_settime(const struct timespec *ts, const struct timezone *tz);
1677int security_vm_enough_memory(long pages);
1678int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); 1685int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
1679int security_vm_enough_memory_kern(long pages);
1680int security_bprm_set_creds(struct linux_binprm *bprm); 1686int security_bprm_set_creds(struct linux_binprm *bprm);
1681int security_bprm_check(struct linux_binprm *bprm); 1687int security_bprm_check(struct linux_binprm *bprm);
1682void security_bprm_committing_creds(struct linux_binprm *bprm); 1688void security_bprm_committing_creds(struct linux_binprm *bprm);
@@ -1752,6 +1758,7 @@ int security_file_send_sigiotask(struct task_struct *tsk,
1752int security_file_receive(struct file *file); 1758int security_file_receive(struct file *file);
1753int security_dentry_open(struct file *file, const struct cred *cred); 1759int security_dentry_open(struct file *file, const struct cred *cred);
1754int security_task_create(unsigned long clone_flags); 1760int security_task_create(unsigned long clone_flags);
1761void security_task_free(struct task_struct *task);
1755int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); 1762int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
1756void security_cred_free(struct cred *cred); 1763void security_cred_free(struct cred *cred);
1757int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); 1764int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
@@ -1896,25 +1903,11 @@ static inline int security_settime(const struct timespec *ts,
1896 return cap_settime(ts, tz); 1903 return cap_settime(ts, tz);
1897} 1904}
1898 1905
1899static inline int security_vm_enough_memory(long pages)
1900{
1901 WARN_ON(current->mm == NULL);
1902 return cap_vm_enough_memory(current->mm, pages);
1903}
1904
1905static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) 1906static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
1906{ 1907{
1907 WARN_ON(mm == NULL);
1908 return cap_vm_enough_memory(mm, pages); 1908 return cap_vm_enough_memory(mm, pages);
1909} 1909}
1910 1910
1911static inline int security_vm_enough_memory_kern(long pages)
1912{
1913 /* If current->mm is a kernel thread then we will pass NULL,
1914 for this specific case that is fine */
1915 return cap_vm_enough_memory(current->mm, pages);
1916}
1917
1918static inline int security_bprm_set_creds(struct linux_binprm *bprm) 1911static inline int security_bprm_set_creds(struct linux_binprm *bprm)
1919{ 1912{
1920 return cap_bprm_set_creds(bprm); 1913 return cap_bprm_set_creds(bprm);
@@ -2245,6 +2238,9 @@ static inline int security_task_create(unsigned long clone_flags)
2245 return 0; 2238 return 0;
2246} 2239}
2247 2240
2241static inline void security_task_free(struct task_struct *task)
2242{ }
2243
2248static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) 2244static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
2249{ 2245{
2250 return 0; 2246 return 0;
diff --git a/include/net/sock.h b/include/net/sock.h
index f84be9ed6110..04bc0b30e9e9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -56,6 +56,8 @@
56#include <linux/memcontrol.h> 56#include <linux/memcontrol.h>
57#include <linux/res_counter.h> 57#include <linux/res_counter.h>
58#include <linux/static_key.h> 58#include <linux/static_key.h>
59#include <linux/aio.h>
60#include <linux/sched.h>
59 61
60#include <linux/filter.h> 62#include <linux/filter.h>
61#include <linux/rculist_nulls.h> 63#include <linux/rculist_nulls.h>
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 5652101cdac0..26143d377c95 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -13,7 +13,9 @@
13#include <linux/security.h> 13#include <linux/security.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/ipc.h> 15#include <linux/ipc.h>
16#include <linux/msg.h>
16#include <linux/ipc_namespace.h> 17#include <linux/ipc_namespace.h>
18#include <linux/utsname.h>
17#include <asm/uaccess.h> 19#include <asm/uaccess.h>
18 20
19#include "util.h" 21#include "util.h"
diff --git a/kernel/cred.c b/kernel/cred.c
index 5791612a4045..97b36eeca4c9 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -16,6 +16,7 @@
16#include <linux/keyctl.h> 16#include <linux/keyctl.h>
17#include <linux/init_task.h> 17#include <linux/init_task.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/binfmts.h>
19#include <linux/cn_proc.h> 20#include <linux/cn_proc.h>
20 21
21#if 0 22#if 0
diff --git a/kernel/exit.c b/kernel/exit.c
index 0ed15fed579f..7ad335c3045a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -52,6 +52,7 @@
52#include <linux/hw_breakpoint.h> 52#include <linux/hw_breakpoint.h>
53#include <linux/oom.h> 53#include <linux/oom.h>
54#include <linux/writeback.h> 54#include <linux/writeback.h>
55#include <linux/shm.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
57#include <asm/unistd.h> 58#include <asm/unistd.h>
diff --git a/kernel/fork.c b/kernel/fork.c
index c4f38a849436..26a7138bb849 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -193,6 +193,7 @@ void __put_task_struct(struct task_struct *tsk)
193 WARN_ON(atomic_read(&tsk->usage)); 193 WARN_ON(atomic_read(&tsk->usage));
194 WARN_ON(tsk == current); 194 WARN_ON(tsk == current);
195 195
196 security_task_free(tsk);
196 exit_creds(tsk); 197 exit_creds(tsk);
197 delayacct_tsk_free(tsk); 198 delayacct_tsk_free(tsk);
198 put_signal_struct(tsk->signal); 199 put_signal_struct(tsk->signal);
@@ -355,7 +356,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
355 charge = 0; 356 charge = 0;
356 if (mpnt->vm_flags & VM_ACCOUNT) { 357 if (mpnt->vm_flags & VM_ACCOUNT) {
357 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; 358 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
358 if (security_vm_enough_memory(len)) 359 if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
359 goto fail_nomem; 360 goto fail_nomem;
360 charge = len; 361 charge = len;
361 } 362 }
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a35cb8dbd8c4..503d6426126d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -71,6 +71,7 @@
71#include <linux/ftrace.h> 71#include <linux/ftrace.h>
72#include <linux/slab.h> 72#include <linux/slab.h>
73#include <linux/init_task.h> 73#include <linux/init_task.h>
74#include <linux/binfmts.h>
74 75
75#include <asm/tlb.h> 76#include <asm/tlb.h>
76#include <asm/irq_regs.h> 77#include <asm/irq_regs.h>
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f487f257e05e..11d53046b905 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -58,6 +58,7 @@
58#include <linux/oom.h> 58#include <linux/oom.h>
59#include <linux/kmod.h> 59#include <linux/kmod.h>
60#include <linux/capability.h> 60#include <linux/capability.h>
61#include <linux/binfmts.h>
61 62
62#include <asm/uaccess.h> 63#include <asm/uaccess.h>
63#include <asm/processor.h> 64#include <asm/processor.h>
diff --git a/mm/mmap.c b/mm/mmap.c
index da15a79b1441..39a68ddf38bd 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -936,6 +936,19 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags,
936#endif /* CONFIG_PROC_FS */ 936#endif /* CONFIG_PROC_FS */
937 937
938/* 938/*
939 * If a hint addr is less than mmap_min_addr change hint to be as
940 * low as possible but still greater than mmap_min_addr
941 */
942static inline unsigned long round_hint_to_min(unsigned long hint)
943{
944 hint &= PAGE_MASK;
945 if (((void *)hint != NULL) &&
946 (hint < mmap_min_addr))
947 return PAGE_ALIGN(mmap_min_addr);
948 return hint;
949}
950
951/*
939 * The caller must hold down_write(&current->mm->mmap_sem). 952 * The caller must hold down_write(&current->mm->mmap_sem).
940 */ 953 */
941 954
@@ -1235,7 +1248,7 @@ munmap_back:
1235 */ 1248 */
1236 if (accountable_mapping(file, vm_flags)) { 1249 if (accountable_mapping(file, vm_flags)) {
1237 charged = len >> PAGE_SHIFT; 1250 charged = len >> PAGE_SHIFT;
1238 if (security_vm_enough_memory(charged)) 1251 if (security_vm_enough_memory_mm(mm, charged))
1239 return -ENOMEM; 1252 return -ENOMEM;
1240 vm_flags |= VM_ACCOUNT; 1253 vm_flags |= VM_ACCOUNT;
1241 } 1254 }
@@ -2180,7 +2193,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
2180 if (mm->map_count > sysctl_max_map_count) 2193 if (mm->map_count > sysctl_max_map_count)
2181 return -ENOMEM; 2194 return -ENOMEM;
2182 2195
2183 if (security_vm_enough_memory(len >> PAGE_SHIFT)) 2196 if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT))
2184 return -ENOMEM; 2197 return -ENOMEM;
2185 2198
2186 /* Can we just expand an old private anonymous mapping? */ 2199 /* Can we just expand an old private anonymous mapping? */
diff --git a/mm/mprotect.c b/mm/mprotect.c
index f437d054c3bf..142ef4a1f480 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -168,7 +168,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
168 if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB| 168 if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB|
169 VM_SHARED|VM_NORESERVE))) { 169 VM_SHARED|VM_NORESERVE))) {
170 charged = nrpages; 170 charged = nrpages;
171 if (security_vm_enough_memory(charged)) 171 if (security_vm_enough_memory_mm(mm, charged))
172 return -ENOMEM; 172 return -ENOMEM;
173 newflags |= VM_ACCOUNT; 173 newflags |= VM_ACCOUNT;
174 } 174 }
diff --git a/mm/mremap.c b/mm/mremap.c
index 87bb8393e7d2..db8d983b5a7d 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -329,7 +329,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
329 329
330 if (vma->vm_flags & VM_ACCOUNT) { 330 if (vma->vm_flags & VM_ACCOUNT) {
331 unsigned long charged = (new_len - old_len) >> PAGE_SHIFT; 331 unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
332 if (security_vm_enough_memory(charged)) 332 if (security_vm_enough_memory_mm(mm, charged))
333 goto Efault; 333 goto Efault;
334 *p = charged; 334 *p = charged;
335 } 335 }
diff --git a/mm/shmem.c b/mm/shmem.c
index b7e195571862..78307d5c5bd9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -127,7 +127,7 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb)
127static inline int shmem_acct_size(unsigned long flags, loff_t size) 127static inline int shmem_acct_size(unsigned long flags, loff_t size)
128{ 128{
129 return (flags & VM_NORESERVE) ? 129 return (flags & VM_NORESERVE) ?
130 0 : security_vm_enough_memory_kern(VM_ACCT(size)); 130 0 : security_vm_enough_memory_mm(current->mm, VM_ACCT(size));
131} 131}
132 132
133static inline void shmem_unacct_size(unsigned long flags, loff_t size) 133static inline void shmem_unacct_size(unsigned long flags, loff_t size)
@@ -145,7 +145,7 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size)
145static inline int shmem_acct_block(unsigned long flags) 145static inline int shmem_acct_block(unsigned long flags)
146{ 146{
147 return (flags & VM_NORESERVE) ? 147 return (flags & VM_NORESERVE) ?
148 security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0; 148 security_vm_enough_memory_mm(current->mm, VM_ACCT(PAGE_CACHE_SIZE)) : 0;
149} 149}
150 150
151static inline void shmem_unacct_blocks(unsigned long flags, long pages) 151static inline void shmem_unacct_blocks(unsigned long flags, long pages)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 00a962caab1a..6bf67ab6e469 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1563,6 +1563,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1563 if (!capable(CAP_SYS_ADMIN)) 1563 if (!capable(CAP_SYS_ADMIN))
1564 return -EPERM; 1564 return -EPERM;
1565 1565
1566 BUG_ON(!current->mm);
1567
1566 pathname = getname(specialfile); 1568 pathname = getname(specialfile);
1567 err = PTR_ERR(pathname); 1569 err = PTR_ERR(pathname);
1568 if (IS_ERR(pathname)) 1570 if (IS_ERR(pathname))
@@ -1590,7 +1592,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1590 spin_unlock(&swap_lock); 1592 spin_unlock(&swap_lock);
1591 goto out_dput; 1593 goto out_dput;
1592 } 1594 }
1593 if (!security_vm_enough_memory(p->pages)) 1595 if (!security_vm_enough_memory_mm(current->mm, p->pages))
1594 vm_unacct_memory(p->pages); 1596 vm_unacct_memory(p->pages);
1595 else { 1597 else {
1596 err = -ENOMEM; 1598 err = -ENOMEM;
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index fa000d26dc60..c73bba326d70 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -281,6 +281,7 @@ static int __init init_dns_resolver(void)
281 281
282 /* instruct request_key() to use this special keyring as a cache for 282 /* instruct request_key() to use this special keyring as a cache for
283 * the results it looks up */ 283 * the results it looks up */
284 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
284 cred->thread_keyring = keyring; 285 cred->thread_keyring = keyring;
285 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 286 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
286 dns_resolver_cache = cred; 287 dns_resolver_cache = cred;
diff --git a/security/Kconfig b/security/Kconfig
index 51bd5a0b69ae..ccc61f8006b2 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -187,6 +187,7 @@ source security/selinux/Kconfig
187source security/smack/Kconfig 187source security/smack/Kconfig
188source security/tomoyo/Kconfig 188source security/tomoyo/Kconfig
189source security/apparmor/Kconfig 189source security/apparmor/Kconfig
190source security/yama/Kconfig
190 191
191source security/integrity/Kconfig 192source security/integrity/Kconfig
192 193
@@ -196,6 +197,7 @@ choice
196 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK 197 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
197 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO 198 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
198 default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR 199 default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
200 default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
199 default DEFAULT_SECURITY_DAC 201 default DEFAULT_SECURITY_DAC
200 202
201 help 203 help
@@ -214,6 +216,9 @@ choice
214 config DEFAULT_SECURITY_APPARMOR 216 config DEFAULT_SECURITY_APPARMOR
215 bool "AppArmor" if SECURITY_APPARMOR=y 217 bool "AppArmor" if SECURITY_APPARMOR=y
216 218
219 config DEFAULT_SECURITY_YAMA
220 bool "Yama" if SECURITY_YAMA=y
221
217 config DEFAULT_SECURITY_DAC 222 config DEFAULT_SECURITY_DAC
218 bool "Unix Discretionary Access Controls" 223 bool "Unix Discretionary Access Controls"
219 224
@@ -225,6 +230,7 @@ config DEFAULT_SECURITY
225 default "smack" if DEFAULT_SECURITY_SMACK 230 default "smack" if DEFAULT_SECURITY_SMACK
226 default "tomoyo" if DEFAULT_SECURITY_TOMOYO 231 default "tomoyo" if DEFAULT_SECURITY_TOMOYO
227 default "apparmor" if DEFAULT_SECURITY_APPARMOR 232 default "apparmor" if DEFAULT_SECURITY_APPARMOR
233 default "yama" if DEFAULT_SECURITY_YAMA
228 default "" if DEFAULT_SECURITY_DAC 234 default "" if DEFAULT_SECURITY_DAC
229 235
230endmenu 236endmenu
diff --git a/security/Makefile b/security/Makefile
index a5e502f8a05b..c26c81e92571 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -7,6 +7,7 @@ subdir-$(CONFIG_SECURITY_SELINUX) += selinux
7subdir-$(CONFIG_SECURITY_SMACK) += smack 7subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor 9subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
10subdir-$(CONFIG_SECURITY_YAMA) += yama
10 11
11# always enable default capabilities 12# always enable default capabilities
12obj-y += commoncap.o 13obj-y += commoncap.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
21obj-$(CONFIG_AUDIT) += lsm_audit.o 22obj-$(CONFIG_AUDIT) += lsm_audit.o
22obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 23obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
23obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o 24obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
25obj-$(CONFIG_SECURITY_YAMA) += yama/built-in.o
24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 26obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
25 27
26# Object integrity file lists 28# Object integrity file lists
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 2dafe50a2e25..806bd19af7f2 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -15,7 +15,7 @@ clean-files := capability_names.h rlim_names.h
15# to 15# to
16# [1] = "dac_override", 16# [1] = "dac_override",
17quiet_cmd_make-caps = GEN $@ 17quiet_cmd_make-caps = GEN $@
18cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ;\ 18cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
19 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \ 19 sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
20 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\ 20 -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
21 echo "};" >> $@ 21 echo "};" >> $@
@@ -28,25 +28,38 @@ cmd_make-caps = echo "static const char *capability_names[] = {" > $@ ;\
28# [RLIMIT_STACK] = "stack", 28# [RLIMIT_STACK] = "stack",
29# 29#
30# and build a second integer table (with the second sed cmd), that maps 30# and build a second integer table (with the second sed cmd), that maps
31# RLIMIT defines to the order defined in asm-generic/resource.h Thi is 31# RLIMIT defines to the order defined in asm-generic/resource.h This is
32# required by policy load to map policy ordering of RLIMITs to internal 32# required by policy load to map policy ordering of RLIMITs to internal
33# ordering for architectures that redefine an RLIMIT. 33# ordering for architectures that redefine an RLIMIT.
34# Transforms lines from 34# Transforms lines from
35# #define RLIMIT_STACK 3 /* max stack size */ 35# #define RLIMIT_STACK 3 /* max stack size */
36# to 36# to
37# RLIMIT_STACK, 37# RLIMIT_STACK,
38#
39# and build the securityfs entries for the mapping.
40# Transforms lines from
41# #define RLIMIT_FSIZE 1 /* Maximum filesize */
42# #define RLIMIT_STACK 3 /* max stack size */
43# to
44# #define AA_FS_RLIMIT_MASK "fsize stack"
38quiet_cmd_make-rlim = GEN $@ 45quiet_cmd_make-rlim = GEN $@
39cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\ 46cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
47 > $@ ;\
40 sed $< >> $@ -r -n \ 48 sed $< >> $@ -r -n \
41 -e 's/^\# ?define[ \t]+(RLIMIT_([A-Z0-9_]+)).*/[\1] = "\L\2",/p';\ 49 -e 's/^\# ?define[ \t]+(RLIMIT_([A-Z0-9_]+)).*/[\1] = "\L\2",/p';\
42 echo "};" >> $@ ;\ 50 echo "};" >> $@ ;\
43 echo "static const int rlim_map[] = {" >> $@ ;\ 51 echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
44 sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\ 52 sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
45 echo "};" >> $@ 53 echo "};" >> $@ ; \
54 echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
55 sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
56 tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
46 57
47$(obj)/capability.o : $(obj)/capability_names.h 58$(obj)/capability.o : $(obj)/capability_names.h
48$(obj)/resource.o : $(obj)/rlim_names.h 59$(obj)/resource.o : $(obj)/rlim_names.h
49$(obj)/capability_names.h : $(srctree)/include/linux/capability.h 60$(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
61 $(src)/Makefile
50 $(call cmd,make-caps) 62 $(call cmd,make-caps)
51$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h 63$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
64 $(src)/Makefile
52 $(call cmd,make-rlim) 65 $(call cmd,make-rlim)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index e39df6d43779..16c15ec6f670 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -18,12 +18,14 @@
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#include <linux/uaccess.h> 19#include <linux/uaccess.h>
20#include <linux/namei.h> 20#include <linux/namei.h>
21#include <linux/capability.h>
21 22
22#include "include/apparmor.h" 23#include "include/apparmor.h"
23#include "include/apparmorfs.h" 24#include "include/apparmorfs.h"
24#include "include/audit.h" 25#include "include/audit.h"
25#include "include/context.h" 26#include "include/context.h"
26#include "include/policy.h" 27#include "include/policy.h"
28#include "include/resource.h"
27 29
28/** 30/**
29 * aa_simple_write_to_buffer - common routine for getting policy from user 31 * aa_simple_write_to_buffer - common routine for getting policy from user
@@ -142,38 +144,166 @@ static const struct file_operations aa_fs_profile_remove = {
142 .llseek = default_llseek, 144 .llseek = default_llseek,
143}; 145};
144 146
145/** Base file system setup **/ 147static int aa_fs_seq_show(struct seq_file *seq, void *v)
148{
149 struct aa_fs_entry *fs_file = seq->private;
150
151 if (!fs_file)
152 return 0;
146 153
147static struct dentry *aa_fs_dentry __initdata; 154 switch (fs_file->v_type) {
155 case AA_FS_TYPE_BOOLEAN:
156 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
157 break;
158 case AA_FS_TYPE_STRING:
159 seq_printf(seq, "%s\n", fs_file->v.string);
160 break;
161 case AA_FS_TYPE_U64:
162 seq_printf(seq, "%#08lx\n", fs_file->v.u64);
163 break;
164 default:
165 /* Ignore unpritable entry types. */
166 break;
167 }
168
169 return 0;
170}
148 171
149static void __init aafs_remove(const char *name) 172static int aa_fs_seq_open(struct inode *inode, struct file *file)
150{ 173{
151 struct dentry *dentry; 174 return single_open(file, aa_fs_seq_show, inode->i_private);
175}
176
177const struct file_operations aa_fs_seq_file_ops = {
178 .owner = THIS_MODULE,
179 .open = aa_fs_seq_open,
180 .read = seq_read,
181 .llseek = seq_lseek,
182 .release = single_release,
183};
184
185/** Base file system setup **/
186
187static struct aa_fs_entry aa_fs_entry_file[] = {
188 AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
189 "link lock"),
190 { }
191};
152 192
153 dentry = lookup_one_len(name, aa_fs_dentry, strlen(name)); 193static struct aa_fs_entry aa_fs_entry_domain[] = {
154 if (!IS_ERR(dentry)) { 194 AA_FS_FILE_BOOLEAN("change_hat", 1),
155 securityfs_remove(dentry); 195 AA_FS_FILE_BOOLEAN("change_hatv", 1),
156 dput(dentry); 196 AA_FS_FILE_BOOLEAN("change_onexec", 1),
197 AA_FS_FILE_BOOLEAN("change_profile", 1),
198 { }
199};
200
201static struct aa_fs_entry aa_fs_entry_features[] = {
202 AA_FS_DIR("domain", aa_fs_entry_domain),
203 AA_FS_DIR("file", aa_fs_entry_file),
204 AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
205 AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
206 { }
207};
208
209static struct aa_fs_entry aa_fs_entry_apparmor[] = {
210 AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
211 AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
212 AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
213 AA_FS_DIR("features", aa_fs_entry_features),
214 { }
215};
216
217static struct aa_fs_entry aa_fs_entry =
218 AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
219
220/**
221 * aafs_create_file - create a file entry in the apparmor securityfs
222 * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
223 * @parent: the parent dentry in the securityfs
224 *
225 * Use aafs_remove_file to remove entries created with this fn.
226 */
227static int __init aafs_create_file(struct aa_fs_entry *fs_file,
228 struct dentry *parent)
229{
230 int error = 0;
231
232 fs_file->dentry = securityfs_create_file(fs_file->name,
233 S_IFREG | fs_file->mode,
234 parent, fs_file,
235 fs_file->file_ops);
236 if (IS_ERR(fs_file->dentry)) {
237 error = PTR_ERR(fs_file->dentry);
238 fs_file->dentry = NULL;
157 } 239 }
240 return error;
158} 241}
159 242
160/** 243/**
161 * aafs_create - create an entry in the apparmor filesystem 244 * aafs_create_dir - recursively create a directory entry in the securityfs
162 * @name: name of the entry (NOT NULL) 245 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
163 * @mask: file permission mask of the file 246 * @parent: the parent dentry in the securityfs
164 * @fops: file operations for the file (NOT NULL)
165 * 247 *
166 * Used aafs_remove to remove entries created with this fn. 248 * Use aafs_remove_dir to remove entries created with this fn.
167 */ 249 */
168static int __init aafs_create(const char *name, umode_t mask, 250static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
169 const struct file_operations *fops) 251 struct dentry *parent)
170{ 252{
171 struct dentry *dentry; 253 int error;
254 struct aa_fs_entry *fs_file;
172 255
173 dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry, 256 fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent);
174 NULL, fops); 257 if (IS_ERR(fs_dir->dentry)) {
258 error = PTR_ERR(fs_dir->dentry);
259 fs_dir->dentry = NULL;
260 goto failed;
261 }
175 262
176 return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; 263 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
264 if (fs_file->v_type == AA_FS_TYPE_DIR)
265 error = aafs_create_dir(fs_file, fs_dir->dentry);
266 else
267 error = aafs_create_file(fs_file, fs_dir->dentry);
268 if (error)
269 goto failed;
270 }
271
272 return 0;
273
274failed:
275 return error;
276}
277
278/**
279 * aafs_remove_file - drop a single file entry in the apparmor securityfs
280 * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
281 */
282static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
283{
284 if (!fs_file->dentry)
285 return;
286
287 securityfs_remove(fs_file->dentry);
288 fs_file->dentry = NULL;
289}
290
291/**
292 * aafs_remove_dir - recursively drop a directory entry from the securityfs
293 * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
294 */
295static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
296{
297 struct aa_fs_entry *fs_file;
298
299 for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
300 if (fs_file->v_type == AA_FS_TYPE_DIR)
301 aafs_remove_dir(fs_file);
302 else
303 aafs_remove_file(fs_file);
304 }
305
306 aafs_remove_file(fs_dir);
177} 307}
178 308
179/** 309/**
@@ -183,14 +313,7 @@ static int __init aafs_create(const char *name, umode_t mask,
183 */ 313 */
184void __init aa_destroy_aafs(void) 314void __init aa_destroy_aafs(void)
185{ 315{
186 if (aa_fs_dentry) { 316 aafs_remove_dir(&aa_fs_entry);
187 aafs_remove(".remove");
188 aafs_remove(".replace");
189 aafs_remove(".load");
190
191 securityfs_remove(aa_fs_dentry);
192 aa_fs_dentry = NULL;
193 }
194} 317}
195 318
196/** 319/**
@@ -207,25 +330,13 @@ static int __init aa_create_aafs(void)
207 if (!apparmor_initialized) 330 if (!apparmor_initialized)
208 return 0; 331 return 0;
209 332
210 if (aa_fs_dentry) { 333 if (aa_fs_entry.dentry) {
211 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__); 334 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
212 return -EEXIST; 335 return -EEXIST;
213 } 336 }
214 337
215 aa_fs_dentry = securityfs_create_dir("apparmor", NULL); 338 /* Populate fs tree. */
216 if (IS_ERR(aa_fs_dentry)) { 339 error = aafs_create_dir(&aa_fs_entry, NULL);
217 error = PTR_ERR(aa_fs_dentry);
218 aa_fs_dentry = NULL;
219 goto error;
220 }
221
222 error = aafs_create(".load", 0640, &aa_fs_profile_load);
223 if (error)
224 goto error;
225 error = aafs_create(".replace", 0640, &aa_fs_profile_replace);
226 if (error)
227 goto error;
228 error = aafs_create(".remove", 0640, &aa_fs_profile_remove);
229 if (error) 340 if (error)
230 goto error; 341 goto error;
231 342
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index f3fafedd798a..5ff67776a5ad 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -19,7 +19,7 @@
19#include "include/audit.h" 19#include "include/audit.h"
20#include "include/policy.h" 20#include "include/policy.h"
21 21
22const char *op_table[] = { 22const char *const op_table[] = {
23 "null", 23 "null",
24 24
25 "sysctl", 25 "sysctl",
@@ -73,7 +73,7 @@ const char *op_table[] = {
73 "profile_remove" 73 "profile_remove"
74}; 74};
75 75
76const char *audit_mode_names[] = { 76const char *const audit_mode_names[] = {
77 "normal", 77 "normal",
78 "quiet_denied", 78 "quiet_denied",
79 "quiet", 79 "quiet",
@@ -81,7 +81,7 @@ const char *audit_mode_names[] = {
81 "all" 81 "all"
82}; 82};
83 83
84static char *aa_audit_type[] = { 84static const char *const aa_audit_type[] = {
85 "AUDIT", 85 "AUDIT",
86 "ALLOWED", 86 "ALLOWED",
87 "DENIED", 87 "DENIED",
@@ -89,6 +89,7 @@ static char *aa_audit_type[] = {
89 "STATUS", 89 "STATUS",
90 "ERROR", 90 "ERROR",
91 "KILLED" 91 "KILLED"
92 "AUTO"
92}; 93};
93 94
94/* 95/*
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c1e18ba5bdc0..7c69599a69e1 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
372 state = profile->file.start; 372 state = profile->file.start;
373 373
374 /* buffer freed below, name is pointer into buffer */ 374 /* buffer freed below, name is pointer into buffer */
375 error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer, 375 error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
376 &name); 376 &name, &info);
377 if (error) { 377 if (error) {
378 if (profile->flags & 378 if (profile->flags &
379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED)) 379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
380 error = 0; 380 error = 0;
381 info = "Exec failed name resolution";
382 name = bprm->filename; 381 name = bprm->filename;
383 goto audit; 382 goto audit;
384 } 383 }
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 7312db741219..3022c0f4f0db 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -173,8 +173,6 @@ static u32 map_old_perms(u32 old)
173 if (old & 0x40) /* AA_EXEC_MMAP */ 173 if (old & 0x40) /* AA_EXEC_MMAP */
174 new |= AA_EXEC_MMAP; 174 new |= AA_EXEC_MMAP;
175 175
176 new |= AA_MAY_META_READ;
177
178 return new; 176 return new;
179} 177}
180 178
@@ -212,6 +210,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
212 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state)); 210 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
213 perms.xindex = dfa_other_xindex(dfa, state); 211 perms.xindex = dfa_other_xindex(dfa, state);
214 } 212 }
213 perms.allow |= AA_MAY_META_READ;
215 214
216 /* change_profile wasn't determined by ownership in old mapping */ 215 /* change_profile wasn't determined by ownership in old mapping */
217 if (ACCEPT_TABLE(dfa)[state] & 0x80000000) 216 if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
@@ -279,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
279 int error; 278 int error;
280 279
281 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0); 280 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
282 error = aa_get_name(path, flags, &buffer, &name); 281 error = aa_path_name(path, flags, &buffer, &name, &info);
283 if (error) { 282 if (error) {
284 if (error == -ENOENT && is_deleted(path->dentry)) { 283 if (error == -ENOENT && is_deleted(path->dentry)) {
285 /* Access to open files that are deleted are 284 /* Access to open files that are deleted are
286 * give a pass (implicit delegation) 285 * give a pass (implicit delegation)
287 */ 286 */
288 error = 0; 287 error = 0;
288 info = NULL;
289 perms.allow = request; 289 perms.allow = request;
290 } else if (error == -ENOENT) 290 }
291 info = "Failed name lookup - deleted entry";
292 else if (error == -ESTALE)
293 info = "Failed name lookup - disconnected path";
294 else if (error == -ENAMETOOLONG)
295 info = "Failed name lookup - name too long";
296 else
297 info = "Failed name lookup";
298 } else { 291 } else {
299 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, 292 aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
300 &perms); 293 &perms);
@@ -365,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
365 lperms = nullperms; 358 lperms = nullperms;
366 359
367 /* buffer freed below, lname is pointer in buffer */ 360 /* buffer freed below, lname is pointer in buffer */
368 error = aa_get_name(&link, profile->path_flags, &buffer, &lname); 361 error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
362 &info);
369 if (error) 363 if (error)
370 goto audit; 364 goto audit;
371 365
372 /* buffer2 freed below, tname is pointer in buffer2 */ 366 /* buffer2 freed below, tname is pointer in buffer2 */
373 error = aa_get_name(&target, profile->path_flags, &buffer2, &tname); 367 error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
368 &info);
374 if (error) 369 if (error)
375 goto audit; 370 goto audit;
376 371
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index df3649560818..40aedd9f73ea 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -19,6 +19,19 @@
19 19
20#include "match.h" 20#include "match.h"
21 21
22/*
23 * Class of mediation types in the AppArmor policy db
24 */
25#define AA_CLASS_ENTRY 0
26#define AA_CLASS_UNKNOWN 1
27#define AA_CLASS_FILE 2
28#define AA_CLASS_CAP 3
29#define AA_CLASS_NET 4
30#define AA_CLASS_RLIMITS 5
31#define AA_CLASS_DOMAIN 6
32
33#define AA_CLASS_LAST AA_CLASS_DOMAIN
34
22/* Control parameters settable through module/boot flags */ 35/* Control parameters settable through module/boot flags */
23extern enum audit_mode aa_g_audit; 36extern enum audit_mode aa_g_audit;
24extern bool aa_g_audit_header; 37extern bool aa_g_audit_header;
@@ -81,7 +94,7 @@ static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
81 unsigned int start) 94 unsigned int start)
82{ 95{
83 /* the null transition only needs the string's null terminator byte */ 96 /* the null transition only needs the string's null terminator byte */
84 return aa_dfa_match_len(dfa, start, "", 1); 97 return aa_dfa_next(dfa, start, 0);
85} 98}
86 99
87static inline bool mediated_filesystem(struct inode *inode) 100static inline bool mediated_filesystem(struct inode *inode)
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index cb1e93a114d7..7ea4769fab3f 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -15,6 +15,50 @@
15#ifndef __AA_APPARMORFS_H 15#ifndef __AA_APPARMORFS_H
16#define __AA_APPARMORFS_H 16#define __AA_APPARMORFS_H
17 17
18enum aa_fs_type {
19 AA_FS_TYPE_BOOLEAN,
20 AA_FS_TYPE_STRING,
21 AA_FS_TYPE_U64,
22 AA_FS_TYPE_FOPS,
23 AA_FS_TYPE_DIR,
24};
25
26struct aa_fs_entry;
27
28struct aa_fs_entry {
29 const char *name;
30 struct dentry *dentry;
31 umode_t mode;
32 enum aa_fs_type v_type;
33 union {
34 bool boolean;
35 char *string;
36 unsigned long u64;
37 struct aa_fs_entry *files;
38 } v;
39 const struct file_operations *file_ops;
40};
41
42extern const struct file_operations aa_fs_seq_file_ops;
43
44#define AA_FS_FILE_BOOLEAN(_name, _value) \
45 { .name = (_name), .mode = 0444, \
46 .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \
47 .file_ops = &aa_fs_seq_file_ops }
48#define AA_FS_FILE_STRING(_name, _value) \
49 { .name = (_name), .mode = 0444, \
50 .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \
51 .file_ops = &aa_fs_seq_file_ops }
52#define AA_FS_FILE_U64(_name, _value) \
53 { .name = (_name), .mode = 0444, \
54 .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \
55 .file_ops = &aa_fs_seq_file_ops }
56#define AA_FS_FILE_FOPS(_name, _mode, _fops) \
57 { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \
58 .mode = (_mode), .file_ops = (_fops) }
59#define AA_FS_DIR(_name, _value) \
60 { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) }
61
18extern void __init aa_destroy_aafs(void); 62extern void __init aa_destroy_aafs(void);
19 63
20#endif /* __AA_APPARMORFS_H */ 64#endif /* __AA_APPARMORFS_H */
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 1951786d32e9..4ba78c203af1 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -25,11 +25,9 @@
25 25
26struct aa_profile; 26struct aa_profile;
27 27
28extern const char *audit_mode_names[]; 28extern const char *const audit_mode_names[];
29#define AUDIT_MAX_INDEX 5 29#define AUDIT_MAX_INDEX 5
30 30
31#define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */
32
33enum audit_mode { 31enum audit_mode {
34 AUDIT_NORMAL, /* follow normal auditing of accesses */ 32 AUDIT_NORMAL, /* follow normal auditing of accesses */
35 AUDIT_QUIET_DENIED, /* quiet all denied access messages */ 33 AUDIT_QUIET_DENIED, /* quiet all denied access messages */
@@ -45,10 +43,11 @@ enum audit_type {
45 AUDIT_APPARMOR_HINT, 43 AUDIT_APPARMOR_HINT,
46 AUDIT_APPARMOR_STATUS, 44 AUDIT_APPARMOR_STATUS,
47 AUDIT_APPARMOR_ERROR, 45 AUDIT_APPARMOR_ERROR,
48 AUDIT_APPARMOR_KILL 46 AUDIT_APPARMOR_KILL,
47 AUDIT_APPARMOR_AUTO
49}; 48};
50 49
51extern const char *op_table[]; 50extern const char *const op_table[];
52enum aa_ops { 51enum aa_ops {
53 OP_NULL, 52 OP_NULL,
54 53
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ab8c6d87f758..f98fd4701d80 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
117 index |= AA_X_NAME; 117 index |= AA_X_NAME;
118 } else if (old_index == 3) { 118 } else if (old_index == 3) {
119 index |= AA_X_NAME | AA_X_CHILD; 119 index |= AA_X_NAME | AA_X_CHILD;
120 } else { 120 } else if (old_index) {
121 index |= AA_X_TABLE; 121 index |= AA_X_TABLE;
122 index |= old_index - 4; 122 index |= old_index - 4;
123 } 123 }
diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
index a4a863997bd5..775843e7f984 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -116,6 +116,9 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
116 const char *str, int len); 116 const char *str, int len);
117unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 117unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
118 const char *str); 118 const char *str);
119unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
120 const char c);
121
119void aa_dfa_free_kref(struct kref *kref); 122void aa_dfa_free_kref(struct kref *kref);
120 123
121/** 124/**
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 27b327a7fae5..286ac75dc88b 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -26,6 +26,7 @@ enum path_flags {
26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ 26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
27}; 27};
28 28
29int aa_get_name(struct path *path, int flags, char **buffer, const char **name); 29int aa_path_name(struct path *path, int flags, char **buffer,
30 const char **name, const char **info);
30 31
31#endif /* __AA_PATH_H */ 32#endif /* __AA_PATH_H */
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index aeda5cf56904..bda4569fdd83 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -29,7 +29,7 @@
29#include "file.h" 29#include "file.h"
30#include "resource.h" 30#include "resource.h"
31 31
32extern const char *profile_mode_names[]; 32extern const char *const profile_mode_names[];
33#define APPARMOR_NAMES_MAX_INDEX 3 33#define APPARMOR_NAMES_MAX_INDEX 3
34 34
35#define COMPLAIN_MODE(_profile) \ 35#define COMPLAIN_MODE(_profile) \
@@ -129,6 +129,17 @@ struct aa_namespace {
129 struct list_head sub_ns; 129 struct list_head sub_ns;
130}; 130};
131 131
132/* struct aa_policydb - match engine for a policy
133 * dfa: dfa pattern match
134 * start: set of start states for the different classes of data
135 */
136struct aa_policydb {
137 /* Generic policy DFA specific rule types will be subsections of it */
138 struct aa_dfa *dfa;
139 unsigned int start[AA_CLASS_LAST + 1];
140
141};
142
132/* struct aa_profile - basic confinement data 143/* struct aa_profile - basic confinement data
133 * @base - base components of the profile (name, refcount, lists, lock ...) 144 * @base - base components of the profile (name, refcount, lists, lock ...)
134 * @parent: parent of profile 145 * @parent: parent of profile
@@ -143,6 +154,7 @@ struct aa_namespace {
143 * @flags: flags controlling profile behavior 154 * @flags: flags controlling profile behavior
144 * @path_flags: flags controlling path generation behavior 155 * @path_flags: flags controlling path generation behavior
145 * @size: the memory consumed by this profiles rules 156 * @size: the memory consumed by this profiles rules
157 * @policy: general match rules governing policy
146 * @file: The set of rules governing basic file access and domain transitions 158 * @file: The set of rules governing basic file access and domain transitions
147 * @caps: capabilities for the profile 159 * @caps: capabilities for the profile
148 * @rlimits: rlimits for the profile 160 * @rlimits: rlimits for the profile
@@ -179,6 +191,7 @@ struct aa_profile {
179 u32 path_flags; 191 u32 path_flags;
180 int size; 192 int size;
181 193
194 struct aa_policydb policy;
182 struct aa_file_rules file; 195 struct aa_file_rules file;
183 struct aa_caps caps; 196 struct aa_caps caps;
184 struct aa_rlimit rlimits; 197 struct aa_rlimit rlimits;
diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
index 02baec732bb5..d3f4cf027957 100644
--- a/security/apparmor/include/resource.h
+++ b/security/apparmor/include/resource.h
@@ -18,6 +18,8 @@
18#include <linux/resource.h> 18#include <linux/resource.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20 20
21#include "apparmorfs.h"
22
21struct aa_profile; 23struct aa_profile;
22 24
23/* struct aa_rlimit - rlimit settings for the profile 25/* struct aa_rlimit - rlimit settings for the profile
@@ -32,6 +34,8 @@ struct aa_rlimit {
32 struct rlimit limits[RLIM_NLIMITS]; 34 struct rlimit limits[RLIM_NLIMITS];
33}; 35};
34 36
37extern struct aa_fs_entry aa_fs_entry_rlimit[];
38
35int aa_map_resource(int resource); 39int aa_map_resource(int resource);
36int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *, 40int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
37 unsigned int resource, struct rlimit *new_rlim); 41 unsigned int resource, struct rlimit *new_rlim);
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 94de6b4907c8..90971a8c3789 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -335,12 +335,12 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
335} 335}
336 336
337/** 337/**
338 * aa_dfa_next_state - traverse @dfa to find state @str stops at 338 * aa_dfa_match - traverse @dfa to find state @str stops at
339 * @dfa: the dfa to match @str against (NOT NULL) 339 * @dfa: the dfa to match @str against (NOT NULL)
340 * @start: the state of the dfa to start matching in 340 * @start: the state of the dfa to start matching in
341 * @str: the null terminated string of bytes to match against the dfa (NOT NULL) 341 * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
342 * 342 *
343 * aa_dfa_next_state will match @str against the dfa and return the state it 343 * aa_dfa_match will match @str against the dfa and return the state it
344 * finished matching in. The final state can be used to look up the accepting 344 * finished matching in. The final state can be used to look up the accepting
345 * label, or as the start state of a continuing match. 345 * label, or as the start state of a continuing match.
346 * 346 *
@@ -349,5 +349,79 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
349unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 349unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
350 const char *str) 350 const char *str)
351{ 351{
352 return aa_dfa_match_len(dfa, start, str, strlen(str)); 352 u16 *def = DEFAULT_TABLE(dfa);
353 u32 *base = BASE_TABLE(dfa);
354 u16 *next = NEXT_TABLE(dfa);
355 u16 *check = CHECK_TABLE(dfa);
356 unsigned int state = start, pos;
357
358 if (state == 0)
359 return 0;
360
361 /* current state is <state>, matching character *str */
362 if (dfa->tables[YYTD_ID_EC]) {
363 /* Equivalence class table defined */
364 u8 *equiv = EQUIV_TABLE(dfa);
365 /* default is direct to next state */
366 while (*str) {
367 pos = base[state] + equiv[(u8) *str++];
368 if (check[pos] == state)
369 state = next[pos];
370 else
371 state = def[state];
372 }
373 } else {
374 /* default is direct to next state */
375 while (*str) {
376 pos = base[state] + (u8) *str++;
377 if (check[pos] == state)
378 state = next[pos];
379 else
380 state = def[state];
381 }
382 }
383
384 return state;
385}
386
387/**
388 * aa_dfa_next - step one character to the next state in the dfa
389 * @dfa: the dfa to tranverse (NOT NULL)
390 * @state: the state to start in
391 * @c: the input character to transition on
392 *
393 * aa_dfa_match will step through the dfa by one input character @c
394 *
395 * Returns: state reach after input @c
396 */
397unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
398 const char c)
399{
400 u16 *def = DEFAULT_TABLE(dfa);
401 u32 *base = BASE_TABLE(dfa);
402 u16 *next = NEXT_TABLE(dfa);
403 u16 *check = CHECK_TABLE(dfa);
404 unsigned int pos;
405
406 /* current state is <state>, matching character *str */
407 if (dfa->tables[YYTD_ID_EC]) {
408 /* Equivalence class table defined */
409 u8 *equiv = EQUIV_TABLE(dfa);
410 /* default is direct to next state */
411
412 pos = base[state] + equiv[(u8) c];
413 if (check[pos] == state)
414 state = next[pos];
415 else
416 state = def[state];
417 } else {
418 /* default is direct to next state */
419 pos = base[state] + (u8) c;
420 if (check[pos] == state)
421 state = next[pos];
422 else
423 state = def[state];
424 }
425
426 return state;
353} 427}
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 9d070a7c3ffc..2daeea4f9266 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -83,31 +83,29 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
83 struct path root; 83 struct path root;
84 get_fs_root(current->fs, &root); 84 get_fs_root(current->fs, &root);
85 res = __d_path(path, &root, buf, buflen); 85 res = __d_path(path, &root, buf, buflen);
86 if (res && !IS_ERR(res)) {
87 /* everything's fine */
88 *name = res;
89 path_put(&root);
90 goto ok;
91 }
92 path_put(&root); 86 path_put(&root);
93 connected = 0; 87 } else {
88 res = d_absolute_path(path, buf, buflen);
89 if (!our_mnt(path->mnt))
90 connected = 0;
94 } 91 }
95 92
96 res = d_absolute_path(path, buf, buflen);
97
98 *name = res;
99 /* handle error conditions - and still allow a partial path to 93 /* handle error conditions - and still allow a partial path to
100 * be returned. 94 * be returned.
101 */ 95 */
102 if (IS_ERR(res)) { 96 if (!res || IS_ERR(res)) {
103 error = PTR_ERR(res);
104 *name = buf;
105 goto out;
106 }
107 if (!our_mnt(path->mnt))
108 connected = 0; 97 connected = 0;
98 res = dentry_path_raw(path->dentry, buf, buflen);
99 if (IS_ERR(res)) {
100 error = PTR_ERR(res);
101 *name = buf;
102 goto out;
103 };
104 } else if (!our_mnt(path->mnt))
105 connected = 0;
106
107 *name = res;
109 108
110ok:
111 /* Handle two cases: 109 /* Handle two cases:
112 * 1. A deleted dentry && profile is not allowing mediation of deleted 110 * 1. A deleted dentry && profile is not allowing mediation of deleted
113 * 2. On some filesystems, newly allocated dentries appear to the 111 * 2. On some filesystems, newly allocated dentries appear to the
@@ -138,7 +136,7 @@ ok:
138 /* disconnected path, don't return pathname starting 136 /* disconnected path, don't return pathname starting
139 * with '/' 137 * with '/'
140 */ 138 */
141 error = -ESTALE; 139 error = -EACCES;
142 if (*res == '/') 140 if (*res == '/')
143 *name = res + 1; 141 *name = res + 1;
144 } 142 }
@@ -159,7 +157,7 @@ out:
159 * Returns: %0 else error on failure 157 * Returns: %0 else error on failure
160 */ 158 */
161static int get_name_to_buffer(struct path *path, int flags, char *buffer, 159static int get_name_to_buffer(struct path *path, int flags, char *buffer,
162 int size, char **name) 160 int size, char **name, const char **info)
163{ 161{
164 int adjust = (flags & PATH_IS_DIR) ? 1 : 0; 162 int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
165 int error = d_namespace_path(path, buffer, size - adjust, name, flags); 163 int error = d_namespace_path(path, buffer, size - adjust, name, flags);
@@ -171,15 +169,27 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
171 */ 169 */
172 strcpy(&buffer[size - 2], "/"); 170 strcpy(&buffer[size - 2], "/");
173 171
172 if (info && error) {
173 if (error == -ENOENT)
174 *info = "Failed name lookup - deleted entry";
175 else if (error == -ESTALE)
176 *info = "Failed name lookup - disconnected path";
177 else if (error == -ENAMETOOLONG)
178 *info = "Failed name lookup - name too long";
179 else
180 *info = "Failed name lookup";
181 }
182
174 return error; 183 return error;
175} 184}
176 185
177/** 186/**
178 * aa_get_name - compute the pathname of a file 187 * aa_path_name - compute the pathname of a file
179 * @path: path the file (NOT NULL) 188 * @path: path the file (NOT NULL)
180 * @flags: flags controlling path name generation 189 * @flags: flags controlling path name generation
181 * @buffer: buffer that aa_get_name() allocated (NOT NULL) 190 * @buffer: buffer that aa_get_name() allocated (NOT NULL)
182 * @name: Returns - the generated path name if !error (NOT NULL) 191 * @name: Returns - the generated path name if !error (NOT NULL)
192 * @info: Returns - information on why the path lookup failed (MAYBE NULL)
183 * 193 *
184 * @name is a pointer to the beginning of the pathname (which usually differs 194 * @name is a pointer to the beginning of the pathname (which usually differs
185 * from the beginning of the buffer), or NULL. If there is an error @name 195 * from the beginning of the buffer), or NULL. If there is an error @name
@@ -192,7 +202,8 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
192 * 202 *
193 * Returns: %0 else error code if could retrieve name 203 * Returns: %0 else error code if could retrieve name
194 */ 204 */
195int aa_get_name(struct path *path, int flags, char **buffer, const char **name) 205int aa_path_name(struct path *path, int flags, char **buffer, const char **name,
206 const char **info)
196{ 207{
197 char *buf, *str = NULL; 208 char *buf, *str = NULL;
198 int size = 256; 209 int size = 256;
@@ -206,7 +217,7 @@ int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
206 if (!buf) 217 if (!buf)
207 return -ENOMEM; 218 return -ENOMEM;
208 219
209 error = get_name_to_buffer(path, flags, buf, size, &str); 220 error = get_name_to_buffer(path, flags, buf, size, &str, info);
210 if (error != -ENAMETOOLONG) 221 if (error != -ENAMETOOLONG)
211 break; 222 break;
212 223
@@ -214,6 +225,7 @@ int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
214 size <<= 1; 225 size <<= 1;
215 if (size > aa_g_path_max) 226 if (size > aa_g_path_max)
216 return -ENAMETOOLONG; 227 return -ENAMETOOLONG;
228 *info = NULL;
217 } 229 }
218 *buffer = buf; 230 *buffer = buf;
219 *name = str; 231 *name = str;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 4f0eadee78b8..906414383022 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -93,7 +93,7 @@
93/* root profile namespace */ 93/* root profile namespace */
94struct aa_namespace *root_ns; 94struct aa_namespace *root_ns;
95 95
96const char *profile_mode_names[] = { 96const char *const profile_mode_names[] = {
97 "enforce", 97 "enforce",
98 "complain", 98 "complain",
99 "kill", 99 "kill",
@@ -749,6 +749,7 @@ static void free_profile(struct aa_profile *profile)
749 749
750 aa_free_sid(profile->sid); 750 aa_free_sid(profile->sid);
751 aa_put_dfa(profile->xmatch); 751 aa_put_dfa(profile->xmatch);
752 aa_put_dfa(profile->policy.dfa);
752 753
753 aa_put_profile(profile->replacedby); 754 aa_put_profile(profile->replacedby);
754 755
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 741dd13e089b..25fd51edc8da 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -84,7 +84,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
84 * @new: profile if it has been allocated (MAYBE NULL) 84 * @new: profile if it has been allocated (MAYBE NULL)
85 * @name: name of the profile being manipulated (MAYBE NULL) 85 * @name: name of the profile being manipulated (MAYBE NULL)
86 * @info: any extra info about the failure (MAYBE NULL) 86 * @info: any extra info about the failure (MAYBE NULL)
87 * @e: buffer position info (NOT NULL) 87 * @e: buffer position info
88 * @error: error code 88 * @error: error code
89 * 89 *
90 * Returns: %0 or error 90 * Returns: %0 or error
@@ -95,7 +95,8 @@ static int audit_iface(struct aa_profile *new, const char *name,
95 struct aa_profile *profile = __aa_current_profile(); 95 struct aa_profile *profile = __aa_current_profile();
96 struct common_audit_data sa; 96 struct common_audit_data sa;
97 COMMON_AUDIT_DATA_INIT(&sa, NONE); 97 COMMON_AUDIT_DATA_INIT(&sa, NONE);
98 sa.aad.iface.pos = e->pos - e->start; 98 if (e)
99 sa.aad.iface.pos = e->pos - e->start;
99 sa.aad.iface.target = new; 100 sa.aad.iface.target = new;
100 sa.aad.name = name; 101 sa.aad.name = name;
101 sa.aad.info = info; 102 sa.aad.info = info;
@@ -468,7 +469,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
468{ 469{
469 struct aa_profile *profile = NULL; 470 struct aa_profile *profile = NULL;
470 const char *name = NULL; 471 const char *name = NULL;
471 int error = -EPROTO; 472 int i, error = -EPROTO;
472 kernel_cap_t tmpcap; 473 kernel_cap_t tmpcap;
473 u32 tmp; 474 u32 tmp;
474 475
@@ -554,11 +555,35 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
554 goto fail; 555 goto fail;
555 if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL)) 556 if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
556 goto fail; 557 goto fail;
558 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
559 goto fail;
557 } 560 }
558 561
559 if (!unpack_rlimits(e, profile)) 562 if (!unpack_rlimits(e, profile))
560 goto fail; 563 goto fail;
561 564
565 if (unpack_nameX(e, AA_STRUCT, "policydb")) {
566 /* generic policy dfa - optional and may be NULL */
567 profile->policy.dfa = unpack_dfa(e);
568 if (IS_ERR(profile->policy.dfa)) {
569 error = PTR_ERR(profile->policy.dfa);
570 profile->policy.dfa = NULL;
571 goto fail;
572 }
573 if (!unpack_u32(e, &profile->policy.start[0], "start"))
574 /* default start state */
575 profile->policy.start[0] = DFA_START;
576 /* setup class index */
577 for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) {
578 profile->policy.start[i] =
579 aa_dfa_next(profile->policy.dfa,
580 profile->policy.start[0],
581 i);
582 }
583 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
584 goto fail;
585 }
586
562 /* get file rules */ 587 /* get file rules */
563 profile->file.dfa = unpack_dfa(e); 588 profile->file.dfa = unpack_dfa(e);
564 if (IS_ERR(profile->file.dfa)) { 589 if (IS_ERR(profile->file.dfa)) {
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index a4136c10b1c6..72c25a4f2cfd 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -23,6 +23,11 @@
23 */ 23 */
24#include "rlim_names.h" 24#include "rlim_names.h"
25 25
26struct aa_fs_entry aa_fs_entry_rlimit[] = {
27 AA_FS_FILE_STRING("mask", AA_FS_RLIMIT_MASK),
28 { }
29};
30
26/* audit callback for resource specific fields */ 31/* audit callback for resource specific fields */
27static void audit_cb(struct audit_buffer *ab, void *va) 32static void audit_cb(struct audit_buffer *ab, void *va)
28{ 33{
diff --git a/security/capability.c b/security/capability.c
index 2f680eb02b59..5bb21b1c448c 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -358,6 +358,10 @@ static int cap_task_create(unsigned long clone_flags)
358 return 0; 358 return 0;
359} 359}
360 360
361static void cap_task_free(struct task_struct *task)
362{
363}
364
361static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp) 365static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp)
362{ 366{
363 return 0; 367 return 0;
@@ -954,6 +958,7 @@ void __init security_fixup_ops(struct security_operations *ops)
954 set_to_cap_if_null(ops, file_receive); 958 set_to_cap_if_null(ops, file_receive);
955 set_to_cap_if_null(ops, dentry_open); 959 set_to_cap_if_null(ops, dentry_open);
956 set_to_cap_if_null(ops, task_create); 960 set_to_cap_if_null(ops, task_create);
961 set_to_cap_if_null(ops, task_free);
957 set_to_cap_if_null(ops, cred_alloc_blank); 962 set_to_cap_if_null(ops, cred_alloc_blank);
958 set_to_cap_if_null(ops, cred_free); 963 set_to_cap_if_null(ops, cred_free);
959 set_to_cap_if_null(ops, cred_prepare); 964 set_to_cap_if_null(ops, cred_prepare);
diff --git a/security/commoncap.c b/security/commoncap.c
index 7ce191ea29a0..0cf4b53480a7 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -28,6 +28,7 @@
28#include <linux/prctl.h> 28#include <linux/prctl.h>
29#include <linux/securebits.h> 29#include <linux/securebits.h>
30#include <linux/user_namespace.h> 30#include <linux/user_namespace.h>
31#include <linux/binfmts.h>
31 32
32/* 33/*
33 * If a non-root user executes a setuid-root binary in 34 * If a non-root user executes a setuid-root binary in
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 4f554f20dc97..35664fe6daa1 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -9,8 +9,8 @@ config IMA
9 select CRYPTO_HMAC 9 select CRYPTO_HMAC
10 select CRYPTO_MD5 10 select CRYPTO_MD5
11 select CRYPTO_SHA1 11 select CRYPTO_SHA1
12 select TCG_TPM if !S390 && !UML 12 select TCG_TPM if HAS_IOMEM && !UML
13 select TCG_TIS if TCG_TPM 13 select TCG_TIS if TCG_TPM && X86
14 help 14 help
15 The Trusted Computing Group(TCG) runtime Integrity 15 The Trusted Computing Group(TCG) runtime Integrity
16 Measurement Architecture(IMA) maintains a list of hash 16 Measurement Architecture(IMA) maintains a list of hash
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 2ad942fb1e23..21e96bf188df 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -61,6 +61,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
61 audit_log_untrustedstring(ab, inode->i_sb->s_id); 61 audit_log_untrustedstring(ab, inode->i_sb->s_id);
62 audit_log_format(ab, " ino=%lu", inode->i_ino); 62 audit_log_format(ab, " ino=%lu", inode->i_ino);
63 } 63 }
64 audit_log_format(ab, " res=%d", !result ? 0 : 1); 64 audit_log_format(ab, " res=%d", !result);
65 audit_log_end(ab); 65 audit_log_end(ab);
66} 66}
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d45061d02fee..d8edff209bf3 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -62,6 +62,7 @@ static struct ima_measure_rule_entry default_rules[] = {
62 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 62 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC}, 64 {.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
65 {.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
65 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC}, 66 {.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
66 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC}, 67 {.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
67 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC, 68 {.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
@@ -417,7 +418,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
417 if (!result && (entry->action == UNKNOWN)) 418 if (!result && (entry->action == UNKNOWN))
418 result = -EINVAL; 419 result = -EINVAL;
419 420
420 audit_log_format(ab, "res=%d", !!result); 421 audit_log_format(ab, "res=%d", !result);
421 audit_log_end(ab); 422 audit_log_end(ab);
422 return result; 423 return result;
423} 424}
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 0b3f5d72af1c..6523599e9ac0 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -388,11 +388,24 @@ long keyctl_keyring_clear(key_serial_t ringid)
388 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); 388 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
389 if (IS_ERR(keyring_ref)) { 389 if (IS_ERR(keyring_ref)) {
390 ret = PTR_ERR(keyring_ref); 390 ret = PTR_ERR(keyring_ref);
391
392 /* Root is permitted to invalidate certain special keyrings */
393 if (capable(CAP_SYS_ADMIN)) {
394 keyring_ref = lookup_user_key(ringid, 0, 0);
395 if (IS_ERR(keyring_ref))
396 goto error;
397 if (test_bit(KEY_FLAG_ROOT_CAN_CLEAR,
398 &key_ref_to_ptr(keyring_ref)->flags))
399 goto clear;
400 goto error_put;
401 }
402
391 goto error; 403 goto error;
392 } 404 }
393 405
406clear:
394 ret = keyring_clear(key_ref_to_ptr(keyring_ref)); 407 ret = keyring_clear(key_ref_to_ptr(keyring_ref));
395 408error_put:
396 key_ref_put(keyring_ref); 409 key_ref_put(keyring_ref);
397error: 410error:
398 return ret; 411 return ret;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 1068cb1939b3..be7ecb2018dd 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -657,7 +657,8 @@ try_again:
657 goto error; 657 goto error;
658 658
659 down_read(&cred->request_key_auth->sem); 659 down_read(&cred->request_key_auth->sem);
660 if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) { 660 if (test_bit(KEY_FLAG_REVOKED,
661 &cred->request_key_auth->flags)) {
661 key_ref = ERR_PTR(-EKEYREVOKED); 662 key_ref = ERR_PTR(-EKEYREVOKED);
662 key = NULL; 663 key = NULL;
663 } else { 664 } else {
diff --git a/security/security.c b/security/security.c
index d7542493454d..bf619ffc9a4d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -19,6 +19,8 @@
19#include <linux/integrity.h> 19#include <linux/integrity.h>
20#include <linux/ima.h> 20#include <linux/ima.h>
21#include <linux/evm.h> 21#include <linux/evm.h>
22#include <linux/fsnotify.h>
23#include <net/flow.h>
22 24
23#define MAX_LSM_EVM_XATTR 2 25#define MAX_LSM_EVM_XATTR 2
24 26
@@ -187,25 +189,11 @@ int security_settime(const struct timespec *ts, const struct timezone *tz)
187 return security_ops->settime(ts, tz); 189 return security_ops->settime(ts, tz);
188} 190}
189 191
190int security_vm_enough_memory(long pages)
191{
192 WARN_ON(current->mm == NULL);
193 return security_ops->vm_enough_memory(current->mm, pages);
194}
195
196int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) 192int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
197{ 193{
198 WARN_ON(mm == NULL);
199 return security_ops->vm_enough_memory(mm, pages); 194 return security_ops->vm_enough_memory(mm, pages);
200} 195}
201 196
202int security_vm_enough_memory_kern(long pages)
203{
204 /* If current->mm is a kernel thread then we will pass NULL,
205 for this specific case that is fine */
206 return security_ops->vm_enough_memory(current->mm, pages);
207}
208
209int security_bprm_set_creds(struct linux_binprm *bprm) 197int security_bprm_set_creds(struct linux_binprm *bprm)
210{ 198{
211 return security_ops->bprm_set_creds(bprm); 199 return security_ops->bprm_set_creds(bprm);
@@ -729,6 +717,11 @@ int security_task_create(unsigned long clone_flags)
729 return security_ops->task_create(clone_flags); 717 return security_ops->task_create(clone_flags);
730} 718}
731 719
720void security_task_free(struct task_struct *task)
721{
722 security_ops->task_free(task);
723}
724
732int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) 725int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
733{ 726{
734 return security_ops->cred_alloc_blank(cred, gfp); 727 return security_ops->cred_alloc_blank(cred, gfp);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6a3683e28426..304929909375 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -81,6 +81,8 @@
81#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h> 82#include <linux/user_namespace.h>
83#include <linux/export.h> 83#include <linux/export.h>
84#include <linux/msg.h>
85#include <linux/shm.h>
84 86
85#include "avc.h" 87#include "avc.h"
86#include "objsec.h" 88#include "objsec.h"
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index e8af5b0ba80f..cd667b4089a5 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -36,6 +36,9 @@
36#include <linux/magic.h> 36#include <linux/magic.h>
37#include <linux/dcache.h> 37#include <linux/dcache.h>
38#include <linux/personality.h> 38#include <linux/personality.h>
39#include <linux/msg.h>
40#include <linux/shm.h>
41#include <linux/binfmts.h>
39#include "smack.h" 42#include "smack.h"
40 43
41#define task_security(task) (task_cred_xxx((task), security)) 44#define task_security(task) (task_cred_xxx((task), security))
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index 5ca47ea3049f..7ef9fa3e37e0 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -446,11 +446,11 @@ void tomoyo_read_log(struct tomoyo_io_buffer *head)
446 * tomoyo_poll_log - Wait for an audit log. 446 * tomoyo_poll_log - Wait for an audit log.
447 * 447 *
448 * @file: Pointer to "struct file". 448 * @file: Pointer to "struct file".
449 * @wait: Pointer to "poll_table". 449 * @wait: Pointer to "poll_table". Maybe NULL.
450 * 450 *
451 * Returns POLLIN | POLLRDNORM when ready to read an audit log. 451 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
452 */ 452 */
453int tomoyo_poll_log(struct file *file, poll_table *wait) 453unsigned int tomoyo_poll_log(struct file *file, poll_table *wait)
454{ 454{
455 if (tomoyo_log_count) 455 if (tomoyo_log_count)
456 return POLLIN | POLLRDNORM; 456 return POLLIN | POLLRDNORM;
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index c47d3ce6c733..8656b16eef7b 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1069,7 +1069,7 @@ static int tomoyo_write_task(struct tomoyo_acl_param *param)
1069 * 1069 *
1070 * @domainname: The name of domain. 1070 * @domainname: The name of domain.
1071 * 1071 *
1072 * Returns 0. 1072 * Returns 0 on success, negative value otherwise.
1073 * 1073 *
1074 * Caller holds tomoyo_read_lock(). 1074 * Caller holds tomoyo_read_lock().
1075 */ 1075 */
@@ -1081,7 +1081,7 @@ static int tomoyo_delete_domain(char *domainname)
1081 name.name = domainname; 1081 name.name = domainname;
1082 tomoyo_fill_path_info(&name); 1082 tomoyo_fill_path_info(&name);
1083 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1083 if (mutex_lock_interruptible(&tomoyo_policy_lock))
1084 return 0; 1084 return -EINTR;
1085 /* Is there an active domain? */ 1085 /* Is there an active domain? */
1086 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1086 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
1087 /* Never delete tomoyo_kernel_domain */ 1087 /* Never delete tomoyo_kernel_domain */
@@ -1164,15 +1164,16 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
1164 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1164 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
1165 unsigned int profile; 1165 unsigned int profile;
1166 if (*data == '<') { 1166 if (*data == '<') {
1167 int ret = 0;
1167 domain = NULL; 1168 domain = NULL;
1168 if (is_delete) 1169 if (is_delete)
1169 tomoyo_delete_domain(data); 1170 ret = tomoyo_delete_domain(data);
1170 else if (is_select) 1171 else if (is_select)
1171 domain = tomoyo_find_domain(data); 1172 domain = tomoyo_find_domain(data);
1172 else 1173 else
1173 domain = tomoyo_assign_domain(data, false); 1174 domain = tomoyo_assign_domain(data, false);
1174 head->w.domain = domain; 1175 head->w.domain = domain;
1175 return 0; 1176 return ret;
1176 } 1177 }
1177 if (!domain) 1178 if (!domain)
1178 return -EINVAL; 1179 return -EINVAL;
@@ -2111,7 +2112,7 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
2111 struct tomoyo_domain_info *domain = NULL; 2112 struct tomoyo_domain_info *domain = NULL;
2112 spin_lock(&tomoyo_query_list_lock); 2113 spin_lock(&tomoyo_query_list_lock);
2113 list_for_each_entry(ptr, &tomoyo_query_list, list) { 2114 list_for_each_entry(ptr, &tomoyo_query_list, list) {
2114 if (ptr->serial != serial || ptr->answer) 2115 if (ptr->serial != serial)
2115 continue; 2116 continue;
2116 domain = ptr->domain; 2117 domain = ptr->domain;
2117 break; 2118 break;
@@ -2130,28 +2131,13 @@ static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
2130 * 2131 *
2131 * Waits for access requests which violated policy in enforcing mode. 2132 * Waits for access requests which violated policy in enforcing mode.
2132 */ 2133 */
2133static int tomoyo_poll_query(struct file *file, poll_table *wait) 2134static unsigned int tomoyo_poll_query(struct file *file, poll_table *wait)
2134{ 2135{
2135 struct list_head *tmp; 2136 if (!list_empty(&tomoyo_query_list))
2136 bool found = false; 2137 return POLLIN | POLLRDNORM;
2137 u8 i; 2138 poll_wait(file, &tomoyo_query_wait, wait);
2138 for (i = 0; i < 2; i++) { 2139 if (!list_empty(&tomoyo_query_list))
2139 spin_lock(&tomoyo_query_list_lock); 2140 return POLLIN | POLLRDNORM;
2140 list_for_each(tmp, &tomoyo_query_list) {
2141 struct tomoyo_query *ptr =
2142 list_entry(tmp, typeof(*ptr), list);
2143 if (ptr->answer)
2144 continue;
2145 found = true;
2146 break;
2147 }
2148 spin_unlock(&tomoyo_query_list_lock);
2149 if (found)
2150 return POLLIN | POLLRDNORM;
2151 if (i)
2152 break;
2153 poll_wait(file, &tomoyo_query_wait, wait);
2154 }
2155 return 0; 2141 return 0;
2156} 2142}
2157 2143
@@ -2175,8 +2161,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
2175 spin_lock(&tomoyo_query_list_lock); 2161 spin_lock(&tomoyo_query_list_lock);
2176 list_for_each(tmp, &tomoyo_query_list) { 2162 list_for_each(tmp, &tomoyo_query_list) {
2177 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2163 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2178 if (ptr->answer)
2179 continue;
2180 if (pos++ != head->r.query_index) 2164 if (pos++ != head->r.query_index)
2181 continue; 2165 continue;
2182 len = ptr->query_len; 2166 len = ptr->query_len;
@@ -2194,8 +2178,6 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
2194 spin_lock(&tomoyo_query_list_lock); 2178 spin_lock(&tomoyo_query_list_lock);
2195 list_for_each(tmp, &tomoyo_query_list) { 2179 list_for_each(tmp, &tomoyo_query_list) {
2196 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2180 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2197 if (ptr->answer)
2198 continue;
2199 if (pos++ != head->r.query_index) 2181 if (pos++ != head->r.query_index)
2200 continue; 2182 continue;
2201 /* 2183 /*
@@ -2243,8 +2225,10 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2243 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2225 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2244 if (ptr->serial != serial) 2226 if (ptr->serial != serial)
2245 continue; 2227 continue;
2246 if (!ptr->answer) 2228 ptr->answer = answer;
2247 ptr->answer = answer; 2229 /* Remove from tomoyo_query_list. */
2230 if (ptr->answer)
2231 list_del_init(&ptr->list);
2248 break; 2232 break;
2249 } 2233 }
2250 spin_unlock(&tomoyo_query_list_lock); 2234 spin_unlock(&tomoyo_query_list_lock);
@@ -2477,18 +2461,17 @@ int tomoyo_open_control(const u8 type, struct file *file)
2477 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. 2461 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2478 * 2462 *
2479 * @file: Pointer to "struct file". 2463 * @file: Pointer to "struct file".
2480 * @wait: Pointer to "poll_table". 2464 * @wait: Pointer to "poll_table". Maybe NULL.
2481 * 2465 *
2482 * Waits for read readiness. 2466 * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
2483 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and 2467 * POLLOUT | POLLWRNORM otherwise.
2484 * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd.
2485 */ 2468 */
2486int tomoyo_poll_control(struct file *file, poll_table *wait) 2469unsigned int tomoyo_poll_control(struct file *file, poll_table *wait)
2487{ 2470{
2488 struct tomoyo_io_buffer *head = file->private_data; 2471 struct tomoyo_io_buffer *head = file->private_data;
2489 if (!head->poll) 2472 if (head->poll)
2490 return -ENOSYS; 2473 return head->poll(file, wait) | POLLOUT | POLLWRNORM;
2491 return head->poll(file, wait); 2474 return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
2492} 2475}
2493 2476
2494/** 2477/**
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 9512222d5581..30fd98369700 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -788,7 +788,7 @@ struct tomoyo_acl_param {
788struct tomoyo_io_buffer { 788struct tomoyo_io_buffer {
789 void (*read) (struct tomoyo_io_buffer *); 789 void (*read) (struct tomoyo_io_buffer *);
790 int (*write) (struct tomoyo_io_buffer *); 790 int (*write) (struct tomoyo_io_buffer *);
791 int (*poll) (struct file *file, poll_table *wait); 791 unsigned int (*poll) (struct file *file, poll_table *wait);
792 /* Exclusive lock for this structure. */ 792 /* Exclusive lock for this structure. */
793 struct mutex io_sem; 793 struct mutex io_sem;
794 char __user *read_user_buf; 794 char __user *read_user_buf;
@@ -981,8 +981,8 @@ int tomoyo_path_number_perm(const u8 operation, struct path *path,
981 unsigned long number); 981 unsigned long number);
982int tomoyo_path_perm(const u8 operation, struct path *path, 982int tomoyo_path_perm(const u8 operation, struct path *path,
983 const char *target); 983 const char *target);
984int tomoyo_poll_control(struct file *file, poll_table *wait); 984unsigned int tomoyo_poll_control(struct file *file, poll_table *wait);
985int tomoyo_poll_log(struct file *file, poll_table *wait); 985unsigned int tomoyo_poll_log(struct file *file, poll_table *wait);
986int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr, 986int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
987 int addr_len); 987 int addr_len);
988int tomoyo_socket_connect_permission(struct socket *sock, 988int tomoyo_socket_connect_permission(struct socket *sock,
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index bee09d062057..fe00cdfd0267 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -199,30 +199,32 @@ int tomoyo_mount_permission(char *dev_name, struct path *path,
199 if (flags & MS_REMOUNT) { 199 if (flags & MS_REMOUNT) {
200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]; 200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
201 flags &= ~MS_REMOUNT; 201 flags &= ~MS_REMOUNT;
202 } 202 } else if (flags & MS_BIND) {
203 if (flags & MS_MOVE) {
204 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
205 flags &= ~MS_MOVE;
206 }
207 if (flags & MS_BIND) {
208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND]; 203 type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
209 flags &= ~MS_BIND; 204 flags &= ~MS_BIND;
210 } 205 } else if (flags & MS_SHARED) {
211 if (flags & MS_UNBINDABLE) { 206 if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
212 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; 207 return -EINVAL;
213 flags &= ~MS_UNBINDABLE; 208 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
214 } 209 flags &= ~MS_SHARED;
215 if (flags & MS_PRIVATE) { 210 } else if (flags & MS_PRIVATE) {
211 if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
212 return -EINVAL;
216 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; 213 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
217 flags &= ~MS_PRIVATE; 214 flags &= ~MS_PRIVATE;
218 } 215 } else if (flags & MS_SLAVE) {
219 if (flags & MS_SLAVE) { 216 if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
217 return -EINVAL;
220 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; 218 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
221 flags &= ~MS_SLAVE; 219 flags &= ~MS_SLAVE;
222 } 220 } else if (flags & MS_UNBINDABLE) {
223 if (flags & MS_SHARED) { 221 if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
224 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]; 222 return -EINVAL;
225 flags &= ~MS_SHARED; 223 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
224 flags &= ~MS_UNBINDABLE;
225 } else if (flags & MS_MOVE) {
226 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
227 flags &= ~MS_MOVE;
226 } 228 }
227 if (!type) 229 if (!type)
228 type = "<NULL>"; 230 type = "<NULL>";
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index 482b2a5f48f0..8592f2fc6ebb 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -157,9 +157,10 @@ static int tomoyo_release(struct inode *inode, struct file *file)
157 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface. 157 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
158 * 158 *
159 * @file: Pointer to "struct file". 159 * @file: Pointer to "struct file".
160 * @wait: Pointer to "poll_table". 160 * @wait: Pointer to "poll_table". Maybe NULL.
161 * 161 *
162 * Returns 0 on success, negative value otherwise. 162 * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
163 * POLLOUT | POLLWRNORM otherwise.
163 */ 164 */
164static unsigned int tomoyo_poll(struct file *file, poll_table *wait) 165static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
165{ 166{
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
new file mode 100644
index 000000000000..51d6709d8bbd
--- /dev/null
+++ b/security/yama/Kconfig
@@ -0,0 +1,13 @@
1config SECURITY_YAMA
2 bool "Yama support"
3 depends on SECURITY
4 select SECURITYFS
5 select SECURITY_PATH
6 default n
7 help
8 This selects Yama, which extends DAC support with additional
9 system-wide security settings beyond regular Linux discretionary
10 access controls. Currently available is ptrace scope restriction.
11 Further information can be found in Documentation/security/Yama.txt.
12
13 If you are unsure how to answer this question, answer N.
diff --git a/security/yama/Makefile b/security/yama/Makefile
new file mode 100644
index 000000000000..8b5e06588456
--- /dev/null
+++ b/security/yama/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_SECURITY_YAMA) := yama.o
2
3yama-y := yama_lsm.o
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
new file mode 100644
index 000000000000..573723843a04
--- /dev/null
+++ b/security/yama/yama_lsm.c
@@ -0,0 +1,323 @@
1/*
2 * Yama Linux Security Module
3 *
4 * Author: Kees Cook <keescook@chromium.org>
5 *
6 * Copyright (C) 2010 Canonical, Ltd.
7 * Copyright (C) 2011 The Chromium OS Authors.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/security.h>
16#include <linux/sysctl.h>
17#include <linux/ptrace.h>
18#include <linux/prctl.h>
19#include <linux/ratelimit.h>
20
21static int ptrace_scope = 1;
22
23/* describe a ptrace relationship for potential exception */
24struct ptrace_relation {
25 struct task_struct *tracer;
26 struct task_struct *tracee;
27 struct list_head node;
28};
29
30static LIST_HEAD(ptracer_relations);
31static DEFINE_SPINLOCK(ptracer_relations_lock);
32
33/**
34 * yama_ptracer_add - add/replace an exception for this tracer/tracee pair
35 * @tracer: the task_struct of the process doing the ptrace
36 * @tracee: the task_struct of the process to be ptraced
37 *
38 * Each tracee can have, at most, one tracer registered. Each time this
39 * is called, the prior registered tracer will be replaced for the tracee.
40 *
41 * Returns 0 if relationship was added, -ve on error.
42 */
43static int yama_ptracer_add(struct task_struct *tracer,
44 struct task_struct *tracee)
45{
46 int rc = 0;
47 struct ptrace_relation *added;
48 struct ptrace_relation *entry, *relation = NULL;
49
50 added = kmalloc(sizeof(*added), GFP_KERNEL);
51 if (!added)
52 return -ENOMEM;
53
54 spin_lock_bh(&ptracer_relations_lock);
55 list_for_each_entry(entry, &ptracer_relations, node)
56 if (entry->tracee == tracee) {
57 relation = entry;
58 break;
59 }
60 if (!relation) {
61 relation = added;
62 relation->tracee = tracee;
63 list_add(&relation->node, &ptracer_relations);
64 }
65 relation->tracer = tracer;
66
67 spin_unlock_bh(&ptracer_relations_lock);
68 if (added != relation)
69 kfree(added);
70
71 return rc;
72}
73
74/**
75 * yama_ptracer_del - remove exceptions related to the given tasks
76 * @tracer: remove any relation where tracer task matches
77 * @tracee: remove any relation where tracee task matches
78 */
79static void yama_ptracer_del(struct task_struct *tracer,
80 struct task_struct *tracee)
81{
82 struct ptrace_relation *relation, *safe;
83
84 spin_lock_bh(&ptracer_relations_lock);
85 list_for_each_entry_safe(relation, safe, &ptracer_relations, node)
86 if (relation->tracee == tracee ||
87 (tracer && relation->tracer == tracer)) {
88 list_del(&relation->node);
89 kfree(relation);
90 }
91 spin_unlock_bh(&ptracer_relations_lock);
92}
93
94/**
95 * yama_task_free - check for task_pid to remove from exception list
96 * @task: task being removed
97 */
98static void yama_task_free(struct task_struct *task)
99{
100 yama_ptracer_del(task, task);
101}
102
103/**
104 * yama_task_prctl - check for Yama-specific prctl operations
105 * @option: operation
106 * @arg2: argument
107 * @arg3: argument
108 * @arg4: argument
109 * @arg5: argument
110 *
111 * Return 0 on success, -ve on error. -ENOSYS is returned when Yama
112 * does not handle the given option.
113 */
114static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
115 unsigned long arg4, unsigned long arg5)
116{
117 int rc;
118 struct task_struct *myself = current;
119
120 rc = cap_task_prctl(option, arg2, arg3, arg4, arg5);
121 if (rc != -ENOSYS)
122 return rc;
123
124 switch (option) {
125 case PR_SET_PTRACER:
126 /* Since a thread can call prctl(), find the group leader
127 * before calling _add() or _del() on it, since we want
128 * process-level granularity of control. The tracer group
129 * leader checking is handled later when walking the ancestry
130 * at the time of PTRACE_ATTACH check.
131 */
132 rcu_read_lock();
133 if (!thread_group_leader(myself))
134 myself = rcu_dereference(myself->group_leader);
135 get_task_struct(myself);
136 rcu_read_unlock();
137
138 if (arg2 == 0) {
139 yama_ptracer_del(NULL, myself);
140 rc = 0;
141 } else if (arg2 == PR_SET_PTRACER_ANY) {
142 rc = yama_ptracer_add(NULL, myself);
143 } else {
144 struct task_struct *tracer;
145
146 rcu_read_lock();
147 tracer = find_task_by_vpid(arg2);
148 if (tracer)
149 get_task_struct(tracer);
150 else
151 rc = -EINVAL;
152 rcu_read_unlock();
153
154 if (tracer) {
155 rc = yama_ptracer_add(tracer, myself);
156 put_task_struct(tracer);
157 }
158 }
159
160 put_task_struct(myself);
161 break;
162 }
163
164 return rc;
165}
166
167/**
168 * task_is_descendant - walk up a process family tree looking for a match
169 * @parent: the process to compare against while walking up from child
170 * @child: the process to start from while looking upwards for parent
171 *
172 * Returns 1 if child is a descendant of parent, 0 if not.
173 */
174static int task_is_descendant(struct task_struct *parent,
175 struct task_struct *child)
176{
177 int rc = 0;
178 struct task_struct *walker = child;
179
180 if (!parent || !child)
181 return 0;
182
183 rcu_read_lock();
184 if (!thread_group_leader(parent))
185 parent = rcu_dereference(parent->group_leader);
186 while (walker->pid > 0) {
187 if (!thread_group_leader(walker))
188 walker = rcu_dereference(walker->group_leader);
189 if (walker == parent) {
190 rc = 1;
191 break;
192 }
193 walker = rcu_dereference(walker->real_parent);
194 }
195 rcu_read_unlock();
196
197 return rc;
198}
199
200/**
201 * ptracer_exception_found - tracer registered as exception for this tracee
202 * @tracer: the task_struct of the process attempting ptrace
203 * @tracee: the task_struct of the process to be ptraced
204 *
205 * Returns 1 if tracer has is ptracer exception ancestor for tracee.
206 */
207static int ptracer_exception_found(struct task_struct *tracer,
208 struct task_struct *tracee)
209{
210 int rc = 0;
211 struct ptrace_relation *relation;
212 struct task_struct *parent = NULL;
213 bool found = false;
214
215 spin_lock_bh(&ptracer_relations_lock);
216 rcu_read_lock();
217 if (!thread_group_leader(tracee))
218 tracee = rcu_dereference(tracee->group_leader);
219 list_for_each_entry(relation, &ptracer_relations, node)
220 if (relation->tracee == tracee) {
221 parent = relation->tracer;
222 found = true;
223 break;
224 }
225
226 if (found && (parent == NULL || task_is_descendant(parent, tracer)))
227 rc = 1;
228 rcu_read_unlock();
229 spin_unlock_bh(&ptracer_relations_lock);
230
231 return rc;
232}
233
234/**
235 * yama_ptrace_access_check - validate PTRACE_ATTACH calls
236 * @child: task that current task is attempting to ptrace
237 * @mode: ptrace attach mode
238 *
239 * Returns 0 if following the ptrace is allowed, -ve on error.
240 */
241static int yama_ptrace_access_check(struct task_struct *child,
242 unsigned int mode)
243{
244 int rc;
245
246 /* If standard caps disallows it, so does Yama. We should
247 * only tighten restrictions further.
248 */
249 rc = cap_ptrace_access_check(child, mode);
250 if (rc)
251 return rc;
252
253 /* require ptrace target be a child of ptracer on attach */
254 if (mode == PTRACE_MODE_ATTACH &&
255 ptrace_scope &&
256 !task_is_descendant(current, child) &&
257 !ptracer_exception_found(current, child) &&
258 !capable(CAP_SYS_PTRACE))
259 rc = -EPERM;
260
261 if (rc) {
262 char name[sizeof(current->comm)];
263 printk_ratelimited(KERN_NOTICE "ptrace of non-child"
264 " pid %d was attempted by: %s (pid %d)\n",
265 child->pid,
266 get_task_comm(name, current),
267 current->pid);
268 }
269
270 return rc;
271}
272
273static struct security_operations yama_ops = {
274 .name = "yama",
275
276 .ptrace_access_check = yama_ptrace_access_check,
277 .task_prctl = yama_task_prctl,
278 .task_free = yama_task_free,
279};
280
281#ifdef CONFIG_SYSCTL
282static int zero;
283static int one = 1;
284
285struct ctl_path yama_sysctl_path[] = {
286 { .procname = "kernel", },
287 { .procname = "yama", },
288 { }
289};
290
291static struct ctl_table yama_sysctl_table[] = {
292 {
293 .procname = "ptrace_scope",
294 .data = &ptrace_scope,
295 .maxlen = sizeof(int),
296 .mode = 0644,
297 .proc_handler = proc_dointvec_minmax,
298 .extra1 = &zero,
299 .extra2 = &one,
300 },
301 { }
302};
303#endif /* CONFIG_SYSCTL */
304
305static __init int yama_init(void)
306{
307 if (!security_module_enable(&yama_ops))
308 return 0;
309
310 printk(KERN_INFO "Yama: becoming mindful.\n");
311
312 if (register_security(&yama_ops))
313 panic("Yama: kernel registration failed.\n");
314
315#ifdef CONFIG_SYSCTL
316 if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
317 panic("Yama: sysctl registration failed.\n");
318#endif
319
320 return 0;
321}
322
323security_initcall(yama_init);