aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 03:45:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 03:45:31 -0400
commit36b8d186e6cc8e32cb5227f5645a58e1bc0af190 (patch)
tree1000ad26e189e6ff2c53fb7eeff605f59c7ad94e
parentcd85b557414fe4cd44ea6608825e96612a5fe2b2 (diff)
parentc45ed235abf1b0b6666417e3c394f18717976acd (diff)
Merge branch 'next' of git://selinuxproject.org/~jmorris/linux-security
* 'next' of git://selinuxproject.org/~jmorris/linux-security: (95 commits) TOMOYO: Fix incomplete read after seek. Smack: allow to access /smack/access as normal user TOMOYO: Fix unused kernel config option. Smack: fix: invalid length set for the result of /smack/access Smack: compilation fix Smack: fix for /smack/access output, use string instead of byte Smack: domain transition protections (v3) Smack: Provide information for UDS getsockopt(SO_PEERCRED) Smack: Clean up comments Smack: Repair processing of fcntl Smack: Rule list lookup performance Smack: check permissions from user space (v2) TOMOYO: Fix quota and garbage collector. TOMOYO: Remove redundant tasklist_lock. TOMOYO: Fix domain transition failure warning. TOMOYO: Remove tomoyo_policy_memory_lock spinlock. TOMOYO: Simplify garbage collector. TOMOYO: Fix make namespacecheck warnings. target: check hex2bin result encrypted-keys: check hex2bin result ...
-rw-r--r--Documentation/ABI/testing/evm23
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/target/target_core_fabric_lib.c12
-rw-r--r--fs/attr.c5
-rw-r--r--fs/btrfs/xattr.c50
-rw-r--r--fs/cifs/xattr.c40
-rw-r--r--fs/ext2/xattr_security.c34
-rw-r--r--fs/ext3/xattr_security.c36
-rw-r--r--fs/ext4/xattr_security.c36
-rw-r--r--fs/gfs2/inode.c38
-rw-r--r--fs/jffs2/security.c35
-rw-r--r--fs/jfs/xattr.c57
-rw-r--r--fs/ocfs2/xattr.c38
-rw-r--r--fs/reiserfs/xattr_security.c4
-rw-r--r--fs/xattr.c63
-rw-r--r--fs/xfs/xfs_iops.c39
-rw-r--r--include/linux/evm.h100
-rw-r--r--include/linux/ima.h13
-rw-r--r--include/linux/integrity.h39
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/security.h32
-rw-r--r--include/linux/xattr.h19
-rw-r--r--kernel/cred.c18
-rw-r--r--lib/hexdump.c15
-rw-r--r--mm/shmem.c4
-rw-r--r--security/Kconfig6
-rw-r--r--security/Makefile4
-rw-r--r--security/apparmor/apparmorfs.c2
-rw-r--r--security/apparmor/ipc.c1
-rw-r--r--security/apparmor/lib.c1
-rw-r--r--security/apparmor/policy_unpack.c12
-rw-r--r--security/apparmor/procattr.c1
-rw-r--r--security/commoncap.c16
-rw-r--r--security/integrity/Kconfig7
-rw-r--r--security/integrity/Makefile12
-rw-r--r--security/integrity/evm/Kconfig13
-rw-r--r--security/integrity/evm/Makefile7
-rw-r--r--security/integrity/evm/evm.h38
-rw-r--r--security/integrity/evm/evm_crypto.c216
-rw-r--r--security/integrity/evm/evm_main.c384
-rw-r--r--security/integrity/evm/evm_posix_acl.c26
-rw-r--r--security/integrity/evm/evm_secfs.c108
-rw-r--r--security/integrity/iint.c172
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/Makefile2
-rw-r--r--security/integrity/ima/ima.h30
-rw-r--r--security/integrity/ima/ima_api.c7
-rw-r--r--security/integrity/ima/ima_fs.c2
-rw-r--r--security/integrity/ima/ima_iint.c169
-rw-r--r--security/integrity/ima/ima_main.c13
-rw-r--r--security/integrity/integrity.h50
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/encrypted-keys/Makefile6
-rw-r--r--security/keys/encrypted-keys/ecryptfs_format.c (renamed from security/keys/ecryptfs_format.c)0
-rw-r--r--security/keys/encrypted-keys/ecryptfs_format.h (renamed from security/keys/ecryptfs_format.h)0
-rw-r--r--security/keys/encrypted-keys/encrypted.c (renamed from security/keys/encrypted.c)49
-rw-r--r--security/keys/encrypted-keys/encrypted.h (renamed from security/keys/encrypted.h)11
-rw-r--r--security/keys/encrypted-keys/masterkey_trusted.c45
-rw-r--r--security/keys/gc.c386
-rw-r--r--security/keys/internal.h4
-rw-r--r--security/keys/key.c121
-rw-r--r--security/keys/keyring.c3
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/trusted.c19
-rw-r--r--security/security.c76
-rw-r--r--security/selinux/exports.c1
-rw-r--r--security/selinux/hooks.c13
-rw-r--r--security/selinux/include/avc_ss.h6
-rw-r--r--security/selinux/include/security.h8
-rw-r--r--security/selinux/netlink.c2
-rw-r--r--security/selinux/nlmsgtab.c1
-rw-r--r--security/selinux/selinuxfs.c5
-rw-r--r--security/selinux/ss/conditional.c2
-rw-r--r--security/selinux/ss/conditional.h1
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c3
-rw-r--r--security/smack/smack.h24
-rw-r--r--security/smack/smack_access.c134
-rw-r--r--security/smack/smack_lsm.c266
-rw-r--r--security/smack/smackfs.c277
-rw-r--r--security/tomoyo/Kconfig2
-rw-r--r--security/tomoyo/Makefile4
-rw-r--r--security/tomoyo/audit.c7
-rw-r--r--security/tomoyo/common.c228
-rw-r--r--security/tomoyo/common.h189
-rw-r--r--security/tomoyo/condition.c71
-rw-r--r--security/tomoyo/domain.c209
-rw-r--r--security/tomoyo/environ.c122
-rw-r--r--security/tomoyo/file.c42
-rw-r--r--security/tomoyo/gc.c540
-rw-r--r--security/tomoyo/group.c61
-rw-r--r--security/tomoyo/memory.c39
-rw-r--r--security/tomoyo/network.c771
-rw-r--r--security/tomoyo/realpath.c32
-rw-r--r--security/tomoyo/securityfs_if.c123
-rw-r--r--security/tomoyo/tomoyo.c62
-rw-r--r--security/tomoyo/util.c80
99 files changed, 4701 insertions, 1432 deletions
diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm
new file mode 100644
index 000000000000..8374d4557e5d
--- /dev/null
+++ b/Documentation/ABI/testing/evm
@@ -0,0 +1,23 @@
1What: security/evm
2Date: March 2011
3Contact: Mimi Zohar <zohar@us.ibm.com>
4Description:
5 EVM protects a file's security extended attributes(xattrs)
6 against integrity attacks. The initial method maintains an
7 HMAC-sha1 value across the extended attributes, storing the
8 value as the extended attribute 'security.evm'.
9
10 EVM depends on the Kernel Key Retention System to provide it
11 with a trusted/encrypted key for the HMAC-sha1 operation.
12 The key is loaded onto the root's keyring using keyctl. Until
13 EVM receives notification that the key has been successfully
14 loaded onto the keyring (echo 1 > <securityfs>/evm), EVM
15 can not create or validate the 'security.evm' xattr, but
16 returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM
17 should be done as early as possible. Normally this is done
18 in the initramfs, which has already been measured as part
19 of the trusted boot. For more information on creating and
20 loading existing trusted/encrypted keys, refer to:
21 Documentation/keys-trusted-encrypted.txt. (A sample dracut
22 patch, which loads the trusted/encrypted key and enables
23 EVM, is available from http://linux-ima.sourceforge.net/#EVM.)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d6e6724446c8..d317f6cf0d35 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -49,6 +49,7 @@ parameter is applicable:
49 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled 49 EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
50 EFI EFI Partitioning (GPT) is enabled 50 EFI EFI Partitioning (GPT) is enabled
51 EIDE EIDE/ATAPI support is enabled. 51 EIDE EIDE/ATAPI support is enabled.
52 EVM Extended Verification Module
52 FB The frame buffer device is enabled. 53 FB The frame buffer device is enabled.
53 FTRACE Function tracing enabled. 54 FTRACE Function tracing enabled.
54 GCOV GCOV profiling is enabled. 55 GCOV GCOV profiling is enabled.
@@ -760,6 +761,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
760 This option is obsoleted by the "netdev=" option, which 761 This option is obsoleted by the "netdev=" option, which
761 has equivalent usage. See its documentation for details. 762 has equivalent usage. See its documentation for details.
762 763
764 evm= [EVM]
765 Format: { "fix" }
766 Permit 'security.evm' to be updated regardless of
767 current integrity status.
768
763 failslab= 769 failslab=
764 fail_page_alloc= 770 fail_page_alloc=
765 fail_make_request=[KNL] 771 fail_make_request=[KNL]
diff --git a/MAINTAINERS b/MAINTAINERS
index 6185d0513584..51a8160dc549 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2552,6 +2552,11 @@ S: Maintained
2552F: Documentation/filesystems/ext4.txt 2552F: Documentation/filesystems/ext4.txt
2553F: fs/ext4/ 2553F: fs/ext4/
2554 2554
2555Extended Verification Module (EVM)
2556M: Mimi Zohar <zohar@us.ibm.com>
2557S: Supported
2558F: security/integrity/evm/
2559
2555F71805F HARDWARE MONITORING DRIVER 2560F71805F HARDWARE MONITORING DRIVER
2556M: Jean Delvare <khali@linux-fr.org> 2561M: Jean Delvare <khali@linux-fr.org>
2557L: lm-sensors@lm-sensors.org 2562L: lm-sensors@lm-sensors.org
@@ -6447,7 +6452,7 @@ L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for users in English)
6447L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) 6452L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
6448L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) 6453L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
6449W: http://tomoyo.sourceforge.jp/ 6454W: http://tomoyo.sourceforge.jp/
6450T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.4.x/tomoyo-lsm/patches/ 6455T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.5.x/tomoyo-lsm/patches/
6451S: Maintained 6456S: Maintained
6452F: security/tomoyo/ 6457F: security/tomoyo/
6453 6458
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9ca5c021d0b6..361a1dff8f77 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -966,6 +966,9 @@ ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr,
966{ 966{
967 struct tpm_chip *chip = dev_get_drvdata(dev); 967 struct tpm_chip *chip = dev_get_drvdata(dev);
968 968
969 if (chip->vendor.duration[TPM_LONG] == 0)
970 return 0;
971
969 return sprintf(buf, "%d %d %d [%s]\n", 972 return sprintf(buf, "%d %d %d [%s]\n",
970 jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), 973 jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
971 jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), 974 jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index c4ea3a9a555b..39f021b855ef 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -63,6 +63,7 @@ u32 sas_get_pr_transport_id(
63 unsigned char *buf) 63 unsigned char *buf)
64{ 64{
65 unsigned char *ptr; 65 unsigned char *ptr;
66 int ret;
66 67
67 /* 68 /*
68 * Set PROTOCOL IDENTIFIER to 6h for SAS 69 * Set PROTOCOL IDENTIFIER to 6h for SAS
@@ -74,7 +75,9 @@ u32 sas_get_pr_transport_id(
74 */ 75 */
75 ptr = &se_nacl->initiatorname[4]; /* Skip over 'naa. prefix */ 76 ptr = &se_nacl->initiatorname[4]; /* Skip over 'naa. prefix */
76 77
77 hex2bin(&buf[4], ptr, 8); 78 ret = hex2bin(&buf[4], ptr, 8);
79 if (ret < 0)
80 pr_debug("sas transport_id: invalid hex string\n");
78 81
79 /* 82 /*
80 * The SAS Transport ID is a hardcoded 24-byte length 83 * The SAS Transport ID is a hardcoded 24-byte length
@@ -156,8 +159,9 @@ u32 fc_get_pr_transport_id(
156 unsigned char *buf) 159 unsigned char *buf)
157{ 160{
158 unsigned char *ptr; 161 unsigned char *ptr;
159 int i; 162 int i, ret;
160 u32 off = 8; 163 u32 off = 8;
164
161 /* 165 /*
162 * PROTOCOL IDENTIFIER is 0h for FCP-2 166 * PROTOCOL IDENTIFIER is 0h for FCP-2
163 * 167 *
@@ -174,7 +178,9 @@ u32 fc_get_pr_transport_id(
174 i++; 178 i++;
175 continue; 179 continue;
176 } 180 }
177 hex2bin(&buf[off++], &ptr[i], 1); 181 ret = hex2bin(&buf[off++], &ptr[i], 1);
182 if (ret < 0)
183 pr_debug("fc transport_id: invalid hex string\n");
178 i += 2; 184 i += 2;
179 } 185 }
180 /* 186 /*
diff --git a/fs/attr.c b/fs/attr.c
index 538e27959d3f..7ee7ba488313 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -13,6 +13,7 @@
13#include <linux/fsnotify.h> 13#include <linux/fsnotify.h>
14#include <linux/fcntl.h> 14#include <linux/fcntl.h>
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/evm.h>
16 17
17/** 18/**
18 * inode_change_ok - check if attribute changes to an inode are allowed 19 * inode_change_ok - check if attribute changes to an inode are allowed
@@ -237,8 +238,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
237 else 238 else
238 error = simple_setattr(dentry, attr); 239 error = simple_setattr(dentry, attr);
239 240
240 if (!error) 241 if (!error) {
241 fsnotify_change(dentry, ia_valid); 242 fsnotify_change(dentry, ia_valid);
243 evm_inode_post_setattr(dentry, ia_valid);
244 }
242 245
243 return error; 246 return error;
244} 247}
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 69565e5fc6a0..426aa464f1af 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -383,36 +383,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
383 XATTR_REPLACE); 383 XATTR_REPLACE);
384} 384}
385 385
386int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, 386int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
387 struct inode *inode, struct inode *dir, 387 void *fs_info)
388 const struct qstr *qstr)
389{ 388{
390 int err; 389 const struct xattr *xattr;
391 size_t len; 390 struct btrfs_trans_handle *trans = fs_info;
392 void *value;
393 char *suffix;
394 char *name; 391 char *name;
392 int err = 0;
395 393
396 err = security_inode_init_security(inode, dir, qstr, &suffix, &value, 394 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
397 &len); 395 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
398 if (err) { 396 strlen(xattr->name) + 1, GFP_NOFS);
399 if (err == -EOPNOTSUPP) 397 if (!name) {
400 return 0; 398 err = -ENOMEM;
401 return err; 399 break;
402 } 400 }
403
404 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
405 GFP_NOFS);
406 if (!name) {
407 err = -ENOMEM;
408 } else {
409 strcpy(name, XATTR_SECURITY_PREFIX); 401 strcpy(name, XATTR_SECURITY_PREFIX);
410 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 402 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
411 err = __btrfs_setxattr(trans, inode, name, value, len, 0); 403 err = __btrfs_setxattr(trans, inode, name,
404 xattr->value, xattr->value_len, 0);
412 kfree(name); 405 kfree(name);
406 if (err < 0)
407 break;
413 } 408 }
414
415 kfree(suffix);
416 kfree(value);
417 return err; 409 return err;
418} 410}
411
412int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
413 struct inode *inode, struct inode *dir,
414 const struct qstr *qstr)
415{
416 return security_inode_init_security(inode, dir, qstr,
417 &btrfs_initxattrs, trans);
418}
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 2a22fb2989e4..c32308882148 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -22,6 +22,7 @@
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/posix_acl_xattr.h> 23#include <linux/posix_acl_xattr.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/xattr.h>
25#include "cifsfs.h" 26#include "cifsfs.h"
26#include "cifspdu.h" 27#include "cifspdu.h"
27#include "cifsglob.h" 28#include "cifsglob.h"
@@ -31,16 +32,8 @@
31#define MAX_EA_VALUE_SIZE 65535 32#define MAX_EA_VALUE_SIZE 65535
32#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib" 33#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
33#define CIFS_XATTR_CIFS_ACL "system.cifs_acl" 34#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
34#define CIFS_XATTR_USER_PREFIX "user."
35#define CIFS_XATTR_SYSTEM_PREFIX "system."
36#define CIFS_XATTR_OS2_PREFIX "os2."
37#define CIFS_XATTR_SECURITY_PREFIX "security."
38#define CIFS_XATTR_TRUSTED_PREFIX "trusted."
39#define XATTR_TRUSTED_PREFIX_LEN 8
40#define XATTR_SECURITY_PREFIX_LEN 9
41/* BB need to add server (Samba e.g) support for security and trusted prefix */
42
43 35
36/* BB need to add server (Samba e.g) support for security and trusted prefix */
44 37
45int cifs_removexattr(struct dentry *direntry, const char *ea_name) 38int cifs_removexattr(struct dentry *direntry, const char *ea_name)
46{ 39{
@@ -76,8 +69,8 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
76 } 69 }
77 if (ea_name == NULL) { 70 if (ea_name == NULL) {
78 cFYI(1, "Null xattr names not supported"); 71 cFYI(1, "Null xattr names not supported");
79 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) 72 } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
80 && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) { 73 && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) {
81 cFYI(1, 74 cFYI(1,
82 "illegal xattr request %s (only user namespace supported)", 75 "illegal xattr request %s (only user namespace supported)",
83 ea_name); 76 ea_name);
@@ -88,7 +81,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
88 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 81 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
89 goto remove_ea_exit; 82 goto remove_ea_exit;
90 83
91 ea_name += 5; /* skip past user. prefix */ 84 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
92 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL, 85 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
93 (__u16)0, cifs_sb->local_nls, 86 (__u16)0, cifs_sb->local_nls,
94 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 87 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -149,21 +142,23 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
149 142
150 if (ea_name == NULL) { 143 if (ea_name == NULL) {
151 cFYI(1, "Null xattr names not supported"); 144 cFYI(1, "Null xattr names not supported");
152 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { 145 } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
146 == 0) {
153 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 147 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
154 goto set_ea_exit; 148 goto set_ea_exit;
155 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) 149 if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
156 cFYI(1, "attempt to set cifs inode metadata"); 150 cFYI(1, "attempt to set cifs inode metadata");
157 151
158 ea_name += 5; /* skip past user. prefix */ 152 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
159 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, 153 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
160 (__u16)value_size, cifs_sb->local_nls, 154 (__u16)value_size, cifs_sb->local_nls,
161 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 155 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
162 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) { 156 } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)
157 == 0) {
163 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 158 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
164 goto set_ea_exit; 159 goto set_ea_exit;
165 160
166 ea_name += 4; /* skip past os2. prefix */ 161 ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
167 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, 162 rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
168 (__u16)value_size, cifs_sb->local_nls, 163 (__u16)value_size, cifs_sb->local_nls,
169 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 164 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -269,7 +264,8 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
269 /* return alt name if available as pseudo attr */ 264 /* return alt name if available as pseudo attr */
270 if (ea_name == NULL) { 265 if (ea_name == NULL) {
271 cFYI(1, "Null xattr names not supported"); 266 cFYI(1, "Null xattr names not supported");
272 } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { 267 } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
268 == 0) {
273 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 269 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
274 goto get_ea_exit; 270 goto get_ea_exit;
275 271
@@ -277,15 +273,15 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
277 cFYI(1, "attempt to query cifs inode metadata"); 273 cFYI(1, "attempt to query cifs inode metadata");
278 /* revalidate/getattr then populate from inode */ 274 /* revalidate/getattr then populate from inode */
279 } /* BB add else when above is implemented */ 275 } /* BB add else when above is implemented */
280 ea_name += 5; /* skip past user. prefix */ 276 ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
281 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value, 277 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
282 buf_size, cifs_sb->local_nls, 278 buf_size, cifs_sb->local_nls,
283 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 279 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
284 } else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) { 280 } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
285 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 281 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
286 goto get_ea_exit; 282 goto get_ea_exit;
287 283
288 ea_name += 4; /* skip past os2. prefix */ 284 ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
289 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value, 285 rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
290 buf_size, cifs_sb->local_nls, 286 buf_size, cifs_sb->local_nls,
291 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 287 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -339,10 +335,10 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
339 cFYI(1, "Query CIFS ACL not supported yet"); 335 cFYI(1, "Query CIFS ACL not supported yet");
340#endif /* CONFIG_CIFS_ACL */ 336#endif /* CONFIG_CIFS_ACL */
341 } else if (strncmp(ea_name, 337 } else if (strncmp(ea_name,
342 CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) { 338 XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
343 cFYI(1, "Trusted xattr namespace not supported yet"); 339 cFYI(1, "Trusted xattr namespace not supported yet");
344 } else if (strncmp(ea_name, 340 } else if (strncmp(ea_name,
345 CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) { 341 XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
346 cFYI(1, "Security xattr namespace not supported yet"); 342 cFYI(1, "Security xattr namespace not supported yet");
347 } else 343 } else
348 cFYI(1, 344 cFYI(1,
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 5d979b4347b0..c922adc8ef41 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
46 value, size, flags); 46 value, size, flags);
47} 47}
48 48
49int 49int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
50ext2_init_security(struct inode *inode, struct inode *dir, 50 void *fs_info)
51 const struct qstr *qstr)
52{ 51{
53 int err; 52 const struct xattr *xattr;
54 size_t len; 53 int err = 0;
55 void *value;
56 char *name;
57 54
58 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 55 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
59 if (err) { 56 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
60 if (err == -EOPNOTSUPP) 57 xattr->name, xattr->value,
61 return 0; 58 xattr->value_len, 0);
62 return err; 59 if (err < 0)
60 break;
63 } 61 }
64 err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
65 name, value, len, 0);
66 kfree(name);
67 kfree(value);
68 return err; 62 return err;
69} 63}
70 64
65int
66ext2_init_security(struct inode *inode, struct inode *dir,
67 const struct qstr *qstr)
68{
69 return security_inode_init_security(inode, dir, qstr,
70 &ext2_initxattrs, NULL);
71}
72
71const struct xattr_handler ext2_xattr_security_handler = { 73const struct xattr_handler ext2_xattr_security_handler = {
72 .prefix = XATTR_SECURITY_PREFIX, 74 .prefix = XATTR_SECURITY_PREFIX,
73 .list = ext2_xattr_security_list, 75 .list = ext2_xattr_security_list,
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b8d9f83aa5c5..3c218b8a51d4 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext3_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT3_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 65 }
66 err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
67 name, value, len, 0);
68 kfree(name);
69 kfree(value);
70 return err; 66 return err;
71} 67}
72 68
69int
70ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext3_initxattrs, handle);
75}
76
73const struct xattr_handler ext3_xattr_security_handler = { 77const struct xattr_handler ext3_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext3_xattr_security_list, 79 .list = ext3_xattr_security_list,
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 007c3bfbf094..34e4350dd4d9 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
48 name, value, size, flags); 48 name, value, size, flags);
49} 49}
50 50
51int 51int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
52ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, 52 void *fs_info)
53 const struct qstr *qstr)
54{ 53{
55 int err; 54 const struct xattr *xattr;
56 size_t len; 55 handle_t *handle = fs_info;
57 void *value; 56 int err = 0;
58 char *name;
59 57
60 err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 58 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
61 if (err) { 59 err = ext4_xattr_set_handle(handle, inode,
62 if (err == -EOPNOTSUPP) 60 EXT4_XATTR_INDEX_SECURITY,
63 return 0; 61 xattr->name, xattr->value,
64 return err; 62 xattr->value_len, 0);
63 if (err < 0)
64 break;
65 } 65 }
66 err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
67 name, value, len, 0);
68 kfree(name);
69 kfree(value);
70 return err; 66 return err;
71} 67}
72 68
69int
70ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
71 const struct qstr *qstr)
72{
73 return security_inode_init_security(inode, dir, qstr,
74 &ext4_initxattrs, handle);
75}
76
73const struct xattr_handler ext4_xattr_security_handler = { 77const struct xattr_handler ext4_xattr_security_handler = {
74 .prefix = XATTR_SECURITY_PREFIX, 78 .prefix = XATTR_SECURITY_PREFIX,
75 .list = ext4_xattr_security_list, 79 .list = ext4_xattr_security_list,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 900cf986aadc..6525b804d5ec 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -624,31 +624,29 @@ fail:
624 return error; 624 return error;
625} 625}
626 626
627static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, 627int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
628 const struct qstr *qstr) 628 void *fs_info)
629{ 629{
630 int err; 630 const struct xattr *xattr;
631 size_t len; 631 int err = 0;
632 void *value; 632
633 char *name; 633 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
634 634 err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
635 err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, 635 xattr->value_len, 0,
636 &name, &value, &len); 636 GFS2_EATYPE_SECURITY);
637 637 if (err < 0)
638 if (err) { 638 break;
639 if (err == -EOPNOTSUPP)
640 return 0;
641 return err;
642 } 639 }
643
644 err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0,
645 GFS2_EATYPE_SECURITY);
646 kfree(value);
647 kfree(name);
648
649 return err; 640 return err;
650} 641}
651 642
643static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
644 const struct qstr *qstr)
645{
646 return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
647 &gfs2_initxattrs, NULL);
648}
649
652/** 650/**
653 * gfs2_create_inode - Create a new inode 651 * gfs2_create_inode - Create a new inode
654 * @dir: The parent directory 652 * @dir: The parent directory
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index cfeb7164b085..0f20208df602 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -22,26 +22,29 @@
22#include <linux/security.h> 22#include <linux/security.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
25/* ---- Initial Security Label Attachment -------------- */ 25/* ---- Initial Security Label(s) Attachment callback --- */
26int jffs2_init_security(struct inode *inode, struct inode *dir, 26int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
27 const struct qstr *qstr) 27 void *fs_info)
28{ 28{
29 int rc; 29 const struct xattr *xattr;
30 size_t len; 30 int err = 0;
31 void *value;
32 char *name;
33 31
34 rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); 32 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
35 if (rc) { 33 err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
36 if (rc == -EOPNOTSUPP) 34 xattr->name, xattr->value,
37 return 0; 35 xattr->value_len, 0);
38 return rc; 36 if (err < 0)
37 break;
39 } 38 }
40 rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); 39 return err;
40}
41 41
42 kfree(name); 42/* ---- Initial Security Label(s) Attachment ----------- */
43 kfree(value); 43int jffs2_init_security(struct inode *inode, struct inode *dir,
44 return rc; 44 const struct qstr *qstr)
45{
46 return security_inode_init_security(inode, dir, qstr,
47 &jffs2_initxattrs, NULL);
45} 48}
46 49
47/* ---- XATTR Handler for "security.*" ----------------- */ 50/* ---- XATTR Handler for "security.*" ----------------- */
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index e87fedef23db..26683e15b3ac 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -1089,38 +1089,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1089} 1089}
1090 1090
1091#ifdef CONFIG_JFS_SECURITY 1091#ifdef CONFIG_JFS_SECURITY
1092int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, 1092int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
1093 const struct qstr *qstr) 1093 void *fs_info)
1094{ 1094{
1095 int rc; 1095 const struct xattr *xattr;
1096 size_t len; 1096 tid_t *tid = fs_info;
1097 void *value;
1098 char *suffix;
1099 char *name; 1097 char *name;
1100 1098 int err = 0;
1101 rc = security_inode_init_security(inode, dir, qstr, &suffix, &value, 1099
1102 &len); 1100 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
1103 if (rc) { 1101 name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
1104 if (rc == -EOPNOTSUPP) 1102 strlen(xattr->name) + 1, GFP_NOFS);
1105 return 0; 1103 if (!name) {
1106 return rc; 1104 err = -ENOMEM;
1107 } 1105 break;
1108 name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), 1106 }
1109 GFP_NOFS); 1107 strcpy(name, XATTR_SECURITY_PREFIX);
1110 if (!name) { 1108 strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
1111 rc = -ENOMEM; 1109
1112 goto kmalloc_failed; 1110 err = __jfs_setxattr(*tid, inode, name,
1111 xattr->value, xattr->value_len, 0);
1112 kfree(name);
1113 if (err < 0)
1114 break;
1113 } 1115 }
1114 strcpy(name, XATTR_SECURITY_PREFIX); 1116 return err;
1115 strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); 1117}
1116
1117 rc = __jfs_setxattr(tid, inode, name, value, len, 0);
1118
1119 kfree(name);
1120kmalloc_failed:
1121 kfree(suffix);
1122 kfree(value);
1123 1118
1124 return rc; 1119int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
1120 const struct qstr *qstr)
1121{
1122 return security_inode_init_security(inode, dir, qstr,
1123 &jfs_initxattrs, &tid);
1125} 1124}
1126#endif 1125#endif
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 81ecf9c0bf0a..194fb22ef79d 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,
7185{ 7185{
7186 int ret = 0; 7186 int ret = 0;
7187 struct buffer_head *dir_bh = NULL; 7187 struct buffer_head *dir_bh = NULL;
7188 struct ocfs2_security_xattr_info si = {
7189 .enable = 1,
7190 };
7191 7188
7192 ret = ocfs2_init_security_get(inode, dir, qstr, &si); 7189 ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
7193 if (!ret) { 7190 if (!ret) {
7194 ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
7195 si.name, si.value, si.value_len,
7196 XATTR_CREATE);
7197 if (ret) {
7198 mlog_errno(ret);
7199 goto leave;
7200 }
7201 } else if (ret != -EOPNOTSUPP) {
7202 mlog_errno(ret); 7191 mlog_errno(ret);
7203 goto leave; 7192 goto leave;
7204 } 7193 }
@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
7255 name, value, size, flags); 7244 name, value, size, flags);
7256} 7245}
7257 7246
7247int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
7248 void *fs_info)
7249{
7250 const struct xattr *xattr;
7251 int err = 0;
7252
7253 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
7254 err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
7255 xattr->name, xattr->value,
7256 xattr->value_len, XATTR_CREATE);
7257 if (err)
7258 break;
7259 }
7260 return err;
7261}
7262
7258int ocfs2_init_security_get(struct inode *inode, 7263int ocfs2_init_security_get(struct inode *inode,
7259 struct inode *dir, 7264 struct inode *dir,
7260 const struct qstr *qstr, 7265 const struct qstr *qstr,
@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode,
7263 /* check whether ocfs2 support feature xattr */ 7268 /* check whether ocfs2 support feature xattr */
7264 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) 7269 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
7265 return -EOPNOTSUPP; 7270 return -EOPNOTSUPP;
7266 return security_inode_init_security(inode, dir, qstr, &si->name, 7271 if (si)
7267 &si->value, &si->value_len); 7272 return security_old_inode_init_security(inode, dir, qstr,
7273 &si->name, &si->value,
7274 &si->value_len);
7275
7276 return security_inode_init_security(inode, dir, qstr,
7277 &ocfs2_initxattrs, NULL);
7268} 7278}
7269 7279
7270int ocfs2_init_security_set(handle_t *handle, 7280int ocfs2_init_security_set(handle_t *handle,
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index ef66c18a9332..534668fa41be 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
66 if (IS_PRIVATE(dir)) 66 if (IS_PRIVATE(dir))
67 return 0; 67 return 0;
68 68
69 error = security_inode_init_security(inode, dir, qstr, &sec->name, 69 error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
70 &sec->value, &sec->length); 70 &sec->value, &sec->length);
71 if (error) { 71 if (error) {
72 if (error == -EOPNOTSUPP) 72 if (error == -EOPNOTSUPP)
73 error = 0; 73 error = 0;
diff --git a/fs/xattr.c b/fs/xattr.c
index f060663ab70c..67583de8218c 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -14,6 +14,7 @@
14#include <linux/mount.h> 14#include <linux/mount.h>
15#include <linux/namei.h> 15#include <linux/namei.h>
16#include <linux/security.h> 16#include <linux/security.h>
17#include <linux/evm.h>
17#include <linux/syscalls.h> 18#include <linux/syscalls.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/fsnotify.h> 20#include <linux/fsnotify.h>
@@ -166,6 +167,64 @@ out_noalloc:
166} 167}
167EXPORT_SYMBOL_GPL(xattr_getsecurity); 168EXPORT_SYMBOL_GPL(xattr_getsecurity);
168 169
170/*
171 * vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
172 *
173 * Allocate memory, if not already allocated, or re-allocate correct size,
174 * before retrieving the extended attribute.
175 *
176 * Returns the result of alloc, if failed, or the getxattr operation.
177 */
178ssize_t
179vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
180 size_t xattr_size, gfp_t flags)
181{
182 struct inode *inode = dentry->d_inode;
183 char *value = *xattr_value;
184 int error;
185
186 error = xattr_permission(inode, name, MAY_READ);
187 if (error)
188 return error;
189
190 if (!inode->i_op->getxattr)
191 return -EOPNOTSUPP;
192
193 error = inode->i_op->getxattr(dentry, name, NULL, 0);
194 if (error < 0)
195 return error;
196
197 if (!value || (error > xattr_size)) {
198 value = krealloc(*xattr_value, error + 1, flags);
199 if (!value)
200 return -ENOMEM;
201 memset(value, 0, error + 1);
202 }
203
204 error = inode->i_op->getxattr(dentry, name, value, error);
205 *xattr_value = value;
206 return error;
207}
208
209/* Compare an extended attribute value with the given value */
210int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
211 const char *value, size_t size, gfp_t flags)
212{
213 char *xattr_value = NULL;
214 int rc;
215
216 rc = vfs_getxattr_alloc(dentry, xattr_name, &xattr_value, 0, flags);
217 if (rc < 0)
218 return rc;
219
220 if ((rc != size) || (memcmp(xattr_value, value, rc) != 0))
221 rc = -EINVAL;
222 else
223 rc = 0;
224 kfree(xattr_value);
225 return rc;
226}
227
169ssize_t 228ssize_t
170vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) 229vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
171{ 230{
@@ -243,8 +302,10 @@ vfs_removexattr(struct dentry *dentry, const char *name)
243 error = inode->i_op->removexattr(dentry, name); 302 error = inode->i_op->removexattr(dentry, name);
244 mutex_unlock(&inode->i_mutex); 303 mutex_unlock(&inode->i_mutex);
245 304
246 if (!error) 305 if (!error) {
247 fsnotify_xattr(dentry); 306 fsnotify_xattr(dentry);
307 evm_inode_post_removexattr(dentry, name);
308 }
248 return error; 309 return error;
249} 310}
250EXPORT_SYMBOL_GPL(vfs_removexattr); 311EXPORT_SYMBOL_GPL(vfs_removexattr);
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 673704fab748..28856accb4fa 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -102,37 +102,38 @@ xfs_mark_inode_dirty(
102 102
103} 103}
104 104
105
106int xfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
107 void *fs_info)
108{
109 const struct xattr *xattr;
110 struct xfs_inode *ip = XFS_I(inode);
111 int error = 0;
112
113 for (xattr = xattr_array; xattr->name != NULL; xattr++) {
114 error = xfs_attr_set(ip, xattr->name, xattr->value,
115 xattr->value_len, ATTR_SECURE);
116 if (error < 0)
117 break;
118 }
119 return error;
120}
121
105/* 122/*
106 * Hook in SELinux. This is not quite correct yet, what we really need 123 * Hook in SELinux. This is not quite correct yet, what we really need
107 * here (as we do for default ACLs) is a mechanism by which creation of 124 * here (as we do for default ACLs) is a mechanism by which creation of
108 * these attrs can be journalled at inode creation time (along with the 125 * these attrs can be journalled at inode creation time (along with the
109 * inode, of course, such that log replay can't cause these to be lost). 126 * inode, of course, such that log replay can't cause these to be lost).
110 */ 127 */
128
111STATIC int 129STATIC int
112xfs_init_security( 130xfs_init_security(
113 struct inode *inode, 131 struct inode *inode,
114 struct inode *dir, 132 struct inode *dir,
115 const struct qstr *qstr) 133 const struct qstr *qstr)
116{ 134{
117 struct xfs_inode *ip = XFS_I(inode); 135 return security_inode_init_security(inode, dir, qstr,
118 size_t length; 136 &xfs_initxattrs, NULL);
119 void *value;
120 unsigned char *name;
121 int error;
122
123 error = security_inode_init_security(inode, dir, qstr, (char **)&name,
124 &value, &length);
125 if (error) {
126 if (error == -EOPNOTSUPP)
127 return 0;
128 return -error;
129 }
130
131 error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
132
133 kfree(name);
134 kfree(value);
135 return error;
136} 137}
137 138
138static void 139static void
diff --git a/include/linux/evm.h b/include/linux/evm.h
new file mode 100644
index 000000000000..9fc13a760928
--- /dev/null
+++ b/include/linux/evm.h
@@ -0,0 +1,100 @@
1/*
2 * evm.h
3 *
4 * Copyright (c) 2009 IBM Corporation
5 * Author: Mimi Zohar <zohar@us.ibm.com>
6 */
7
8#ifndef _LINUX_EVM_H
9#define _LINUX_EVM_H
10
11#include <linux/integrity.h>
12#include <linux/xattr.h>
13
14struct integrity_iint_cache;
15
16#ifdef CONFIG_EVM
17extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
18 const char *xattr_name,
19 void *xattr_value,
20 size_t xattr_value_len,
21 struct integrity_iint_cache *iint);
22extern int evm_inode_setattr(struct dentry *dentry, struct iattr *attr);
23extern void evm_inode_post_setattr(struct dentry *dentry, int ia_valid);
24extern int evm_inode_setxattr(struct dentry *dentry, const char *name,
25 const void *value, size_t size);
26extern void evm_inode_post_setxattr(struct dentry *dentry,
27 const char *xattr_name,
28 const void *xattr_value,
29 size_t xattr_value_len);
30extern int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name);
31extern void evm_inode_post_removexattr(struct dentry *dentry,
32 const char *xattr_name);
33extern int evm_inode_init_security(struct inode *inode,
34 const struct xattr *xattr_array,
35 struct xattr *evm);
36#ifdef CONFIG_FS_POSIX_ACL
37extern int posix_xattr_acl(const char *xattrname);
38#else
39static inline int posix_xattr_acl(const char *xattrname)
40{
41 return 0;
42}
43#endif
44#else
45#ifdef CONFIG_INTEGRITY
46static inline enum integrity_status evm_verifyxattr(struct dentry *dentry,
47 const char *xattr_name,
48 void *xattr_value,
49 size_t xattr_value_len,
50 struct integrity_iint_cache *iint)
51{
52 return INTEGRITY_UNKNOWN;
53}
54#endif
55
56static inline int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
57{
58 return 0;
59}
60
61static inline void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
62{
63 return;
64}
65
66static inline int evm_inode_setxattr(struct dentry *dentry, const char *name,
67 const void *value, size_t size)
68{
69 return 0;
70}
71
72static inline void evm_inode_post_setxattr(struct dentry *dentry,
73 const char *xattr_name,
74 const void *xattr_value,
75 size_t xattr_value_len)
76{
77 return;
78}
79
80static inline int evm_inode_removexattr(struct dentry *dentry,
81 const char *xattr_name)
82{
83 return 0;
84}
85
86static inline void evm_inode_post_removexattr(struct dentry *dentry,
87 const char *xattr_name)
88{
89 return;
90}
91
92static inline int evm_inode_init_security(struct inode *inode,
93 const struct xattr *xattr_array,
94 struct xattr *evm)
95{
96 return 0;
97}
98
99#endif /* CONFIG_EVM_H */
100#endif /* LINUX_EVM_H */
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 09e6e62f9953..6ac8e50c6cf5 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -15,8 +15,6 @@ struct linux_binprm;
15 15
16#ifdef CONFIG_IMA 16#ifdef CONFIG_IMA
17extern int ima_bprm_check(struct linux_binprm *bprm); 17extern int ima_bprm_check(struct linux_binprm *bprm);
18extern int ima_inode_alloc(struct inode *inode);
19extern void ima_inode_free(struct inode *inode);
20extern int ima_file_check(struct file *file, int mask); 18extern int ima_file_check(struct file *file, int mask);
21extern void ima_file_free(struct file *file); 19extern void ima_file_free(struct file *file);
22extern int ima_file_mmap(struct file *file, unsigned long prot); 20extern int ima_file_mmap(struct file *file, unsigned long prot);
@@ -27,16 +25,6 @@ static inline int ima_bprm_check(struct linux_binprm *bprm)
27 return 0; 25 return 0;
28} 26}
29 27
30static inline int ima_inode_alloc(struct inode *inode)
31{
32 return 0;
33}
34
35static inline void ima_inode_free(struct inode *inode)
36{
37 return;
38}
39
40static inline int ima_file_check(struct file *file, int mask) 28static inline int ima_file_check(struct file *file, int mask)
41{ 29{
42 return 0; 30 return 0;
@@ -51,6 +39,5 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
51{ 39{
52 return 0; 40 return 0;
53} 41}
54
55#endif /* CONFIG_IMA_H */ 42#endif /* CONFIG_IMA_H */
56#endif /* _LINUX_IMA_H */ 43#endif /* _LINUX_IMA_H */
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
new file mode 100644
index 000000000000..a0c41256cb92
--- /dev/null
+++ b/include/linux/integrity.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2009 IBM Corporation
3 * Author: Mimi Zohar <zohar@us.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
8 */
9
10#ifndef _LINUX_INTEGRITY_H
11#define _LINUX_INTEGRITY_H
12
13#include <linux/fs.h>
14
15enum integrity_status {
16 INTEGRITY_PASS = 0,
17 INTEGRITY_FAIL,
18 INTEGRITY_NOLABEL,
19 INTEGRITY_NOXATTRS,
20 INTEGRITY_UNKNOWN,
21};
22
23/* List of EVM protected security xattrs */
24#ifdef CONFIG_INTEGRITY
25extern int integrity_inode_alloc(struct inode *inode);
26extern void integrity_inode_free(struct inode *inode);
27
28#else
29static inline int integrity_inode_alloc(struct inode *inode)
30{
31 return 0;
32}
33
34static inline void integrity_inode_free(struct inode *inode)
35{
36 return;
37}
38#endif /* CONFIG_INTEGRITY_H */
39#endif /* _LINUX_INTEGRITY_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 46ac9a50528d..8eefcf7e95eb 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -382,7 +382,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
382} 382}
383 383
384extern int hex_to_bin(char ch); 384extern int hex_to_bin(char ch);
385extern void hex2bin(u8 *dst, const char *src, size_t count); 385extern int __must_check hex2bin(u8 *dst, const char *src, size_t count);
386 386
387/* 387/*
388 * General tracing related utility functions - trace_printk(), 388 * General tracing related utility functions - trace_printk(),
diff --git a/include/linux/security.h b/include/linux/security.h
index ebd2a53a3d07..19d8e04e1688 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -36,6 +36,7 @@
36#include <linux/key.h> 36#include <linux/key.h>
37#include <linux/xfrm.h> 37#include <linux/xfrm.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/xattr.h>
39#include <net/flow.h> 40#include <net/flow.h>
40 41
41/* Maximum number of letters for an LSM name string */ 42/* Maximum number of letters for an LSM name string */
@@ -147,6 +148,10 @@ extern int mmap_min_addr_handler(struct ctl_table *table, int write,
147 void __user *buffer, size_t *lenp, loff_t *ppos); 148 void __user *buffer, size_t *lenp, loff_t *ppos);
148#endif 149#endif
149 150
151/* security_inode_init_security callback function to write xattrs */
152typedef int (*initxattrs) (struct inode *inode,
153 const struct xattr *xattr_array, void *fs_data);
154
150#ifdef CONFIG_SECURITY 155#ifdef CONFIG_SECURITY
151 156
152struct security_mnt_opts { 157struct security_mnt_opts {
@@ -1367,7 +1372,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1367 * @inode_getsecctx: 1372 * @inode_getsecctx:
1368 * Returns a string containing all relavent security context information 1373 * Returns a string containing all relavent security context information
1369 * 1374 *
1370 * @inode we wish to set the security context of. 1375 * @inode we wish to get the security context of.
1371 * @ctx is a pointer in which to place the allocated security context. 1376 * @ctx is a pointer in which to place the allocated security context.
1372 * @ctxlen points to the place to put the length of @ctx. 1377 * @ctxlen points to the place to put the length of @ctx.
1373 * This is the main security structure. 1378 * This is the main security structure.
@@ -1655,6 +1660,8 @@ struct security_operations {
1655extern int security_init(void); 1660extern int security_init(void);
1656extern int security_module_enable(struct security_operations *ops); 1661extern int security_module_enable(struct security_operations *ops);
1657extern int register_security(struct security_operations *ops); 1662extern int register_security(struct security_operations *ops);
1663extern void __init security_fixup_ops(struct security_operations *ops);
1664
1658 1665
1659/* Security operations */ 1666/* Security operations */
1660int security_ptrace_access_check(struct task_struct *child, unsigned int mode); 1667int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
@@ -1704,8 +1711,11 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
1704int security_inode_alloc(struct inode *inode); 1711int security_inode_alloc(struct inode *inode);
1705void security_inode_free(struct inode *inode); 1712void security_inode_free(struct inode *inode);
1706int security_inode_init_security(struct inode *inode, struct inode *dir, 1713int security_inode_init_security(struct inode *inode, struct inode *dir,
1707 const struct qstr *qstr, char **name, 1714 const struct qstr *qstr,
1708 void **value, size_t *len); 1715 initxattrs initxattrs, void *fs_data);
1716int security_old_inode_init_security(struct inode *inode, struct inode *dir,
1717 const struct qstr *qstr, char **name,
1718 void **value, size_t *len);
1709int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); 1719int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
1710int security_inode_link(struct dentry *old_dentry, struct inode *dir, 1720int security_inode_link(struct dentry *old_dentry, struct inode *dir,
1711 struct dentry *new_dentry); 1721 struct dentry *new_dentry);
@@ -2034,11 +2044,19 @@ static inline void security_inode_free(struct inode *inode)
2034static inline int security_inode_init_security(struct inode *inode, 2044static inline int security_inode_init_security(struct inode *inode,
2035 struct inode *dir, 2045 struct inode *dir,
2036 const struct qstr *qstr, 2046 const struct qstr *qstr,
2037 char **name, 2047 initxattrs initxattrs,
2038 void **value, 2048 void *fs_data)
2039 size_t *len)
2040{ 2049{
2041 return -EOPNOTSUPP; 2050 return 0;
2051}
2052
2053static inline int security_old_inode_init_security(struct inode *inode,
2054 struct inode *dir,
2055 const struct qstr *qstr,
2056 char **name, void **value,
2057 size_t *len)
2058{
2059 return 0;
2042} 2060}
2043 2061
2044static inline int security_inode_create(struct inode *dir, 2062static inline int security_inode_create(struct inode *dir,
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index aed54c50aa66..e5d122031542 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -30,6 +30,9 @@
30#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1) 30#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
31 31
32/* Security namespace */ 32/* Security namespace */
33#define XATTR_EVM_SUFFIX "evm"
34#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
35
33#define XATTR_SELINUX_SUFFIX "selinux" 36#define XATTR_SELINUX_SUFFIX "selinux"
34#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 37#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
35 38
@@ -49,6 +52,11 @@
49#define XATTR_CAPS_SUFFIX "capability" 52#define XATTR_CAPS_SUFFIX "capability"
50#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 53#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
51 54
55#define XATTR_POSIX_ACL_ACCESS "posix_acl_access"
56#define XATTR_NAME_POSIX_ACL_ACCESS XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_ACCESS
57#define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
58#define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
59
52#ifdef __KERNEL__ 60#ifdef __KERNEL__
53 61
54#include <linux/types.h> 62#include <linux/types.h>
@@ -67,6 +75,12 @@ struct xattr_handler {
67 size_t size, int flags, int handler_flags); 75 size_t size, int flags, int handler_flags);
68}; 76};
69 77
78struct xattr {
79 char *name;
80 void *value;
81 size_t value_len;
82};
83
70ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); 84ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
71ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); 85ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
72ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); 86ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
@@ -78,7 +92,10 @@ ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer,
78ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); 92ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
79int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); 93int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
80int generic_removexattr(struct dentry *dentry, const char *name); 94int generic_removexattr(struct dentry *dentry, const char *name);
81 95ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
96 char **xattr_value, size_t size, gfp_t flags);
97int vfs_xattr_cmp(struct dentry *dentry, const char *xattr_name,
98 const char *value, size_t size, gfp_t flags);
82#endif /* __KERNEL__ */ 99#endif /* __KERNEL__ */
83 100
84#endif /* _LINUX_XATTR_H */ 101#endif /* _LINUX_XATTR_H */
diff --git a/kernel/cred.c b/kernel/cred.c
index 8ef31f53c44c..bb55d052d858 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -644,6 +644,9 @@ void __init cred_init(void)
644 */ 644 */
645struct cred *prepare_kernel_cred(struct task_struct *daemon) 645struct cred *prepare_kernel_cred(struct task_struct *daemon)
646{ 646{
647#ifdef CONFIG_KEYS
648 struct thread_group_cred *tgcred;
649#endif
647 const struct cred *old; 650 const struct cred *old;
648 struct cred *new; 651 struct cred *new;
649 652
@@ -651,6 +654,14 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
651 if (!new) 654 if (!new)
652 return NULL; 655 return NULL;
653 656
657#ifdef CONFIG_KEYS
658 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
659 if (!tgcred) {
660 kmem_cache_free(cred_jar, new);
661 return NULL;
662 }
663#endif
664
654 kdebug("prepare_kernel_cred() alloc %p", new); 665 kdebug("prepare_kernel_cred() alloc %p", new);
655 666
656 if (daemon) 667 if (daemon)
@@ -667,8 +678,11 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
667 get_group_info(new->group_info); 678 get_group_info(new->group_info);
668 679
669#ifdef CONFIG_KEYS 680#ifdef CONFIG_KEYS
670 atomic_inc(&init_tgcred.usage); 681 atomic_set(&tgcred->usage, 1);
671 new->tgcred = &init_tgcred; 682 spin_lock_init(&tgcred->lock);
683 tgcred->process_keyring = NULL;
684 tgcred->session_keyring = NULL;
685 new->tgcred = tgcred;
672 new->request_key_auth = NULL; 686 new->request_key_auth = NULL;
673 new->thread_keyring = NULL; 687 new->thread_keyring = NULL;
674 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 688 new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
diff --git a/lib/hexdump.c b/lib/hexdump.c
index f5fe6ba7a3ab..51d5ae210244 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -38,14 +38,21 @@ EXPORT_SYMBOL(hex_to_bin);
38 * @dst: binary result 38 * @dst: binary result
39 * @src: ascii hexadecimal string 39 * @src: ascii hexadecimal string
40 * @count: result length 40 * @count: result length
41 *
42 * Return 0 on success, -1 in case of bad input.
41 */ 43 */
42void hex2bin(u8 *dst, const char *src, size_t count) 44int hex2bin(u8 *dst, const char *src, size_t count)
43{ 45{
44 while (count--) { 46 while (count--) {
45 *dst = hex_to_bin(*src++) << 4; 47 int hi = hex_to_bin(*src++);
46 *dst += hex_to_bin(*src++); 48 int lo = hex_to_bin(*src++);
47 dst++; 49
50 if ((hi < 0) || (lo < 0))
51 return -1;
52
53 *dst++ = (hi << 4) | lo;
48 } 54 }
55 return 0;
49} 56}
50EXPORT_SYMBOL(hex2bin); 57EXPORT_SYMBOL(hex2bin);
51 58
diff --git a/mm/shmem.c b/mm/shmem.c
index 32f6763f16fb..2d3577295298 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1458,7 +1458,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1458 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); 1458 inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
1459 if (inode) { 1459 if (inode) {
1460 error = security_inode_init_security(inode, dir, 1460 error = security_inode_init_security(inode, dir,
1461 &dentry->d_name, NULL, 1461 &dentry->d_name,
1462 NULL, NULL); 1462 NULL, NULL);
1463 if (error) { 1463 if (error) {
1464 if (error != -EOPNOTSUPP) { 1464 if (error != -EOPNOTSUPP) {
@@ -1598,7 +1598,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
1598 if (!inode) 1598 if (!inode)
1599 return -ENOSPC; 1599 return -ENOSPC;
1600 1600
1601 error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, 1601 error = security_inode_init_security(inode, dir, &dentry->d_name,
1602 NULL, NULL); 1602 NULL, NULL);
1603 if (error) { 1603 if (error) {
1604 if (error != -EOPNOTSUPP) { 1604 if (error != -EOPNOTSUPP) {
diff --git a/security/Kconfig b/security/Kconfig
index e0f08b52e4ab..51bd5a0b69ae 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -38,7 +38,9 @@ config TRUSTED_KEYS
38 38
39config ENCRYPTED_KEYS 39config ENCRYPTED_KEYS
40 tristate "ENCRYPTED KEYS" 40 tristate "ENCRYPTED KEYS"
41 depends on KEYS && TRUSTED_KEYS 41 depends on KEYS
42 select CRYPTO
43 select CRYPTO_HMAC
42 select CRYPTO_AES 44 select CRYPTO_AES
43 select CRYPTO_CBC 45 select CRYPTO_CBC
44 select CRYPTO_SHA256 46 select CRYPTO_SHA256
@@ -186,7 +188,7 @@ source security/smack/Kconfig
186source security/tomoyo/Kconfig 188source security/tomoyo/Kconfig
187source security/apparmor/Kconfig 189source security/apparmor/Kconfig
188 190
189source security/integrity/ima/Kconfig 191source security/integrity/Kconfig
190 192
191choice 193choice
192 prompt "Default security module" 194 prompt "Default security module"
diff --git a/security/Makefile b/security/Makefile
index 8bb0fe9e1ca9..a5e502f8a05b 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -24,5 +24,5 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 24obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
25 25
26# Object integrity file lists 26# Object integrity file lists
27subdir-$(CONFIG_IMA) += integrity/ima 27subdir-$(CONFIG_INTEGRITY) += integrity
28obj-$(CONFIG_IMA) += integrity/ima/built-in.o 28obj-$(CONFIG_INTEGRITY) += integrity/built-in.o
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0848292982a2..69ddb47787b2 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -200,7 +200,7 @@ void __init aa_destroy_aafs(void)
200 * 200 *
201 * Returns: error on failure 201 * Returns: error on failure
202 */ 202 */
203int __init aa_create_aafs(void) 203static int __init aa_create_aafs(void)
204{ 204{
205 int error; 205 int error;
206 206
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 649fad88869b..7ee05c6f3c64 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -19,6 +19,7 @@
19#include "include/capability.h" 19#include "include/capability.h"
20#include "include/context.h" 20#include "include/context.h"
21#include "include/policy.h" 21#include "include/policy.h"
22#include "include/ipc.h"
22 23
23/* call back to audit ptrace fields */ 24/* call back to audit ptrace fields */
24static void audit_cb(struct audit_buffer *ab, void *va) 25static void audit_cb(struct audit_buffer *ab, void *va)
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index b82e383beb77..9516948041ad 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -18,6 +18,7 @@
18#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
19 19
20#include "include/audit.h" 20#include "include/audit.h"
21#include "include/apparmor.h"
21 22
22 23
23/** 24/**
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index d6d9a57b5652..741dd13e089b 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -381,11 +381,11 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
381 profile->file.trans.size = size; 381 profile->file.trans.size = size;
382 for (i = 0; i < size; i++) { 382 for (i = 0; i < size; i++) {
383 char *str; 383 char *str;
384 int c, j, size = unpack_strdup(e, &str, NULL); 384 int c, j, size2 = unpack_strdup(e, &str, NULL);
385 /* unpack_strdup verifies that the last character is 385 /* unpack_strdup verifies that the last character is
386 * null termination byte. 386 * null termination byte.
387 */ 387 */
388 if (!size) 388 if (!size2)
389 goto fail; 389 goto fail;
390 profile->file.trans.table[i] = str; 390 profile->file.trans.table[i] = str;
391 /* verify that name doesn't start with space */ 391 /* verify that name doesn't start with space */
@@ -393,7 +393,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
393 goto fail; 393 goto fail;
394 394
395 /* count internal # of internal \0 */ 395 /* count internal # of internal \0 */
396 for (c = j = 0; j < size - 2; j++) { 396 for (c = j = 0; j < size2 - 2; j++) {
397 if (!str[j]) 397 if (!str[j])
398 c++; 398 c++;
399 } 399 }
@@ -440,11 +440,11 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
440 if (size > RLIM_NLIMITS) 440 if (size > RLIM_NLIMITS)
441 goto fail; 441 goto fail;
442 for (i = 0; i < size; i++) { 442 for (i = 0; i < size; i++) {
443 u64 tmp = 0; 443 u64 tmp2 = 0;
444 int a = aa_map_resource(i); 444 int a = aa_map_resource(i);
445 if (!unpack_u64(e, &tmp, NULL)) 445 if (!unpack_u64(e, &tmp2, NULL))
446 goto fail; 446 goto fail;
447 profile->rlimits.limits[a].rlim_max = tmp; 447 profile->rlimits.limits[a].rlim_max = tmp2;
448 } 448 }
449 if (!unpack_nameX(e, AA_ARRAYEND, NULL)) 449 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
450 goto fail; 450 goto fail;
diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
index 04a2cf8d1b65..1b41c542d376 100644
--- a/security/apparmor/procattr.c
+++ b/security/apparmor/procattr.c
@@ -16,6 +16,7 @@
16#include "include/context.h" 16#include "include/context.h"
17#include "include/policy.h" 17#include "include/policy.h"
18#include "include/domain.h" 18#include "include/domain.h"
19#include "include/procattr.h"
19 20
20 21
21/** 22/**
diff --git a/security/commoncap.c b/security/commoncap.c
index a93b3b733079..ee4f8486e5f5 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -332,7 +332,8 @@ int cap_inode_killpriv(struct dentry *dentry)
332 */ 332 */
333static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, 333static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
334 struct linux_binprm *bprm, 334 struct linux_binprm *bprm,
335 bool *effective) 335 bool *effective,
336 bool *has_cap)
336{ 337{
337 struct cred *new = bprm->cred; 338 struct cred *new = bprm->cred;
338 unsigned i; 339 unsigned i;
@@ -341,6 +342,9 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
341 if (caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE) 342 if (caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE)
342 *effective = true; 343 *effective = true;
343 344
345 if (caps->magic_etc & VFS_CAP_REVISION_MASK)
346 *has_cap = true;
347
344 CAP_FOR_EACH_U32(i) { 348 CAP_FOR_EACH_U32(i) {
345 __u32 permitted = caps->permitted.cap[i]; 349 __u32 permitted = caps->permitted.cap[i];
346 __u32 inheritable = caps->inheritable.cap[i]; 350 __u32 inheritable = caps->inheritable.cap[i];
@@ -424,7 +428,7 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
424 * its xattrs and, if present, apply them to the proposed credentials being 428 * its xattrs and, if present, apply them to the proposed credentials being
425 * constructed by execve(). 429 * constructed by execve().
426 */ 430 */
427static int get_file_caps(struct linux_binprm *bprm, bool *effective) 431static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap)
428{ 432{
429 struct dentry *dentry; 433 struct dentry *dentry;
430 int rc = 0; 434 int rc = 0;
@@ -450,7 +454,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective)
450 goto out; 454 goto out;
451 } 455 }
452 456
453 rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective); 457 rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap);
454 if (rc == -EINVAL) 458 if (rc == -EINVAL)
455 printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", 459 printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
456 __func__, rc, bprm->filename); 460 __func__, rc, bprm->filename);
@@ -475,11 +479,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
475{ 479{
476 const struct cred *old = current_cred(); 480 const struct cred *old = current_cred();
477 struct cred *new = bprm->cred; 481 struct cred *new = bprm->cred;
478 bool effective; 482 bool effective, has_cap = false;
479 int ret; 483 int ret;
480 484
481 effective = false; 485 effective = false;
482 ret = get_file_caps(bprm, &effective); 486 ret = get_file_caps(bprm, &effective, &has_cap);
483 if (ret < 0) 487 if (ret < 0)
484 return ret; 488 return ret;
485 489
@@ -489,7 +493,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
489 * for a setuid root binary run by a non-root user. Do set it 493 * for a setuid root binary run by a non-root user. Do set it
490 * for a root user just to cause least surprise to an admin. 494 * for a root user just to cause least surprise to an admin.
491 */ 495 */
492 if (effective && new->uid != 0 && new->euid == 0) { 496 if (has_cap && new->uid != 0 && new->euid == 0) {
493 warn_setuid_and_fcaps_mixed(bprm->filename); 497 warn_setuid_and_fcaps_mixed(bprm->filename);
494 goto skip; 498 goto skip;
495 } 499 }
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
new file mode 100644
index 000000000000..4bf00acf7937
--- /dev/null
+++ b/security/integrity/Kconfig
@@ -0,0 +1,7 @@
1#
2config INTEGRITY
3 def_bool y
4 depends on IMA || EVM
5
6source security/integrity/ima/Kconfig
7source security/integrity/evm/Kconfig
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
new file mode 100644
index 000000000000..0ae44aea6516
--- /dev/null
+++ b/security/integrity/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for caching inode integrity data (iint)
3#
4
5obj-$(CONFIG_INTEGRITY) += integrity.o
6
7integrity-y := iint.o
8
9subdir-$(CONFIG_IMA) += ima
10obj-$(CONFIG_IMA) += ima/built-in.o
11subdir-$(CONFIG_EVM) += evm
12obj-$(CONFIG_EVM) += evm/built-in.o
diff --git a/security/integrity/evm/Kconfig b/security/integrity/evm/Kconfig
new file mode 100644
index 000000000000..afbb59dd262d
--- /dev/null
+++ b/security/integrity/evm/Kconfig
@@ -0,0 +1,13 @@
1config EVM
2 boolean "EVM support"
3 depends on SECURITY && KEYS && (TRUSTED_KEYS=y || TRUSTED_KEYS=n)
4 select CRYPTO_HMAC
5 select CRYPTO_MD5
6 select CRYPTO_SHA1
7 select ENCRYPTED_KEYS
8 default n
9 help
10 EVM protects a file's security extended attributes against
11 integrity attacks.
12
13 If you are unsure how to answer this question, answer N.
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile
new file mode 100644
index 000000000000..7393c415a066
--- /dev/null
+++ b/security/integrity/evm/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for building the Extended Verification Module(EVM)
3#
4obj-$(CONFIG_EVM) += evm.o
5
6evm-y := evm_main.o evm_crypto.o evm_secfs.o
7evm-$(CONFIG_FS_POSIX_ACL) += evm_posix_acl.o
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
new file mode 100644
index 000000000000..d320f5197437
--- /dev/null
+++ b/security/integrity/evm/evm.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm.h
13 *
14 */
15#include <linux/xattr.h>
16#include <linux/security.h>
17#include "../integrity.h"
18
19extern int evm_initialized;
20extern char *evm_hmac;
21
22extern struct crypto_shash *hmac_tfm;
23
24/* List of EVM protected security xattrs */
25extern char *evm_config_xattrnames[];
26
27extern int evm_init_key(void);
28extern int evm_update_evmxattr(struct dentry *dentry,
29 const char *req_xattr_name,
30 const char *req_xattr_value,
31 size_t req_xattr_value_len);
32extern int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
33 const char *req_xattr_value,
34 size_t req_xattr_value_len, char *digest);
35extern int evm_init_hmac(struct inode *inode, const struct xattr *xattr,
36 char *hmac_val);
37extern int evm_init_secfs(void);
38extern void evm_cleanup_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
new file mode 100644
index 000000000000..5dd5b140242c
--- /dev/null
+++ b/security/integrity/evm/evm_crypto.c
@@ -0,0 +1,216 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_crypto.c
13 * Using root's kernel master key (kmk), calculate the HMAC
14 */
15
16#include <linux/module.h>
17#include <linux/crypto.h>
18#include <linux/xattr.h>
19#include <keys/encrypted-type.h>
20#include <crypto/hash.h>
21#include "evm.h"
22
23#define EVMKEY "evm-key"
24#define MAX_KEY_SIZE 128
25static unsigned char evmkey[MAX_KEY_SIZE];
26static int evmkey_len = MAX_KEY_SIZE;
27
28struct crypto_shash *hmac_tfm;
29
30static struct shash_desc *init_desc(void)
31{
32 int rc;
33 struct shash_desc *desc;
34
35 if (hmac_tfm == NULL) {
36 hmac_tfm = crypto_alloc_shash(evm_hmac, 0, CRYPTO_ALG_ASYNC);
37 if (IS_ERR(hmac_tfm)) {
38 pr_err("Can not allocate %s (reason: %ld)\n",
39 evm_hmac, PTR_ERR(hmac_tfm));
40 rc = PTR_ERR(hmac_tfm);
41 hmac_tfm = NULL;
42 return ERR_PTR(rc);
43 }
44 }
45
46 desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(hmac_tfm),
47 GFP_KERNEL);
48 if (!desc)
49 return ERR_PTR(-ENOMEM);
50
51 desc->tfm = hmac_tfm;
52 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
53
54 rc = crypto_shash_setkey(hmac_tfm, evmkey, evmkey_len);
55 if (rc)
56 goto out;
57 rc = crypto_shash_init(desc);
58out:
59 if (rc) {
60 kfree(desc);
61 return ERR_PTR(rc);
62 }
63 return desc;
64}
65
66/* Protect against 'cutting & pasting' security.evm xattr, include inode
67 * specific info.
68 *
69 * (Additional directory/file metadata needs to be added for more complete
70 * protection.)
71 */
72static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
73 char *digest)
74{
75 struct h_misc {
76 unsigned long ino;
77 __u32 generation;
78 uid_t uid;
79 gid_t gid;
80 umode_t mode;
81 } hmac_misc;
82
83 memset(&hmac_misc, 0, sizeof hmac_misc);
84 hmac_misc.ino = inode->i_ino;
85 hmac_misc.generation = inode->i_generation;
86 hmac_misc.uid = inode->i_uid;
87 hmac_misc.gid = inode->i_gid;
88 hmac_misc.mode = inode->i_mode;
89 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
90 crypto_shash_final(desc, digest);
91}
92
93/*
94 * Calculate the HMAC value across the set of protected security xattrs.
95 *
96 * Instead of retrieving the requested xattr, for performance, calculate
97 * the hmac using the requested xattr value. Don't alloc/free memory for
98 * each xattr, but attempt to re-use the previously allocated memory.
99 */
100int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
101 const char *req_xattr_value, size_t req_xattr_value_len,
102 char *digest)
103{
104 struct inode *inode = dentry->d_inode;
105 struct shash_desc *desc;
106 char **xattrname;
107 size_t xattr_size = 0;
108 char *xattr_value = NULL;
109 int error;
110 int size;
111
112 if (!inode->i_op || !inode->i_op->getxattr)
113 return -EOPNOTSUPP;
114 desc = init_desc();
115 if (IS_ERR(desc))
116 return PTR_ERR(desc);
117
118 error = -ENODATA;
119 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
120 if ((req_xattr_name && req_xattr_value)
121 && !strcmp(*xattrname, req_xattr_name)) {
122 error = 0;
123 crypto_shash_update(desc, (const u8 *)req_xattr_value,
124 req_xattr_value_len);
125 continue;
126 }
127 size = vfs_getxattr_alloc(dentry, *xattrname,
128 &xattr_value, xattr_size, GFP_NOFS);
129 if (size == -ENOMEM) {
130 error = -ENOMEM;
131 goto out;
132 }
133 if (size < 0)
134 continue;
135
136 error = 0;
137 xattr_size = size;
138 crypto_shash_update(desc, (const u8 *)xattr_value, xattr_size);
139 }
140 hmac_add_misc(desc, inode, digest);
141
142out:
143 kfree(xattr_value);
144 kfree(desc);
145 return error;
146}
147
148/*
149 * Calculate the hmac and update security.evm xattr
150 *
151 * Expects to be called with i_mutex locked.
152 */
153int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
154 const char *xattr_value, size_t xattr_value_len)
155{
156 struct inode *inode = dentry->d_inode;
157 struct evm_ima_xattr_data xattr_data;
158 int rc = 0;
159
160 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
161 xattr_value_len, xattr_data.digest);
162 if (rc == 0) {
163 xattr_data.type = EVM_XATTR_HMAC;
164 rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
165 &xattr_data,
166 sizeof(xattr_data), 0);
167 }
168 else if (rc == -ENODATA)
169 rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
170 return rc;
171}
172
173int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
174 char *hmac_val)
175{
176 struct shash_desc *desc;
177
178 desc = init_desc();
179 if (IS_ERR(desc)) {
180 printk(KERN_INFO "init_desc failed\n");
181 return PTR_ERR(desc);
182 }
183
184 crypto_shash_update(desc, lsm_xattr->value, lsm_xattr->value_len);
185 hmac_add_misc(desc, inode, hmac_val);
186 kfree(desc);
187 return 0;
188}
189
190/*
191 * Get the key from the TPM for the SHA1-HMAC
192 */
193int evm_init_key(void)
194{
195 struct key *evm_key;
196 struct encrypted_key_payload *ekp;
197 int rc = 0;
198
199 evm_key = request_key(&key_type_encrypted, EVMKEY, NULL);
200 if (IS_ERR(evm_key))
201 return -ENOENT;
202
203 down_read(&evm_key->sem);
204 ekp = evm_key->payload.data;
205 if (ekp->decrypted_datalen > MAX_KEY_SIZE) {
206 rc = -EINVAL;
207 goto out;
208 }
209 memcpy(evmkey, ekp->decrypted_data, ekp->decrypted_datalen);
210out:
211 /* burn the original key contents */
212 memset(ekp->decrypted_data, 0, ekp->decrypted_datalen);
213 up_read(&evm_key->sem);
214 key_put(evm_key);
215 return rc;
216}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
new file mode 100644
index 000000000000..92d3d99a9f7b
--- /dev/null
+++ b/security/integrity/evm/evm_main.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright (C) 2005-2010 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2 of the License.
11 *
12 * File: evm_main.c
13 * implements evm_inode_setxattr, evm_inode_post_setxattr,
14 * evm_inode_removexattr, and evm_verifyxattr
15 */
16
17#include <linux/module.h>
18#include <linux/crypto.h>
19#include <linux/xattr.h>
20#include <linux/integrity.h>
21#include <linux/evm.h>
22#include <crypto/hash.h>
23#include "evm.h"
24
25int evm_initialized;
26
27char *evm_hmac = "hmac(sha1)";
28
29char *evm_config_xattrnames[] = {
30#ifdef CONFIG_SECURITY_SELINUX
31 XATTR_NAME_SELINUX,
32#endif
33#ifdef CONFIG_SECURITY_SMACK
34 XATTR_NAME_SMACK,
35#endif
36 XATTR_NAME_CAPS,
37 NULL
38};
39
40static int evm_fixmode;
41static int __init evm_set_fixmode(char *str)
42{
43 if (strncmp(str, "fix", 3) == 0)
44 evm_fixmode = 1;
45 return 0;
46}
47__setup("evm=", evm_set_fixmode);
48
49/*
50 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
51 *
52 * Compute the HMAC on the dentry's protected set of extended attributes
53 * and compare it against the stored security.evm xattr.
54 *
55 * For performance:
56 * - use the previoulsy retrieved xattr value and length to calculate the
57 * HMAC.)
58 * - cache the verification result in the iint, when available.
59 *
60 * Returns integrity status
61 */
62static enum integrity_status evm_verify_hmac(struct dentry *dentry,
63 const char *xattr_name,
64 char *xattr_value,
65 size_t xattr_value_len,
66 struct integrity_iint_cache *iint)
67{
68 struct evm_ima_xattr_data xattr_data;
69 enum integrity_status evm_status = INTEGRITY_PASS;
70 int rc;
71
72 if (iint && iint->evm_status == INTEGRITY_PASS)
73 return iint->evm_status;
74
75 /* if status is not PASS, try to check again - against -ENOMEM */
76
77 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
78 xattr_value_len, xattr_data.digest);
79 if (rc < 0) {
80 evm_status = (rc == -ENODATA)
81 ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
82 goto out;
83 }
84
85 xattr_data.type = EVM_XATTR_HMAC;
86 rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
87 sizeof xattr_data, GFP_NOFS);
88 if (rc < 0)
89 evm_status = (rc == -ENODATA)
90 ? INTEGRITY_NOLABEL : INTEGRITY_FAIL;
91out:
92 if (iint)
93 iint->evm_status = evm_status;
94 return evm_status;
95}
96
97static int evm_protected_xattr(const char *req_xattr_name)
98{
99 char **xattrname;
100 int namelen;
101 int found = 0;
102
103 namelen = strlen(req_xattr_name);
104 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++) {
105 if ((strlen(*xattrname) == namelen)
106 && (strncmp(req_xattr_name, *xattrname, namelen) == 0)) {
107 found = 1;
108 break;
109 }
110 if (strncmp(req_xattr_name,
111 *xattrname + XATTR_SECURITY_PREFIX_LEN,
112 strlen(req_xattr_name)) == 0) {
113 found = 1;
114 break;
115 }
116 }
117 return found;
118}
119
120/**
121 * evm_verifyxattr - verify the integrity of the requested xattr
122 * @dentry: object of the verify xattr
123 * @xattr_name: requested xattr
124 * @xattr_value: requested xattr value
125 * @xattr_value_len: requested xattr value length
126 *
127 * Calculate the HMAC for the given dentry and verify it against the stored
128 * security.evm xattr. For performance, use the xattr value and length
129 * previously retrieved to calculate the HMAC.
130 *
131 * Returns the xattr integrity status.
132 *
133 * This function requires the caller to lock the inode's i_mutex before it
134 * is executed.
135 */
136enum integrity_status evm_verifyxattr(struct dentry *dentry,
137 const char *xattr_name,
138 void *xattr_value, size_t xattr_value_len,
139 struct integrity_iint_cache *iint)
140{
141 if (!evm_initialized || !evm_protected_xattr(xattr_name))
142 return INTEGRITY_UNKNOWN;
143
144 if (!iint) {
145 iint = integrity_iint_find(dentry->d_inode);
146 if (!iint)
147 return INTEGRITY_UNKNOWN;
148 }
149 return evm_verify_hmac(dentry, xattr_name, xattr_value,
150 xattr_value_len, iint);
151}
152EXPORT_SYMBOL_GPL(evm_verifyxattr);
153
154/*
155 * evm_verify_current_integrity - verify the dentry's metadata integrity
156 * @dentry: pointer to the affected dentry
157 *
158 * Verify and return the dentry's metadata integrity. The exceptions are
159 * before EVM is initialized or in 'fix' mode.
160 */
161static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
162{
163 struct inode *inode = dentry->d_inode;
164
165 if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode)
166 return 0;
167 return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
168}
169
170/*
171 * evm_protect_xattr - protect the EVM extended attribute
172 *
173 * Prevent security.evm from being modified or removed without the
174 * necessary permissions or when the existing value is invalid.
175 *
176 * The posix xattr acls are 'system' prefixed, which normally would not
177 * affect security.evm. An interesting side affect of writing posix xattr
178 * acls is their modifying of the i_mode, which is included in security.evm.
179 * For posix xattr acls only, permit security.evm, even if it currently
180 * doesn't exist, to be updated.
181 */
182static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
183 const void *xattr_value, size_t xattr_value_len)
184{
185 enum integrity_status evm_status;
186
187 if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
188 if (!capable(CAP_SYS_ADMIN))
189 return -EPERM;
190 } else if (!evm_protected_xattr(xattr_name)) {
191 if (!posix_xattr_acl(xattr_name))
192 return 0;
193 evm_status = evm_verify_current_integrity(dentry);
194 if ((evm_status == INTEGRITY_PASS) ||
195 (evm_status == INTEGRITY_NOXATTRS))
196 return 0;
197 return -EPERM;
198 }
199 evm_status = evm_verify_current_integrity(dentry);
200 return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
201}
202
203/**
204 * evm_inode_setxattr - protect the EVM extended attribute
205 * @dentry: pointer to the affected dentry
206 * @xattr_name: pointer to the affected extended attribute name
207 * @xattr_value: pointer to the new extended attribute value
208 * @xattr_value_len: pointer to the new extended attribute value length
209 *
210 * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
211 * the current value is valid.
212 */
213int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
214 const void *xattr_value, size_t xattr_value_len)
215{
216 return evm_protect_xattr(dentry, xattr_name, xattr_value,
217 xattr_value_len);
218}
219
220/**
221 * evm_inode_removexattr - protect the EVM extended attribute
222 * @dentry: pointer to the affected dentry
223 * @xattr_name: pointer to the affected extended attribute name
224 *
225 * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
226 * the current value is valid.
227 */
228int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
229{
230 return evm_protect_xattr(dentry, xattr_name, NULL, 0);
231}
232
233/**
234 * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
235 * @dentry: pointer to the affected dentry
236 * @xattr_name: pointer to the affected extended attribute name
237 * @xattr_value: pointer to the new extended attribute value
238 * @xattr_value_len: pointer to the new extended attribute value length
239 *
240 * Update the HMAC stored in 'security.evm' to reflect the change.
241 *
242 * No need to take the i_mutex lock here, as this function is called from
243 * __vfs_setxattr_noperm(). The caller of which has taken the inode's
244 * i_mutex lock.
245 */
246void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
247 const void *xattr_value, size_t xattr_value_len)
248{
249 if (!evm_initialized || (!evm_protected_xattr(xattr_name)
250 && !posix_xattr_acl(xattr_name)))
251 return;
252
253 evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
254 return;
255}
256
257/**
258 * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
259 * @dentry: pointer to the affected dentry
260 * @xattr_name: pointer to the affected extended attribute name
261 *
262 * Update the HMAC stored in 'security.evm' to reflect removal of the xattr.
263 */
264void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
265{
266 struct inode *inode = dentry->d_inode;
267
268 if (!evm_initialized || !evm_protected_xattr(xattr_name))
269 return;
270
271 mutex_lock(&inode->i_mutex);
272 evm_update_evmxattr(dentry, xattr_name, NULL, 0);
273 mutex_unlock(&inode->i_mutex);
274 return;
275}
276
277/**
278 * evm_inode_setattr - prevent updating an invalid EVM extended attribute
279 * @dentry: pointer to the affected dentry
280 */
281int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
282{
283 unsigned int ia_valid = attr->ia_valid;
284 enum integrity_status evm_status;
285
286 if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
287 return 0;
288 evm_status = evm_verify_current_integrity(dentry);
289 if ((evm_status == INTEGRITY_PASS) ||
290 (evm_status == INTEGRITY_NOXATTRS))
291 return 0;
292 return -EPERM;
293}
294
295/**
296 * evm_inode_post_setattr - update 'security.evm' after modifying metadata
297 * @dentry: pointer to the affected dentry
298 * @ia_valid: for the UID and GID status
299 *
300 * For now, update the HMAC stored in 'security.evm' to reflect UID/GID
301 * changes.
302 *
303 * This function is called from notify_change(), which expects the caller
304 * to lock the inode's i_mutex.
305 */
306void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
307{
308 if (!evm_initialized)
309 return;
310
311 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
312 evm_update_evmxattr(dentry, NULL, NULL, 0);
313 return;
314}
315
316/*
317 * evm_inode_init_security - initializes security.evm
318 */
319int evm_inode_init_security(struct inode *inode,
320 const struct xattr *lsm_xattr,
321 struct xattr *evm_xattr)
322{
323 struct evm_ima_xattr_data *xattr_data;
324 int rc;
325
326 if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
327 return 0;
328
329 xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
330 if (!xattr_data)
331 return -ENOMEM;
332
333 xattr_data->type = EVM_XATTR_HMAC;
334 rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
335 if (rc < 0)
336 goto out;
337
338 evm_xattr->value = xattr_data;
339 evm_xattr->value_len = sizeof(*xattr_data);
340 evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS);
341 return 0;
342out:
343 kfree(xattr_data);
344 return rc;
345}
346EXPORT_SYMBOL_GPL(evm_inode_init_security);
347
348static int __init init_evm(void)
349{
350 int error;
351
352 error = evm_init_secfs();
353 if (error < 0) {
354 printk(KERN_INFO "EVM: Error registering secfs\n");
355 goto err;
356 }
357err:
358 return error;
359}
360
361static void __exit cleanup_evm(void)
362{
363 evm_cleanup_secfs();
364 if (hmac_tfm)
365 crypto_free_shash(hmac_tfm);
366}
367
368/*
369 * evm_display_config - list the EVM protected security extended attributes
370 */
371static int __init evm_display_config(void)
372{
373 char **xattrname;
374
375 for (xattrname = evm_config_xattrnames; *xattrname != NULL; xattrname++)
376 printk(KERN_INFO "EVM: %s\n", *xattrname);
377 return 0;
378}
379
380pure_initcall(evm_display_config);
381late_initcall(init_evm);
382
383MODULE_DESCRIPTION("Extended Verification Module");
384MODULE_LICENSE("GPL");
diff --git a/security/integrity/evm/evm_posix_acl.c b/security/integrity/evm/evm_posix_acl.c
new file mode 100644
index 000000000000..b1753e98bf9a
--- /dev/null
+++ b/security/integrity/evm/evm_posix_acl.c
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2011 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 */
11
12#include <linux/module.h>
13#include <linux/xattr.h>
14
15int posix_xattr_acl(char *xattr)
16{
17 int xattr_len = strlen(xattr);
18
19 if ((strlen(XATTR_NAME_POSIX_ACL_ACCESS) == xattr_len)
20 && (strncmp(XATTR_NAME_POSIX_ACL_ACCESS, xattr, xattr_len) == 0))
21 return 1;
22 if ((strlen(XATTR_NAME_POSIX_ACL_DEFAULT) == xattr_len)
23 && (strncmp(XATTR_NAME_POSIX_ACL_DEFAULT, xattr, xattr_len) == 0))
24 return 1;
25 return 0;
26}
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
new file mode 100644
index 000000000000..ac7629950578
--- /dev/null
+++ b/security/integrity/evm/evm_secfs.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * File: evm_secfs.c
12 * - Used to signal when key is on keyring
13 * - Get the key and enable EVM
14 */
15
16#include <linux/uaccess.h>
17#include <linux/module.h>
18#include "evm.h"
19
20static struct dentry *evm_init_tpm;
21
22/**
23 * evm_read_key - read() for <securityfs>/evm
24 *
25 * @filp: file pointer, not actually used
26 * @buf: where to put the result
27 * @count: maximum to send along
28 * @ppos: where to start
29 *
30 * Returns number of bytes read or error code, as appropriate
31 */
32static ssize_t evm_read_key(struct file *filp, char __user *buf,
33 size_t count, loff_t *ppos)
34{
35 char temp[80];
36 ssize_t rc;
37
38 if (*ppos != 0)
39 return 0;
40
41 sprintf(temp, "%d", evm_initialized);
42 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
43
44 return rc;
45}
46
47/**
48 * evm_write_key - write() for <securityfs>/evm
49 * @file: file pointer, not actually used
50 * @buf: where to get the data from
51 * @count: bytes sent
52 * @ppos: where to start
53 *
54 * Used to signal that key is on the kernel key ring.
55 * - get the integrity hmac key from the kernel key ring
56 * - create list of hmac protected extended attributes
57 * Returns number of bytes written or error code, as appropriate
58 */
59static ssize_t evm_write_key(struct file *file, const char __user *buf,
60 size_t count, loff_t *ppos)
61{
62 char temp[80];
63 int i, error;
64
65 if (!capable(CAP_SYS_ADMIN) || evm_initialized)
66 return -EPERM;
67
68 if (count >= sizeof(temp) || count == 0)
69 return -EINVAL;
70
71 if (copy_from_user(temp, buf, count) != 0)
72 return -EFAULT;
73
74 temp[count] = '\0';
75
76 if ((sscanf(temp, "%d", &i) != 1) || (i != 1))
77 return -EINVAL;
78
79 error = evm_init_key();
80 if (!error) {
81 evm_initialized = 1;
82 pr_info("EVM: initialized\n");
83 } else
84 pr_err("EVM: initialization failed\n");
85 return count;
86}
87
88static const struct file_operations evm_key_ops = {
89 .read = evm_read_key,
90 .write = evm_write_key,
91};
92
93int __init evm_init_secfs(void)
94{
95 int error = 0;
96
97 evm_init_tpm = securityfs_create_file("evm", S_IRUSR | S_IRGRP,
98 NULL, NULL, &evm_key_ops);
99 if (!evm_init_tpm || IS_ERR(evm_init_tpm))
100 error = -EFAULT;
101 return error;
102}
103
104void __exit evm_cleanup_secfs(void)
105{
106 if (evm_init_tpm)
107 securityfs_remove(evm_init_tpm);
108}
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
new file mode 100644
index 000000000000..399641c3e846
--- /dev/null
+++ b/security/integrity/iint.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: integrity_iint.c
13 * - implements the integrity hooks: integrity_inode_alloc,
14 * integrity_inode_free
15 * - cache integrity information associated with an inode
16 * using a rbtree tree.
17 */
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <linux/spinlock.h>
21#include <linux/rbtree.h>
22#include "integrity.h"
23
24static struct rb_root integrity_iint_tree = RB_ROOT;
25static DEFINE_SPINLOCK(integrity_iint_lock);
26static struct kmem_cache *iint_cache __read_mostly;
27
28int iint_initialized;
29
30/*
31 * __integrity_iint_find - return the iint associated with an inode
32 */
33static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
34{
35 struct integrity_iint_cache *iint;
36 struct rb_node *n = integrity_iint_tree.rb_node;
37
38 assert_spin_locked(&integrity_iint_lock);
39
40 while (n) {
41 iint = rb_entry(n, struct integrity_iint_cache, rb_node);
42
43 if (inode < iint->inode)
44 n = n->rb_left;
45 else if (inode > iint->inode)
46 n = n->rb_right;
47 else
48 break;
49 }
50 if (!n)
51 return NULL;
52
53 return iint;
54}
55
56/*
57 * integrity_iint_find - return the iint associated with an inode
58 */
59struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
60{
61 struct integrity_iint_cache *iint;
62
63 if (!IS_IMA(inode))
64 return NULL;
65
66 spin_lock(&integrity_iint_lock);
67 iint = __integrity_iint_find(inode);
68 spin_unlock(&integrity_iint_lock);
69
70 return iint;
71}
72
73static void iint_free(struct integrity_iint_cache *iint)
74{
75 iint->version = 0;
76 iint->flags = 0UL;
77 iint->evm_status = INTEGRITY_UNKNOWN;
78 kmem_cache_free(iint_cache, iint);
79}
80
81/**
82 * integrity_inode_alloc - allocate an iint associated with an inode
83 * @inode: pointer to the inode
84 */
85int integrity_inode_alloc(struct inode *inode)
86{
87 struct rb_node **p;
88 struct rb_node *new_node, *parent = NULL;
89 struct integrity_iint_cache *new_iint, *test_iint;
90 int rc;
91
92 new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
93 if (!new_iint)
94 return -ENOMEM;
95
96 new_iint->inode = inode;
97 new_node = &new_iint->rb_node;
98
99 mutex_lock(&inode->i_mutex); /* i_flags */
100 spin_lock(&integrity_iint_lock);
101
102 p = &integrity_iint_tree.rb_node;
103 while (*p) {
104 parent = *p;
105 test_iint = rb_entry(parent, struct integrity_iint_cache,
106 rb_node);
107 rc = -EEXIST;
108 if (inode < test_iint->inode)
109 p = &(*p)->rb_left;
110 else if (inode > test_iint->inode)
111 p = &(*p)->rb_right;
112 else
113 goto out_err;
114 }
115
116 inode->i_flags |= S_IMA;
117 rb_link_node(new_node, parent, p);
118 rb_insert_color(new_node, &integrity_iint_tree);
119
120 spin_unlock(&integrity_iint_lock);
121 mutex_unlock(&inode->i_mutex); /* i_flags */
122
123 return 0;
124out_err:
125 spin_unlock(&integrity_iint_lock);
126 mutex_unlock(&inode->i_mutex); /* i_flags */
127 iint_free(new_iint);
128
129 return rc;
130}
131
132/**
133 * integrity_inode_free - called on security_inode_free
134 * @inode: pointer to the inode
135 *
136 * Free the integrity information(iint) associated with an inode.
137 */
138void integrity_inode_free(struct inode *inode)
139{
140 struct integrity_iint_cache *iint;
141
142 if (!IS_IMA(inode))
143 return;
144
145 spin_lock(&integrity_iint_lock);
146 iint = __integrity_iint_find(inode);
147 rb_erase(&iint->rb_node, &integrity_iint_tree);
148 spin_unlock(&integrity_iint_lock);
149
150 iint_free(iint);
151}
152
153static void init_once(void *foo)
154{
155 struct integrity_iint_cache *iint = foo;
156
157 memset(iint, 0, sizeof *iint);
158 iint->version = 0;
159 iint->flags = 0UL;
160 mutex_init(&iint->mutex);
161 iint->evm_status = INTEGRITY_UNKNOWN;
162}
163
164static int __init integrity_iintcache_init(void)
165{
166 iint_cache =
167 kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
168 0, SLAB_PANIC, init_once);
169 iint_initialized = 1;
170 return 0;
171}
172security_initcall(integrity_iintcache_init);
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index b6ecfd4d8d78..19c053b82303 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -3,6 +3,7 @@
3config IMA 3config IMA
4 bool "Integrity Measurement Architecture(IMA)" 4 bool "Integrity Measurement Architecture(IMA)"
5 depends on SECURITY 5 depends on SECURITY
6 select INTEGRITY
6 select SECURITYFS 7 select SECURITYFS
7 select CRYPTO 8 select CRYPTO
8 select CRYPTO_HMAC 9 select CRYPTO_HMAC
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 787c4cb916cd..5690c021de8f 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -6,4 +6,4 @@
6obj-$(CONFIG_IMA) += ima.o 6obj-$(CONFIG_IMA) += ima.o
7 7
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o ima_iint.o ima_audit.o 9 ima_policy.o ima_audit.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 08408bd71462..3ccf7acac6df 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -24,18 +24,19 @@
24#include <linux/tpm.h> 24#include <linux/tpm.h>
25#include <linux/audit.h> 25#include <linux/audit.h>
26 26
27#include "../integrity.h"
28
27enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII }; 29enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_ASCII };
28enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; 30enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
29 31
30/* digest size for IMA, fits SHA1 or MD5 */ 32/* digest size for IMA, fits SHA1 or MD5 */
31#define IMA_DIGEST_SIZE 20 33#define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE
32#define IMA_EVENT_NAME_LEN_MAX 255 34#define IMA_EVENT_NAME_LEN_MAX 255
33 35
34#define IMA_HASH_BITS 9 36#define IMA_HASH_BITS 9
35#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) 37#define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS)
36 38
37/* set during initialization */ 39/* set during initialization */
38extern int iint_initialized;
39extern int ima_initialized; 40extern int ima_initialized;
40extern int ima_used_chip; 41extern int ima_used_chip;
41extern char *ima_hash; 42extern char *ima_hash;
@@ -96,34 +97,21 @@ static inline unsigned long ima_hash_key(u8 *digest)
96 return hash_long(*digest, IMA_HASH_BITS); 97 return hash_long(*digest, IMA_HASH_BITS);
97} 98}
98 99
99/* iint cache flags */
100#define IMA_MEASURED 0x01
101
102/* integrity data associated with an inode */
103struct ima_iint_cache {
104 struct rb_node rb_node; /* rooted in ima_iint_tree */
105 struct inode *inode; /* back pointer to inode in question */
106 u64 version; /* track inode changes */
107 unsigned char flags;
108 u8 digest[IMA_DIGEST_SIZE];
109 struct mutex mutex; /* protects: version, flags, digest */
110};
111
112/* LIM API function definitions */ 100/* LIM API function definitions */
113int ima_must_measure(struct inode *inode, int mask, int function); 101int ima_must_measure(struct inode *inode, int mask, int function);
114int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file); 102int ima_collect_measurement(struct integrity_iint_cache *iint,
115void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, 103 struct file *file);
104void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
116 const unsigned char *filename); 105 const unsigned char *filename);
117int ima_store_template(struct ima_template_entry *entry, int violation, 106int ima_store_template(struct ima_template_entry *entry, int violation,
118 struct inode *inode); 107 struct inode *inode);
119void ima_template_show(struct seq_file *m, void *e, 108void ima_template_show(struct seq_file *m, void *e, enum ima_show_type show);
120 enum ima_show_type show);
121 109
122/* rbtree tree calls to lookup, insert, delete 110/* rbtree tree calls to lookup, insert, delete
123 * integrity data associated with an inode. 111 * integrity data associated with an inode.
124 */ 112 */
125struct ima_iint_cache *ima_iint_insert(struct inode *inode); 113struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
126struct ima_iint_cache *ima_iint_find(struct inode *inode); 114struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
127 115
128/* IMA policy related functions */ 116/* IMA policy related functions */
129enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 117enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index da36d2c085a4..0d50df04ccc4 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -126,7 +126,8 @@ int ima_must_measure(struct inode *inode, int mask, int function)
126 * 126 *
127 * Return 0 on success, error code otherwise 127 * Return 0 on success, error code otherwise
128 */ 128 */
129int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file) 129int ima_collect_measurement(struct integrity_iint_cache *iint,
130 struct file *file)
130{ 131{
131 int result = -EEXIST; 132 int result = -EEXIST;
132 133
@@ -156,8 +157,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file)
156 * 157 *
157 * Must be called with iint->mutex held. 158 * Must be called with iint->mutex held.
158 */ 159 */
159void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, 160void ima_store_measurement(struct integrity_iint_cache *iint,
160 const unsigned char *filename) 161 struct file *file, const unsigned char *filename)
161{ 162{
162 const char *op = "add_template_measure"; 163 const char *op = "add_template_measure";
163 const char *audit_cause = "ENOMEM"; 164 const char *audit_cause = "ENOMEM";
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index ef21b96a0b42..e1aa2b482dd2 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -287,7 +287,7 @@ static atomic_t policy_opencount = ATOMIC_INIT(1);
287/* 287/*
288 * ima_open_policy: sequentialize access to the policy file 288 * ima_open_policy: sequentialize access to the policy file
289 */ 289 */
290int ima_open_policy(struct inode * inode, struct file * filp) 290static int ima_open_policy(struct inode * inode, struct file * filp)
291{ 291{
292 /* No point in being allowed to open it if you aren't going to write */ 292 /* No point in being allowed to open it if you aren't going to write */
293 if (!(filp->f_flags & O_WRONLY)) 293 if (!(filp->f_flags & O_WRONLY))
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
deleted file mode 100644
index 4ae73040ab7b..000000000000
--- a/security/integrity/ima/ima_iint.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 * File: ima_iint.c
13 * - implements the IMA hooks: ima_inode_alloc, ima_inode_free
14 * - cache integrity information associated with an inode
15 * using a rbtree tree.
16 */
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/spinlock.h>
20#include <linux/rbtree.h>
21#include "ima.h"
22
23static struct rb_root ima_iint_tree = RB_ROOT;
24static DEFINE_SPINLOCK(ima_iint_lock);
25static struct kmem_cache *iint_cache __read_mostly;
26
27int iint_initialized = 0;
28
29/*
30 * __ima_iint_find - return the iint associated with an inode
31 */
32static struct ima_iint_cache *__ima_iint_find(struct inode *inode)
33{
34 struct ima_iint_cache *iint;
35 struct rb_node *n = ima_iint_tree.rb_node;
36
37 assert_spin_locked(&ima_iint_lock);
38
39 while (n) {
40 iint = rb_entry(n, struct ima_iint_cache, rb_node);
41
42 if (inode < iint->inode)
43 n = n->rb_left;
44 else if (inode > iint->inode)
45 n = n->rb_right;
46 else
47 break;
48 }
49 if (!n)
50 return NULL;
51
52 return iint;
53}
54
55/*
56 * ima_iint_find - return the iint associated with an inode
57 */
58struct ima_iint_cache *ima_iint_find(struct inode *inode)
59{
60 struct ima_iint_cache *iint;
61
62 if (!IS_IMA(inode))
63 return NULL;
64
65 spin_lock(&ima_iint_lock);
66 iint = __ima_iint_find(inode);
67 spin_unlock(&ima_iint_lock);
68
69 return iint;
70}
71
72static void iint_free(struct ima_iint_cache *iint)
73{
74 iint->version = 0;
75 iint->flags = 0UL;
76 kmem_cache_free(iint_cache, iint);
77}
78
79/**
80 * ima_inode_alloc - allocate an iint associated with an inode
81 * @inode: pointer to the inode
82 */
83int ima_inode_alloc(struct inode *inode)
84{
85 struct rb_node **p;
86 struct rb_node *new_node, *parent = NULL;
87 struct ima_iint_cache *new_iint, *test_iint;
88 int rc;
89
90 new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
91 if (!new_iint)
92 return -ENOMEM;
93
94 new_iint->inode = inode;
95 new_node = &new_iint->rb_node;
96
97 mutex_lock(&inode->i_mutex); /* i_flags */
98 spin_lock(&ima_iint_lock);
99
100 p = &ima_iint_tree.rb_node;
101 while (*p) {
102 parent = *p;
103 test_iint = rb_entry(parent, struct ima_iint_cache, rb_node);
104
105 rc = -EEXIST;
106 if (inode < test_iint->inode)
107 p = &(*p)->rb_left;
108 else if (inode > test_iint->inode)
109 p = &(*p)->rb_right;
110 else
111 goto out_err;
112 }
113
114 inode->i_flags |= S_IMA;
115 rb_link_node(new_node, parent, p);
116 rb_insert_color(new_node, &ima_iint_tree);
117
118 spin_unlock(&ima_iint_lock);
119 mutex_unlock(&inode->i_mutex); /* i_flags */
120
121 return 0;
122out_err:
123 spin_unlock(&ima_iint_lock);
124 mutex_unlock(&inode->i_mutex); /* i_flags */
125 iint_free(new_iint);
126
127 return rc;
128}
129
130/**
131 * ima_inode_free - called on security_inode_free
132 * @inode: pointer to the inode
133 *
134 * Free the integrity information(iint) associated with an inode.
135 */
136void ima_inode_free(struct inode *inode)
137{
138 struct ima_iint_cache *iint;
139
140 if (!IS_IMA(inode))
141 return;
142
143 spin_lock(&ima_iint_lock);
144 iint = __ima_iint_find(inode);
145 rb_erase(&iint->rb_node, &ima_iint_tree);
146 spin_unlock(&ima_iint_lock);
147
148 iint_free(iint);
149}
150
151static void init_once(void *foo)
152{
153 struct ima_iint_cache *iint = foo;
154
155 memset(iint, 0, sizeof *iint);
156 iint->version = 0;
157 iint->flags = 0UL;
158 mutex_init(&iint->mutex);
159}
160
161static int __init ima_iintcache_init(void)
162{
163 iint_cache =
164 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
165 SLAB_PANIC, init_once);
166 iint_initialized = 1;
167 return 0;
168}
169security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 26b46ff74663..1eff5cb001e5 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -22,6 +22,7 @@
22#include <linux/mount.h> 22#include <linux/mount.h>
23#include <linux/mman.h> 23#include <linux/mman.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/ima.h>
25 26
26#include "ima.h" 27#include "ima.h"
27 28
@@ -82,7 +83,7 @@ out:
82 "open_writers"); 83 "open_writers");
83} 84}
84 85
85static void ima_check_last_writer(struct ima_iint_cache *iint, 86static void ima_check_last_writer(struct integrity_iint_cache *iint,
86 struct inode *inode, 87 struct inode *inode,
87 struct file *file) 88 struct file *file)
88{ 89{
@@ -105,12 +106,12 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
105void ima_file_free(struct file *file) 106void ima_file_free(struct file *file)
106{ 107{
107 struct inode *inode = file->f_dentry->d_inode; 108 struct inode *inode = file->f_dentry->d_inode;
108 struct ima_iint_cache *iint; 109 struct integrity_iint_cache *iint;
109 110
110 if (!iint_initialized || !S_ISREG(inode->i_mode)) 111 if (!iint_initialized || !S_ISREG(inode->i_mode))
111 return; 112 return;
112 113
113 iint = ima_iint_find(inode); 114 iint = integrity_iint_find(inode);
114 if (!iint) 115 if (!iint)
115 return; 116 return;
116 117
@@ -121,7 +122,7 @@ static int process_measurement(struct file *file, const unsigned char *filename,
121 int mask, int function) 122 int mask, int function)
122{ 123{
123 struct inode *inode = file->f_dentry->d_inode; 124 struct inode *inode = file->f_dentry->d_inode;
124 struct ima_iint_cache *iint; 125 struct integrity_iint_cache *iint;
125 int rc = 0; 126 int rc = 0;
126 127
127 if (!ima_initialized || !S_ISREG(inode->i_mode)) 128 if (!ima_initialized || !S_ISREG(inode->i_mode))
@@ -131,9 +132,9 @@ static int process_measurement(struct file *file, const unsigned char *filename,
131 if (rc != 0) 132 if (rc != 0)
132 return rc; 133 return rc;
133retry: 134retry:
134 iint = ima_iint_find(inode); 135 iint = integrity_iint_find(inode);
135 if (!iint) { 136 if (!iint) {
136 rc = ima_inode_alloc(inode); 137 rc = integrity_inode_alloc(inode);
137 if (!rc || rc == -EEXIST) 138 if (!rc || rc == -EEXIST)
138 goto retry; 139 goto retry;
139 return rc; 140 return rc;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
new file mode 100644
index 000000000000..3143a3c39868
--- /dev/null
+++ b/security/integrity/integrity.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2009-2010 IBM Corporation
3 *
4 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2 of the
10 * License.
11 *
12 */
13
14#include <linux/types.h>
15#include <linux/integrity.h>
16#include <crypto/sha.h>
17
18/* iint cache flags */
19#define IMA_MEASURED 0x01
20
21enum evm_ima_xattr_type {
22 IMA_XATTR_DIGEST = 0x01,
23 EVM_XATTR_HMAC,
24 EVM_IMA_XATTR_DIGSIG,
25};
26
27struct evm_ima_xattr_data {
28 u8 type;
29 u8 digest[SHA1_DIGEST_SIZE];
30} __attribute__((packed));
31
32/* integrity data associated with an inode */
33struct integrity_iint_cache {
34 struct rb_node rb_node; /* rooted in integrity_iint_tree */
35 struct inode *inode; /* back pointer to inode in question */
36 u64 version; /* track inode changes */
37 unsigned char flags;
38 u8 digest[SHA1_DIGEST_SIZE];
39 struct mutex mutex; /* protects: version, flags, digest */
40 enum integrity_status evm_status;
41};
42
43/* rbtree tree calls to lookup, insert, delete
44 * integrity data associated with an inode.
45 */
46struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
47struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
48
49/* set during initialization */
50extern int iint_initialized;
diff --git a/security/keys/Makefile b/security/keys/Makefile
index b34cc6ee6900..a56f1ffdc64d 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,7 +14,7 @@ obj-y := \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o 16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += ecryptfs_format.o encrypted.o 17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted-keys/
18obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/encrypted-keys/Makefile b/security/keys/encrypted-keys/Makefile
new file mode 100644
index 000000000000..6bc7a86d1027
--- /dev/null
+++ b/security/keys/encrypted-keys/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for encrypted keys
3#
4
5obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o ecryptfs_format.o
6obj-$(CONFIG_TRUSTED_KEYS) += masterkey_trusted.o
diff --git a/security/keys/ecryptfs_format.c b/security/keys/encrypted-keys/ecryptfs_format.c
index 6daa3b6ff9ed..6daa3b6ff9ed 100644
--- a/security/keys/ecryptfs_format.c
+++ b/security/keys/encrypted-keys/ecryptfs_format.c
diff --git a/security/keys/ecryptfs_format.h b/security/keys/encrypted-keys/ecryptfs_format.h
index 40294de238bb..40294de238bb 100644
--- a/security/keys/ecryptfs_format.h
+++ b/security/keys/encrypted-keys/ecryptfs_format.h
diff --git a/security/keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index e7eca9ec4c65..f33804c1b4c8 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -299,31 +299,6 @@ out:
299} 299}
300 300
301/* 301/*
302 * request_trusted_key - request the trusted key
303 *
304 * Trusted keys are sealed to PCRs and other metadata. Although userspace
305 * manages both trusted/encrypted key-types, like the encrypted key type
306 * data, trusted key type data is not visible decrypted from userspace.
307 */
308static struct key *request_trusted_key(const char *trusted_desc,
309 u8 **master_key, size_t *master_keylen)
310{
311 struct trusted_key_payload *tpayload;
312 struct key *tkey;
313
314 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
315 if (IS_ERR(tkey))
316 goto error;
317
318 down_read(&tkey->sem);
319 tpayload = rcu_dereference(tkey->payload.data);
320 *master_key = tpayload->key;
321 *master_keylen = tpayload->key_len;
322error:
323 return tkey;
324}
325
326/*
327 * request_user_key - request the user key 302 * request_user_key - request the user key
328 * 303 *
329 * Use a user provided key to encrypt/decrypt an encrypted-key. 304 * Use a user provided key to encrypt/decrypt an encrypted-key.
@@ -469,8 +444,14 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
469 goto out; 444 goto out;
470 445
471 if (IS_ERR(mkey)) { 446 if (IS_ERR(mkey)) {
472 pr_info("encrypted_key: key %s not found", 447 int ret = PTR_ERR(epayload);
473 epayload->master_desc); 448
449 if (ret == -ENOTSUPP)
450 pr_info("encrypted_key: key %s not supported",
451 epayload->master_desc);
452 else
453 pr_info("encrypted_key: key %s not found",
454 epayload->master_desc);
474 goto out; 455 goto out;
475 } 456 }
476 457
@@ -686,11 +667,19 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
686 return -EINVAL; 667 return -EINVAL;
687 668
688 hex_encoded_data = hex_encoded_iv + (2 * ivsize) + 2; 669 hex_encoded_data = hex_encoded_iv + (2 * ivsize) + 2;
689 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 670 ret = hex2bin(epayload->iv, hex_encoded_iv, ivsize);
690 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 671 if (ret < 0)
672 return -EINVAL;
673 ret = hex2bin(epayload->encrypted_data, hex_encoded_data,
674 encrypted_datalen);
675 if (ret < 0)
676 return -EINVAL;
691 677
692 hmac = epayload->format + epayload->datablob_len; 678 hmac = epayload->format + epayload->datablob_len;
693 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 679 ret = hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2),
680 HASH_SIZE);
681 if (ret < 0)
682 return -EINVAL;
694 683
695 mkey = request_master_key(epayload, &master_key, &master_keylen); 684 mkey = request_master_key(epayload, &master_key, &master_keylen);
696 if (IS_ERR(mkey)) 685 if (IS_ERR(mkey))
diff --git a/security/keys/encrypted.h b/security/keys/encrypted-keys/encrypted.h
index cef5e2f2b7d1..b6ade8945250 100644
--- a/security/keys/encrypted.h
+++ b/security/keys/encrypted-keys/encrypted.h
@@ -2,6 +2,17 @@
2#define __ENCRYPTED_KEY_H 2#define __ENCRYPTED_KEY_H
3 3
4#define ENCRYPTED_DEBUG 0 4#define ENCRYPTED_DEBUG 0
5#ifdef CONFIG_TRUSTED_KEYS
6extern struct key *request_trusted_key(const char *trusted_desc,
7 u8 **master_key, size_t *master_keylen);
8#else
9static inline struct key *request_trusted_key(const char *trusted_desc,
10 u8 **master_key,
11 size_t *master_keylen)
12{
13 return ERR_PTR(-EOPNOTSUPP);
14}
15#endif
5 16
6#if ENCRYPTED_DEBUG 17#if ENCRYPTED_DEBUG
7static inline void dump_master_key(const u8 *master_key, size_t master_keylen) 18static inline void dump_master_key(const u8 *master_key, size_t master_keylen)
diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c
new file mode 100644
index 000000000000..df87272e3f51
--- /dev/null
+++ b/security/keys/encrypted-keys/masterkey_trusted.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 * Copyright (C) 2010 Politecnico di Torino, Italy
4 * TORSEC group -- http://security.polito.it
5 *
6 * Authors:
7 * Mimi Zohar <zohar@us.ibm.com>
8 * Roberto Sassu <roberto.sassu@polito.it>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, version 2 of the License.
13 *
14 * See Documentation/security/keys-trusted-encrypted.txt
15 */
16
17#include <linux/uaccess.h>
18#include <linux/module.h>
19#include <linux/err.h>
20#include <keys/trusted-type.h>
21
22/*
23 * request_trusted_key - request the trusted key
24 *
25 * Trusted keys are sealed to PCRs and other metadata. Although userspace
26 * manages both trusted/encrypted key-types, like the encrypted key type
27 * data, trusted key type data is not visible decrypted from userspace.
28 */
29struct key *request_trusted_key(const char *trusted_desc,
30 u8 **master_key, size_t *master_keylen)
31{
32 struct trusted_key_payload *tpayload;
33 struct key *tkey;
34
35 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
36 if (IS_ERR(tkey))
37 goto error;
38
39 down_read(&tkey->sem);
40 tpayload = rcu_dereference(tkey->payload.data);
41 *master_key = tpayload->key;
42 *master_keylen = tpayload->key_len;
43error:
44 return tkey;
45}
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 89df6b5f203c..bf4d8da5a795 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -1,6 +1,6 @@
1/* Key garbage collector 1/* Key garbage collector
2 * 2 *
3 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2009-2011 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -10,6 +10,8 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/security.h>
13#include <keys/keyring-type.h> 15#include <keys/keyring-type.h>
14#include "internal.h" 16#include "internal.h"
15 17
@@ -19,17 +21,33 @@
19unsigned key_gc_delay = 5 * 60; 21unsigned key_gc_delay = 5 * 60;
20 22
21/* 23/*
22 * Reaper 24 * Reaper for unused keys.
25 */
26static void key_garbage_collector(struct work_struct *work);
27DECLARE_WORK(key_gc_work, key_garbage_collector);
28
29/*
30 * Reaper for links from keyrings to dead keys.
23 */ 31 */
24static void key_gc_timer_func(unsigned long); 32static void key_gc_timer_func(unsigned long);
25static void key_garbage_collector(struct work_struct *);
26static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0); 33static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
27static DECLARE_WORK(key_gc_work, key_garbage_collector); 34
28static key_serial_t key_gc_cursor; /* the last key the gc considered */
29static bool key_gc_again;
30static unsigned long key_gc_executing;
31static time_t key_gc_next_run = LONG_MAX; 35static time_t key_gc_next_run = LONG_MAX;
32static time_t key_gc_new_timer; 36static struct key_type *key_gc_dead_keytype;
37
38static unsigned long key_gc_flags;
39#define KEY_GC_KEY_EXPIRED 0 /* A key expired and needs unlinking */
40#define KEY_GC_REAP_KEYTYPE 1 /* A keytype is being unregistered */
41#define KEY_GC_REAPING_KEYTYPE 2 /* Cleared when keytype reaped */
42
43
44/*
45 * Any key whose type gets unregistered will be re-typed to this if it can't be
46 * immediately unlinked.
47 */
48struct key_type key_type_dead = {
49 .name = "dead",
50};
33 51
34/* 52/*
35 * Schedule a garbage collection run. 53 * Schedule a garbage collection run.
@@ -42,31 +60,75 @@ void key_schedule_gc(time_t gc_at)
42 60
43 kenter("%ld", gc_at - now); 61 kenter("%ld", gc_at - now);
44 62
45 if (gc_at <= now) { 63 if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
46 schedule_work(&key_gc_work); 64 kdebug("IMMEDIATE");
65 queue_work(system_nrt_wq, &key_gc_work);
47 } else if (gc_at < key_gc_next_run) { 66 } else if (gc_at < key_gc_next_run) {
67 kdebug("DEFERRED");
68 key_gc_next_run = gc_at;
48 expires = jiffies + (gc_at - now) * HZ; 69 expires = jiffies + (gc_at - now) * HZ;
49 mod_timer(&key_gc_timer, expires); 70 mod_timer(&key_gc_timer, expires);
50 } 71 }
51} 72}
52 73
53/* 74/*
54 * The garbage collector timer kicked off 75 * Some key's cleanup time was met after it expired, so we need to get the
76 * reaper to go through a cycle finding expired keys.
55 */ 77 */
56static void key_gc_timer_func(unsigned long data) 78static void key_gc_timer_func(unsigned long data)
57{ 79{
58 kenter(""); 80 kenter("");
59 key_gc_next_run = LONG_MAX; 81 key_gc_next_run = LONG_MAX;
60 schedule_work(&key_gc_work); 82 set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags);
83 queue_work(system_nrt_wq, &key_gc_work);
84}
85
86/*
87 * wait_on_bit() sleep function for uninterruptible waiting
88 */
89static int key_gc_wait_bit(void *flags)
90{
91 schedule();
92 return 0;
93}
94
95/*
96 * Reap keys of dead type.
97 *
98 * We use three flags to make sure we see three complete cycles of the garbage
99 * collector: the first to mark keys of that type as being dead, the second to
100 * collect dead links and the third to clean up the dead keys. We have to be
101 * careful as there may already be a cycle in progress.
102 *
103 * The caller must be holding key_types_sem.
104 */
105void key_gc_keytype(struct key_type *ktype)
106{
107 kenter("%s", ktype->name);
108
109 key_gc_dead_keytype = ktype;
110 set_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
111 smp_mb();
112 set_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags);
113
114 kdebug("schedule");
115 queue_work(system_nrt_wq, &key_gc_work);
116
117 kdebug("sleep");
118 wait_on_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE, key_gc_wait_bit,
119 TASK_UNINTERRUPTIBLE);
120
121 key_gc_dead_keytype = NULL;
122 kleave("");
61} 123}
62 124
63/* 125/*
64 * Garbage collect pointers from a keyring. 126 * Garbage collect pointers from a keyring.
65 * 127 *
66 * Return true if we altered the keyring. 128 * Not called with any locks held. The keyring's key struct will not be
129 * deallocated under us as only our caller may deallocate it.
67 */ 130 */
68static bool key_gc_keyring(struct key *keyring, time_t limit) 131static void key_gc_keyring(struct key *keyring, time_t limit)
69 __releases(key_serial_lock)
70{ 132{
71 struct keyring_list *klist; 133 struct keyring_list *klist;
72 struct key *key; 134 struct key *key;
@@ -93,130 +155,234 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
93unlock_dont_gc: 155unlock_dont_gc:
94 rcu_read_unlock(); 156 rcu_read_unlock();
95dont_gc: 157dont_gc:
96 kleave(" = false"); 158 kleave(" [no gc]");
97 return false; 159 return;
98 160
99do_gc: 161do_gc:
100 rcu_read_unlock(); 162 rcu_read_unlock();
101 key_gc_cursor = keyring->serial; 163
102 key_get(keyring);
103 spin_unlock(&key_serial_lock);
104 keyring_gc(keyring, limit); 164 keyring_gc(keyring, limit);
105 key_put(keyring); 165 kleave(" [gc]");
106 kleave(" = true");
107 return true;
108} 166}
109 167
110/* 168/*
111 * Garbage collector for keys. This involves scanning the keyrings for dead, 169 * Garbage collect an unreferenced, detached key
112 * expired and revoked keys that have overstayed their welcome
113 */ 170 */
114static void key_garbage_collector(struct work_struct *work) 171static noinline void key_gc_unused_key(struct key *key)
115{ 172{
116 struct rb_node *rb; 173 key_check(key);
117 key_serial_t cursor; 174
118 struct key *key, *xkey; 175 security_key_free(key);
119 time_t new_timer = LONG_MAX, limit, now; 176
120 177 /* deal with the user's key tracking and quota */
121 now = current_kernel_time().tv_sec; 178 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
122 kenter("[%x,%ld]", key_gc_cursor, key_gc_new_timer - now); 179 spin_lock(&key->user->lock);
123 180 key->user->qnkeys--;
124 if (test_and_set_bit(0, &key_gc_executing)) { 181 key->user->qnbytes -= key->quotalen;
125 key_schedule_gc(current_kernel_time().tv_sec + 1); 182 spin_unlock(&key->user->lock);
126 kleave(" [busy; deferring]");
127 return;
128 } 183 }
129 184
130 limit = now; 185 atomic_dec(&key->user->nkeys);
186 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
187 atomic_dec(&key->user->nikeys);
188
189 key_user_put(key->user);
190
191 /* now throw away the key memory */
192 if (key->type->destroy)
193 key->type->destroy(key);
194
195 kfree(key->description);
196
197#ifdef KEY_DEBUGGING
198 key->magic = KEY_DEBUG_MAGIC_X;
199#endif
200 kmem_cache_free(key_jar, key);
201}
202
203/*
204 * Garbage collector for unused keys.
205 *
206 * This is done in process context so that we don't have to disable interrupts
207 * all over the place. key_put() schedules this rather than trying to do the
208 * cleanup itself, which means key_put() doesn't have to sleep.
209 */
210static void key_garbage_collector(struct work_struct *work)
211{
212 static u8 gc_state; /* Internal persistent state */
213#define KEY_GC_REAP_AGAIN 0x01 /* - Need another cycle */
214#define KEY_GC_REAPING_LINKS 0x02 /* - We need to reap links */
215#define KEY_GC_SET_TIMER 0x04 /* - We need to restart the timer */
216#define KEY_GC_REAPING_DEAD_1 0x10 /* - We need to mark dead keys */
217#define KEY_GC_REAPING_DEAD_2 0x20 /* - We need to reap dead key links */
218#define KEY_GC_REAPING_DEAD_3 0x40 /* - We need to reap dead keys */
219#define KEY_GC_FOUND_DEAD_KEY 0x80 /* - We found at least one dead key */
220
221 struct rb_node *cursor;
222 struct key *key;
223 time_t new_timer, limit;
224
225 kenter("[%lx,%x]", key_gc_flags, gc_state);
226
227 limit = current_kernel_time().tv_sec;
131 if (limit > key_gc_delay) 228 if (limit > key_gc_delay)
132 limit -= key_gc_delay; 229 limit -= key_gc_delay;
133 else 230 else
134 limit = key_gc_delay; 231 limit = key_gc_delay;
135 232
233 /* Work out what we're going to be doing in this pass */
234 gc_state &= KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2;
235 gc_state <<= 1;
236 if (test_and_clear_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags))
237 gc_state |= KEY_GC_REAPING_LINKS | KEY_GC_SET_TIMER;
238
239 if (test_and_clear_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags))
240 gc_state |= KEY_GC_REAPING_DEAD_1;
241 kdebug("new pass %x", gc_state);
242
243 new_timer = LONG_MAX;
244
245 /* As only this function is permitted to remove things from the key
246 * serial tree, if cursor is non-NULL then it will always point to a
247 * valid node in the tree - even if lock got dropped.
248 */
136 spin_lock(&key_serial_lock); 249 spin_lock(&key_serial_lock);
250 cursor = rb_first(&key_serial_tree);
137 251
138 if (unlikely(RB_EMPTY_ROOT(&key_serial_tree))) { 252continue_scanning:
139 spin_unlock(&key_serial_lock); 253 while (cursor) {
140 clear_bit(0, &key_gc_executing); 254 key = rb_entry(cursor, struct key, serial_node);
141 return; 255 cursor = rb_next(cursor);
142 }
143 256
144 cursor = key_gc_cursor; 257 if (atomic_read(&key->usage) == 0)
145 if (cursor < 0) 258 goto found_unreferenced_key;
146 cursor = 0; 259
147 if (cursor > 0) 260 if (unlikely(gc_state & KEY_GC_REAPING_DEAD_1)) {
148 new_timer = key_gc_new_timer; 261 if (key->type == key_gc_dead_keytype) {
149 else 262 gc_state |= KEY_GC_FOUND_DEAD_KEY;
150 key_gc_again = false; 263 set_bit(KEY_FLAG_DEAD, &key->flags);
151 264 key->perm = 0;
152 /* find the first key above the cursor */ 265 goto skip_dead_key;
153 key = NULL; 266 }
154 rb = key_serial_tree.rb_node; 267 }
155 while (rb) { 268
156 xkey = rb_entry(rb, struct key, serial_node); 269 if (gc_state & KEY_GC_SET_TIMER) {
157 if (cursor < xkey->serial) { 270 if (key->expiry > limit && key->expiry < new_timer) {
158 key = xkey; 271 kdebug("will expire %x in %ld",
159 rb = rb->rb_left; 272 key_serial(key), key->expiry - limit);
160 } else if (cursor > xkey->serial) { 273 new_timer = key->expiry;
161 rb = rb->rb_right; 274 }
162 } else {
163 rb = rb_next(rb);
164 if (!rb)
165 goto reached_the_end;
166 key = rb_entry(rb, struct key, serial_node);
167 break;
168 } 275 }
169 }
170 276
171 if (!key) 277 if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2))
172 goto reached_the_end; 278 if (key->type == key_gc_dead_keytype)
279 gc_state |= KEY_GC_FOUND_DEAD_KEY;
173 280
174 /* trawl through the keys looking for keyrings */ 281 if ((gc_state & KEY_GC_REAPING_LINKS) ||
175 for (;;) { 282 unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
176 if (key->expiry > limit && key->expiry < new_timer) { 283 if (key->type == &key_type_keyring)
177 kdebug("will expire %x in %ld", 284 goto found_keyring;
178 key_serial(key), key->expiry - limit);
179 new_timer = key->expiry;
180 } 285 }
181 286
182 if (key->type == &key_type_keyring && 287 if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3))
183 key_gc_keyring(key, limit)) 288 if (key->type == key_gc_dead_keytype)
184 /* the gc had to release our lock so that the keyring 289 goto destroy_dead_key;
185 * could be modified, so we have to get it again */
186 goto gc_released_our_lock;
187 290
188 rb = rb_next(&key->serial_node); 291 skip_dead_key:
189 if (!rb) 292 if (spin_is_contended(&key_serial_lock) || need_resched())
190 goto reached_the_end; 293 goto contended;
191 key = rb_entry(rb, struct key, serial_node);
192 } 294 }
193 295
194gc_released_our_lock: 296contended:
195 kdebug("gc_released_our_lock");
196 key_gc_new_timer = new_timer;
197 key_gc_again = true;
198 clear_bit(0, &key_gc_executing);
199 schedule_work(&key_gc_work);
200 kleave(" [continue]");
201 return;
202
203 /* when we reach the end of the run, we set the timer for the next one */
204reached_the_end:
205 kdebug("reached_the_end");
206 spin_unlock(&key_serial_lock); 297 spin_unlock(&key_serial_lock);
207 key_gc_new_timer = new_timer; 298
208 key_gc_cursor = 0; 299maybe_resched:
209 clear_bit(0, &key_gc_executing); 300 if (cursor) {
210 301 cond_resched();
211 if (key_gc_again) { 302 spin_lock(&key_serial_lock);
212 /* there may have been a key that expired whilst we were 303 goto continue_scanning;
213 * scanning, so if we discarded any links we should do another 304 }
214 * scan */ 305
215 new_timer = now + 1; 306 /* We've completed the pass. Set the timer if we need to and queue a
216 key_schedule_gc(new_timer); 307 * new cycle if necessary. We keep executing cycles until we find one
217 } else if (new_timer < LONG_MAX) { 308 * where we didn't reap any keys.
309 */
310 kdebug("pass complete");
311
312 if (gc_state & KEY_GC_SET_TIMER && new_timer != (time_t)LONG_MAX) {
218 new_timer += key_gc_delay; 313 new_timer += key_gc_delay;
219 key_schedule_gc(new_timer); 314 key_schedule_gc(new_timer);
220 } 315 }
221 kleave(" [end]"); 316
317 if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
318 /* Make sure everyone revalidates their keys if we marked a
319 * bunch as being dead and make sure all keyring ex-payloads
320 * are destroyed.
321 */
322 kdebug("dead sync");
323 synchronize_rcu();
324 }
325
326 if (unlikely(gc_state & (KEY_GC_REAPING_DEAD_1 |
327 KEY_GC_REAPING_DEAD_2))) {
328 if (!(gc_state & KEY_GC_FOUND_DEAD_KEY)) {
329 /* No remaining dead keys: short circuit the remaining
330 * keytype reap cycles.
331 */
332 kdebug("dead short");
333 gc_state &= ~(KEY_GC_REAPING_DEAD_1 | KEY_GC_REAPING_DEAD_2);
334 gc_state |= KEY_GC_REAPING_DEAD_3;
335 } else {
336 gc_state |= KEY_GC_REAP_AGAIN;
337 }
338 }
339
340 if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
341 kdebug("dead wake");
342 smp_mb();
343 clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
344 wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
345 }
346
347 if (gc_state & KEY_GC_REAP_AGAIN)
348 queue_work(system_nrt_wq, &key_gc_work);
349 kleave(" [end %x]", gc_state);
350 return;
351
352 /* We found an unreferenced key - once we've removed it from the tree,
353 * we can safely drop the lock.
354 */
355found_unreferenced_key:
356 kdebug("unrefd key %d", key->serial);
357 rb_erase(&key->serial_node, &key_serial_tree);
358 spin_unlock(&key_serial_lock);
359
360 key_gc_unused_key(key);
361 gc_state |= KEY_GC_REAP_AGAIN;
362 goto maybe_resched;
363
364 /* We found a keyring and we need to check the payload for links to
365 * dead or expired keys. We don't flag another reap immediately as we
366 * have to wait for the old payload to be destroyed by RCU before we
367 * can reap the keys to which it refers.
368 */
369found_keyring:
370 spin_unlock(&key_serial_lock);
371 kdebug("scan keyring %d", key->serial);
372 key_gc_keyring(key, limit);
373 goto maybe_resched;
374
375 /* We found a dead key that is still referenced. Reset its type and
376 * destroy its payload with its semaphore held.
377 */
378destroy_dead_key:
379 spin_unlock(&key_serial_lock);
380 kdebug("destroy key %d", key->serial);
381 down_write(&key->sem);
382 key->type = &key_type_dead;
383 if (key_gc_dead_keytype->destroy)
384 key_gc_dead_keytype->destroy(key);
385 memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
386 up_write(&key->sem);
387 goto maybe_resched;
222} 388}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index f375152a2500..c7a7caec4830 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -31,6 +31,7 @@
31 no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__) 31 no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__)
32#endif 32#endif
33 33
34extern struct key_type key_type_dead;
34extern struct key_type key_type_user; 35extern struct key_type key_type_user;
35 36
36/*****************************************************************************/ 37/*****************************************************************************/
@@ -75,6 +76,7 @@ extern unsigned key_quota_maxbytes;
75#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */ 76#define KEYQUOTA_LINK_BYTES 4 /* a link in a keyring is worth 4 bytes */
76 77
77 78
79extern struct kmem_cache *key_jar;
78extern struct rb_root key_serial_tree; 80extern struct rb_root key_serial_tree;
79extern spinlock_t key_serial_lock; 81extern spinlock_t key_serial_lock;
80extern struct mutex key_construction_mutex; 82extern struct mutex key_construction_mutex;
@@ -146,9 +148,11 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
146 148
147extern long join_session_keyring(const char *name); 149extern long join_session_keyring(const char *name);
148 150
151extern struct work_struct key_gc_work;
149extern unsigned key_gc_delay; 152extern unsigned key_gc_delay;
150extern void keyring_gc(struct key *keyring, time_t limit); 153extern void keyring_gc(struct key *keyring, time_t limit);
151extern void key_schedule_gc(time_t expiry_at); 154extern void key_schedule_gc(time_t expiry_at);
155extern void key_gc_keytype(struct key_type *ktype);
152 156
153extern int key_task_permission(const key_ref_t key_ref, 157extern int key_task_permission(const key_ref_t key_ref,
154 const struct cred *cred, 158 const struct cred *cred,
diff --git a/security/keys/key.c b/security/keys/key.c
index f7f9d93f08d9..4414abddcb5b 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -21,7 +21,7 @@
21#include <linux/user_namespace.h> 21#include <linux/user_namespace.h>
22#include "internal.h" 22#include "internal.h"
23 23
24static struct kmem_cache *key_jar; 24struct kmem_cache *key_jar;
25struct rb_root key_serial_tree; /* tree of keys indexed by serial */ 25struct rb_root key_serial_tree; /* tree of keys indexed by serial */
26DEFINE_SPINLOCK(key_serial_lock); 26DEFINE_SPINLOCK(key_serial_lock);
27 27
@@ -36,17 +36,9 @@ unsigned int key_quota_maxbytes = 20000; /* general key space quota */
36static LIST_HEAD(key_types_list); 36static LIST_HEAD(key_types_list);
37static DECLARE_RWSEM(key_types_sem); 37static DECLARE_RWSEM(key_types_sem);
38 38
39static void key_cleanup(struct work_struct *work);
40static DECLARE_WORK(key_cleanup_task, key_cleanup);
41
42/* We serialise key instantiation and link */ 39/* We serialise key instantiation and link */
43DEFINE_MUTEX(key_construction_mutex); 40DEFINE_MUTEX(key_construction_mutex);
44 41
45/* Any key who's type gets unegistered will be re-typed to this */
46static struct key_type key_type_dead = {
47 .name = "dead",
48};
49
50#ifdef KEY_DEBUGGING 42#ifdef KEY_DEBUGGING
51void __key_check(const struct key *key) 43void __key_check(const struct key *key)
52{ 44{
@@ -591,71 +583,6 @@ int key_reject_and_link(struct key *key,
591} 583}
592EXPORT_SYMBOL(key_reject_and_link); 584EXPORT_SYMBOL(key_reject_and_link);
593 585
594/*
595 * Garbage collect keys in process context so that we don't have to disable
596 * interrupts all over the place.
597 *
598 * key_put() schedules this rather than trying to do the cleanup itself, which
599 * means key_put() doesn't have to sleep.
600 */
601static void key_cleanup(struct work_struct *work)
602{
603 struct rb_node *_n;
604 struct key *key;
605
606go_again:
607 /* look for a dead key in the tree */
608 spin_lock(&key_serial_lock);
609
610 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
611 key = rb_entry(_n, struct key, serial_node);
612
613 if (atomic_read(&key->usage) == 0)
614 goto found_dead_key;
615 }
616
617 spin_unlock(&key_serial_lock);
618 return;
619
620found_dead_key:
621 /* we found a dead key - once we've removed it from the tree, we can
622 * drop the lock */
623 rb_erase(&key->serial_node, &key_serial_tree);
624 spin_unlock(&key_serial_lock);
625
626 key_check(key);
627
628 security_key_free(key);
629
630 /* deal with the user's key tracking and quota */
631 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
632 spin_lock(&key->user->lock);
633 key->user->qnkeys--;
634 key->user->qnbytes -= key->quotalen;
635 spin_unlock(&key->user->lock);
636 }
637
638 atomic_dec(&key->user->nkeys);
639 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
640 atomic_dec(&key->user->nikeys);
641
642 key_user_put(key->user);
643
644 /* now throw away the key memory */
645 if (key->type->destroy)
646 key->type->destroy(key);
647
648 kfree(key->description);
649
650#ifdef KEY_DEBUGGING
651 key->magic = KEY_DEBUG_MAGIC_X;
652#endif
653 kmem_cache_free(key_jar, key);
654
655 /* there may, of course, be more than one key to destroy */
656 goto go_again;
657}
658
659/** 586/**
660 * key_put - Discard a reference to a key. 587 * key_put - Discard a reference to a key.
661 * @key: The key to discard a reference from. 588 * @key: The key to discard a reference from.
@@ -670,7 +597,7 @@ void key_put(struct key *key)
670 key_check(key); 597 key_check(key);
671 598
672 if (atomic_dec_and_test(&key->usage)) 599 if (atomic_dec_and_test(&key->usage))
673 schedule_work(&key_cleanup_task); 600 queue_work(system_nrt_wq, &key_gc_work);
674 } 601 }
675} 602}
676EXPORT_SYMBOL(key_put); 603EXPORT_SYMBOL(key_put);
@@ -1048,49 +975,11 @@ EXPORT_SYMBOL(register_key_type);
1048 */ 975 */
1049void unregister_key_type(struct key_type *ktype) 976void unregister_key_type(struct key_type *ktype)
1050{ 977{
1051 struct rb_node *_n;
1052 struct key *key;
1053
1054 down_write(&key_types_sem); 978 down_write(&key_types_sem);
1055
1056 /* withdraw the key type */
1057 list_del_init(&ktype->link); 979 list_del_init(&ktype->link);
1058 980 downgrade_write(&key_types_sem);
1059 /* mark all the keys of this type dead */ 981 key_gc_keytype(ktype);
1060 spin_lock(&key_serial_lock); 982 up_read(&key_types_sem);
1061
1062 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
1063 key = rb_entry(_n, struct key, serial_node);
1064
1065 if (key->type == ktype) {
1066 key->type = &key_type_dead;
1067 set_bit(KEY_FLAG_DEAD, &key->flags);
1068 }
1069 }
1070
1071 spin_unlock(&key_serial_lock);
1072
1073 /* make sure everyone revalidates their keys */
1074 synchronize_rcu();
1075
1076 /* we should now be able to destroy the payloads of all the keys of
1077 * this type with impunity */
1078 spin_lock(&key_serial_lock);
1079
1080 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
1081 key = rb_entry(_n, struct key, serial_node);
1082
1083 if (key->type == ktype) {
1084 if (ktype->destroy)
1085 ktype->destroy(key);
1086 memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
1087 }
1088 }
1089
1090 spin_unlock(&key_serial_lock);
1091 up_write(&key_types_sem);
1092
1093 key_schedule_gc(0);
1094} 983}
1095EXPORT_SYMBOL(unregister_key_type); 984EXPORT_SYMBOL(unregister_key_type);
1096 985
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 30e242f7bd0e..37a7f3b28852 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -860,8 +860,7 @@ void __key_link(struct key *keyring, struct key *key,
860 860
861 kenter("%d,%d,%p", keyring->serial, key->serial, nklist); 861 kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
862 862
863 klist = rcu_dereference_protected(keyring->payload.subscriptions, 863 klist = rcu_dereference_locked_keyring(keyring);
864 rwsem_is_locked(&keyring->sem));
865 864
866 atomic_inc(&key->usage); 865 atomic_inc(&key->usage);
867 866
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a3063eb3dc23..1068cb1939b3 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -270,7 +270,7 @@ static int install_session_keyring(struct key *keyring)
270 if (!new) 270 if (!new)
271 return -ENOMEM; 271 return -ENOMEM;
272 272
273 ret = install_session_keyring_to_cred(new, NULL); 273 ret = install_session_keyring_to_cred(new, keyring);
274 if (ret < 0) { 274 if (ret < 0) {
275 abort_creds(new); 275 abort_creds(new);
276 return ret; 276 return ret;
@@ -589,12 +589,22 @@ try_again:
589 ret = install_user_keyrings(); 589 ret = install_user_keyrings();
590 if (ret < 0) 590 if (ret < 0)
591 goto error; 591 goto error;
592 ret = install_session_keyring( 592 if (lflags & KEY_LOOKUP_CREATE)
593 cred->user->session_keyring); 593 ret = join_session_keyring(NULL);
594 else
595 ret = install_session_keyring(
596 cred->user->session_keyring);
594 597
595 if (ret < 0) 598 if (ret < 0)
596 goto error; 599 goto error;
597 goto reget_creds; 600 goto reget_creds;
601 } else if (cred->tgcred->session_keyring ==
602 cred->user->session_keyring &&
603 lflags & KEY_LOOKUP_CREATE) {
604 ret = join_session_keyring(NULL);
605 if (ret < 0)
606 goto error;
607 goto reget_creds;
598 } 608 }
599 609
600 rcu_read_lock(); 610 rcu_read_lock();
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 0c33e2ea1f3c..0964fc236946 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -779,7 +779,10 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
779 opt->pcrinfo_len = strlen(args[0].from) / 2; 779 opt->pcrinfo_len = strlen(args[0].from) / 2;
780 if (opt->pcrinfo_len > MAX_PCRINFO_SIZE) 780 if (opt->pcrinfo_len > MAX_PCRINFO_SIZE)
781 return -EINVAL; 781 return -EINVAL;
782 hex2bin(opt->pcrinfo, args[0].from, opt->pcrinfo_len); 782 res = hex2bin(opt->pcrinfo, args[0].from,
783 opt->pcrinfo_len);
784 if (res < 0)
785 return -EINVAL;
783 break; 786 break;
784 case Opt_keyhandle: 787 case Opt_keyhandle:
785 res = strict_strtoul(args[0].from, 16, &handle); 788 res = strict_strtoul(args[0].from, 16, &handle);
@@ -791,12 +794,18 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
791 case Opt_keyauth: 794 case Opt_keyauth:
792 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) 795 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
793 return -EINVAL; 796 return -EINVAL;
794 hex2bin(opt->keyauth, args[0].from, SHA1_DIGEST_SIZE); 797 res = hex2bin(opt->keyauth, args[0].from,
798 SHA1_DIGEST_SIZE);
799 if (res < 0)
800 return -EINVAL;
795 break; 801 break;
796 case Opt_blobauth: 802 case Opt_blobauth:
797 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) 803 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
798 return -EINVAL; 804 return -EINVAL;
799 hex2bin(opt->blobauth, args[0].from, SHA1_DIGEST_SIZE); 805 res = hex2bin(opt->blobauth, args[0].from,
806 SHA1_DIGEST_SIZE);
807 if (res < 0)
808 return -EINVAL;
800 break; 809 break;
801 case Opt_migratable: 810 case Opt_migratable:
802 if (*args[0].from == '0') 811 if (*args[0].from == '0')
@@ -860,7 +869,9 @@ static int datablob_parse(char *datablob, struct trusted_key_payload *p,
860 p->blob_len = strlen(c) / 2; 869 p->blob_len = strlen(c) / 2;
861 if (p->blob_len > MAX_BLOB_SIZE) 870 if (p->blob_len > MAX_BLOB_SIZE)
862 return -EINVAL; 871 return -EINVAL;
863 hex2bin(p->blob, c, p->blob_len); 872 ret = hex2bin(p->blob, c, p->blob_len);
873 if (ret < 0)
874 return -EINVAL;
864 ret = getoptions(datablob, p, o); 875 ret = getoptions(datablob, p, o);
865 if (ret < 0) 876 if (ret < 0)
866 return ret; 877 return ret;
diff --git a/security/security.c b/security/security.c
index d9e153390926..0c6cc69c8f86 100644
--- a/security/security.c
+++ b/security/security.c
@@ -16,15 +16,16 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/integrity.h>
19#include <linux/ima.h> 20#include <linux/ima.h>
21#include <linux/evm.h>
22
23#define MAX_LSM_EVM_XATTR 2
20 24
21/* Boot-time LSM user choice */ 25/* Boot-time LSM user choice */
22static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 26static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
23 CONFIG_DEFAULT_SECURITY; 27 CONFIG_DEFAULT_SECURITY;
24 28
25/* things that live in capability.c */
26extern void __init security_fixup_ops(struct security_operations *ops);
27
28static struct security_operations *security_ops; 29static struct security_operations *security_ops;
29static struct security_operations default_security_ops = { 30static struct security_operations default_security_ops = {
30 .name = "default", 31 .name = "default",
@@ -334,20 +335,57 @@ int security_inode_alloc(struct inode *inode)
334 335
335void security_inode_free(struct inode *inode) 336void security_inode_free(struct inode *inode)
336{ 337{
337 ima_inode_free(inode); 338 integrity_inode_free(inode);
338 security_ops->inode_free_security(inode); 339 security_ops->inode_free_security(inode);
339} 340}
340 341
341int security_inode_init_security(struct inode *inode, struct inode *dir, 342int security_inode_init_security(struct inode *inode, struct inode *dir,
342 const struct qstr *qstr, char **name, 343 const struct qstr *qstr,
343 void **value, size_t *len) 344 const initxattrs initxattrs, void *fs_data)
344{ 345{
346 struct xattr new_xattrs[MAX_LSM_EVM_XATTR + 1];
347 struct xattr *lsm_xattr, *evm_xattr, *xattr;
348 int ret;
349
345 if (unlikely(IS_PRIVATE(inode))) 350 if (unlikely(IS_PRIVATE(inode)))
346 return -EOPNOTSUPP; 351 return 0;
352
353 memset(new_xattrs, 0, sizeof new_xattrs);
354 if (!initxattrs)
355 return security_ops->inode_init_security(inode, dir, qstr,
356 NULL, NULL, NULL);
357 lsm_xattr = new_xattrs;
358 ret = security_ops->inode_init_security(inode, dir, qstr,
359 &lsm_xattr->name,
360 &lsm_xattr->value,
361 &lsm_xattr->value_len);
362 if (ret)
363 goto out;
364
365 evm_xattr = lsm_xattr + 1;
366 ret = evm_inode_init_security(inode, lsm_xattr, evm_xattr);
367 if (ret)
368 goto out;
369 ret = initxattrs(inode, new_xattrs, fs_data);
370out:
371 for (xattr = new_xattrs; xattr->name != NULL; xattr++) {
372 kfree(xattr->name);
373 kfree(xattr->value);
374 }
375 return (ret == -EOPNOTSUPP) ? 0 : ret;
376}
377EXPORT_SYMBOL(security_inode_init_security);
378
379int security_old_inode_init_security(struct inode *inode, struct inode *dir,
380 const struct qstr *qstr, char **name,
381 void **value, size_t *len)
382{
383 if (unlikely(IS_PRIVATE(inode)))
384 return 0;
347 return security_ops->inode_init_security(inode, dir, qstr, name, value, 385 return security_ops->inode_init_security(inode, dir, qstr, name, value,
348 len); 386 len);
349} 387}
350EXPORT_SYMBOL(security_inode_init_security); 388EXPORT_SYMBOL(security_old_inode_init_security);
351 389
352#ifdef CONFIG_SECURITY_PATH 390#ifdef CONFIG_SECURITY_PATH
353int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, 391int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
@@ -523,9 +561,14 @@ int security_inode_permission(struct inode *inode, int mask)
523 561
524int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 562int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
525{ 563{
564 int ret;
565
526 if (unlikely(IS_PRIVATE(dentry->d_inode))) 566 if (unlikely(IS_PRIVATE(dentry->d_inode)))
527 return 0; 567 return 0;
528 return security_ops->inode_setattr(dentry, attr); 568 ret = security_ops->inode_setattr(dentry, attr);
569 if (ret)
570 return ret;
571 return evm_inode_setattr(dentry, attr);
529} 572}
530EXPORT_SYMBOL_GPL(security_inode_setattr); 573EXPORT_SYMBOL_GPL(security_inode_setattr);
531 574
@@ -539,9 +582,14 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
539int security_inode_setxattr(struct dentry *dentry, const char *name, 582int security_inode_setxattr(struct dentry *dentry, const char *name,
540 const void *value, size_t size, int flags) 583 const void *value, size_t size, int flags)
541{ 584{
585 int ret;
586
542 if (unlikely(IS_PRIVATE(dentry->d_inode))) 587 if (unlikely(IS_PRIVATE(dentry->d_inode)))
543 return 0; 588 return 0;
544 return security_ops->inode_setxattr(dentry, name, value, size, flags); 589 ret = security_ops->inode_setxattr(dentry, name, value, size, flags);
590 if (ret)
591 return ret;
592 return evm_inode_setxattr(dentry, name, value, size);
545} 593}
546 594
547void security_inode_post_setxattr(struct dentry *dentry, const char *name, 595void security_inode_post_setxattr(struct dentry *dentry, const char *name,
@@ -550,6 +598,7 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
550 if (unlikely(IS_PRIVATE(dentry->d_inode))) 598 if (unlikely(IS_PRIVATE(dentry->d_inode)))
551 return; 599 return;
552 security_ops->inode_post_setxattr(dentry, name, value, size, flags); 600 security_ops->inode_post_setxattr(dentry, name, value, size, flags);
601 evm_inode_post_setxattr(dentry, name, value, size);
553} 602}
554 603
555int security_inode_getxattr(struct dentry *dentry, const char *name) 604int security_inode_getxattr(struct dentry *dentry, const char *name)
@@ -568,9 +617,14 @@ int security_inode_listxattr(struct dentry *dentry)
568 617
569int security_inode_removexattr(struct dentry *dentry, const char *name) 618int security_inode_removexattr(struct dentry *dentry, const char *name)
570{ 619{
620 int ret;
621
571 if (unlikely(IS_PRIVATE(dentry->d_inode))) 622 if (unlikely(IS_PRIVATE(dentry->d_inode)))
572 return 0; 623 return 0;
573 return security_ops->inode_removexattr(dentry, name); 624 ret = security_ops->inode_removexattr(dentry, name);
625 if (ret)
626 return ret;
627 return evm_inode_removexattr(dentry, name);
574} 628}
575 629
576int security_inode_need_killpriv(struct dentry *dentry) 630int security_inode_need_killpriv(struct dentry *dentry)
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index 90664385dead..e75dd94e2d2b 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -12,6 +12,7 @@
12 * as published by the Free Software Foundation. 12 * as published by the Free Software Foundation.
13 */ 13 */
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/selinux.h>
15 16
16#include "security.h" 17#include "security.h"
17 18
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 266a2292451d..e545b9f67072 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -89,14 +89,14 @@
89#include "xfrm.h" 89#include "xfrm.h"
90#include "netlabel.h" 90#include "netlabel.h"
91#include "audit.h" 91#include "audit.h"
92#include "avc_ss.h"
92 93
93#define NUM_SEL_MNT_OPTS 5 94#define NUM_SEL_MNT_OPTS 5
94 95
95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
96extern struct security_operations *security_ops; 96extern struct security_operations *security_ops;
97 97
98/* SECMARK reference count */ 98/* SECMARK reference count */
99atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); 99static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
100 100
101#ifdef CONFIG_SECURITY_SELINUX_DEVELOP 101#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
102int selinux_enforcing; 102int selinux_enforcing;
@@ -279,10 +279,6 @@ static void superblock_free_security(struct super_block *sb)
279 kfree(sbsec); 279 kfree(sbsec);
280} 280}
281 281
282/* The security server must be initialized before
283 any labeling or access decisions can be provided. */
284extern int ss_initialized;
285
286/* The file system's label must be initialized prior to use. */ 282/* The file system's label must be initialized prior to use. */
287 283
288static const char *labeling_behaviors[6] = { 284static const char *labeling_behaviors[6] = {
@@ -2097,9 +2093,6 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2097 return (atsecure || cap_bprm_secureexec(bprm)); 2093 return (atsecure || cap_bprm_secureexec(bprm));
2098} 2094}
2099 2095
2100extern struct vfsmount *selinuxfs_mount;
2101extern struct dentry *selinux_null;
2102
2103/* Derived from fs/exec.c:flush_old_files. */ 2096/* Derived from fs/exec.c:flush_old_files. */
2104static inline void flush_unauthorized_files(const struct cred *cred, 2097static inline void flush_unauthorized_files(const struct cred *cred,
2105 struct files_struct *files) 2098 struct files_struct *files)
@@ -5803,8 +5796,6 @@ static int selinux_disabled;
5803 5796
5804int selinux_disable(void) 5797int selinux_disable(void)
5805{ 5798{
5806 extern void exit_sel_fs(void);
5807
5808 if (ss_initialized) { 5799 if (ss_initialized) {
5809 /* Not permitted after initial policy load. */ 5800 /* Not permitted after initial policy load. */
5810 return -EINVAL; 5801 return -EINVAL;
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h
index 4677aa519b04..d5c328452df0 100644
--- a/security/selinux/include/avc_ss.h
+++ b/security/selinux/include/avc_ss.h
@@ -18,5 +18,11 @@ struct security_class_mapping {
18 18
19extern struct security_class_mapping secclass_map[]; 19extern struct security_class_mapping secclass_map[];
20 20
21/*
22 * The security server must be initialized before
23 * any labeling or access decisions can be provided.
24 */
25extern int ss_initialized;
26
21#endif /* _SELINUX_AVC_SS_H_ */ 27#endif /* _SELINUX_AVC_SS_H_ */
22 28
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 3ba4feba048a..d871e8ad2103 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -216,6 +216,14 @@ struct selinux_kernel_status {
216 216
217extern void selinux_status_update_setenforce(int enforcing); 217extern void selinux_status_update_setenforce(int enforcing);
218extern void selinux_status_update_policyload(int seqno); 218extern void selinux_status_update_policyload(int seqno);
219extern void selinux_complete_init(void);
220extern int selinux_disable(void);
221extern void exit_sel_fs(void);
222extern struct dentry *selinux_null;
223extern struct vfsmount *selinuxfs_mount;
224extern void selnl_notify_setenforce(int val);
225extern void selnl_notify_policyload(u32 seqno);
226extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
219 227
220#endif /* _SELINUX_SECURITY_H_ */ 228#endif /* _SELINUX_SECURITY_H_ */
221 229
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 36ac257cec9a..ce3f481558d8 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -19,6 +19,8 @@
19#include <linux/selinux_netlink.h> 19#include <linux/selinux_netlink.h>
20#include <net/net_namespace.h> 20#include <net/net_namespace.h>
21 21
22#include "security.h"
23
22static struct sock *selnl; 24static struct sock *selnl;
23 25
24static int selnl_msglen(int msgtype) 26static int selnl_msglen(int msgtype)
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 8b02b2137da2..0920ea3bf599 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -21,6 +21,7 @@
21 21
22#include "flask.h" 22#include "flask.h"
23#include "av_permissions.h" 23#include "av_permissions.h"
24#include "security.h"
24 25
25struct nlmsg_perm { 26struct nlmsg_perm {
26 u16 nlmsg_type; 27 u16 nlmsg_type;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 55d92cbb177a..f46658722c78 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -75,8 +75,6 @@ static char policy_opened;
75/* global data for policy capabilities */ 75/* global data for policy capabilities */
76static struct dentry *policycap_dir; 76static struct dentry *policycap_dir;
77 77
78extern void selnl_notify_setenforce(int val);
79
80/* Check whether a task is allowed to use a security operation. */ 78/* Check whether a task is allowed to use a security operation. */
81static int task_has_security(struct task_struct *tsk, 79static int task_has_security(struct task_struct *tsk,
82 u32 perms) 80 u32 perms)
@@ -278,7 +276,6 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
278 char *page = NULL; 276 char *page = NULL;
279 ssize_t length; 277 ssize_t length;
280 int new_value; 278 int new_value;
281 extern int selinux_disable(void);
282 279
283 length = -ENOMEM; 280 length = -ENOMEM;
284 if (count >= PAGE_SIZE) 281 if (count >= PAGE_SIZE)
@@ -478,7 +475,7 @@ static struct vm_operations_struct sel_mmap_policy_ops = {
478 .page_mkwrite = sel_mmap_policy_fault, 475 .page_mkwrite = sel_mmap_policy_fault,
479}; 476};
480 477
481int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma) 478static int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
482{ 479{
483 if (vma->vm_flags & VM_SHARED) { 480 if (vma->vm_flags & VM_SHARED) {
484 /* do not allow mprotect to make mapping writable */ 481 /* do not allow mprotect to make mapping writable */
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index a53373207fb4..2ec904177fe0 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -555,7 +555,7 @@ static int cond_write_av_list(struct policydb *p,
555 return 0; 555 return 0;
556} 556}
557 557
558int cond_write_node(struct policydb *p, struct cond_node *node, 558static int cond_write_node(struct policydb *p, struct cond_node *node,
559 struct policy_file *fp) 559 struct policy_file *fp)
560{ 560{
561 struct cond_expr *cur_expr; 561 struct cond_expr *cur_expr;
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index 3f209c635295..4d1f87466508 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -13,6 +13,7 @@
13#include "avtab.h" 13#include "avtab.h"
14#include "symtab.h" 14#include "symtab.h"
15#include "policydb.h" 15#include "policydb.h"
16#include "../include/conditional.h"
16 17
17#define COND_EXPR_MAXDEPTH 10 18#define COND_EXPR_MAXDEPTH 10
18 19
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 2381d0ded228..a7f61d52f05c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1743,8 +1743,6 @@ static int policydb_bounds_sanity_check(struct policydb *p)
1743 return 0; 1743 return 0;
1744} 1744}
1745 1745
1746extern int ss_initialized;
1747
1748u16 string_to_security_class(struct policydb *p, const char *name) 1746u16 string_to_security_class(struct policydb *p, const char *name)
1749{ 1747{
1750 struct class_datum *cladatum; 1748 struct class_datum *cladatum;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f6917bc0aa05..185f849a26f6 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -70,8 +70,6 @@
70#include "ebitmap.h" 70#include "ebitmap.h"
71#include "audit.h" 71#include "audit.h"
72 72
73extern void selnl_notify_policyload(u32 seqno);
74
75int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
76int selinux_policycap_openperm; 74int selinux_policycap_openperm;
77 75
@@ -1790,7 +1788,6 @@ static void security_load_policycaps(void)
1790 POLICYDB_CAPABILITY_OPENPERM); 1788 POLICYDB_CAPABILITY_OPENPERM);
1791} 1789}
1792 1790
1793extern void selinux_complete_init(void);
1794static int security_preserve_bools(struct policydb *p); 1791static int security_preserve_bools(struct policydb *p);
1795 1792
1796/** 1793/**
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 2b6c6a516123..2ad00657b801 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -41,9 +41,9 @@ struct superblock_smack {
41}; 41};
42 42
43struct socket_smack { 43struct socket_smack {
44 char *smk_out; /* outbound label */ 44 char *smk_out; /* outbound label */
45 char *smk_in; /* inbound label */ 45 char *smk_in; /* inbound label */
46 char smk_packet[SMK_LABELLEN]; /* TCP peer label */ 46 char *smk_packet; /* TCP peer label */
47}; 47};
48 48
49/* 49/*
@@ -116,13 +116,19 @@ struct smk_netlbladdr {
116 * If there is a cipso value associated with the label it 116 * If there is a cipso value associated with the label it
117 * gets stored here, too. This will most likely be rare as 117 * gets stored here, too. This will most likely be rare as
118 * the cipso direct mapping in used internally. 118 * the cipso direct mapping in used internally.
119 *
120 * Keep the access rules for this subject label here so that
121 * the entire set of rules does not need to be examined every
122 * time.
119 */ 123 */
120struct smack_known { 124struct smack_known {
121 struct list_head list; 125 struct list_head list;
122 char smk_known[SMK_LABELLEN]; 126 char smk_known[SMK_LABELLEN];
123 u32 smk_secid; 127 u32 smk_secid;
124 struct smack_cipso *smk_cipso; 128 struct smack_cipso *smk_cipso;
125 spinlock_t smk_cipsolock; /* for changing cipso map */ 129 spinlock_t smk_cipsolock; /* for changing cipso map */
130 struct list_head smk_rules; /* access rules */
131 struct mutex smk_rules_lock; /* lock for the rules */
126}; 132};
127 133
128/* 134/*
@@ -150,7 +156,6 @@ struct smack_known {
150 156
151/* 157/*
152 * smackfs magic number 158 * smackfs magic number
153 * smackfs macic number
154 */ 159 */
155#define SMACK_MAGIC 0x43415d53 /* "SMAC" */ 160#define SMACK_MAGIC 0x43415d53 /* "SMAC" */
156 161
@@ -176,9 +181,9 @@ struct smack_known {
176#define MAY_NOT 0 181#define MAY_NOT 0
177 182
178/* 183/*
179 * Number of access types used by Smack (rwxa) 184 * Number of access types used by Smack (rwxat)
180 */ 185 */
181#define SMK_NUM_ACCESS_TYPE 4 186#define SMK_NUM_ACCESS_TYPE 5
182 187
183/* 188/*
184 * Smack audit data; is empty if CONFIG_AUDIT not set 189 * Smack audit data; is empty if CONFIG_AUDIT not set
@@ -201,10 +206,12 @@ int smk_access_entry(char *, char *, struct list_head *);
201int smk_access(char *, char *, int, struct smk_audit_info *); 206int smk_access(char *, char *, int, struct smk_audit_info *);
202int smk_curacc(char *, u32, struct smk_audit_info *); 207int smk_curacc(char *, u32, struct smk_audit_info *);
203int smack_to_cipso(const char *, struct smack_cipso *); 208int smack_to_cipso(const char *, struct smack_cipso *);
204void smack_from_cipso(u32, char *, char *); 209char *smack_from_cipso(u32, char *);
205char *smack_from_secid(const u32); 210char *smack_from_secid(const u32);
211void smk_parse_smack(const char *string, int len, char *smack);
206char *smk_import(const char *, int); 212char *smk_import(const char *, int);
207struct smack_known *smk_import_entry(const char *, int); 213struct smack_known *smk_import_entry(const char *, int);
214struct smack_known *smk_find_entry(const char *);
208u32 smack_to_secid(const char *); 215u32 smack_to_secid(const char *);
209 216
210/* 217/*
@@ -223,7 +230,6 @@ extern struct smack_known smack_known_star;
223extern struct smack_known smack_known_web; 230extern struct smack_known smack_known_web;
224 231
225extern struct list_head smack_known_list; 232extern struct list_head smack_known_list;
226extern struct list_head smack_rule_list;
227extern struct list_head smk_netlbladdr_list; 233extern struct list_head smk_netlbladdr_list;
228 234
229extern struct security_operations smack_ops; 235extern struct security_operations smack_ops;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 9637e107f7ea..cc7cb6edba08 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -77,14 +77,19 @@ int log_policy = SMACK_AUDIT_DENIED;
77 * entry is found returns -ENOENT. 77 * entry is found returns -ENOENT.
78 * 78 *
79 * NOTE: 79 * NOTE:
80 * Even though Smack labels are usually shared on smack_list
81 * labels that come in off the network can't be imported
82 * and added to the list for locking reasons.
83 * 80 *
84 * Therefore, it is necessary to check the contents of the labels, 81 * Earlier versions of this function allowed for labels that
85 * not just the pointer values. Of course, in most cases the labels 82 * were not on the label list. This was done to allow for
86 * will be on the list, so checking the pointers may be a worthwhile 83 * labels to come over the network that had never been seen
87 * optimization. 84 * before on this host. Unless the receiving socket has the
85 * star label this will always result in a failure check. The
86 * star labeled socket case is now handled in the networking
87 * hooks so there is no case where the label is not on the
88 * label list. Checking to see if the address of two labels
89 * is the same is now a reliable test.
90 *
91 * Do the object check first because that is more
92 * likely to differ.
88 */ 93 */
89int smk_access_entry(char *subject_label, char *object_label, 94int smk_access_entry(char *subject_label, char *object_label,
90 struct list_head *rule_list) 95 struct list_head *rule_list)
@@ -93,13 +98,10 @@ int smk_access_entry(char *subject_label, char *object_label,
93 struct smack_rule *srp; 98 struct smack_rule *srp;
94 99
95 list_for_each_entry_rcu(srp, rule_list, list) { 100 list_for_each_entry_rcu(srp, rule_list, list) {
96 if (srp->smk_subject == subject_label || 101 if (srp->smk_object == object_label &&
97 strcmp(srp->smk_subject, subject_label) == 0) { 102 srp->smk_subject == subject_label) {
98 if (srp->smk_object == object_label || 103 may = srp->smk_access;
99 strcmp(srp->smk_object, object_label) == 0) { 104 break;
100 may = srp->smk_access;
101 break;
102 }
103 } 105 }
104 } 106 }
105 107
@@ -117,18 +119,12 @@ int smk_access_entry(char *subject_label, char *object_label,
117 * access rule list and returns 0 if the access is permitted, 119 * access rule list and returns 0 if the access is permitted,
118 * non zero otherwise. 120 * non zero otherwise.
119 * 121 *
120 * Even though Smack labels are usually shared on smack_list 122 * Smack labels are shared on smack_list
121 * labels that come in off the network can't be imported
122 * and added to the list for locking reasons.
123 *
124 * Therefore, it is necessary to check the contents of the labels,
125 * not just the pointer values. Of course, in most cases the labels
126 * will be on the list, so checking the pointers may be a worthwhile
127 * optimization.
128 */ 123 */
129int smk_access(char *subject_label, char *object_label, int request, 124int smk_access(char *subject_label, char *object_label, int request,
130 struct smk_audit_info *a) 125 struct smk_audit_info *a)
131{ 126{
127 struct smack_known *skp;
132 int may = MAY_NOT; 128 int may = MAY_NOT;
133 int rc = 0; 129 int rc = 0;
134 130
@@ -137,8 +133,7 @@ int smk_access(char *subject_label, char *object_label, int request,
137 * 133 *
138 * A star subject can't access any object. 134 * A star subject can't access any object.
139 */ 135 */
140 if (subject_label == smack_known_star.smk_known || 136 if (subject_label == smack_known_star.smk_known) {
141 strcmp(subject_label, smack_known_star.smk_known) == 0) {
142 rc = -EACCES; 137 rc = -EACCES;
143 goto out_audit; 138 goto out_audit;
144 } 139 }
@@ -148,33 +143,27 @@ int smk_access(char *subject_label, char *object_label, int request,
148 * An internet subject can access any object. 143 * An internet subject can access any object.
149 */ 144 */
150 if (object_label == smack_known_web.smk_known || 145 if (object_label == smack_known_web.smk_known ||
151 subject_label == smack_known_web.smk_known || 146 subject_label == smack_known_web.smk_known)
152 strcmp(object_label, smack_known_web.smk_known) == 0 ||
153 strcmp(subject_label, smack_known_web.smk_known) == 0)
154 goto out_audit; 147 goto out_audit;
155 /* 148 /*
156 * A star object can be accessed by any subject. 149 * A star object can be accessed by any subject.
157 */ 150 */
158 if (object_label == smack_known_star.smk_known || 151 if (object_label == smack_known_star.smk_known)
159 strcmp(object_label, smack_known_star.smk_known) == 0)
160 goto out_audit; 152 goto out_audit;
161 /* 153 /*
162 * An object can be accessed in any way by a subject 154 * An object can be accessed in any way by a subject
163 * with the same label. 155 * with the same label.
164 */ 156 */
165 if (subject_label == object_label || 157 if (subject_label == object_label)
166 strcmp(subject_label, object_label) == 0)
167 goto out_audit; 158 goto out_audit;
168 /* 159 /*
169 * A hat subject can read any object. 160 * A hat subject can read any object.
170 * A floor object can be read by any subject. 161 * A floor object can be read by any subject.
171 */ 162 */
172 if ((request & MAY_ANYREAD) == request) { 163 if ((request & MAY_ANYREAD) == request) {
173 if (object_label == smack_known_floor.smk_known || 164 if (object_label == smack_known_floor.smk_known)
174 strcmp(object_label, smack_known_floor.smk_known) == 0)
175 goto out_audit; 165 goto out_audit;
176 if (subject_label == smack_known_hat.smk_known || 166 if (subject_label == smack_known_hat.smk_known)
177 strcmp(subject_label, smack_known_hat.smk_known) == 0)
178 goto out_audit; 167 goto out_audit;
179 } 168 }
180 /* 169 /*
@@ -184,8 +173,9 @@ int smk_access(char *subject_label, char *object_label, int request,
184 * good. A negative response from smk_access_entry() 173 * good. A negative response from smk_access_entry()
185 * indicates there is no entry for this pair. 174 * indicates there is no entry for this pair.
186 */ 175 */
176 skp = smk_find_entry(subject_label);
187 rcu_read_lock(); 177 rcu_read_lock();
188 may = smk_access_entry(subject_label, object_label, &smack_rule_list); 178 may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
189 rcu_read_unlock(); 179 rcu_read_unlock();
190 180
191 if (may > 0 && (request & may) == request) 181 if (may > 0 && (request & may) == request)
@@ -344,17 +334,32 @@ void smack_log(char *subject_label, char *object_label, int request,
344static DEFINE_MUTEX(smack_known_lock); 334static DEFINE_MUTEX(smack_known_lock);
345 335
346/** 336/**
347 * smk_import_entry - import a label, return the list entry 337 * smk_find_entry - find a label on the list, return the list entry
348 * @string: a text string that might be a Smack label 338 * @string: a text string that might be a Smack label
349 * @len: the maximum size, or zero if it is NULL terminated.
350 * 339 *
351 * Returns a pointer to the entry in the label list that 340 * Returns a pointer to the entry in the label list that
352 * matches the passed string, adding it if necessary. 341 * matches the passed string.
353 */ 342 */
354struct smack_known *smk_import_entry(const char *string, int len) 343struct smack_known *smk_find_entry(const char *string)
355{ 344{
356 struct smack_known *skp; 345 struct smack_known *skp;
357 char smack[SMK_LABELLEN]; 346
347 list_for_each_entry_rcu(skp, &smack_known_list, list) {
348 if (strncmp(skp->smk_known, string, SMK_MAXLEN) == 0)
349 return skp;
350 }
351
352 return NULL;
353}
354
355/**
356 * smk_parse_smack - parse smack label from a text string
357 * @string: a text string that might contain a Smack label
358 * @len: the maximum size, or zero if it is NULL terminated.
359 * @smack: parsed smack label, or NULL if parse error
360 */
361void smk_parse_smack(const char *string, int len, char *smack)
362{
358 int found; 363 int found;
359 int i; 364 int i;
360 365
@@ -372,27 +377,38 @@ struct smack_known *smk_import_entry(const char *string, int len)
372 } else 377 } else
373 smack[i] = string[i]; 378 smack[i] = string[i];
374 } 379 }
380}
381
382/**
383 * smk_import_entry - import a label, return the list entry
384 * @string: a text string that might be a Smack label
385 * @len: the maximum size, or zero if it is NULL terminated.
386 *
387 * Returns a pointer to the entry in the label list that
388 * matches the passed string, adding it if necessary.
389 */
390struct smack_known *smk_import_entry(const char *string, int len)
391{
392 struct smack_known *skp;
393 char smack[SMK_LABELLEN];
375 394
395 smk_parse_smack(string, len, smack);
376 if (smack[0] == '\0') 396 if (smack[0] == '\0')
377 return NULL; 397 return NULL;
378 398
379 mutex_lock(&smack_known_lock); 399 mutex_lock(&smack_known_lock);
380 400
381 found = 0; 401 skp = smk_find_entry(smack);
382 list_for_each_entry_rcu(skp, &smack_known_list, list) {
383 if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
384 found = 1;
385 break;
386 }
387 }
388 402
389 if (found == 0) { 403 if (skp == NULL) {
390 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL); 404 skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
391 if (skp != NULL) { 405 if (skp != NULL) {
392 strncpy(skp->smk_known, smack, SMK_MAXLEN); 406 strncpy(skp->smk_known, smack, SMK_MAXLEN);
393 skp->smk_secid = smack_next_secid++; 407 skp->smk_secid = smack_next_secid++;
394 skp->smk_cipso = NULL; 408 skp->smk_cipso = NULL;
409 INIT_LIST_HEAD(&skp->smk_rules);
395 spin_lock_init(&skp->smk_cipsolock); 410 spin_lock_init(&skp->smk_cipsolock);
411 mutex_init(&skp->smk_rules_lock);
396 /* 412 /*
397 * Make sure that the entry is actually 413 * Make sure that the entry is actually
398 * filled before putting it on the list. 414 * filled before putting it on the list.
@@ -480,19 +496,12 @@ u32 smack_to_secid(const char *smack)
480 * smack_from_cipso - find the Smack label associated with a CIPSO option 496 * smack_from_cipso - find the Smack label associated with a CIPSO option
481 * @level: Bell & LaPadula level from the network 497 * @level: Bell & LaPadula level from the network
482 * @cp: Bell & LaPadula categories from the network 498 * @cp: Bell & LaPadula categories from the network
483 * @result: where to put the Smack value
484 * 499 *
485 * This is a simple lookup in the label table. 500 * This is a simple lookup in the label table.
486 * 501 *
487 * This is an odd duck as far as smack handling goes in that 502 * Return the matching label from the label list or NULL.
488 * it sends back a copy of the smack label rather than a pointer
489 * to the master list. This is done because it is possible for
490 * a foreign host to send a smack label that is new to this
491 * machine and hence not on the list. That would not be an
492 * issue except that adding an entry to the master list can't
493 * be done at that point.
494 */ 503 */
495void smack_from_cipso(u32 level, char *cp, char *result) 504char *smack_from_cipso(u32 level, char *cp)
496{ 505{
497 struct smack_known *kp; 506 struct smack_known *kp;
498 char *final = NULL; 507 char *final = NULL;
@@ -509,12 +518,13 @@ void smack_from_cipso(u32 level, char *cp, char *result)
509 final = kp->smk_known; 518 final = kp->smk_known;
510 519
511 spin_unlock_bh(&kp->smk_cipsolock); 520 spin_unlock_bh(&kp->smk_cipsolock);
521
522 if (final != NULL)
523 break;
512 } 524 }
513 rcu_read_unlock(); 525 rcu_read_unlock();
514 if (final == NULL) 526
515 final = smack_known_huh.smk_known; 527 return final;
516 strncpy(result, final, SMK_MAXLEN);
517 return;
518} 528}
519 529
520/** 530/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b9c5e149903b..7db62b48eb42 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -5,12 +5,13 @@
5 * 5 *
6 * Authors: 6 * Authors:
7 * Casey Schaufler <casey@schaufler-ca.com> 7 * Casey Schaufler <casey@schaufler-ca.com>
8 * Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com> 8 * Jarkko Sakkinen <jarkko.sakkinen@intel.com>
9 * 9 *
10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
12 * Paul Moore <paul@paul-moore.com> 12 * Paul Moore <paul@paul-moore.com>
13 * Copyright (C) 2010 Nokia Corporation 13 * Copyright (C) 2010 Nokia Corporation
14 * Copyright (C) 2011 Intel Corporation.
14 * 15 *
15 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2, 17 * it under the terms of the GNU General Public License version 2,
@@ -34,6 +35,7 @@
34#include <linux/audit.h> 35#include <linux/audit.h>
35#include <linux/magic.h> 36#include <linux/magic.h>
36#include <linux/dcache.h> 37#include <linux/dcache.h>
38#include <linux/personality.h>
37#include "smack.h" 39#include "smack.h"
38 40
39#define task_security(task) (task_cred_xxx((task), security)) 41#define task_security(task) (task_cred_xxx((task), security))
@@ -441,11 +443,17 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
441 * BPRM hooks 443 * BPRM hooks
442 */ 444 */
443 445
446/**
447 * smack_bprm_set_creds - set creds for exec
448 * @bprm: the exec information
449 *
450 * Returns 0 if it gets a blob, -ENOMEM otherwise
451 */
444static int smack_bprm_set_creds(struct linux_binprm *bprm) 452static int smack_bprm_set_creds(struct linux_binprm *bprm)
445{ 453{
446 struct task_smack *tsp = bprm->cred->security; 454 struct inode *inode = bprm->file->f_path.dentry->d_inode;
455 struct task_smack *bsp = bprm->cred->security;
447 struct inode_smack *isp; 456 struct inode_smack *isp;
448 struct dentry *dp;
449 int rc; 457 int rc;
450 458
451 rc = cap_bprm_set_creds(bprm); 459 rc = cap_bprm_set_creds(bprm);
@@ -455,20 +463,48 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
455 if (bprm->cred_prepared) 463 if (bprm->cred_prepared)
456 return 0; 464 return 0;
457 465
458 if (bprm->file == NULL || bprm->file->f_dentry == NULL) 466 isp = inode->i_security;
467 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
459 return 0; 468 return 0;
460 469
461 dp = bprm->file->f_dentry; 470 if (bprm->unsafe)
471 return -EPERM;
462 472
463 if (dp->d_inode == NULL) 473 bsp->smk_task = isp->smk_task;
464 return 0; 474 bprm->per_clear |= PER_CLEAR_ON_SETID;
465 475
466 isp = dp->d_inode->i_security; 476 return 0;
477}
467 478
468 if (isp->smk_task != NULL) 479/**
469 tsp->smk_task = isp->smk_task; 480 * smack_bprm_committing_creds - Prepare to install the new credentials
481 * from bprm.
482 *
483 * @bprm: binprm for exec
484 */
485static void smack_bprm_committing_creds(struct linux_binprm *bprm)
486{
487 struct task_smack *bsp = bprm->cred->security;
470 488
471 return 0; 489 if (bsp->smk_task != bsp->smk_forked)
490 current->pdeath_signal = 0;
491}
492
493/**
494 * smack_bprm_secureexec - Return the decision to use secureexec.
495 * @bprm: binprm for exec
496 *
497 * Returns 0 on success.
498 */
499static int smack_bprm_secureexec(struct linux_binprm *bprm)
500{
501 struct task_smack *tsp = current_security();
502 int ret = cap_bprm_secureexec(bprm);
503
504 if (!ret && (tsp->smk_task != tsp->smk_forked))
505 ret = 1;
506
507 return ret;
472} 508}
473 509
474/* 510/*
@@ -516,6 +552,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
516 const struct qstr *qstr, char **name, 552 const struct qstr *qstr, char **name,
517 void **value, size_t *len) 553 void **value, size_t *len)
518{ 554{
555 struct smack_known *skp;
556 char *csp = smk_of_current();
519 char *isp = smk_of_inode(inode); 557 char *isp = smk_of_inode(inode);
520 char *dsp = smk_of_inode(dir); 558 char *dsp = smk_of_inode(dir);
521 int may; 559 int may;
@@ -527,8 +565,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
527 } 565 }
528 566
529 if (value) { 567 if (value) {
568 skp = smk_find_entry(csp);
530 rcu_read_lock(); 569 rcu_read_lock();
531 may = smk_access_entry(smk_of_current(), dsp, &smack_rule_list); 570 may = smk_access_entry(csp, dsp, &skp->smk_rules);
532 rcu_read_unlock(); 571 rcu_read_unlock();
533 572
534 /* 573 /*
@@ -841,7 +880,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
841 return; 880 return;
842} 881}
843 882
844/* 883/**
845 * smack_inode_getxattr - Smack check on getxattr 884 * smack_inode_getxattr - Smack check on getxattr
846 * @dentry: the object 885 * @dentry: the object
847 * @name: unused 886 * @name: unused
@@ -858,7 +897,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
858 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 897 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
859} 898}
860 899
861/* 900/**
862 * smack_inode_removexattr - Smack check on removexattr 901 * smack_inode_removexattr - Smack check on removexattr
863 * @dentry: the object 902 * @dentry: the object
864 * @name: name of the attribute 903 * @name: name of the attribute
@@ -1088,36 +1127,31 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1088 * @cmd: what action to check 1127 * @cmd: what action to check
1089 * @arg: unused 1128 * @arg: unused
1090 * 1129 *
1130 * Generally these operations are harmless.
1131 * File locking operations present an obvious mechanism
1132 * for passing information, so they require write access.
1133 *
1091 * Returns 0 if current has access, error code otherwise 1134 * Returns 0 if current has access, error code otherwise
1092 */ 1135 */
1093static int smack_file_fcntl(struct file *file, unsigned int cmd, 1136static int smack_file_fcntl(struct file *file, unsigned int cmd,
1094 unsigned long arg) 1137 unsigned long arg)
1095{ 1138{
1096 struct smk_audit_info ad; 1139 struct smk_audit_info ad;
1097 int rc; 1140 int rc = 0;
1098 1141
1099 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1100 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1101 1142
1102 switch (cmd) { 1143 switch (cmd) {
1103 case F_DUPFD:
1104 case F_GETFD:
1105 case F_GETFL:
1106 case F_GETLK: 1144 case F_GETLK:
1107 case F_GETOWN:
1108 case F_GETSIG:
1109 rc = smk_curacc(file->f_security, MAY_READ, &ad);
1110 break;
1111 case F_SETFD:
1112 case F_SETFL:
1113 case F_SETLK: 1145 case F_SETLK:
1114 case F_SETLKW: 1146 case F_SETLKW:
1115 case F_SETOWN: 1147 case F_SETOWN:
1116 case F_SETSIG: 1148 case F_SETSIG:
1149 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1150 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1117 rc = smk_curacc(file->f_security, MAY_WRITE, &ad); 1151 rc = smk_curacc(file->f_security, MAY_WRITE, &ad);
1118 break; 1152 break;
1119 default: 1153 default:
1120 rc = smk_curacc(file->f_security, MAY_READWRITE, &ad); 1154 break;
1121 } 1155 }
1122 1156
1123 return rc; 1157 return rc;
@@ -1138,6 +1172,7 @@ static int smack_file_mmap(struct file *file,
1138 unsigned long flags, unsigned long addr, 1172 unsigned long flags, unsigned long addr,
1139 unsigned long addr_only) 1173 unsigned long addr_only)
1140{ 1174{
1175 struct smack_known *skp;
1141 struct smack_rule *srp; 1176 struct smack_rule *srp;
1142 struct task_smack *tsp; 1177 struct task_smack *tsp;
1143 char *sp; 1178 char *sp;
@@ -1170,6 +1205,7 @@ static int smack_file_mmap(struct file *file,
1170 1205
1171 tsp = current_security(); 1206 tsp = current_security();
1172 sp = smk_of_current(); 1207 sp = smk_of_current();
1208 skp = smk_find_entry(sp);
1173 rc = 0; 1209 rc = 0;
1174 1210
1175 rcu_read_lock(); 1211 rcu_read_lock();
@@ -1177,15 +1213,8 @@ static int smack_file_mmap(struct file *file,
1177 * For each Smack rule associated with the subject 1213 * For each Smack rule associated with the subject
1178 * label verify that the SMACK64MMAP also has access 1214 * label verify that the SMACK64MMAP also has access
1179 * to that rule's object label. 1215 * to that rule's object label.
1180 *
1181 * Because neither of the labels comes
1182 * from the networking code it is sufficient
1183 * to compare pointers.
1184 */ 1216 */
1185 list_for_each_entry_rcu(srp, &smack_rule_list, list) { 1217 list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
1186 if (srp->smk_subject != sp)
1187 continue;
1188
1189 osmack = srp->smk_object; 1218 osmack = srp->smk_object;
1190 /* 1219 /*
1191 * Matching labels always allows access. 1220 * Matching labels always allows access.
@@ -1214,7 +1243,8 @@ static int smack_file_mmap(struct file *file,
1214 * If there isn't one a SMACK64MMAP subject 1243 * If there isn't one a SMACK64MMAP subject
1215 * can't have as much access as current. 1244 * can't have as much access as current.
1216 */ 1245 */
1217 mmay = smk_access_entry(msmack, osmack, &smack_rule_list); 1246 skp = smk_find_entry(msmack);
1247 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
1218 if (mmay == -ENOENT) { 1248 if (mmay == -ENOENT) {
1219 rc = -EACCES; 1249 rc = -EACCES;
1220 break; 1250 break;
@@ -1315,6 +1345,24 @@ static int smack_file_receive(struct file *file)
1315 return smk_curacc(file->f_security, may, &ad); 1345 return smk_curacc(file->f_security, may, &ad);
1316} 1346}
1317 1347
1348/**
1349 * smack_dentry_open - Smack dentry open processing
1350 * @file: the object
1351 * @cred: unused
1352 *
1353 * Set the security blob in the file structure.
1354 *
1355 * Returns 0
1356 */
1357static int smack_dentry_open(struct file *file, const struct cred *cred)
1358{
1359 struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
1360
1361 file->f_security = isp->smk_inode;
1362
1363 return 0;
1364}
1365
1318/* 1366/*
1319 * Task hooks 1367 * Task hooks
1320 */ 1368 */
@@ -1455,15 +1503,17 @@ static int smack_kernel_create_files_as(struct cred *new,
1455/** 1503/**
1456 * smk_curacc_on_task - helper to log task related access 1504 * smk_curacc_on_task - helper to log task related access
1457 * @p: the task object 1505 * @p: the task object
1458 * @access : the access requested 1506 * @access: the access requested
1507 * @caller: name of the calling function for audit
1459 * 1508 *
1460 * Return 0 if access is permitted 1509 * Return 0 if access is permitted
1461 */ 1510 */
1462static int smk_curacc_on_task(struct task_struct *p, int access) 1511static int smk_curacc_on_task(struct task_struct *p, int access,
1512 const char *caller)
1463{ 1513{
1464 struct smk_audit_info ad; 1514 struct smk_audit_info ad;
1465 1515
1466 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1516 smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
1467 smk_ad_setfield_u_tsk(&ad, p); 1517 smk_ad_setfield_u_tsk(&ad, p);
1468 return smk_curacc(smk_of_task(task_security(p)), access, &ad); 1518 return smk_curacc(smk_of_task(task_security(p)), access, &ad);
1469} 1519}
@@ -1477,7 +1527,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access)
1477 */ 1527 */
1478static int smack_task_setpgid(struct task_struct *p, pid_t pgid) 1528static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1479{ 1529{
1480 return smk_curacc_on_task(p, MAY_WRITE); 1530 return smk_curacc_on_task(p, MAY_WRITE, __func__);
1481} 1531}
1482 1532
1483/** 1533/**
@@ -1488,7 +1538,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
1488 */ 1538 */
1489static int smack_task_getpgid(struct task_struct *p) 1539static int smack_task_getpgid(struct task_struct *p)
1490{ 1540{
1491 return smk_curacc_on_task(p, MAY_READ); 1541 return smk_curacc_on_task(p, MAY_READ, __func__);
1492} 1542}
1493 1543
1494/** 1544/**
@@ -1499,7 +1549,7 @@ static int smack_task_getpgid(struct task_struct *p)
1499 */ 1549 */
1500static int smack_task_getsid(struct task_struct *p) 1550static int smack_task_getsid(struct task_struct *p)
1501{ 1551{
1502 return smk_curacc_on_task(p, MAY_READ); 1552 return smk_curacc_on_task(p, MAY_READ, __func__);
1503} 1553}
1504 1554
1505/** 1555/**
@@ -1527,7 +1577,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
1527 1577
1528 rc = cap_task_setnice(p, nice); 1578 rc = cap_task_setnice(p, nice);
1529 if (rc == 0) 1579 if (rc == 0)
1530 rc = smk_curacc_on_task(p, MAY_WRITE); 1580 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
1531 return rc; 1581 return rc;
1532} 1582}
1533 1583
@@ -1544,7 +1594,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1544 1594
1545 rc = cap_task_setioprio(p, ioprio); 1595 rc = cap_task_setioprio(p, ioprio);
1546 if (rc == 0) 1596 if (rc == 0)
1547 rc = smk_curacc_on_task(p, MAY_WRITE); 1597 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
1548 return rc; 1598 return rc;
1549} 1599}
1550 1600
@@ -1556,7 +1606,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
1556 */ 1606 */
1557static int smack_task_getioprio(struct task_struct *p) 1607static int smack_task_getioprio(struct task_struct *p)
1558{ 1608{
1559 return smk_curacc_on_task(p, MAY_READ); 1609 return smk_curacc_on_task(p, MAY_READ, __func__);
1560} 1610}
1561 1611
1562/** 1612/**
@@ -1573,7 +1623,7 @@ static int smack_task_setscheduler(struct task_struct *p)
1573 1623
1574 rc = cap_task_setscheduler(p); 1624 rc = cap_task_setscheduler(p);
1575 if (rc == 0) 1625 if (rc == 0)
1576 rc = smk_curacc_on_task(p, MAY_WRITE); 1626 rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
1577 return rc; 1627 return rc;
1578} 1628}
1579 1629
@@ -1585,7 +1635,7 @@ static int smack_task_setscheduler(struct task_struct *p)
1585 */ 1635 */
1586static int smack_task_getscheduler(struct task_struct *p) 1636static int smack_task_getscheduler(struct task_struct *p)
1587{ 1637{
1588 return smk_curacc_on_task(p, MAY_READ); 1638 return smk_curacc_on_task(p, MAY_READ, __func__);
1589} 1639}
1590 1640
1591/** 1641/**
@@ -1596,7 +1646,7 @@ static int smack_task_getscheduler(struct task_struct *p)
1596 */ 1646 */
1597static int smack_task_movememory(struct task_struct *p) 1647static int smack_task_movememory(struct task_struct *p)
1598{ 1648{
1599 return smk_curacc_on_task(p, MAY_WRITE); 1649 return smk_curacc_on_task(p, MAY_WRITE, __func__);
1600} 1650}
1601 1651
1602/** 1652/**
@@ -1711,7 +1761,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1711 1761
1712 ssp->smk_in = csp; 1762 ssp->smk_in = csp;
1713 ssp->smk_out = csp; 1763 ssp->smk_out = csp;
1714 ssp->smk_packet[0] = '\0'; 1764 ssp->smk_packet = NULL;
1715 1765
1716 sk->sk_security = ssp; 1766 sk->sk_security = ssp;
1717 1767
@@ -2753,6 +2803,7 @@ static int smack_unix_stream_connect(struct sock *sock,
2753{ 2803{
2754 struct socket_smack *ssp = sock->sk_security; 2804 struct socket_smack *ssp = sock->sk_security;
2755 struct socket_smack *osp = other->sk_security; 2805 struct socket_smack *osp = other->sk_security;
2806 struct socket_smack *nsp = newsk->sk_security;
2756 struct smk_audit_info ad; 2807 struct smk_audit_info ad;
2757 int rc = 0; 2808 int rc = 0;
2758 2809
@@ -2762,6 +2813,14 @@ static int smack_unix_stream_connect(struct sock *sock,
2762 if (!capable(CAP_MAC_OVERRIDE)) 2813 if (!capable(CAP_MAC_OVERRIDE))
2763 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); 2814 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2764 2815
2816 /*
2817 * Cross reference the peer labels for SO_PEERSEC.
2818 */
2819 if (rc == 0) {
2820 nsp->smk_packet = ssp->smk_out;
2821 ssp->smk_packet = osp->smk_out;
2822 }
2823
2765 return rc; 2824 return rc;
2766} 2825}
2767 2826
@@ -2813,16 +2872,17 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2813 return smack_netlabel_send(sock->sk, sip); 2872 return smack_netlabel_send(sock->sk, sip);
2814} 2873}
2815 2874
2816
2817/** 2875/**
2818 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack 2876 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
2819 * @sap: netlabel secattr 2877 * @sap: netlabel secattr
2820 * @sip: where to put the result 2878 * @ssp: socket security information
2821 * 2879 *
2822 * Copies a smack label into sip 2880 * Returns a pointer to a Smack label found on the label list.
2823 */ 2881 */
2824static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip) 2882static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2883 struct socket_smack *ssp)
2825{ 2884{
2885 struct smack_known *skp;
2826 char smack[SMK_LABELLEN]; 2886 char smack[SMK_LABELLEN];
2827 char *sp; 2887 char *sp;
2828 int pcat; 2888 int pcat;
@@ -2852,15 +2912,43 @@ static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2852 * we are already done. WeeHee. 2912 * we are already done. WeeHee.
2853 */ 2913 */
2854 if (sap->attr.mls.lvl == smack_cipso_direct) { 2914 if (sap->attr.mls.lvl == smack_cipso_direct) {
2855 memcpy(sip, smack, SMK_MAXLEN); 2915 /*
2856 return; 2916 * The label sent is usually on the label list.
2917 *
2918 * If it is not we may still want to allow the
2919 * delivery.
2920 *
2921 * If the recipient is accepting all packets
2922 * because it is using the star ("*") label
2923 * for SMACK64IPIN provide the web ("@") label
2924 * so that a directed response will succeed.
2925 * This is not very correct from a MAC point
2926 * of view, but gets around the problem that
2927 * locking prevents adding the newly discovered
2928 * label to the list.
2929 * The case where the recipient is not using
2930 * the star label should obviously fail.
2931 * The easy way to do this is to provide the
2932 * star label as the subject label.
2933 */
2934 skp = smk_find_entry(smack);
2935 if (skp != NULL)
2936 return skp->smk_known;
2937 if (ssp != NULL &&
2938 ssp->smk_in == smack_known_star.smk_known)
2939 return smack_known_web.smk_known;
2940 return smack_known_star.smk_known;
2857 } 2941 }
2858 /* 2942 /*
2859 * Look it up in the supplied table if it is not 2943 * Look it up in the supplied table if it is not
2860 * a direct mapping. 2944 * a direct mapping.
2861 */ 2945 */
2862 smack_from_cipso(sap->attr.mls.lvl, smack, sip); 2946 sp = smack_from_cipso(sap->attr.mls.lvl, smack);
2863 return; 2947 if (sp != NULL)
2948 return sp;
2949 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
2950 return smack_known_web.smk_known;
2951 return smack_known_star.smk_known;
2864 } 2952 }
2865 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 2953 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
2866 /* 2954 /*
@@ -2875,16 +2963,14 @@ static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2875 * secid is from a fallback. 2963 * secid is from a fallback.
2876 */ 2964 */
2877 BUG_ON(sp == NULL); 2965 BUG_ON(sp == NULL);
2878 strncpy(sip, sp, SMK_MAXLEN); 2966 return sp;
2879 return;
2880 } 2967 }
2881 /* 2968 /*
2882 * Without guidance regarding the smack value 2969 * Without guidance regarding the smack value
2883 * for the packet fall back on the network 2970 * for the packet fall back on the network
2884 * ambient value. 2971 * ambient value.
2885 */ 2972 */
2886 strncpy(sip, smack_net_ambient, SMK_MAXLEN); 2973 return smack_net_ambient;
2887 return;
2888} 2974}
2889 2975
2890/** 2976/**
@@ -2898,7 +2984,6 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2898{ 2984{
2899 struct netlbl_lsm_secattr secattr; 2985 struct netlbl_lsm_secattr secattr;
2900 struct socket_smack *ssp = sk->sk_security; 2986 struct socket_smack *ssp = sk->sk_security;
2901 char smack[SMK_LABELLEN];
2902 char *csp; 2987 char *csp;
2903 int rc; 2988 int rc;
2904 struct smk_audit_info ad; 2989 struct smk_audit_info ad;
@@ -2911,10 +2996,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2911 netlbl_secattr_init(&secattr); 2996 netlbl_secattr_init(&secattr);
2912 2997
2913 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 2998 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2914 if (rc == 0) { 2999 if (rc == 0)
2915 smack_from_secattr(&secattr, smack); 3000 csp = smack_from_secattr(&secattr, ssp);
2916 csp = smack; 3001 else
2917 } else
2918 csp = smack_net_ambient; 3002 csp = smack_net_ambient;
2919 3003
2920 netlbl_secattr_destroy(&secattr); 3004 netlbl_secattr_destroy(&secattr);
@@ -2951,15 +3035,19 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2951 int __user *optlen, unsigned len) 3035 int __user *optlen, unsigned len)
2952{ 3036{
2953 struct socket_smack *ssp; 3037 struct socket_smack *ssp;
2954 int slen; 3038 char *rcp = "";
3039 int slen = 1;
2955 int rc = 0; 3040 int rc = 0;
2956 3041
2957 ssp = sock->sk->sk_security; 3042 ssp = sock->sk->sk_security;
2958 slen = strlen(ssp->smk_packet) + 1; 3043 if (ssp->smk_packet != NULL) {
3044 rcp = ssp->smk_packet;
3045 slen = strlen(rcp) + 1;
3046 }
2959 3047
2960 if (slen > len) 3048 if (slen > len)
2961 rc = -ERANGE; 3049 rc = -ERANGE;
2962 else if (copy_to_user(optval, ssp->smk_packet, slen) != 0) 3050 else if (copy_to_user(optval, rcp, slen) != 0)
2963 rc = -EFAULT; 3051 rc = -EFAULT;
2964 3052
2965 if (put_user(slen, optlen) != 0) 3053 if (put_user(slen, optlen) != 0)
@@ -2982,8 +3070,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2982 3070
2983{ 3071{
2984 struct netlbl_lsm_secattr secattr; 3072 struct netlbl_lsm_secattr secattr;
2985 struct socket_smack *sp; 3073 struct socket_smack *ssp = NULL;
2986 char smack[SMK_LABELLEN]; 3074 char *sp;
2987 int family = PF_UNSPEC; 3075 int family = PF_UNSPEC;
2988 u32 s = 0; /* 0 is the invalid secid */ 3076 u32 s = 0; /* 0 is the invalid secid */
2989 int rc; 3077 int rc;
@@ -2998,17 +3086,19 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2998 family = sock->sk->sk_family; 3086 family = sock->sk->sk_family;
2999 3087
3000 if (family == PF_UNIX) { 3088 if (family == PF_UNIX) {
3001 sp = sock->sk->sk_security; 3089 ssp = sock->sk->sk_security;
3002 s = smack_to_secid(sp->smk_out); 3090 s = smack_to_secid(ssp->smk_out);
3003 } else if (family == PF_INET || family == PF_INET6) { 3091 } else if (family == PF_INET || family == PF_INET6) {
3004 /* 3092 /*
3005 * Translate what netlabel gave us. 3093 * Translate what netlabel gave us.
3006 */ 3094 */
3095 if (sock != NULL && sock->sk != NULL)
3096 ssp = sock->sk->sk_security;
3007 netlbl_secattr_init(&secattr); 3097 netlbl_secattr_init(&secattr);
3008 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3098 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3009 if (rc == 0) { 3099 if (rc == 0) {
3010 smack_from_secattr(&secattr, smack); 3100 sp = smack_from_secattr(&secattr, ssp);
3011 s = smack_to_secid(smack); 3101 s = smack_to_secid(sp);
3012 } 3102 }
3013 netlbl_secattr_destroy(&secattr); 3103 netlbl_secattr_destroy(&secattr);
3014 } 3104 }
@@ -3056,7 +3146,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3056 struct netlbl_lsm_secattr secattr; 3146 struct netlbl_lsm_secattr secattr;
3057 struct sockaddr_in addr; 3147 struct sockaddr_in addr;
3058 struct iphdr *hdr; 3148 struct iphdr *hdr;
3059 char smack[SMK_LABELLEN]; 3149 char *sp;
3060 int rc; 3150 int rc;
3061 struct smk_audit_info ad; 3151 struct smk_audit_info ad;
3062 3152
@@ -3067,9 +3157,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3067 netlbl_secattr_init(&secattr); 3157 netlbl_secattr_init(&secattr);
3068 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3158 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3069 if (rc == 0) 3159 if (rc == 0)
3070 smack_from_secattr(&secattr, smack); 3160 sp = smack_from_secattr(&secattr, ssp);
3071 else 3161 else
3072 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); 3162 sp = smack_known_huh.smk_known;
3073 netlbl_secattr_destroy(&secattr); 3163 netlbl_secattr_destroy(&secattr);
3074 3164
3075#ifdef CONFIG_AUDIT 3165#ifdef CONFIG_AUDIT
@@ -3082,7 +3172,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3082 * Receiving a packet requires that the other end be able to write 3172 * Receiving a packet requires that the other end be able to write
3083 * here. Read access is not required. 3173 * here. Read access is not required.
3084 */ 3174 */
3085 rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad); 3175 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad);
3086 if (rc != 0) 3176 if (rc != 0)
3087 return rc; 3177 return rc;
3088 3178
@@ -3090,7 +3180,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3090 * Save the peer's label in the request_sock so we can later setup 3180 * Save the peer's label in the request_sock so we can later setup
3091 * smk_packet in the child socket so that SO_PEERCRED can report it. 3181 * smk_packet in the child socket so that SO_PEERCRED can report it.
3092 */ 3182 */
3093 req->peer_secid = smack_to_secid(smack); 3183 req->peer_secid = smack_to_secid(sp);
3094 3184
3095 /* 3185 /*
3096 * We need to decide if we want to label the incoming connection here 3186 * We need to decide if we want to label the incoming connection here
@@ -3103,7 +3193,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3103 if (smack_host_label(&addr) == NULL) { 3193 if (smack_host_label(&addr) == NULL) {
3104 rcu_read_unlock(); 3194 rcu_read_unlock();
3105 netlbl_secattr_init(&secattr); 3195 netlbl_secattr_init(&secattr);
3106 smack_to_secattr(smack, &secattr); 3196 smack_to_secattr(sp, &secattr);
3107 rc = netlbl_req_setattr(req, &secattr); 3197 rc = netlbl_req_setattr(req, &secattr);
3108 netlbl_secattr_destroy(&secattr); 3198 netlbl_secattr_destroy(&secattr);
3109 } else { 3199 } else {
@@ -3125,13 +3215,11 @@ static void smack_inet_csk_clone(struct sock *sk,
3125 const struct request_sock *req) 3215 const struct request_sock *req)
3126{ 3216{
3127 struct socket_smack *ssp = sk->sk_security; 3217 struct socket_smack *ssp = sk->sk_security;
3128 char *smack;
3129 3218
3130 if (req->peer_secid != 0) { 3219 if (req->peer_secid != 0)
3131 smack = smack_from_secid(req->peer_secid); 3220 ssp->smk_packet = smack_from_secid(req->peer_secid);
3132 strncpy(ssp->smk_packet, smack, SMK_MAXLEN); 3221 else
3133 } else 3222 ssp->smk_packet = NULL;
3134 ssp->smk_packet[0] = '\0';
3135} 3223}
3136 3224
3137/* 3225/*
@@ -3409,6 +3497,8 @@ struct security_operations smack_ops = {
3409 .sb_umount = smack_sb_umount, 3497 .sb_umount = smack_sb_umount,
3410 3498
3411 .bprm_set_creds = smack_bprm_set_creds, 3499 .bprm_set_creds = smack_bprm_set_creds,
3500 .bprm_committing_creds = smack_bprm_committing_creds,
3501 .bprm_secureexec = smack_bprm_secureexec,
3412 3502
3413 .inode_alloc_security = smack_inode_alloc_security, 3503 .inode_alloc_security = smack_inode_alloc_security,
3414 .inode_free_security = smack_inode_free_security, 3504 .inode_free_security = smack_inode_free_security,
@@ -3440,6 +3530,8 @@ struct security_operations smack_ops = {
3440 .file_send_sigiotask = smack_file_send_sigiotask, 3530 .file_send_sigiotask = smack_file_send_sigiotask,
3441 .file_receive = smack_file_receive, 3531 .file_receive = smack_file_receive,
3442 3532
3533 .dentry_open = smack_dentry_open,
3534
3443 .cred_alloc_blank = smack_cred_alloc_blank, 3535 .cred_alloc_blank = smack_cred_alloc_blank,
3444 .cred_free = smack_cred_free, 3536 .cred_free = smack_cred_free,
3445 .cred_prepare = smack_cred_prepare, 3537 .cred_prepare = smack_cred_prepare,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index f93460156dce..6aceef518a41 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -44,6 +44,7 @@ enum smk_inos {
44 SMK_ONLYCAP = 9, /* the only "capable" label */ 44 SMK_ONLYCAP = 9, /* the only "capable" label */
45 SMK_LOGGING = 10, /* logging */ 45 SMK_LOGGING = 10, /* logging */
46 SMK_LOAD_SELF = 11, /* task specific rules */ 46 SMK_LOAD_SELF = 11, /* task specific rules */
47 SMK_ACCESSES = 12, /* access policy */
47}; 48};
48 49
49/* 50/*
@@ -85,6 +86,16 @@ char *smack_onlycap;
85 */ 86 */
86 87
87LIST_HEAD(smk_netlbladdr_list); 88LIST_HEAD(smk_netlbladdr_list);
89
90/*
91 * Rule lists are maintained for each label.
92 * This master list is just for reading /smack/load.
93 */
94struct smack_master_list {
95 struct list_head list;
96 struct smack_rule *smk_rule;
97};
98
88LIST_HEAD(smack_rule_list); 99LIST_HEAD(smack_rule_list);
89 100
90static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 101static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
@@ -92,7 +103,7 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
92const char *smack_cipso_option = SMACK_CIPSO_OPTION; 103const char *smack_cipso_option = SMACK_CIPSO_OPTION;
93 104
94 105
95#define SEQ_READ_FINISHED 1 106#define SEQ_READ_FINISHED ((loff_t)-1)
96 107
97/* 108/*
98 * Values for parsing cipso rules 109 * Values for parsing cipso rules
@@ -159,9 +170,13 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
159 170
160 mutex_lock(rule_lock); 171 mutex_lock(rule_lock);
161 172
173 /*
174 * Because the object label is less likely to match
175 * than the subject label check it first
176 */
162 list_for_each_entry_rcu(sp, rule_list, list) { 177 list_for_each_entry_rcu(sp, rule_list, list) {
163 if (sp->smk_subject == srp->smk_subject && 178 if (sp->smk_object == srp->smk_object &&
164 sp->smk_object == srp->smk_object) { 179 sp->smk_subject == srp->smk_subject) {
165 found = 1; 180 found = 1;
166 sp->smk_access = srp->smk_access; 181 sp->smk_access = srp->smk_access;
167 break; 182 break;
@@ -176,6 +191,99 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
176} 191}
177 192
178/** 193/**
194 * smk_parse_rule - parse Smack rule from load string
195 * @data: string to be parsed whose size is SMK_LOADLEN
196 * @rule: Smack rule
197 * @import: if non-zero, import labels
198 */
199static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
200{
201 char smack[SMK_LABELLEN];
202 struct smack_known *skp;
203
204 if (import) {
205 rule->smk_subject = smk_import(data, 0);
206 if (rule->smk_subject == NULL)
207 return -1;
208
209 rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
210 if (rule->smk_object == NULL)
211 return -1;
212 } else {
213 smk_parse_smack(data, 0, smack);
214 skp = smk_find_entry(smack);
215 if (skp == NULL)
216 return -1;
217 rule->smk_subject = skp->smk_known;
218
219 smk_parse_smack(data + SMK_LABELLEN, 0, smack);
220 skp = smk_find_entry(smack);
221 if (skp == NULL)
222 return -1;
223 rule->smk_object = skp->smk_known;
224 }
225
226 rule->smk_access = 0;
227
228 switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
229 case '-':
230 break;
231 case 'r':
232 case 'R':
233 rule->smk_access |= MAY_READ;
234 break;
235 default:
236 return -1;
237 }
238
239 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
240 case '-':
241 break;
242 case 'w':
243 case 'W':
244 rule->smk_access |= MAY_WRITE;
245 break;
246 default:
247 return -1;
248 }
249
250 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
251 case '-':
252 break;
253 case 'x':
254 case 'X':
255 rule->smk_access |= MAY_EXEC;
256 break;
257 default:
258 return -1;
259 }
260
261 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
262 case '-':
263 break;
264 case 'a':
265 case 'A':
266 rule->smk_access |= MAY_APPEND;
267 break;
268 default:
269 return -1;
270 }
271
272 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
273 case '-':
274 break;
275 case 't':
276 case 'T':
277 rule->smk_access |= MAY_TRANSMUTE;
278 break;
279 default:
280 return -1;
281 }
282
283 return 0;
284}
285
286/**
179 * smk_write_load_list - write() for any /smack/load 287 * smk_write_load_list - write() for any /smack/load
180 * @file: file pointer, not actually used 288 * @file: file pointer, not actually used
181 * @buf: where to get the data from 289 * @buf: where to get the data from
@@ -197,9 +305,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
197 struct list_head *rule_list, 305 struct list_head *rule_list,
198 struct mutex *rule_lock) 306 struct mutex *rule_lock)
199{ 307{
308 struct smack_master_list *smlp;
309 struct smack_known *skp;
200 struct smack_rule *rule; 310 struct smack_rule *rule;
201 char *data; 311 char *data;
202 int rc = -EINVAL; 312 int rc = -EINVAL;
313 int load = 0;
203 314
204 /* 315 /*
205 * No partial writes. 316 * No partial writes.
@@ -234,69 +345,14 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
234 goto out; 345 goto out;
235 } 346 }
236 347
237 rule->smk_subject = smk_import(data, 0); 348 if (smk_parse_rule(data, rule, 1))
238 if (rule->smk_subject == NULL)
239 goto out_free_rule;
240
241 rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
242 if (rule->smk_object == NULL)
243 goto out_free_rule; 349 goto out_free_rule;
244 350
245 rule->smk_access = 0; 351 if (rule_list == NULL) {
246 352 load = 1;
247 switch (data[SMK_LABELLEN + SMK_LABELLEN]) { 353 skp = smk_find_entry(rule->smk_subject);
248 case '-': 354 rule_list = &skp->smk_rules;
249 break; 355 rule_lock = &skp->smk_rules_lock;
250 case 'r':
251 case 'R':
252 rule->smk_access |= MAY_READ;
253 break;
254 default:
255 goto out_free_rule;
256 }
257
258 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
259 case '-':
260 break;
261 case 'w':
262 case 'W':
263 rule->smk_access |= MAY_WRITE;
264 break;
265 default:
266 goto out_free_rule;
267 }
268
269 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
270 case '-':
271 break;
272 case 'x':
273 case 'X':
274 rule->smk_access |= MAY_EXEC;
275 break;
276 default:
277 goto out_free_rule;
278 }
279
280 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
281 case '-':
282 break;
283 case 'a':
284 case 'A':
285 rule->smk_access |= MAY_APPEND;
286 break;
287 default:
288 goto out_free_rule;
289 }
290
291 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
292 case '-':
293 break;
294 case 't':
295 case 'T':
296 rule->smk_access |= MAY_TRANSMUTE;
297 break;
298 default:
299 goto out_free_rule;
300 } 356 }
301 357
302 rc = count; 358 rc = count;
@@ -304,8 +360,15 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
304 * smk_set_access returns true if there was already a rule 360 * smk_set_access returns true if there was already a rule
305 * for the subject/object pair, and false if it was new. 361 * for the subject/object pair, and false if it was new.
306 */ 362 */
307 if (!smk_set_access(rule, rule_list, rule_lock)) 363 if (!smk_set_access(rule, rule_list, rule_lock)) {
364 smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
365 if (smlp != NULL) {
366 smlp->smk_rule = rule;
367 list_add_rcu(&smlp->list, &smack_rule_list);
368 } else
369 rc = -ENOMEM;
308 goto out; 370 goto out;
371 }
309 372
310out_free_rule: 373out_free_rule:
311 kfree(rule); 374 kfree(rule);
@@ -321,11 +384,24 @@ out:
321 384
322static void *load_seq_start(struct seq_file *s, loff_t *pos) 385static void *load_seq_start(struct seq_file *s, loff_t *pos)
323{ 386{
324 if (*pos == SEQ_READ_FINISHED) 387 struct list_head *list;
388
389 /*
390 * This is 0 the first time through.
391 */
392 if (s->index == 0)
393 s->private = &smack_rule_list;
394
395 if (s->private == NULL)
325 return NULL; 396 return NULL;
326 if (list_empty(&smack_rule_list)) 397
398 list = s->private;
399 if (list_empty(list))
327 return NULL; 400 return NULL;
328 return smack_rule_list.next; 401
402 if (s->index == 0)
403 return list->next;
404 return list;
329} 405}
330 406
331static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) 407static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
@@ -333,17 +409,19 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
333 struct list_head *list = v; 409 struct list_head *list = v;
334 410
335 if (list_is_last(list, &smack_rule_list)) { 411 if (list_is_last(list, &smack_rule_list)) {
336 *pos = SEQ_READ_FINISHED; 412 s->private = NULL;
337 return NULL; 413 return NULL;
338 } 414 }
415 s->private = list->next;
339 return list->next; 416 return list->next;
340} 417}
341 418
342static int load_seq_show(struct seq_file *s, void *v) 419static int load_seq_show(struct seq_file *s, void *v)
343{ 420{
344 struct list_head *list = v; 421 struct list_head *list = v;
345 struct smack_rule *srp = 422 struct smack_master_list *smlp =
346 list_entry(list, struct smack_rule, list); 423 list_entry(list, struct smack_master_list, list);
424 struct smack_rule *srp = smlp->smk_rule;
347 425
348 seq_printf(s, "%s %s", (char *)srp->smk_subject, 426 seq_printf(s, "%s %s", (char *)srp->smk_subject,
349 (char *)srp->smk_object); 427 (char *)srp->smk_object);
@@ -412,8 +490,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
412 if (!capable(CAP_MAC_ADMIN)) 490 if (!capable(CAP_MAC_ADMIN))
413 return -EPERM; 491 return -EPERM;
414 492
415 return smk_write_load_list(file, buf, count, ppos, &smack_rule_list, 493 return smk_write_load_list(file, buf, count, ppos, NULL, NULL);
416 &smack_list_lock);
417} 494}
418 495
419static const struct file_operations smk_load_ops = { 496static const struct file_operations smk_load_ops = {
@@ -1425,6 +1502,44 @@ static const struct file_operations smk_load_self_ops = {
1425 .write = smk_write_load_self, 1502 .write = smk_write_load_self,
1426 .release = seq_release, 1503 .release = seq_release,
1427}; 1504};
1505
1506/**
1507 * smk_write_access - handle access check transaction
1508 * @file: file pointer
1509 * @buf: data from user space
1510 * @count: bytes sent
1511 * @ppos: where to start - must be 0
1512 */
1513static ssize_t smk_write_access(struct file *file, const char __user *buf,
1514 size_t count, loff_t *ppos)
1515{
1516 struct smack_rule rule;
1517 char *data;
1518 int res;
1519
1520 data = simple_transaction_get(file, buf, count);
1521 if (IS_ERR(data))
1522 return PTR_ERR(data);
1523
1524 if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0))
1525 return -EINVAL;
1526
1527 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
1528 NULL);
1529 data[0] = res == 0 ? '1' : '0';
1530 data[1] = '\0';
1531
1532 simple_transaction_set(file, 2);
1533 return SMK_LOADLEN;
1534}
1535
1536static const struct file_operations smk_access_ops = {
1537 .write = smk_write_access,
1538 .read = simple_transaction_read,
1539 .release = simple_transaction_release,
1540 .llseek = generic_file_llseek,
1541};
1542
1428/** 1543/**
1429 * smk_fill_super - fill the /smackfs superblock 1544 * smk_fill_super - fill the /smackfs superblock
1430 * @sb: the empty superblock 1545 * @sb: the empty superblock
@@ -1459,6 +1574,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
1459 "logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, 1574 "logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
1460 [SMK_LOAD_SELF] = { 1575 [SMK_LOAD_SELF] = {
1461 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, 1576 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
1577 [SMK_ACCESSES] = {
1578 "access", &smk_access_ops, S_IRUGO|S_IWUGO},
1462 /* last one */ 1579 /* last one */
1463 {""} 1580 {""}
1464 }; 1581 };
@@ -1534,6 +1651,20 @@ static int __init init_smk_fs(void)
1534 smk_cipso_doi(); 1651 smk_cipso_doi();
1535 smk_unlbl_ambient(NULL); 1652 smk_unlbl_ambient(NULL);
1536 1653
1654 mutex_init(&smack_known_floor.smk_rules_lock);
1655 mutex_init(&smack_known_hat.smk_rules_lock);
1656 mutex_init(&smack_known_huh.smk_rules_lock);
1657 mutex_init(&smack_known_invalid.smk_rules_lock);
1658 mutex_init(&smack_known_star.smk_rules_lock);
1659 mutex_init(&smack_known_web.smk_rules_lock);
1660
1661 INIT_LIST_HEAD(&smack_known_floor.smk_rules);
1662 INIT_LIST_HEAD(&smack_known_hat.smk_rules);
1663 INIT_LIST_HEAD(&smack_known_huh.smk_rules);
1664 INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
1665 INIT_LIST_HEAD(&smack_known_star.smk_rules);
1666 INIT_LIST_HEAD(&smack_known_web.smk_rules);
1667
1537 return err; 1668 return err;
1538} 1669}
1539 1670
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index 7c7f8c16c10f..8eb779b9d77f 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -1,8 +1,10 @@
1config SECURITY_TOMOYO 1config SECURITY_TOMOYO
2 bool "TOMOYO Linux Support" 2 bool "TOMOYO Linux Support"
3 depends on SECURITY 3 depends on SECURITY
4 depends on NET
4 select SECURITYFS 5 select SECURITYFS
5 select SECURITY_PATH 6 select SECURITY_PATH
7 select SECURITY_NETWORK
6 default n 8 default n
7 help 9 help
8 This selects TOMOYO Linux, pathname-based access control. 10 This selects TOMOYO Linux, pathname-based access control.
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index 95278b71fc21..56a0c7be409e 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1,4 +1,4 @@
1obj-y = audit.o common.o condition.o domain.o file.o gc.o group.o load_policy.o memory.o mount.o realpath.o securityfs_if.o tomoyo.o util.o 1obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o
2 2
3$(obj)/policy/profile.conf: 3$(obj)/policy/profile.conf:
4 @mkdir -p $(obj)/policy/ 4 @mkdir -p $(obj)/policy/
@@ -27,7 +27,7 @@ $(obj)/policy/stat.conf:
27 @touch $@ 27 @touch $@
28 28
29$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf 29$(obj)/builtin-policy.h: $(obj)/policy/profile.conf $(obj)/policy/exception_policy.conf $(obj)/policy/domain_policy.conf $(obj)/policy/manager.conf $(obj)/policy/stat.conf
30 @echo Generating built-in policy for TOMOYO 2.4.x. 30 @echo Generating built-in policy for TOMOYO 2.5.x.
31 @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp 31 @echo "static char tomoyo_builtin_profile[] __initdata =" > $@.tmp
32 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp 32 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/profile.conf >> $@.tmp
33 @echo "\"\";" >> $@.tmp 33 @echo "\"\";" >> $@.tmp
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index 5dbb1f7617c0..075c3a6d1649 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -313,6 +313,7 @@ static unsigned int tomoyo_log_count;
313 */ 313 */
314static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns, 314static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
315 const u8 profile, const u8 index, 315 const u8 profile, const u8 index,
316 const struct tomoyo_acl_info *matched_acl,
316 const bool is_granted) 317 const bool is_granted)
317{ 318{
318 u8 mode; 319 u8 mode;
@@ -324,6 +325,9 @@ static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
324 p = tomoyo_profile(ns, profile); 325 p = tomoyo_profile(ns, profile);
325 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG]) 326 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
326 return false; 327 return false;
328 if (is_granted && matched_acl && matched_acl->cond &&
329 matched_acl->cond->grant_log != TOMOYO_GRANTLOG_AUTO)
330 return matched_acl->cond->grant_log == TOMOYO_GRANTLOG_YES;
327 mode = p->config[index]; 331 mode = p->config[index];
328 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 332 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
329 mode = p->config[category]; 333 mode = p->config[category];
@@ -350,7 +354,8 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
350 char *buf; 354 char *buf;
351 struct tomoyo_log *entry; 355 struct tomoyo_log *entry;
352 bool quota_exceeded = false; 356 bool quota_exceeded = false;
353 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted)) 357 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type,
358 r->matched_acl, r->granted))
354 goto out; 359 goto out;
355 buf = tomoyo_init_log(r, len, fmt, args); 360 buf = tomoyo_init_log(r, len, fmt, args);
356 if (!buf) 361 if (!buf)
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 2e43aec1c36b..150911c7ff08 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -20,6 +20,7 @@ const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
20/* String table for /sys/kernel/security/tomoyo/profile */ 20/* String table for /sys/kernel/security/tomoyo/profile */
21const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 21const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
22 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 22 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
23 /* CONFIG::file group */
23 [TOMOYO_MAC_FILE_EXECUTE] = "execute", 24 [TOMOYO_MAC_FILE_EXECUTE] = "execute",
24 [TOMOYO_MAC_FILE_OPEN] = "open", 25 [TOMOYO_MAC_FILE_OPEN] = "open",
25 [TOMOYO_MAC_FILE_CREATE] = "create", 26 [TOMOYO_MAC_FILE_CREATE] = "create",
@@ -43,7 +44,28 @@ const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
43 [TOMOYO_MAC_FILE_MOUNT] = "mount", 44 [TOMOYO_MAC_FILE_MOUNT] = "mount",
44 [TOMOYO_MAC_FILE_UMOUNT] = "unmount", 45 [TOMOYO_MAC_FILE_UMOUNT] = "unmount",
45 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", 46 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
47 /* CONFIG::network group */
48 [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind",
49 [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen",
50 [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect",
51 [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind",
52 [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send",
53 [TOMOYO_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind",
54 [TOMOYO_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send",
55 [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind",
56 [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen",
57 [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect",
58 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind",
59 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send",
60 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
61 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
62 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
63 /* CONFIG::misc group */
64 [TOMOYO_MAC_ENVIRON] = "env",
65 /* CONFIG group */
46 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", 66 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
67 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network",
68 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc",
47}; 69};
48 70
49/* String table for conditions. */ 71/* String table for conditions. */
@@ -130,10 +152,20 @@ const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
130 [TOMOYO_TYPE_UMOUNT] = "unmount", 152 [TOMOYO_TYPE_UMOUNT] = "unmount",
131}; 153};
132 154
155/* String table for socket's operation. */
156const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = {
157 [TOMOYO_NETWORK_BIND] = "bind",
158 [TOMOYO_NETWORK_LISTEN] = "listen",
159 [TOMOYO_NETWORK_CONNECT] = "connect",
160 [TOMOYO_NETWORK_SEND] = "send",
161};
162
133/* String table for categories. */ 163/* String table for categories. */
134static const char * const tomoyo_category_keywords 164static const char * const tomoyo_category_keywords
135[TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 165[TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
136 [TOMOYO_MAC_CATEGORY_FILE] = "file", 166 [TOMOYO_MAC_CATEGORY_FILE] = "file",
167 [TOMOYO_MAC_CATEGORY_NETWORK] = "network",
168 [TOMOYO_MAC_CATEGORY_MISC] = "misc",
137}; 169};
138 170
139/* Permit policy management by non-root user? */ 171/* Permit policy management by non-root user? */
@@ -230,13 +262,17 @@ static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
230 WARN_ON(1); 262 WARN_ON(1);
231} 263}
232 264
265static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
266 ...) __printf(2, 3);
267
233/** 268/**
234 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. 269 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
235 * 270 *
236 * @head: Pointer to "struct tomoyo_io_buffer". 271 * @head: Pointer to "struct tomoyo_io_buffer".
237 * @fmt: The printf()'s format string, followed by parameters. 272 * @fmt: The printf()'s format string, followed by parameters.
238 */ 273 */
239void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 274static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
275 ...)
240{ 276{
241 va_list args; 277 va_list args;
242 size_t len; 278 size_t len;
@@ -313,7 +349,7 @@ void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
313 INIT_LIST_HEAD(&ns->group_list[idx]); 349 INIT_LIST_HEAD(&ns->group_list[idx]);
314 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) 350 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
315 INIT_LIST_HEAD(&ns->policy_list[idx]); 351 INIT_LIST_HEAD(&ns->policy_list[idx]);
316 ns->profile_version = 20100903; 352 ns->profile_version = 20110903;
317 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); 353 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
318 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); 354 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
319} 355}
@@ -466,8 +502,10 @@ static struct tomoyo_profile *tomoyo_assign_profile
466 TOMOYO_CONFIG_WANT_REJECT_LOG; 502 TOMOYO_CONFIG_WANT_REJECT_LOG;
467 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 503 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
468 sizeof(ptr->config)); 504 sizeof(ptr->config));
469 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024; 505 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] =
470 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048; 506 CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG;
507 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] =
508 CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY;
471 mb(); /* Avoid out-of-order execution. */ 509 mb(); /* Avoid out-of-order execution. */
472 ns->profile_ptr[profile] = ptr; 510 ns->profile_ptr[profile] = ptr;
473 entry = NULL; 511 entry = NULL;
@@ -951,14 +989,12 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
951 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 989 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
952 struct task_struct *p; 990 struct task_struct *p;
953 rcu_read_lock(); 991 rcu_read_lock();
954 read_lock(&tasklist_lock);
955 if (global_pid) 992 if (global_pid)
956 p = find_task_by_pid_ns(pid, &init_pid_ns); 993 p = find_task_by_pid_ns(pid, &init_pid_ns);
957 else 994 else
958 p = find_task_by_vpid(pid); 995 p = find_task_by_vpid(pid);
959 if (p) 996 if (p)
960 domain = tomoyo_real_domain(p); 997 domain = tomoyo_real_domain(p);
961 read_unlock(&tasklist_lock);
962 rcu_read_unlock(); 998 rcu_read_unlock();
963 } else if (!strncmp(data, "domain=", 7)) { 999 } else if (!strncmp(data, "domain=", 7)) {
964 if (tomoyo_domain_def(data + 7)) 1000 if (tomoyo_domain_def(data + 7))
@@ -982,6 +1018,48 @@ static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
982} 1018}
983 1019
984/** 1020/**
1021 * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry.
1022 *
1023 * @a: Pointer to "struct tomoyo_acl_info".
1024 * @b: Pointer to "struct tomoyo_acl_info".
1025 *
1026 * Returns true if @a == @b, false otherwise.
1027 */
1028static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a,
1029 const struct tomoyo_acl_info *b)
1030{
1031 const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head);
1032 const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head);
1033 return p1->domainname == p2->domainname;
1034}
1035
1036/**
1037 * tomoyo_write_task - Update task related list.
1038 *
1039 * @param: Pointer to "struct tomoyo_acl_param".
1040 *
1041 * Returns 0 on success, negative value otherwise.
1042 *
1043 * Caller holds tomoyo_read_lock().
1044 */
1045static int tomoyo_write_task(struct tomoyo_acl_param *param)
1046{
1047 int error = -EINVAL;
1048 if (tomoyo_str_starts(&param->data, "manual_domain_transition ")) {
1049 struct tomoyo_task_acl e = {
1050 .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL,
1051 .domainname = tomoyo_get_domainname(param),
1052 };
1053 if (e.domainname)
1054 error = tomoyo_update_domain(&e.head, sizeof(e), param,
1055 tomoyo_same_task_acl,
1056 NULL);
1057 tomoyo_put_name(e.domainname);
1058 }
1059 return error;
1060}
1061
1062/**
985 * tomoyo_delete_domain - Delete a domain. 1063 * tomoyo_delete_domain - Delete a domain.
986 * 1064 *
987 * @domainname: The name of domain. 1065 * @domainname: The name of domain.
@@ -1039,11 +1117,16 @@ static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
1039 static const struct { 1117 static const struct {
1040 const char *keyword; 1118 const char *keyword;
1041 int (*write) (struct tomoyo_acl_param *); 1119 int (*write) (struct tomoyo_acl_param *);
1042 } tomoyo_callback[1] = { 1120 } tomoyo_callback[5] = {
1043 { "file ", tomoyo_write_file }, 1121 { "file ", tomoyo_write_file },
1122 { "network inet ", tomoyo_write_inet_network },
1123 { "network unix ", tomoyo_write_unix_network },
1124 { "misc ", tomoyo_write_misc },
1125 { "task ", tomoyo_write_task },
1044 }; 1126 };
1045 u8 i; 1127 u8 i;
1046 for (i = 0; i < 1; i++) { 1128
1129 for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) {
1047 if (!tomoyo_str_starts(&param.data, 1130 if (!tomoyo_str_starts(&param.data,
1048 tomoyo_callback[i].keyword)) 1131 tomoyo_callback[i].keyword))
1049 continue; 1132 continue;
@@ -1127,6 +1210,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1127 case 0: 1210 case 0:
1128 head->r.cond_index = 0; 1211 head->r.cond_index = 0;
1129 head->r.cond_step++; 1212 head->r.cond_step++;
1213 if (cond->transit) {
1214 tomoyo_set_space(head);
1215 tomoyo_set_string(head, cond->transit->name);
1216 }
1130 /* fall through */ 1217 /* fall through */
1131 case 1: 1218 case 1:
1132 { 1219 {
@@ -1239,6 +1326,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1239 head->r.cond_step++; 1326 head->r.cond_step++;
1240 /* fall through */ 1327 /* fall through */
1241 case 3: 1328 case 3:
1329 if (cond->grant_log != TOMOYO_GRANTLOG_AUTO)
1330 tomoyo_io_printf(head, " grant_log=%s",
1331 tomoyo_yesno(cond->grant_log ==
1332 TOMOYO_GRANTLOG_YES));
1242 tomoyo_set_lf(head); 1333 tomoyo_set_lf(head);
1243 return true; 1334 return true;
1244 } 1335 }
@@ -1306,6 +1397,12 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1306 if (first) 1397 if (first)
1307 return true; 1398 return true;
1308 tomoyo_print_name_union(head, &ptr->name); 1399 tomoyo_print_name_union(head, &ptr->name);
1400 } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) {
1401 struct tomoyo_task_acl *ptr =
1402 container_of(acl, typeof(*ptr), head);
1403 tomoyo_set_group(head, "task ");
1404 tomoyo_set_string(head, "manual_domain_transition ");
1405 tomoyo_set_string(head, ptr->domainname->name);
1309 } else if (head->r.print_transition_related_only) { 1406 } else if (head->r.print_transition_related_only) {
1310 return true; 1407 return true;
1311 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1408 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
@@ -1370,6 +1467,60 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1370 tomoyo_print_number_union(head, &ptr->mode); 1467 tomoyo_print_number_union(head, &ptr->mode);
1371 tomoyo_print_number_union(head, &ptr->major); 1468 tomoyo_print_number_union(head, &ptr->major);
1372 tomoyo_print_number_union(head, &ptr->minor); 1469 tomoyo_print_number_union(head, &ptr->minor);
1470 } else if (acl_type == TOMOYO_TYPE_INET_ACL) {
1471 struct tomoyo_inet_acl *ptr =
1472 container_of(acl, typeof(*ptr), head);
1473 const u8 perm = ptr->perm;
1474
1475 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
1476 if (!(perm & (1 << bit)))
1477 continue;
1478 if (first) {
1479 tomoyo_set_group(head, "network inet ");
1480 tomoyo_set_string(head, tomoyo_proto_keyword
1481 [ptr->protocol]);
1482 tomoyo_set_space(head);
1483 first = false;
1484 } else {
1485 tomoyo_set_slash(head);
1486 }
1487 tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
1488 }
1489 if (first)
1490 return true;
1491 tomoyo_set_space(head);
1492 if (ptr->address.group) {
1493 tomoyo_set_string(head, "@");
1494 tomoyo_set_string(head, ptr->address.group->group_name
1495 ->name);
1496 } else {
1497 char buf[128];
1498 tomoyo_print_ip(buf, sizeof(buf), &ptr->address);
1499 tomoyo_io_printf(head, "%s", buf);
1500 }
1501 tomoyo_print_number_union(head, &ptr->port);
1502 } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) {
1503 struct tomoyo_unix_acl *ptr =
1504 container_of(acl, typeof(*ptr), head);
1505 const u8 perm = ptr->perm;
1506
1507 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
1508 if (!(perm & (1 << bit)))
1509 continue;
1510 if (first) {
1511 tomoyo_set_group(head, "network unix ");
1512 tomoyo_set_string(head, tomoyo_proto_keyword
1513 [ptr->protocol]);
1514 tomoyo_set_space(head);
1515 first = false;
1516 } else {
1517 tomoyo_set_slash(head);
1518 }
1519 tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
1520 }
1521 if (first)
1522 return true;
1523 tomoyo_print_name_union(head, &ptr->name);
1373 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 1524 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
1374 struct tomoyo_mount_acl *ptr = 1525 struct tomoyo_mount_acl *ptr =
1375 container_of(acl, typeof(*ptr), head); 1526 container_of(acl, typeof(*ptr), head);
@@ -1378,6 +1529,12 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1378 tomoyo_print_name_union(head, &ptr->dir_name); 1529 tomoyo_print_name_union(head, &ptr->dir_name);
1379 tomoyo_print_name_union(head, &ptr->fs_type); 1530 tomoyo_print_name_union(head, &ptr->fs_type);
1380 tomoyo_print_number_union(head, &ptr->flags); 1531 tomoyo_print_number_union(head, &ptr->flags);
1532 } else if (acl_type == TOMOYO_TYPE_ENV_ACL) {
1533 struct tomoyo_env_acl *ptr =
1534 container_of(acl, typeof(*ptr), head);
1535
1536 tomoyo_set_group(head, "misc env ");
1537 tomoyo_set_string(head, ptr->env->name);
1381 } 1538 }
1382 if (acl->cond) { 1539 if (acl->cond) {
1383 head->r.print_cond_part = true; 1540 head->r.print_cond_part = true;
@@ -1510,14 +1667,12 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1510 global_pid = true; 1667 global_pid = true;
1511 pid = (unsigned int) simple_strtoul(buf, NULL, 10); 1668 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1512 rcu_read_lock(); 1669 rcu_read_lock();
1513 read_lock(&tasklist_lock);
1514 if (global_pid) 1670 if (global_pid)
1515 p = find_task_by_pid_ns(pid, &init_pid_ns); 1671 p = find_task_by_pid_ns(pid, &init_pid_ns);
1516 else 1672 else
1517 p = find_task_by_vpid(pid); 1673 p = find_task_by_vpid(pid);
1518 if (p) 1674 if (p)
1519 domain = tomoyo_real_domain(p); 1675 domain = tomoyo_real_domain(p);
1520 read_unlock(&tasklist_lock);
1521 rcu_read_unlock(); 1676 rcu_read_unlock();
1522 if (!domain) 1677 if (!domain)
1523 return; 1678 return;
@@ -1537,8 +1692,9 @@ static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1537 1692
1538/* String table for grouping keywords. */ 1693/* String table for grouping keywords. */
1539static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1694static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1540 [TOMOYO_PATH_GROUP] = "path_group ", 1695 [TOMOYO_PATH_GROUP] = "path_group ",
1541 [TOMOYO_NUMBER_GROUP] = "number_group ", 1696 [TOMOYO_NUMBER_GROUP] = "number_group ",
1697 [TOMOYO_ADDRESS_GROUP] = "address_group ",
1542}; 1698};
1543 1699
1544/** 1700/**
@@ -1580,7 +1736,7 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1580} 1736}
1581 1737
1582/** 1738/**
1583 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 1739 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
1584 * 1740 *
1585 * @head: Pointer to "struct tomoyo_io_buffer". 1741 * @head: Pointer to "struct tomoyo_io_buffer".
1586 * @idx: Index number. 1742 * @idx: Index number.
@@ -1617,6 +1773,15 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1617 (ptr, 1773 (ptr,
1618 struct tomoyo_number_group, 1774 struct tomoyo_number_group,
1619 head)->number); 1775 head)->number);
1776 } else if (idx == TOMOYO_ADDRESS_GROUP) {
1777 char buffer[128];
1778
1779 struct tomoyo_address_group *member =
1780 container_of(ptr, typeof(*member),
1781 head);
1782 tomoyo_print_ip(buffer, sizeof(buffer),
1783 &member->address);
1784 tomoyo_io_printf(head, " %s", buffer);
1620 } 1785 }
1621 tomoyo_set_lf(head); 1786 tomoyo_set_lf(head);
1622 } 1787 }
@@ -2066,27 +2231,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2066static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2231static void tomoyo_read_version(struct tomoyo_io_buffer *head)
2067{ 2232{
2068 if (!head->r.eof) { 2233 if (!head->r.eof) {
2069 tomoyo_io_printf(head, "2.4.0"); 2234 tomoyo_io_printf(head, "2.5.0");
2070 head->r.eof = true;
2071 }
2072}
2073
2074/**
2075 * tomoyo_read_self_domain - Get the current process's domainname.
2076 *
2077 * @head: Pointer to "struct tomoyo_io_buffer".
2078 *
2079 * Returns the current process's domainname.
2080 */
2081static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
2082{
2083 if (!head->r.eof) {
2084 /*
2085 * tomoyo_domain()->domainname != NULL
2086 * because every process belongs to a domain and
2087 * the domain's name cannot be NULL.
2088 */
2089 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
2090 head->r.eof = true; 2235 head->r.eof = true;
2091 } 2236 }
2092} 2237}
@@ -2221,10 +2366,6 @@ int tomoyo_open_control(const u8 type, struct file *file)
2221 head->poll = tomoyo_poll_log; 2366 head->poll = tomoyo_poll_log;
2222 head->read = tomoyo_read_log; 2367 head->read = tomoyo_read_log;
2223 break; 2368 break;
2224 case TOMOYO_SELFDOMAIN:
2225 /* /sys/kernel/security/tomoyo/self_domain */
2226 head->read = tomoyo_read_self_domain;
2227 break;
2228 case TOMOYO_PROCESS_STATUS: 2369 case TOMOYO_PROCESS_STATUS:
2229 /* /sys/kernel/security/tomoyo/.process_status */ 2370 /* /sys/kernel/security/tomoyo/.process_status */
2230 head->write = tomoyo_write_pid; 2371 head->write = tomoyo_write_pid;
@@ -2453,6 +2594,7 @@ ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
2453 return -EFAULT; 2594 return -EFAULT;
2454 if (mutex_lock_interruptible(&head->io_sem)) 2595 if (mutex_lock_interruptible(&head->io_sem))
2455 return -EINTR; 2596 return -EINTR;
2597 head->read_user_buf_avail = 0;
2456 idx = tomoyo_read_lock(); 2598 idx = tomoyo_read_lock();
2457 /* Read a line and dispatch it to the policy handler. */ 2599 /* Read a line and dispatch it to the policy handler. */
2458 while (avail_len > 0) { 2600 while (avail_len > 0) {
@@ -2562,11 +2704,11 @@ void tomoyo_check_profile(void)
2562 struct tomoyo_domain_info *domain; 2704 struct tomoyo_domain_info *domain;
2563 const int idx = tomoyo_read_lock(); 2705 const int idx = tomoyo_read_lock();
2564 tomoyo_policy_loaded = true; 2706 tomoyo_policy_loaded = true;
2565 printk(KERN_INFO "TOMOYO: 2.4.0\n"); 2707 printk(KERN_INFO "TOMOYO: 2.5.0\n");
2566 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2708 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2567 const u8 profile = domain->profile; 2709 const u8 profile = domain->profile;
2568 const struct tomoyo_policy_namespace *ns = domain->ns; 2710 const struct tomoyo_policy_namespace *ns = domain->ns;
2569 if (ns->profile_version != 20100903) 2711 if (ns->profile_version != 20110903)
2570 printk(KERN_ERR 2712 printk(KERN_ERR
2571 "Profile version %u is not supported.\n", 2713 "Profile version %u is not supported.\n",
2572 ns->profile_version); 2714 ns->profile_version);
@@ -2577,9 +2719,9 @@ void tomoyo_check_profile(void)
2577 else 2719 else
2578 continue; 2720 continue;
2579 printk(KERN_ERR 2721 printk(KERN_ERR
2580 "Userland tools for TOMOYO 2.4 must be installed and " 2722 "Userland tools for TOMOYO 2.5 must be installed and "
2581 "policy must be initialized.\n"); 2723 "policy must be initialized.\n");
2582 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ " 2724 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.5/ "
2583 "for more information.\n"); 2725 "for more information.\n");
2584 panic("STOP!"); 2726 panic("STOP!");
2585 } 2727 }
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index f7fbaa66e443..ed311d7a8ce0 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Header file for TOMOYO. 4 * Header file for TOMOYO.
5 * 5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION 6 * Copyright (C) 2005-2011 NTT DATA CORPORATION
7 */ 7 */
8 8
9#ifndef _SECURITY_TOMOYO_COMMON_H 9#ifndef _SECURITY_TOMOYO_COMMON_H
@@ -23,6 +23,16 @@
23#include <linux/poll.h> 23#include <linux/poll.h>
24#include <linux/binfmts.h> 24#include <linux/binfmts.h>
25#include <linux/highmem.h> 25#include <linux/highmem.h>
26#include <linux/net.h>
27#include <linux/inet.h>
28#include <linux/in.h>
29#include <linux/in6.h>
30#include <linux/un.h>
31#include <net/sock.h>
32#include <net/af_unix.h>
33#include <net/ip.h>
34#include <net/ipv6.h>
35#include <net/udp.h>
26 36
27/********** Constants definitions. **********/ 37/********** Constants definitions. **********/
28 38
@@ -34,8 +44,17 @@
34#define TOMOYO_HASH_BITS 8 44#define TOMOYO_HASH_BITS 8
35#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) 45#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
36 46
47/*
48 * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
49 * Therefore, we don't need SOCK_MAX.
50 */
51#define TOMOYO_SOCK_MAX 6
52
37#define TOMOYO_EXEC_TMPSIZE 4096 53#define TOMOYO_EXEC_TMPSIZE 4096
38 54
55/* Garbage collector is trying to kfree() this element. */
56#define TOMOYO_GC_IN_PROGRESS -1
57
39/* Profile number is an integer between 0 and 255. */ 58/* Profile number is an integer between 0 and 255. */
40#define TOMOYO_MAX_PROFILES 256 59#define TOMOYO_MAX_PROFILES 256
41 60
@@ -136,6 +155,7 @@ enum tomoyo_mode_index {
136/* Index numbers for entry type. */ 155/* Index numbers for entry type. */
137enum tomoyo_policy_id { 156enum tomoyo_policy_id {
138 TOMOYO_ID_GROUP, 157 TOMOYO_ID_GROUP,
158 TOMOYO_ID_ADDRESS_GROUP,
139 TOMOYO_ID_PATH_GROUP, 159 TOMOYO_ID_PATH_GROUP,
140 TOMOYO_ID_NUMBER_GROUP, 160 TOMOYO_ID_NUMBER_GROUP,
141 TOMOYO_ID_TRANSITION_CONTROL, 161 TOMOYO_ID_TRANSITION_CONTROL,
@@ -162,10 +182,21 @@ enum tomoyo_domain_info_flags_index {
162 TOMOYO_MAX_DOMAIN_INFO_FLAGS 182 TOMOYO_MAX_DOMAIN_INFO_FLAGS
163}; 183};
164 184
185/* Index numbers for audit type. */
186enum tomoyo_grant_log {
187 /* Follow profile's configuration. */
188 TOMOYO_GRANTLOG_AUTO,
189 /* Do not generate grant log. */
190 TOMOYO_GRANTLOG_NO,
191 /* Generate grant_log. */
192 TOMOYO_GRANTLOG_YES,
193};
194
165/* Index numbers for group entries. */ 195/* Index numbers for group entries. */
166enum tomoyo_group_id { 196enum tomoyo_group_id {
167 TOMOYO_PATH_GROUP, 197 TOMOYO_PATH_GROUP,
168 TOMOYO_NUMBER_GROUP, 198 TOMOYO_NUMBER_GROUP,
199 TOMOYO_ADDRESS_GROUP,
169 TOMOYO_MAX_GROUP 200 TOMOYO_MAX_GROUP
170}; 201};
171 202
@@ -196,6 +227,10 @@ enum tomoyo_acl_entry_type_index {
196 TOMOYO_TYPE_PATH_NUMBER_ACL, 227 TOMOYO_TYPE_PATH_NUMBER_ACL,
197 TOMOYO_TYPE_MKDEV_ACL, 228 TOMOYO_TYPE_MKDEV_ACL,
198 TOMOYO_TYPE_MOUNT_ACL, 229 TOMOYO_TYPE_MOUNT_ACL,
230 TOMOYO_TYPE_INET_ACL,
231 TOMOYO_TYPE_UNIX_ACL,
232 TOMOYO_TYPE_ENV_ACL,
233 TOMOYO_TYPE_MANUAL_TASK_ACL,
199}; 234};
200 235
201/* Index numbers for access controls with one pathname. */ 236/* Index numbers for access controls with one pathname. */
@@ -228,6 +263,15 @@ enum tomoyo_mkdev_acl_index {
228 TOMOYO_MAX_MKDEV_OPERATION 263 TOMOYO_MAX_MKDEV_OPERATION
229}; 264};
230 265
266/* Index numbers for socket operations. */
267enum tomoyo_network_acl_index {
268 TOMOYO_NETWORK_BIND, /* bind() operation. */
269 TOMOYO_NETWORK_LISTEN, /* listen() operation. */
270 TOMOYO_NETWORK_CONNECT, /* connect() operation. */
271 TOMOYO_NETWORK_SEND, /* send() operation. */
272 TOMOYO_MAX_NETWORK_OPERATION
273};
274
231/* Index numbers for access controls with two pathnames. */ 275/* Index numbers for access controls with two pathnames. */
232enum tomoyo_path2_acl_index { 276enum tomoyo_path2_acl_index {
233 TOMOYO_TYPE_LINK, 277 TOMOYO_TYPE_LINK,
@@ -255,7 +299,6 @@ enum tomoyo_securityfs_interface_index {
255 TOMOYO_EXCEPTIONPOLICY, 299 TOMOYO_EXCEPTIONPOLICY,
256 TOMOYO_PROCESS_STATUS, 300 TOMOYO_PROCESS_STATUS,
257 TOMOYO_STAT, 301 TOMOYO_STAT,
258 TOMOYO_SELFDOMAIN,
259 TOMOYO_AUDIT, 302 TOMOYO_AUDIT,
260 TOMOYO_VERSION, 303 TOMOYO_VERSION,
261 TOMOYO_PROFILE, 304 TOMOYO_PROFILE,
@@ -300,12 +343,30 @@ enum tomoyo_mac_index {
300 TOMOYO_MAC_FILE_MOUNT, 343 TOMOYO_MAC_FILE_MOUNT,
301 TOMOYO_MAC_FILE_UMOUNT, 344 TOMOYO_MAC_FILE_UMOUNT,
302 TOMOYO_MAC_FILE_PIVOT_ROOT, 345 TOMOYO_MAC_FILE_PIVOT_ROOT,
346 TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
347 TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
348 TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
349 TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
350 TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
351 TOMOYO_MAC_NETWORK_INET_RAW_BIND,
352 TOMOYO_MAC_NETWORK_INET_RAW_SEND,
353 TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
354 TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
355 TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
356 TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
357 TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
358 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
359 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
360 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
361 TOMOYO_MAC_ENVIRON,
303 TOMOYO_MAX_MAC_INDEX 362 TOMOYO_MAX_MAC_INDEX
304}; 363};
305 364
306/* Index numbers for category of functionality. */ 365/* Index numbers for category of functionality. */
307enum tomoyo_mac_category_index { 366enum tomoyo_mac_category_index {
308 TOMOYO_MAC_CATEGORY_FILE, 367 TOMOYO_MAC_CATEGORY_FILE,
368 TOMOYO_MAC_CATEGORY_NETWORK,
369 TOMOYO_MAC_CATEGORY_MISC,
309 TOMOYO_MAX_MAC_CATEGORY_INDEX 370 TOMOYO_MAX_MAC_CATEGORY_INDEX
310}; 371};
311 372
@@ -340,7 +401,7 @@ enum tomoyo_pref_index {
340/* Common header for holding ACL entries. */ 401/* Common header for holding ACL entries. */
341struct tomoyo_acl_head { 402struct tomoyo_acl_head {
342 struct list_head list; 403 struct list_head list;
343 bool is_deleted; 404 s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
344} __packed; 405} __packed;
345 406
346/* Common header for shared entries. */ 407/* Common header for shared entries. */
@@ -397,13 +458,36 @@ struct tomoyo_request_info {
397 u8 operation; 458 u8 operation;
398 } path_number; 459 } path_number;
399 struct { 460 struct {
461 const struct tomoyo_path_info *name;
462 } environ;
463 struct {
464 const __be32 *address;
465 u16 port;
466 /* One of values smaller than TOMOYO_SOCK_MAX. */
467 u8 protocol;
468 /* One of values in "enum tomoyo_network_acl_index". */
469 u8 operation;
470 bool is_ipv6;
471 } inet_network;
472 struct {
473 const struct tomoyo_path_info *address;
474 /* One of values smaller than TOMOYO_SOCK_MAX. */
475 u8 protocol;
476 /* One of values in "enum tomoyo_network_acl_index". */
477 u8 operation;
478 } unix_network;
479 struct {
400 const struct tomoyo_path_info *type; 480 const struct tomoyo_path_info *type;
401 const struct tomoyo_path_info *dir; 481 const struct tomoyo_path_info *dir;
402 const struct tomoyo_path_info *dev; 482 const struct tomoyo_path_info *dev;
403 unsigned long flags; 483 unsigned long flags;
404 int need_dev; 484 int need_dev;
405 } mount; 485 } mount;
486 struct {
487 const struct tomoyo_path_info *domainname;
488 } task;
406 } param; 489 } param;
490 struct tomoyo_acl_info *matched_acl;
407 u8 param_type; 491 u8 param_type;
408 bool granted; 492 bool granted;
409 u8 retry; 493 u8 retry;
@@ -442,7 +526,14 @@ struct tomoyo_number_union {
442 u8 value_type[2]; 526 u8 value_type[2];
443}; 527};
444 528
445/* Structure for "path_group"/"number_group" directive. */ 529/* Structure for holding an IP address. */
530struct tomoyo_ipaddr_union {
531 struct in6_addr ip[2]; /* Big endian. */
532 struct tomoyo_group *group; /* Pointer to address group. */
533 bool is_ipv6; /* Valid only if @group == NULL. */
534};
535
536/* Structure for "path_group"/"number_group"/"address_group" directive. */
446struct tomoyo_group { 537struct tomoyo_group {
447 struct tomoyo_shared_acl_head head; 538 struct tomoyo_shared_acl_head head;
448 const struct tomoyo_path_info *group_name; 539 const struct tomoyo_path_info *group_name;
@@ -461,6 +552,13 @@ struct tomoyo_number_group {
461 struct tomoyo_number_union number; 552 struct tomoyo_number_union number;
462}; 553};
463 554
555/* Structure for "address_group" directive. */
556struct tomoyo_address_group {
557 struct tomoyo_acl_head head;
558 /* Structure for holding an IP address. */
559 struct tomoyo_ipaddr_union address;
560};
561
464/* Subset of "struct stat". Used by conditional ACL and audit logs. */ 562/* Subset of "struct stat". Used by conditional ACL and audit logs. */
465struct tomoyo_mini_stat { 563struct tomoyo_mini_stat {
466 uid_t uid; 564 uid_t uid;
@@ -520,6 +618,7 @@ struct tomoyo_execve {
520 struct tomoyo_request_info r; 618 struct tomoyo_request_info r;
521 struct tomoyo_obj_info obj; 619 struct tomoyo_obj_info obj;
522 struct linux_binprm *bprm; 620 struct linux_binprm *bprm;
621 const struct tomoyo_path_info *transition;
523 /* For dumping argv[] and envp[]. */ 622 /* For dumping argv[] and envp[]. */
524 struct tomoyo_page_dump dump; 623 struct tomoyo_page_dump dump;
525 /* For temporary use. */ 624 /* For temporary use. */
@@ -554,6 +653,8 @@ struct tomoyo_condition {
554 u16 names_count; /* Number of "struct tomoyo_name_union names". */ 653 u16 names_count; /* Number of "struct tomoyo_name_union names". */
555 u16 argc; /* Number of "struct tomoyo_argv". */ 654 u16 argc; /* Number of "struct tomoyo_argv". */
556 u16 envc; /* Number of "struct tomoyo_envp". */ 655 u16 envc; /* Number of "struct tomoyo_envp". */
656 u8 grant_log; /* One of values in "enum tomoyo_grant_log". */
657 const struct tomoyo_path_info *transit; /* Maybe NULL. */
557 /* 658 /*
558 * struct tomoyo_condition_element condition[condc]; 659 * struct tomoyo_condition_element condition[condc];
559 * struct tomoyo_number_union values[numbers_count]; 660 * struct tomoyo_number_union values[numbers_count];
@@ -567,7 +668,7 @@ struct tomoyo_condition {
567struct tomoyo_acl_info { 668struct tomoyo_acl_info {
568 struct list_head list; 669 struct list_head list;
569 struct tomoyo_condition *cond; /* Maybe NULL. */ 670 struct tomoyo_condition *cond; /* Maybe NULL. */
570 bool is_deleted; 671 s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
571 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */ 672 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */
572} __packed; 673} __packed;
573 674
@@ -587,6 +688,15 @@ struct tomoyo_domain_info {
587}; 688};
588 689
589/* 690/*
691 * Structure for "task manual_domain_transition" directive.
692 */
693struct tomoyo_task_acl {
694 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MANUAL_TASK_ACL */
695 /* Pointer to domainname. */
696 const struct tomoyo_path_info *domainname;
697};
698
699/*
590 * Structure for "file execute", "file read", "file write", "file append", 700 * Structure for "file execute", "file read", "file write", "file append",
591 * "file unlink", "file getattr", "file rmdir", "file truncate", 701 * "file unlink", "file getattr", "file rmdir", "file truncate",
592 * "file symlink", "file chroot" and "file unmount" directive. 702 * "file symlink", "file chroot" and "file unmount" directive.
@@ -638,6 +748,29 @@ struct tomoyo_mount_acl {
638 struct tomoyo_number_union flags; 748 struct tomoyo_number_union flags;
639}; 749};
640 750
751/* Structure for "misc env" directive in domain policy. */
752struct tomoyo_env_acl {
753 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_ENV_ACL */
754 const struct tomoyo_path_info *env; /* environment variable */
755};
756
757/* Structure for "network inet" directive. */
758struct tomoyo_inet_acl {
759 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_INET_ACL */
760 u8 protocol;
761 u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
762 struct tomoyo_ipaddr_union address;
763 struct tomoyo_number_union port;
764};
765
766/* Structure for "network unix" directive. */
767struct tomoyo_unix_acl {
768 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_UNIX_ACL */
769 u8 protocol;
770 u8 perm; /* Bitmask of values in "enum tomoyo_network_acl_index" */
771 struct tomoyo_name_union name;
772};
773
641/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */ 774/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
642struct tomoyo_acl_param { 775struct tomoyo_acl_param {
643 char *data; 776 char *data;
@@ -773,7 +906,7 @@ struct tomoyo_policy_namespace {
773 struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS]; 906 struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS];
774 /* List for connecting to tomoyo_namespace_list list. */ 907 /* List for connecting to tomoyo_namespace_list list. */
775 struct list_head namespace_list; 908 struct list_head namespace_list;
776 /* Profile version. Currently only 20100903 is defined. */ 909 /* Profile version. Currently only 20110903 is defined. */
777 unsigned int profile_version; 910 unsigned int profile_version;
778 /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */ 911 /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
779 const char *name; 912 const char *name;
@@ -781,6 +914,8 @@ struct tomoyo_policy_namespace {
781 914
782/********** Function prototypes. **********/ 915/********** Function prototypes. **********/
783 916
917bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
918 const struct tomoyo_group *group);
784bool tomoyo_compare_number_union(const unsigned long value, 919bool tomoyo_compare_number_union(const unsigned long value,
785 const struct tomoyo_number_union *ptr); 920 const struct tomoyo_number_union *ptr);
786bool tomoyo_condition(struct tomoyo_request_info *r, 921bool tomoyo_condition(struct tomoyo_request_info *r,
@@ -796,6 +931,8 @@ bool tomoyo_memory_ok(void *ptr);
796bool tomoyo_number_matches_group(const unsigned long min, 931bool tomoyo_number_matches_group(const unsigned long min,
797 const unsigned long max, 932 const unsigned long max,
798 const struct tomoyo_group *group); 933 const struct tomoyo_group *group);
934bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
935 struct tomoyo_ipaddr_union *ptr);
799bool tomoyo_parse_name_union(struct tomoyo_acl_param *param, 936bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
800 struct tomoyo_name_union *ptr); 937 struct tomoyo_name_union *ptr);
801bool tomoyo_parse_number_union(struct tomoyo_acl_param *param, 938bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
@@ -805,6 +942,7 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
805bool tomoyo_permstr(const char *string, const char *keyword); 942bool tomoyo_permstr(const char *string, const char *keyword);
806bool tomoyo_str_starts(char **src, const char *find); 943bool tomoyo_str_starts(char **src, const char *find);
807char *tomoyo_encode(const char *str); 944char *tomoyo_encode(const char *str);
945char *tomoyo_encode2(const char *str, int str_len);
808char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, 946char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
809 va_list args); 947 va_list args);
810char *tomoyo_read_token(struct tomoyo_acl_param *param); 948char *tomoyo_read_token(struct tomoyo_acl_param *param);
@@ -814,12 +952,17 @@ const char *tomoyo_get_exe(void);
814const char *tomoyo_yesno(const unsigned int value); 952const char *tomoyo_yesno(const unsigned int value);
815const struct tomoyo_path_info *tomoyo_compare_name_union 953const struct tomoyo_path_info *tomoyo_compare_name_union
816(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr); 954(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr);
955const struct tomoyo_path_info *tomoyo_get_domainname
956(struct tomoyo_acl_param *param);
817const struct tomoyo_path_info *tomoyo_get_name(const char *name); 957const struct tomoyo_path_info *tomoyo_get_name(const char *name);
818const struct tomoyo_path_info *tomoyo_path_matches_group 958const struct tomoyo_path_info *tomoyo_path_matches_group
819(const struct tomoyo_path_info *pathname, const struct tomoyo_group *group); 959(const struct tomoyo_path_info *pathname, const struct tomoyo_group *group);
820int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 960int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
821 struct path *path, const int flag); 961 struct path *path, const int flag);
822int tomoyo_close_control(struct tomoyo_io_buffer *head); 962int tomoyo_close_control(struct tomoyo_io_buffer *head);
963int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env);
964int tomoyo_execute_permission(struct tomoyo_request_info *r,
965 const struct tomoyo_path_info *filename);
823int tomoyo_find_next_domain(struct linux_binprm *bprm); 966int tomoyo_find_next_domain(struct linux_binprm *bprm);
824int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile, 967int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
825 const u8 index); 968 const u8 index);
@@ -838,10 +981,15 @@ int tomoyo_path_number_perm(const u8 operation, struct path *path,
838 unsigned long number); 981 unsigned long number);
839int tomoyo_path_perm(const u8 operation, struct path *path, 982int tomoyo_path_perm(const u8 operation, struct path *path,
840 const char *target); 983 const char *target);
841int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
842 const struct tomoyo_path_info *filename);
843int tomoyo_poll_control(struct file *file, poll_table *wait); 984int tomoyo_poll_control(struct file *file, poll_table *wait);
844int tomoyo_poll_log(struct file *file, poll_table *wait); 985int tomoyo_poll_log(struct file *file, poll_table *wait);
986int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
987 int addr_len);
988int tomoyo_socket_connect_permission(struct socket *sock,
989 struct sockaddr *addr, int addr_len);
990int tomoyo_socket_listen_permission(struct socket *sock);
991int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
992 int size);
845int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 993int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
846 __printf(2, 3); 994 __printf(2, 3);
847int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 995int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
@@ -860,8 +1008,11 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
860int tomoyo_write_aggregator(struct tomoyo_acl_param *param); 1008int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
861int tomoyo_write_file(struct tomoyo_acl_param *param); 1009int tomoyo_write_file(struct tomoyo_acl_param *param);
862int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type); 1010int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
1011int tomoyo_write_misc(struct tomoyo_acl_param *param);
1012int tomoyo_write_inet_network(struct tomoyo_acl_param *param);
863int tomoyo_write_transition_control(struct tomoyo_acl_param *param, 1013int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
864 const u8 type); 1014 const u8 type);
1015int tomoyo_write_unix_network(struct tomoyo_acl_param *param);
865ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, 1016ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
866 const int buffer_len); 1017 const int buffer_len);
867ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, 1018ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
@@ -891,12 +1042,11 @@ void tomoyo_del_condition(struct list_head *element);
891void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 1042void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
892void tomoyo_get_attributes(struct tomoyo_obj_info *obj); 1043void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
893void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns); 1044void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
894void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
895 __printf(2, 3);
896void tomoyo_load_policy(const char *filename); 1045void tomoyo_load_policy(const char *filename);
897void tomoyo_memory_free(void *ptr);
898void tomoyo_normalize_line(unsigned char *buffer); 1046void tomoyo_normalize_line(unsigned char *buffer);
899void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register); 1047void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
1048void tomoyo_print_ip(char *buf, const unsigned int size,
1049 const struct tomoyo_ipaddr_union *ptr);
900void tomoyo_print_ulong(char *buffer, const int buffer_len, 1050void tomoyo_print_ulong(char *buffer, const int buffer_len,
901 const unsigned long value, const u8 type); 1051 const unsigned long value, const u8 type);
902void tomoyo_put_name_union(struct tomoyo_name_union *ptr); 1052void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
@@ -919,6 +1069,8 @@ extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
919 + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 1069 + TOMOYO_MAX_MAC_CATEGORY_INDEX];
920extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE]; 1070extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE];
921extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 1071extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
1072extern const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX];
1073extern const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION];
922extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX]; 1074extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX];
923extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION]; 1075extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION];
924extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION]; 1076extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION];
@@ -1098,6 +1250,21 @@ static inline bool tomoyo_same_number_union
1098} 1250}
1099 1251
1100/** 1252/**
1253 * tomoyo_same_ipaddr_union - Check for duplicated "struct tomoyo_ipaddr_union" entry.
1254 *
1255 * @a: Pointer to "struct tomoyo_ipaddr_union".
1256 * @b: Pointer to "struct tomoyo_ipaddr_union".
1257 *
1258 * Returns true if @a == @b, false otherwise.
1259 */
1260static inline bool tomoyo_same_ipaddr_union
1261(const struct tomoyo_ipaddr_union *a, const struct tomoyo_ipaddr_union *b)
1262{
1263 return !memcmp(a->ip, b->ip, sizeof(a->ip)) && a->group == b->group &&
1264 a->is_ipv6 == b->is_ipv6;
1265}
1266
1267/**
1101 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread. 1268 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
1102 * 1269 *
1103 * Returns pointer to "struct tomoyo_policy_namespace" for current thread. 1270 * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index 8a05f71eaf67..986330b8c73e 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -348,6 +348,7 @@ static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
348 a->numbers_count == b->numbers_count && 348 a->numbers_count == b->numbers_count &&
349 a->names_count == b->names_count && 349 a->names_count == b->names_count &&
350 a->argc == b->argc && a->envc == b->envc && 350 a->argc == b->argc && a->envc == b->envc &&
351 a->grant_log == b->grant_log && a->transit == b->transit &&
351 !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 352 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
352} 353}
353 354
@@ -399,8 +400,9 @@ static struct tomoyo_condition *tomoyo_commit_condition
399 found = true; 400 found = true;
400 goto out; 401 goto out;
401 } 402 }
402 list_for_each_entry_rcu(ptr, &tomoyo_condition_list, head.list) { 403 list_for_each_entry(ptr, &tomoyo_condition_list, head.list) {
403 if (!tomoyo_same_condition(ptr, entry)) 404 if (!tomoyo_same_condition(ptr, entry) ||
405 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
404 continue; 406 continue;
405 /* Same entry found. Share this entry. */ 407 /* Same entry found. Share this entry. */
406 atomic_inc(&ptr->head.users); 408 atomic_inc(&ptr->head.users);
@@ -410,8 +412,7 @@ static struct tomoyo_condition *tomoyo_commit_condition
410 if (!found) { 412 if (!found) {
411 if (tomoyo_memory_ok(entry)) { 413 if (tomoyo_memory_ok(entry)) {
412 atomic_set(&entry->head.users, 1); 414 atomic_set(&entry->head.users, 1);
413 list_add_rcu(&entry->head.list, 415 list_add(&entry->head.list, &tomoyo_condition_list);
414 &tomoyo_condition_list);
415 } else { 416 } else {
416 found = true; 417 found = true;
417 ptr = NULL; 418 ptr = NULL;
@@ -428,6 +429,46 @@ out:
428} 429}
429 430
430/** 431/**
432 * tomoyo_get_transit_preference - Parse domain transition preference for execve().
433 *
434 * @param: Pointer to "struct tomoyo_acl_param".
435 * @e: Pointer to "struct tomoyo_condition".
436 *
437 * Returns the condition string part.
438 */
439static char *tomoyo_get_transit_preference(struct tomoyo_acl_param *param,
440 struct tomoyo_condition *e)
441{
442 char * const pos = param->data;
443 bool flag;
444 if (*pos == '<') {
445 e->transit = tomoyo_get_domainname(param);
446 goto done;
447 }
448 {
449 char *cp = strchr(pos, ' ');
450 if (cp)
451 *cp = '\0';
452 flag = tomoyo_correct_path(pos) || !strcmp(pos, "keep") ||
453 !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
454 !strcmp(pos, "child") || !strcmp(pos, "parent");
455 if (cp)
456 *cp = ' ';
457 }
458 if (!flag)
459 return pos;
460 e->transit = tomoyo_get_name(tomoyo_read_token(param));
461done:
462 if (e->transit)
463 return param->data;
464 /*
465 * Return a bad read-only condition string that will let
466 * tomoyo_get_condition() return NULL.
467 */
468 return "/";
469}
470
471/**
431 * tomoyo_get_condition - Parse condition part. 472 * tomoyo_get_condition - Parse condition part.
432 * 473 *
433 * @param: Pointer to "struct tomoyo_acl_param". 474 * @param: Pointer to "struct tomoyo_acl_param".
@@ -443,7 +484,8 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
443 struct tomoyo_argv *argv = NULL; 484 struct tomoyo_argv *argv = NULL;
444 struct tomoyo_envp *envp = NULL; 485 struct tomoyo_envp *envp = NULL;
445 struct tomoyo_condition e = { }; 486 struct tomoyo_condition e = { };
446 char * const start_of_string = param->data; 487 char * const start_of_string =
488 tomoyo_get_transit_preference(param, &e);
447 char * const end_of_string = start_of_string + strlen(start_of_string); 489 char * const end_of_string = start_of_string + strlen(start_of_string);
448 char *pos; 490 char *pos;
449rerun: 491rerun:
@@ -486,6 +528,20 @@ rerun:
486 goto out; 528 goto out;
487 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word, 529 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
488 is_not ? "!" : "", right_word); 530 is_not ? "!" : "", right_word);
531 if (!strcmp(left_word, "grant_log")) {
532 if (entry) {
533 if (is_not ||
534 entry->grant_log != TOMOYO_GRANTLOG_AUTO)
535 goto out;
536 else if (!strcmp(right_word, "yes"))
537 entry->grant_log = TOMOYO_GRANTLOG_YES;
538 else if (!strcmp(right_word, "no"))
539 entry->grant_log = TOMOYO_GRANTLOG_NO;
540 else
541 goto out;
542 }
543 continue;
544 }
489 if (!strncmp(left_word, "exec.argv[", 10)) { 545 if (!strncmp(left_word, "exec.argv[", 10)) {
490 if (!argv) { 546 if (!argv) {
491 e.argc++; 547 e.argc++;
@@ -593,8 +649,9 @@ store_value:
593 + e.envc * sizeof(struct tomoyo_envp); 649 + e.envc * sizeof(struct tomoyo_envp);
594 entry = kzalloc(e.size, GFP_NOFS); 650 entry = kzalloc(e.size, GFP_NOFS);
595 if (!entry) 651 if (!entry)
596 return NULL; 652 goto out2;
597 *entry = e; 653 *entry = e;
654 e.transit = NULL;
598 condp = (struct tomoyo_condition_element *) (entry + 1); 655 condp = (struct tomoyo_condition_element *) (entry + 1);
599 numbers_p = (struct tomoyo_number_union *) (condp + e.condc); 656 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
600 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count); 657 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
@@ -621,6 +678,8 @@ out:
621 tomoyo_del_condition(&entry->head.list); 678 tomoyo_del_condition(&entry->head.list);
622 kfree(entry); 679 kfree(entry);
623 } 680 }
681out2:
682 tomoyo_put_name(e.transit);
624 return NULL; 683 return NULL;
625} 684}
626 685
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index cd0f92d88bb4..9027ac1534af 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -39,6 +39,8 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
39 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 39 if (mutex_lock_interruptible(&tomoyo_policy_lock))
40 return -ENOMEM; 40 return -ENOMEM;
41 list_for_each_entry_rcu(entry, list, list) { 41 list_for_each_entry_rcu(entry, list, list) {
42 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
43 continue;
42 if (!check_duplicate(entry, new_entry)) 44 if (!check_duplicate(entry, new_entry))
43 continue; 45 continue;
44 entry->is_deleted = param->is_delete; 46 entry->is_deleted = param->is_delete;
@@ -102,10 +104,21 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
102 new_entry->cond = tomoyo_get_condition(param); 104 new_entry->cond = tomoyo_get_condition(param);
103 if (!new_entry->cond) 105 if (!new_entry->cond)
104 return -EINVAL; 106 return -EINVAL;
107 /*
108 * Domain transition preference is allowed for only
109 * "file execute" entries.
110 */
111 if (new_entry->cond->transit &&
112 !(new_entry->type == TOMOYO_TYPE_PATH_ACL &&
113 container_of(new_entry, struct tomoyo_path_acl, head)
114 ->perm == 1 << TOMOYO_TYPE_EXECUTE))
115 goto out;
105 } 116 }
106 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 117 if (mutex_lock_interruptible(&tomoyo_policy_lock))
107 goto out; 118 goto out;
108 list_for_each_entry_rcu(entry, list, list) { 119 list_for_each_entry_rcu(entry, list, list) {
120 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
121 continue;
109 if (!tomoyo_same_acl_head(entry, new_entry) || 122 if (!tomoyo_same_acl_head(entry, new_entry) ||
110 !check_duplicate(entry, new_entry)) 123 !check_duplicate(entry, new_entry))
111 continue; 124 continue;
@@ -157,6 +170,7 @@ retry:
157 continue; 170 continue;
158 if (!tomoyo_condition(r, ptr->cond)) 171 if (!tomoyo_condition(r, ptr->cond))
159 continue; 172 continue;
173 r->matched_acl = ptr;
160 r->granted = true; 174 r->granted = true;
161 return; 175 return;
162 } 176 }
@@ -501,7 +515,8 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
501 * that domain. Do not perform domain transition if 515 * that domain. Do not perform domain transition if
502 * profile for that domain is not yet created. 516 * profile for that domain is not yet created.
503 */ 517 */
504 if (!entry->ns->profile_ptr[entry->profile]) 518 if (tomoyo_policy_loaded &&
519 !entry->ns->profile_ptr[entry->profile])
505 return NULL; 520 return NULL;
506 } 521 }
507 return entry; 522 return entry;
@@ -557,12 +572,99 @@ out:
557 tomoyo_write_log(&r, "use_profile %u\n", 572 tomoyo_write_log(&r, "use_profile %u\n",
558 entry->profile); 573 entry->profile);
559 tomoyo_write_log(&r, "use_group %u\n", entry->group); 574 tomoyo_write_log(&r, "use_group %u\n", entry->group);
575 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
560 } 576 }
561 } 577 }
562 return entry; 578 return entry;
563} 579}
564 580
565/** 581/**
582 * tomoyo_environ - Check permission for environment variable names.
583 *
584 * @ee: Pointer to "struct tomoyo_execve".
585 *
586 * Returns 0 on success, negative value otherwise.
587 */
588static int tomoyo_environ(struct tomoyo_execve *ee)
589{
590 struct tomoyo_request_info *r = &ee->r;
591 struct linux_binprm *bprm = ee->bprm;
592 /* env_page.data is allocated by tomoyo_dump_page(). */
593 struct tomoyo_page_dump env_page = { };
594 char *arg_ptr; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
595 int arg_len = 0;
596 unsigned long pos = bprm->p;
597 int offset = pos % PAGE_SIZE;
598 int argv_count = bprm->argc;
599 int envp_count = bprm->envc;
600 int error = -ENOMEM;
601
602 ee->r.type = TOMOYO_MAC_ENVIRON;
603 ee->r.profile = r->domain->profile;
604 ee->r.mode = tomoyo_get_mode(r->domain->ns, ee->r.profile,
605 TOMOYO_MAC_ENVIRON);
606 if (!r->mode || !envp_count)
607 return 0;
608 arg_ptr = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
609 if (!arg_ptr)
610 goto out;
611 while (error == -ENOMEM) {
612 if (!tomoyo_dump_page(bprm, pos, &env_page))
613 goto out;
614 pos += PAGE_SIZE - offset;
615 /* Read. */
616 while (argv_count && offset < PAGE_SIZE) {
617 if (!env_page.data[offset++])
618 argv_count--;
619 }
620 if (argv_count) {
621 offset = 0;
622 continue;
623 }
624 while (offset < PAGE_SIZE) {
625 const unsigned char c = env_page.data[offset++];
626
627 if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
628 if (c == '=') {
629 arg_ptr[arg_len++] = '\0';
630 } else if (c == '\\') {
631 arg_ptr[arg_len++] = '\\';
632 arg_ptr[arg_len++] = '\\';
633 } else if (c > ' ' && c < 127) {
634 arg_ptr[arg_len++] = c;
635 } else {
636 arg_ptr[arg_len++] = '\\';
637 arg_ptr[arg_len++] = (c >> 6) + '0';
638 arg_ptr[arg_len++]
639 = ((c >> 3) & 7) + '0';
640 arg_ptr[arg_len++] = (c & 7) + '0';
641 }
642 } else {
643 arg_ptr[arg_len] = '\0';
644 }
645 if (c)
646 continue;
647 if (tomoyo_env_perm(r, arg_ptr)) {
648 error = -EPERM;
649 break;
650 }
651 if (!--envp_count) {
652 error = 0;
653 break;
654 }
655 arg_len = 0;
656 }
657 offset = 0;
658 }
659out:
660 if (r->mode != TOMOYO_CONFIG_ENFORCING)
661 error = 0;
662 kfree(env_page.data);
663 kfree(arg_ptr);
664 return error;
665}
666
667/**
566 * tomoyo_find_next_domain - Find a domain. 668 * tomoyo_find_next_domain - Find a domain.
567 * 669 *
568 * @bprm: Pointer to "struct linux_binprm". 670 * @bprm: Pointer to "struct linux_binprm".
@@ -577,10 +679,11 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
577 struct tomoyo_domain_info *domain = NULL; 679 struct tomoyo_domain_info *domain = NULL;
578 const char *original_name = bprm->filename; 680 const char *original_name = bprm->filename;
579 int retval = -ENOMEM; 681 int retval = -ENOMEM;
580 bool need_kfree = false;
581 bool reject_on_transition_failure = false; 682 bool reject_on_transition_failure = false;
582 struct tomoyo_path_info rn = { }; /* real name */ 683 const struct tomoyo_path_info *candidate;
684 struct tomoyo_path_info exename;
583 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS); 685 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
686
584 if (!ee) 687 if (!ee)
585 return -ENOMEM; 688 return -ENOMEM;
586 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); 689 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
@@ -594,40 +697,32 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
594 ee->bprm = bprm; 697 ee->bprm = bprm;
595 ee->r.obj = &ee->obj; 698 ee->r.obj = &ee->obj;
596 ee->obj.path1 = bprm->file->f_path; 699 ee->obj.path1 = bprm->file->f_path;
597 retry:
598 if (need_kfree) {
599 kfree(rn.name);
600 need_kfree = false;
601 }
602 /* Get symlink's pathname of program. */ 700 /* Get symlink's pathname of program. */
603 retval = -ENOENT; 701 retval = -ENOENT;
604 rn.name = tomoyo_realpath_nofollow(original_name); 702 exename.name = tomoyo_realpath_nofollow(original_name);
605 if (!rn.name) 703 if (!exename.name)
606 goto out; 704 goto out;
607 tomoyo_fill_path_info(&rn); 705 tomoyo_fill_path_info(&exename);
608 need_kfree = true; 706retry:
609
610 /* Check 'aggregator' directive. */ 707 /* Check 'aggregator' directive. */
611 { 708 {
612 struct tomoyo_aggregator *ptr; 709 struct tomoyo_aggregator *ptr;
613 struct list_head *list = 710 struct list_head *list =
614 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 711 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
615 /* Check 'aggregator' directive. */ 712 /* Check 'aggregator' directive. */
713 candidate = &exename;
616 list_for_each_entry_rcu(ptr, list, head.list) { 714 list_for_each_entry_rcu(ptr, list, head.list) {
617 if (ptr->head.is_deleted || 715 if (ptr->head.is_deleted ||
618 !tomoyo_path_matches_pattern(&rn, 716 !tomoyo_path_matches_pattern(&exename,
619 ptr->original_name)) 717 ptr->original_name))
620 continue; 718 continue;
621 kfree(rn.name); 719 candidate = ptr->aggregated_name;
622 need_kfree = false;
623 /* This is OK because it is read only. */
624 rn = *ptr->aggregated_name;
625 break; 720 break;
626 } 721 }
627 } 722 }
628 723
629 /* Check execute permission. */ 724 /* Check execute permission. */
630 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn); 725 retval = tomoyo_execute_permission(&ee->r, candidate);
631 if (retval == TOMOYO_RETRY_REQUEST) 726 if (retval == TOMOYO_RETRY_REQUEST)
632 goto retry; 727 goto retry;
633 if (retval < 0) 728 if (retval < 0)
@@ -638,20 +733,51 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
638 * wildcard) rather than the pathname passed to execve() 733 * wildcard) rather than the pathname passed to execve()
639 * (which never contains wildcard). 734 * (which never contains wildcard).
640 */ 735 */
641 if (ee->r.param.path.matched_path) { 736 if (ee->r.param.path.matched_path)
642 if (need_kfree) 737 candidate = ee->r.param.path.matched_path;
643 kfree(rn.name);
644 need_kfree = false;
645 /* This is OK because it is read only. */
646 rn = *ee->r.param.path.matched_path;
647 }
648 738
649 /* Calculate domain to transit to. */ 739 /*
740 * Check for domain transition preference if "file execute" matched.
741 * If preference is given, make do_execve() fail if domain transition
742 * has failed, for domain transition preference should be used with
743 * destination domain defined.
744 */
745 if (ee->transition) {
746 const char *domainname = ee->transition->name;
747 reject_on_transition_failure = true;
748 if (!strcmp(domainname, "keep"))
749 goto force_keep_domain;
750 if (!strcmp(domainname, "child"))
751 goto force_child_domain;
752 if (!strcmp(domainname, "reset"))
753 goto force_reset_domain;
754 if (!strcmp(domainname, "initialize"))
755 goto force_initialize_domain;
756 if (!strcmp(domainname, "parent")) {
757 char *cp;
758 strncpy(ee->tmp, old_domain->domainname->name,
759 TOMOYO_EXEC_TMPSIZE - 1);
760 cp = strrchr(ee->tmp, ' ');
761 if (cp)
762 *cp = '\0';
763 } else if (*domainname == '<')
764 strncpy(ee->tmp, domainname, TOMOYO_EXEC_TMPSIZE - 1);
765 else
766 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
767 old_domain->domainname->name, domainname);
768 goto force_jump_domain;
769 }
770 /*
771 * No domain transition preference specified.
772 * Calculate domain to transit to.
773 */
650 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, 774 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
651 &rn)) { 775 candidate)) {
652 case TOMOYO_TRANSITION_CONTROL_RESET: 776 case TOMOYO_TRANSITION_CONTROL_RESET:
777force_reset_domain:
653 /* Transit to the root of specified namespace. */ 778 /* Transit to the root of specified namespace. */
654 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); 779 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
780 candidate->name);
655 /* 781 /*
656 * Make do_execve() fail if domain transition across namespaces 782 * Make do_execve() fail if domain transition across namespaces
657 * has failed. 783 * has failed.
@@ -659,11 +785,13 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
659 reject_on_transition_failure = true; 785 reject_on_transition_failure = true;
660 break; 786 break;
661 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 787 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
788force_initialize_domain:
662 /* Transit to the child of current namespace's root. */ 789 /* Transit to the child of current namespace's root. */
663 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 790 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
664 old_domain->ns->name, rn.name); 791 old_domain->ns->name, candidate->name);
665 break; 792 break;
666 case TOMOYO_TRANSITION_CONTROL_KEEP: 793 case TOMOYO_TRANSITION_CONTROL_KEEP:
794force_keep_domain:
667 /* Keep current domain. */ 795 /* Keep current domain. */
668 domain = old_domain; 796 domain = old_domain;
669 break; 797 break;
@@ -677,13 +805,15 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
677 * before /sbin/init. 805 * before /sbin/init.
678 */ 806 */
679 domain = old_domain; 807 domain = old_domain;
680 } else { 808 break;
681 /* Normal domain transition. */
682 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
683 old_domain->domainname->name, rn.name);
684 } 809 }
810force_child_domain:
811 /* Normal domain transition. */
812 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
813 old_domain->domainname->name, candidate->name);
685 break; 814 break;
686 } 815 }
816force_jump_domain:
687 if (!domain) 817 if (!domain)
688 domain = tomoyo_assign_domain(ee->tmp, true); 818 domain = tomoyo_assign_domain(ee->tmp, true);
689 if (domain) 819 if (domain)
@@ -711,8 +841,11 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
711 /* Update reference count on "struct tomoyo_domain_info". */ 841 /* Update reference count on "struct tomoyo_domain_info". */
712 atomic_inc(&domain->users); 842 atomic_inc(&domain->users);
713 bprm->cred->security = domain; 843 bprm->cred->security = domain;
714 if (need_kfree) 844 kfree(exename.name);
715 kfree(rn.name); 845 if (!retval) {
846 ee->r.domain = domain;
847 retval = tomoyo_environ(ee);
848 }
716 kfree(ee->tmp); 849 kfree(ee->tmp);
717 kfree(ee->dump.data); 850 kfree(ee->dump.data);
718 kfree(ee); 851 kfree(ee);
@@ -732,7 +865,8 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
732 struct tomoyo_page_dump *dump) 865 struct tomoyo_page_dump *dump)
733{ 866{
734 struct page *page; 867 struct page *page;
735 /* dump->data is released by tomoyo_finish_execve(). */ 868
869 /* dump->data is released by tomoyo_find_next_domain(). */
736 if (!dump->data) { 870 if (!dump->data) {
737 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS); 871 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
738 if (!dump->data) 872 if (!dump->data)
@@ -753,6 +887,7 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
753 * So do I. 887 * So do I.
754 */ 888 */
755 char *kaddr = kmap_atomic(page, KM_USER0); 889 char *kaddr = kmap_atomic(page, KM_USER0);
890
756 dump->page = page; 891 dump->page = page;
757 memcpy(dump->data + offset, kaddr + offset, 892 memcpy(dump->data + offset, kaddr + offset,
758 PAGE_SIZE - offset); 893 PAGE_SIZE - offset);
diff --git a/security/tomoyo/environ.c b/security/tomoyo/environ.c
new file mode 100644
index 000000000000..ad4c6e18a437
--- /dev/null
+++ b/security/tomoyo/environ.c
@@ -0,0 +1,122 @@
1/*
2 * security/tomoyo/environ.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8
9/**
10 * tomoyo_check_env_acl - Check permission for environment variable's name.
11 *
12 * @r: Pointer to "struct tomoyo_request_info".
13 * @ptr: Pointer to "struct tomoyo_acl_info".
14 *
15 * Returns true if granted, false otherwise.
16 */
17static bool tomoyo_check_env_acl(struct tomoyo_request_info *r,
18 const struct tomoyo_acl_info *ptr)
19{
20 const struct tomoyo_env_acl *acl =
21 container_of(ptr, typeof(*acl), head);
22
23 return tomoyo_path_matches_pattern(r->param.environ.name, acl->env);
24}
25
26/**
27 * tomoyo_audit_env_log - Audit environment variable name log.
28 *
29 * @r: Pointer to "struct tomoyo_request_info".
30 *
31 * Returns 0 on success, negative value otherwise.
32 */
33static int tomoyo_audit_env_log(struct tomoyo_request_info *r)
34{
35 return tomoyo_supervisor(r, "misc env %s\n",
36 r->param.environ.name->name);
37}
38
39/**
40 * tomoyo_env_perm - Check permission for environment variable's name.
41 *
42 * @r: Pointer to "struct tomoyo_request_info".
43 * @env: The name of environment variable.
44 *
45 * Returns 0 on success, negative value otherwise.
46 *
47 * Caller holds tomoyo_read_lock().
48 */
49int tomoyo_env_perm(struct tomoyo_request_info *r, const char *env)
50{
51 struct tomoyo_path_info environ;
52 int error;
53
54 if (!env || !*env)
55 return 0;
56 environ.name = env;
57 tomoyo_fill_path_info(&environ);
58 r->param_type = TOMOYO_TYPE_ENV_ACL;
59 r->param.environ.name = &environ;
60 do {
61 tomoyo_check_acl(r, tomoyo_check_env_acl);
62 error = tomoyo_audit_env_log(r);
63 } while (error == TOMOYO_RETRY_REQUEST);
64 return error;
65}
66
67/**
68 * tomoyo_same_env_acl - Check for duplicated "struct tomoyo_env_acl" entry.
69 *
70 * @a: Pointer to "struct tomoyo_acl_info".
71 * @b: Pointer to "struct tomoyo_acl_info".
72 *
73 * Returns true if @a == @b, false otherwise.
74 */
75static bool tomoyo_same_env_acl(const struct tomoyo_acl_info *a,
76 const struct tomoyo_acl_info *b)
77{
78 const struct tomoyo_env_acl *p1 = container_of(a, typeof(*p1), head);
79 const struct tomoyo_env_acl *p2 = container_of(b, typeof(*p2), head);
80
81 return p1->env == p2->env;
82}
83
84/**
85 * tomoyo_write_env - Write "struct tomoyo_env_acl" list.
86 *
87 * @param: Pointer to "struct tomoyo_acl_param".
88 *
89 * Returns 0 on success, negative value otherwise.
90 *
91 * Caller holds tomoyo_read_lock().
92 */
93static int tomoyo_write_env(struct tomoyo_acl_param *param)
94{
95 struct tomoyo_env_acl e = { .head.type = TOMOYO_TYPE_ENV_ACL };
96 int error = -ENOMEM;
97 const char *data = tomoyo_read_token(param);
98
99 if (!tomoyo_correct_word(data) || strchr(data, '='))
100 return -EINVAL;
101 e.env = tomoyo_get_name(data);
102 if (!e.env)
103 return error;
104 error = tomoyo_update_domain(&e.head, sizeof(e), param,
105 tomoyo_same_env_acl, NULL);
106 tomoyo_put_name(e.env);
107 return error;
108}
109
110/**
111 * tomoyo_write_misc - Update environment variable list.
112 *
113 * @param: Pointer to "struct tomoyo_acl_param".
114 *
115 * Returns 0 on success, negative value otherwise.
116 */
117int tomoyo_write_misc(struct tomoyo_acl_param *param)
118{
119 if (tomoyo_str_starts(&param->data, "env "))
120 return tomoyo_write_env(param);
121 return -EINVAL;
122}
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 743c35f5084a..400390790745 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -555,8 +555,8 @@ static int tomoyo_update_path2_acl(const u8 perm,
555 * 555 *
556 * Caller holds tomoyo_read_lock(). 556 * Caller holds tomoyo_read_lock().
557 */ 557 */
558int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 558static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
559 const struct tomoyo_path_info *filename) 559 const struct tomoyo_path_info *filename)
560{ 560{
561 int error; 561 int error;
562 562
@@ -570,16 +570,42 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
570 do { 570 do {
571 tomoyo_check_acl(r, tomoyo_check_path_acl); 571 tomoyo_check_acl(r, tomoyo_check_path_acl);
572 error = tomoyo_audit_path_log(r); 572 error = tomoyo_audit_path_log(r);
573 /* 573 } while (error == TOMOYO_RETRY_REQUEST);
574 * Do not retry for execute request, for alias may have
575 * changed.
576 */
577 } while (error == TOMOYO_RETRY_REQUEST &&
578 operation != TOMOYO_TYPE_EXECUTE);
579 return error; 574 return error;
580} 575}
581 576
582/** 577/**
578 * tomoyo_execute_permission - Check permission for execute operation.
579 *
580 * @r: Pointer to "struct tomoyo_request_info".
581 * @filename: Filename to check.
582 *
583 * Returns 0 on success, negative value otherwise.
584 *
585 * Caller holds tomoyo_read_lock().
586 */
587int tomoyo_execute_permission(struct tomoyo_request_info *r,
588 const struct tomoyo_path_info *filename)
589{
590 /*
591 * Unlike other permission checks, this check is done regardless of
592 * profile mode settings in order to check for domain transition
593 * preference.
594 */
595 r->type = TOMOYO_MAC_FILE_EXECUTE;
596 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
597 r->param_type = TOMOYO_TYPE_PATH_ACL;
598 r->param.path.filename = filename;
599 r->param.path.operation = TOMOYO_TYPE_EXECUTE;
600 tomoyo_check_acl(r, tomoyo_check_path_acl);
601 r->ee->transition = r->matched_acl && r->matched_acl->cond ?
602 r->matched_acl->cond->transit : NULL;
603 if (r->mode != TOMOYO_CONFIG_DISABLED)
604 return tomoyo_audit_path_log(r);
605 return 0;
606}
607
608/**
583 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry. 609 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
584 * 610 *
585 * @a: Pointer to "struct tomoyo_acl_info". 611 * @a: Pointer to "struct tomoyo_acl_info".
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index ae135fbbbe95..986a6a756868 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -8,36 +8,26 @@
8#include <linux/kthread.h> 8#include <linux/kthread.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10 10
11/**
12 * tomoyo_memory_free - Free memory for elements.
13 *
14 * @ptr: Pointer to allocated memory.
15 *
16 * Returns nothing.
17 *
18 * Caller holds tomoyo_policy_lock mutex.
19 */
20static inline void tomoyo_memory_free(void *ptr)
21{
22 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
23 kfree(ptr);
24}
25
11/* The list for "struct tomoyo_io_buffer". */ 26/* The list for "struct tomoyo_io_buffer". */
12static LIST_HEAD(tomoyo_io_buffer_list); 27static LIST_HEAD(tomoyo_io_buffer_list);
13/* Lock for protecting tomoyo_io_buffer_list. */ 28/* Lock for protecting tomoyo_io_buffer_list. */
14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock); 29static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
15 30
16/* Size of an element. */
17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
19 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
20 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
21 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
22 [TOMOYO_ID_TRANSITION_CONTROL] =
23 sizeof(struct tomoyo_transition_control),
24 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
25 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
26 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
27 /* [TOMOYO_ID_ACL] =
28 tomoyo_acl_size["struct tomoyo_acl_info"->type], */
29 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
30};
31
32/* Size of a domain ACL element. */
33static const u8 tomoyo_acl_size[] = {
34 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
35 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
36 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
37 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
38 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
39};
40
41/** 31/**
42 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not. 32 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
43 * 33 *
@@ -55,15 +45,11 @@ static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
55 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 45 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
56 head->users++; 46 head->users++;
57 spin_unlock(&tomoyo_io_buffer_list_lock); 47 spin_unlock(&tomoyo_io_buffer_list_lock);
58 if (mutex_lock_interruptible(&head->io_sem)) { 48 mutex_lock(&head->io_sem);
59 in_use = true;
60 goto out;
61 }
62 if (head->r.domain == element || head->r.group == element || 49 if (head->r.domain == element || head->r.group == element ||
63 head->r.acl == element || &head->w.domain->list == element) 50 head->r.acl == element || &head->w.domain->list == element)
64 in_use = true; 51 in_use = true;
65 mutex_unlock(&head->io_sem); 52 mutex_unlock(&head->io_sem);
66out:
67 spin_lock(&tomoyo_io_buffer_list_lock); 53 spin_lock(&tomoyo_io_buffer_list_lock);
68 head->users--; 54 head->users--;
69 if (in_use) 55 if (in_use)
@@ -77,15 +63,14 @@ out:
77 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not. 63 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
78 * 64 *
79 * @string: String to check. 65 * @string: String to check.
80 * @size: Memory allocated for @string .
81 * 66 *
82 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users, 67 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
83 * false otherwise. 68 * false otherwise.
84 */ 69 */
85static bool tomoyo_name_used_by_io_buffer(const char *string, 70static bool tomoyo_name_used_by_io_buffer(const char *string)
86 const size_t size)
87{ 71{
88 struct tomoyo_io_buffer *head; 72 struct tomoyo_io_buffer *head;
73 const size_t size = strlen(string) + 1;
89 bool in_use = false; 74 bool in_use = false;
90 75
91 spin_lock(&tomoyo_io_buffer_list_lock); 76 spin_lock(&tomoyo_io_buffer_list_lock);
@@ -93,10 +78,7 @@ static bool tomoyo_name_used_by_io_buffer(const char *string,
93 int i; 78 int i;
94 head->users++; 79 head->users++;
95 spin_unlock(&tomoyo_io_buffer_list_lock); 80 spin_unlock(&tomoyo_io_buffer_list_lock);
96 if (mutex_lock_interruptible(&head->io_sem)) { 81 mutex_lock(&head->io_sem);
97 in_use = true;
98 goto out;
99 }
100 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) { 82 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
101 const char *w = head->r.w[i]; 83 const char *w = head->r.w[i];
102 if (w < string || w > string + size) 84 if (w < string || w > string + size)
@@ -105,7 +87,6 @@ static bool tomoyo_name_used_by_io_buffer(const char *string,
105 break; 87 break;
106 } 88 }
107 mutex_unlock(&head->io_sem); 89 mutex_unlock(&head->io_sem);
108out:
109 spin_lock(&tomoyo_io_buffer_list_lock); 90 spin_lock(&tomoyo_io_buffer_list_lock);
110 head->users--; 91 head->users--;
111 if (in_use) 92 if (in_use)
@@ -115,84 +96,6 @@ out:
115 return in_use; 96 return in_use;
116} 97}
117 98
118/* Structure for garbage collection. */
119struct tomoyo_gc {
120 struct list_head list;
121 enum tomoyo_policy_id type;
122 size_t size;
123 struct list_head *element;
124};
125/* List of entries to be deleted. */
126static LIST_HEAD(tomoyo_gc_list);
127/* Length of tomoyo_gc_list. */
128static int tomoyo_gc_list_len;
129
130/**
131 * tomoyo_add_to_gc - Add an entry to to be deleted list.
132 *
133 * @type: One of values in "enum tomoyo_policy_id".
134 * @element: Pointer to "struct list_head".
135 *
136 * Returns true on success, false otherwise.
137 *
138 * Caller holds tomoyo_policy_lock mutex.
139 *
140 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
141 * entries at once, it will take too long time. Thus, do not add more than 128
142 * entries per a scan. But to be able to handle worst case where all entries
143 * are in-use, we accept one more entry per a scan.
144 *
145 * If we use singly linked list using "struct list_head"->prev (which is
146 * LIST_POISON2), we can avoid kmalloc().
147 */
148static bool tomoyo_add_to_gc(const int type, struct list_head *element)
149{
150 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
151 if (!entry)
152 return false;
153 entry->type = type;
154 if (type == TOMOYO_ID_ACL)
155 entry->size = tomoyo_acl_size[
156 container_of(element,
157 typeof(struct tomoyo_acl_info),
158 list)->type];
159 else if (type == TOMOYO_ID_NAME)
160 entry->size = strlen(container_of(element,
161 typeof(struct tomoyo_name),
162 head.list)->entry.name) + 1;
163 else if (type == TOMOYO_ID_CONDITION)
164 entry->size =
165 container_of(element, typeof(struct tomoyo_condition),
166 head.list)->size;
167 else
168 entry->size = tomoyo_element_size[type];
169 entry->element = element;
170 list_add(&entry->list, &tomoyo_gc_list);
171 list_del_rcu(element);
172 return tomoyo_gc_list_len++ < 128;
173}
174
175/**
176 * tomoyo_element_linked_by_gc - Validate next element of an entry.
177 *
178 * @element: Pointer to an element.
179 * @size: Size of @element in byte.
180 *
181 * Returns true if @element is linked by other elements in the garbage
182 * collector's queue, false otherwise.
183 */
184static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
185{
186 struct tomoyo_gc *p;
187 list_for_each_entry(p, &tomoyo_gc_list, list) {
188 const u8 *ptr = (const u8 *) p->element->next;
189 if (ptr < element || element + size < ptr)
190 continue;
191 return true;
192 }
193 return false;
194}
195
196/** 99/**
197 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control". 100 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
198 * 101 *
@@ -200,7 +103,7 @@ static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
200 * 103 *
201 * Returns nothing. 104 * Returns nothing.
202 */ 105 */
203static void tomoyo_del_transition_control(struct list_head *element) 106static inline void tomoyo_del_transition_control(struct list_head *element)
204{ 107{
205 struct tomoyo_transition_control *ptr = 108 struct tomoyo_transition_control *ptr =
206 container_of(element, typeof(*ptr), head.list); 109 container_of(element, typeof(*ptr), head.list);
@@ -215,7 +118,7 @@ static void tomoyo_del_transition_control(struct list_head *element)
215 * 118 *
216 * Returns nothing. 119 * Returns nothing.
217 */ 120 */
218static void tomoyo_del_aggregator(struct list_head *element) 121static inline void tomoyo_del_aggregator(struct list_head *element)
219{ 122{
220 struct tomoyo_aggregator *ptr = 123 struct tomoyo_aggregator *ptr =
221 container_of(element, typeof(*ptr), head.list); 124 container_of(element, typeof(*ptr), head.list);
@@ -230,7 +133,7 @@ static void tomoyo_del_aggregator(struct list_head *element)
230 * 133 *
231 * Returns nothing. 134 * Returns nothing.
232 */ 135 */
233static void tomoyo_del_manager(struct list_head *element) 136static inline void tomoyo_del_manager(struct list_head *element)
234{ 137{
235 struct tomoyo_manager *ptr = 138 struct tomoyo_manager *ptr =
236 container_of(element, typeof(*ptr), head.list); 139 container_of(element, typeof(*ptr), head.list);
@@ -293,6 +196,38 @@ static void tomoyo_del_acl(struct list_head *element)
293 tomoyo_put_number_union(&entry->flags); 196 tomoyo_put_number_union(&entry->flags);
294 } 197 }
295 break; 198 break;
199 case TOMOYO_TYPE_ENV_ACL:
200 {
201 struct tomoyo_env_acl *entry =
202 container_of(acl, typeof(*entry), head);
203
204 tomoyo_put_name(entry->env);
205 }
206 break;
207 case TOMOYO_TYPE_INET_ACL:
208 {
209 struct tomoyo_inet_acl *entry =
210 container_of(acl, typeof(*entry), head);
211
212 tomoyo_put_group(entry->address.group);
213 tomoyo_put_number_union(&entry->port);
214 }
215 break;
216 case TOMOYO_TYPE_UNIX_ACL:
217 {
218 struct tomoyo_unix_acl *entry =
219 container_of(acl, typeof(*entry), head);
220
221 tomoyo_put_name_union(&entry->name);
222 }
223 break;
224 case TOMOYO_TYPE_MANUAL_TASK_ACL:
225 {
226 struct tomoyo_task_acl *entry =
227 container_of(acl, typeof(*entry), head);
228 tomoyo_put_name(entry->domainname);
229 }
230 break;
296 } 231 }
297} 232}
298 233
@@ -301,44 +236,26 @@ static void tomoyo_del_acl(struct list_head *element)
301 * 236 *
302 * @element: Pointer to "struct list_head". 237 * @element: Pointer to "struct list_head".
303 * 238 *
304 * Returns true if deleted, false otherwise. 239 * Returns nothing.
240 *
241 * Caller holds tomoyo_policy_lock mutex.
305 */ 242 */
306static bool tomoyo_del_domain(struct list_head *element) 243static inline void tomoyo_del_domain(struct list_head *element)
307{ 244{
308 struct tomoyo_domain_info *domain = 245 struct tomoyo_domain_info *domain =
309 container_of(element, typeof(*domain), list); 246 container_of(element, typeof(*domain), list);
310 struct tomoyo_acl_info *acl; 247 struct tomoyo_acl_info *acl;
311 struct tomoyo_acl_info *tmp; 248 struct tomoyo_acl_info *tmp;
312 /* 249 /*
313 * Since we don't protect whole execve() operation using SRCU, 250 * Since this domain is referenced from neither
314 * we need to recheck domain->users at this point. 251 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
315 * 252 * elements without checking for is_deleted flag.
316 * (1) Reader starts SRCU section upon execve().
317 * (2) Reader traverses tomoyo_domain_list and finds this domain.
318 * (3) Writer marks this domain as deleted.
319 * (4) Garbage collector removes this domain from tomoyo_domain_list
320 * because this domain is marked as deleted and used by nobody.
321 * (5) Reader saves reference to this domain into
322 * "struct linux_binprm"->cred->security .
323 * (6) Reader finishes SRCU section, although execve() operation has
324 * not finished yet.
325 * (7) Garbage collector waits for SRCU synchronization.
326 * (8) Garbage collector kfree() this domain because this domain is
327 * used by nobody.
328 * (9) Reader finishes execve() operation and restores this domain from
329 * "struct linux_binprm"->cred->security.
330 *
331 * By updating domain->users at (5), we can solve this race problem
332 * by rechecking domain->users at (8).
333 */ 253 */
334 if (atomic_read(&domain->users))
335 return false;
336 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 254 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
337 tomoyo_del_acl(&acl->list); 255 tomoyo_del_acl(&acl->list);
338 tomoyo_memory_free(acl); 256 tomoyo_memory_free(acl);
339 } 257 }
340 tomoyo_put_name(domain->domainname); 258 tomoyo_put_name(domain->domainname);
341 return true;
342} 259}
343 260
344/** 261/**
@@ -387,10 +304,9 @@ void tomoyo_del_condition(struct list_head *element)
387 * 304 *
388 * Returns nothing. 305 * Returns nothing.
389 */ 306 */
390static void tomoyo_del_name(struct list_head *element) 307static inline void tomoyo_del_name(struct list_head *element)
391{ 308{
392 const struct tomoyo_name *ptr = 309 /* Nothing to do. */
393 container_of(element, typeof(*ptr), head.list);
394} 310}
395 311
396/** 312/**
@@ -400,7 +316,7 @@ static void tomoyo_del_name(struct list_head *element)
400 * 316 *
401 * Returns nothing. 317 * Returns nothing.
402 */ 318 */
403static void tomoyo_del_path_group(struct list_head *element) 319static inline void tomoyo_del_path_group(struct list_head *element)
404{ 320{
405 struct tomoyo_path_group *member = 321 struct tomoyo_path_group *member =
406 container_of(element, typeof(*member), head.list); 322 container_of(element, typeof(*member), head.list);
@@ -414,7 +330,7 @@ static void tomoyo_del_path_group(struct list_head *element)
414 * 330 *
415 * Returns nothing. 331 * Returns nothing.
416 */ 332 */
417static void tomoyo_del_group(struct list_head *element) 333static inline void tomoyo_del_group(struct list_head *element)
418{ 334{
419 struct tomoyo_group *group = 335 struct tomoyo_group *group =
420 container_of(element, typeof(*group), head.list); 336 container_of(element, typeof(*group), head.list);
@@ -422,16 +338,128 @@ static void tomoyo_del_group(struct list_head *element)
422} 338}
423 339
424/** 340/**
341 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
342 *
343 * @element: Pointer to "struct list_head".
344 *
345 * Returns nothing.
346 */
347static inline void tomoyo_del_address_group(struct list_head *element)
348{
349 /* Nothing to do. */
350}
351
352/**
425 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group". 353 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
426 * 354 *
427 * @element: Pointer to "struct list_head". 355 * @element: Pointer to "struct list_head".
428 * 356 *
429 * Returns nothing. 357 * Returns nothing.
430 */ 358 */
431static void tomoyo_del_number_group(struct list_head *element) 359static inline void tomoyo_del_number_group(struct list_head *element)
432{ 360{
433 struct tomoyo_number_group *member = 361 /* Nothing to do. */
434 container_of(element, typeof(*member), head.list); 362}
363
364/**
365 * tomoyo_try_to_gc - Try to kfree() an entry.
366 *
367 * @type: One of values in "enum tomoyo_policy_id".
368 * @element: Pointer to "struct list_head".
369 *
370 * Returns nothing.
371 *
372 * Caller holds tomoyo_policy_lock mutex.
373 */
374static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
375 struct list_head *element)
376{
377 /*
378 * __list_del_entry() guarantees that the list element became no longer
379 * reachable from the list which the element was originally on (e.g.
380 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
381 * list element became no longer referenced by syscall users.
382 */
383 __list_del_entry(element);
384 mutex_unlock(&tomoyo_policy_lock);
385 synchronize_srcu(&tomoyo_ss);
386 /*
387 * However, there are two users which may still be using the list
388 * element. We need to defer until both users forget this element.
389 *
390 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
391 * and "struct tomoyo_io_buffer"->w.domain forget this element.
392 */
393 if (tomoyo_struct_used_by_io_buffer(element))
394 goto reinject;
395 switch (type) {
396 case TOMOYO_ID_TRANSITION_CONTROL:
397 tomoyo_del_transition_control(element);
398 break;
399 case TOMOYO_ID_MANAGER:
400 tomoyo_del_manager(element);
401 break;
402 case TOMOYO_ID_AGGREGATOR:
403 tomoyo_del_aggregator(element);
404 break;
405 case TOMOYO_ID_GROUP:
406 tomoyo_del_group(element);
407 break;
408 case TOMOYO_ID_PATH_GROUP:
409 tomoyo_del_path_group(element);
410 break;
411 case TOMOYO_ID_ADDRESS_GROUP:
412 tomoyo_del_address_group(element);
413 break;
414 case TOMOYO_ID_NUMBER_GROUP:
415 tomoyo_del_number_group(element);
416 break;
417 case TOMOYO_ID_CONDITION:
418 tomoyo_del_condition(element);
419 break;
420 case TOMOYO_ID_NAME:
421 /*
422 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
423 * forget this element.
424 */
425 if (tomoyo_name_used_by_io_buffer
426 (container_of(element, typeof(struct tomoyo_name),
427 head.list)->entry.name))
428 goto reinject;
429 tomoyo_del_name(element);
430 break;
431 case TOMOYO_ID_ACL:
432 tomoyo_del_acl(element);
433 break;
434 case TOMOYO_ID_DOMAIN:
435 /*
436 * Don't kfree() until all "struct cred"->security forget this
437 * element.
438 */
439 if (atomic_read(&container_of
440 (element, typeof(struct tomoyo_domain_info),
441 list)->users))
442 goto reinject;
443 break;
444 case TOMOYO_MAX_POLICY:
445 break;
446 }
447 mutex_lock(&tomoyo_policy_lock);
448 if (type == TOMOYO_ID_DOMAIN)
449 tomoyo_del_domain(element);
450 tomoyo_memory_free(element);
451 return;
452reinject:
453 /*
454 * We can safely reinject this element here bacause
455 * (1) Appending list elements and removing list elements are protected
456 * by tomoyo_policy_lock mutex.
457 * (2) Only this function removes list elements and this function is
458 * exclusively executed by tomoyo_gc_mutex mutex.
459 * are true.
460 */
461 mutex_lock(&tomoyo_policy_lock);
462 list_add_rcu(element, element->prev);
435} 463}
436 464
437/** 465/**
@@ -440,19 +468,19 @@ static void tomoyo_del_number_group(struct list_head *element)
440 * @id: One of values in "enum tomoyo_policy_id". 468 * @id: One of values in "enum tomoyo_policy_id".
441 * @member_list: Pointer to "struct list_head". 469 * @member_list: Pointer to "struct list_head".
442 * 470 *
443 * Returns true if some elements are deleted, false otherwise. 471 * Returns nothing.
444 */ 472 */
445static bool tomoyo_collect_member(const enum tomoyo_policy_id id, 473static void tomoyo_collect_member(const enum tomoyo_policy_id id,
446 struct list_head *member_list) 474 struct list_head *member_list)
447{ 475{
448 struct tomoyo_acl_head *member; 476 struct tomoyo_acl_head *member;
449 list_for_each_entry(member, member_list, list) { 477 struct tomoyo_acl_head *tmp;
478 list_for_each_entry_safe(member, tmp, member_list, list) {
450 if (!member->is_deleted) 479 if (!member->is_deleted)
451 continue; 480 continue;
452 if (!tomoyo_add_to_gc(id, &member->list)) 481 member->is_deleted = TOMOYO_GC_IN_PROGRESS;
453 return false; 482 tomoyo_try_to_gc(id, &member->list);
454 } 483 }
455 return true;
456} 484}
457 485
458/** 486/**
@@ -460,22 +488,22 @@ static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
460 * 488 *
461 * @list: Pointer to "struct list_head". 489 * @list: Pointer to "struct list_head".
462 * 490 *
463 * Returns true if some elements are deleted, false otherwise. 491 * Returns nothing.
464 */ 492 */
465static bool tomoyo_collect_acl(struct list_head *list) 493static void tomoyo_collect_acl(struct list_head *list)
466{ 494{
467 struct tomoyo_acl_info *acl; 495 struct tomoyo_acl_info *acl;
468 list_for_each_entry(acl, list, list) { 496 struct tomoyo_acl_info *tmp;
497 list_for_each_entry_safe(acl, tmp, list, list) {
469 if (!acl->is_deleted) 498 if (!acl->is_deleted)
470 continue; 499 continue;
471 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 500 acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
472 return false; 501 tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
473 } 502 }
474 return true;
475} 503}
476 504
477/** 505/**
478 * tomoyo_collect_entry - Scan lists for deleted elements. 506 * tomoyo_collect_entry - Try to kfree() deleted elements.
479 * 507 *
480 * Returns nothing. 508 * Returns nothing.
481 */ 509 */
@@ -484,174 +512,82 @@ static void tomoyo_collect_entry(void)
484 int i; 512 int i;
485 enum tomoyo_policy_id id; 513 enum tomoyo_policy_id id;
486 struct tomoyo_policy_namespace *ns; 514 struct tomoyo_policy_namespace *ns;
487 int idx; 515 mutex_lock(&tomoyo_policy_lock);
488 if (mutex_lock_interruptible(&tomoyo_policy_lock))
489 return;
490 idx = tomoyo_read_lock();
491 { 516 {
492 struct tomoyo_domain_info *domain; 517 struct tomoyo_domain_info *domain;
493 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 518 struct tomoyo_domain_info *tmp;
494 if (!tomoyo_collect_acl(&domain->acl_info_list)) 519 list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
495 goto unlock; 520 list) {
521 tomoyo_collect_acl(&domain->acl_info_list);
496 if (!domain->is_deleted || atomic_read(&domain->users)) 522 if (!domain->is_deleted || atomic_read(&domain->users))
497 continue; 523 continue;
498 /* 524 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
499 * Nobody is referring this domain. But somebody may
500 * refer this domain after successful execve().
501 * We recheck domain->users after SRCU synchronization.
502 */
503 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
504 goto unlock;
505 } 525 }
506 } 526 }
507 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) { 527 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
508 for (id = 0; id < TOMOYO_MAX_POLICY; id++) 528 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
509 if (!tomoyo_collect_member(id, &ns->policy_list[id])) 529 tomoyo_collect_member(id, &ns->policy_list[id]);
510 goto unlock;
511 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 530 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
512 if (!tomoyo_collect_acl(&ns->acl_group[i])) 531 tomoyo_collect_acl(&ns->acl_group[i]);
513 goto unlock; 532 }
533 {
534 struct tomoyo_shared_acl_head *ptr;
535 struct tomoyo_shared_acl_head *tmp;
536 list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
537 list) {
538 if (atomic_read(&ptr->users) > 0)
539 continue;
540 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
541 tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
542 }
543 }
544 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
514 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 545 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
515 struct list_head *list = &ns->group_list[i]; 546 struct list_head *list = &ns->group_list[i];
516 struct tomoyo_group *group; 547 struct tomoyo_group *group;
548 struct tomoyo_group *tmp;
517 switch (i) { 549 switch (i) {
518 case 0: 550 case 0:
519 id = TOMOYO_ID_PATH_GROUP; 551 id = TOMOYO_ID_PATH_GROUP;
520 break; 552 break;
521 default: 553 case 1:
522 id = TOMOYO_ID_NUMBER_GROUP; 554 id = TOMOYO_ID_NUMBER_GROUP;
523 break; 555 break;
556 default:
557 id = TOMOYO_ID_ADDRESS_GROUP;
558 break;
524 } 559 }
525 list_for_each_entry(group, list, head.list) { 560 list_for_each_entry_safe(group, tmp, list, head.list) {
526 if (!tomoyo_collect_member 561 tomoyo_collect_member(id, &group->member_list);
527 (id, &group->member_list))
528 goto unlock;
529 if (!list_empty(&group->member_list) || 562 if (!list_empty(&group->member_list) ||
530 atomic_read(&group->head.users)) 563 atomic_read(&group->head.users) > 0)
531 continue; 564 continue;
532 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, 565 atomic_set(&group->head.users,
533 &group->head.list)) 566 TOMOYO_GC_IN_PROGRESS);
534 goto unlock; 567 tomoyo_try_to_gc(TOMOYO_ID_GROUP,
568 &group->head.list);
535 } 569 }
536 } 570 }
537 } 571 }
538 id = TOMOYO_ID_CONDITION; 572 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
539 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) { 573 struct list_head *list = &tomoyo_name_list[i];
540 struct list_head *list = !i ?
541 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
542 struct tomoyo_shared_acl_head *ptr; 574 struct tomoyo_shared_acl_head *ptr;
543 list_for_each_entry(ptr, list, list) { 575 struct tomoyo_shared_acl_head *tmp;
544 if (atomic_read(&ptr->users)) 576 list_for_each_entry_safe(ptr, tmp, list, list) {
577 if (atomic_read(&ptr->users) > 0)
545 continue; 578 continue;
546 if (!tomoyo_add_to_gc(id, &ptr->list)) 579 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
547 goto unlock; 580 tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
548 } 581 }
549 id = TOMOYO_ID_NAME;
550 } 582 }
551unlock:
552 tomoyo_read_unlock(idx);
553 mutex_unlock(&tomoyo_policy_lock); 583 mutex_unlock(&tomoyo_policy_lock);
554} 584}
555 585
556/** 586/**
557 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
558 *
559 * Returns true if some entries were kfree()d, false otherwise.
560 */
561static bool tomoyo_kfree_entry(void)
562{
563 struct tomoyo_gc *p;
564 struct tomoyo_gc *tmp;
565 bool result = false;
566
567 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
568 struct list_head *element = p->element;
569
570 /*
571 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
572 * list element became no longer reachable from the list which
573 * the element was originally on (e.g. tomoyo_domain_list).
574 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
575 * that the list element became no longer referenced by syscall
576 * users.
577 *
578 * However, there are three users which may still be using the
579 * list element. We need to defer until all of these users
580 * forget the list element.
581 *
582 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
583 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
584 * the list element.
585 */
586 if (tomoyo_struct_used_by_io_buffer(element))
587 continue;
588 /*
589 * Secondly, defer until all other elements in the
590 * tomoyo_gc_list list forget the list element.
591 */
592 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
593 continue;
594 switch (p->type) {
595 case TOMOYO_ID_TRANSITION_CONTROL:
596 tomoyo_del_transition_control(element);
597 break;
598 case TOMOYO_ID_AGGREGATOR:
599 tomoyo_del_aggregator(element);
600 break;
601 case TOMOYO_ID_MANAGER:
602 tomoyo_del_manager(element);
603 break;
604 case TOMOYO_ID_CONDITION:
605 tomoyo_del_condition(element);
606 break;
607 case TOMOYO_ID_NAME:
608 /*
609 * Thirdly, defer until all "struct tomoyo_io_buffer"
610 * ->r.w[] forget the list element.
611 */
612 if (tomoyo_name_used_by_io_buffer(
613 container_of(element, typeof(struct tomoyo_name),
614 head.list)->entry.name, p->size))
615 continue;
616 tomoyo_del_name(element);
617 break;
618 case TOMOYO_ID_ACL:
619 tomoyo_del_acl(element);
620 break;
621 case TOMOYO_ID_DOMAIN:
622 if (!tomoyo_del_domain(element))
623 continue;
624 break;
625 case TOMOYO_ID_PATH_GROUP:
626 tomoyo_del_path_group(element);
627 break;
628 case TOMOYO_ID_GROUP:
629 tomoyo_del_group(element);
630 break;
631 case TOMOYO_ID_NUMBER_GROUP:
632 tomoyo_del_number_group(element);
633 break;
634 case TOMOYO_MAX_POLICY:
635 break;
636 }
637 tomoyo_memory_free(element);
638 list_del(&p->list);
639 kfree(p);
640 tomoyo_gc_list_len--;
641 result = true;
642 }
643 return result;
644}
645
646/**
647 * tomoyo_gc_thread - Garbage collector thread function. 587 * tomoyo_gc_thread - Garbage collector thread function.
648 * 588 *
649 * @unused: Unused. 589 * @unused: Unused.
650 * 590 *
651 * In case OOM-killer choose this thread for termination, we create this thread
652 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
653 * close()d.
654 *
655 * Returns 0. 591 * Returns 0.
656 */ 592 */
657static int tomoyo_gc_thread(void *unused) 593static int tomoyo_gc_thread(void *unused)
@@ -660,13 +596,7 @@ static int tomoyo_gc_thread(void *unused)
660 static DEFINE_MUTEX(tomoyo_gc_mutex); 596 static DEFINE_MUTEX(tomoyo_gc_mutex);
661 if (!mutex_trylock(&tomoyo_gc_mutex)) 597 if (!mutex_trylock(&tomoyo_gc_mutex))
662 goto out; 598 goto out;
663 daemonize("GC for TOMOYO"); 599 tomoyo_collect_entry();
664 do {
665 tomoyo_collect_entry();
666 if (list_empty(&tomoyo_gc_list))
667 break;
668 synchronize_srcu(&tomoyo_ss);
669 } while (tomoyo_kfree_entry());
670 { 600 {
671 struct tomoyo_io_buffer *head; 601 struct tomoyo_io_buffer *head;
672 struct tomoyo_io_buffer *tmp; 602 struct tomoyo_io_buffer *tmp;
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index 5fb0e1298400..50092534ec54 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -42,7 +42,26 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
42} 42}
43 43
44/** 44/**
45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 45 * tomoyo_same_address_group - Check for duplicated "struct tomoyo_address_group" entry.
46 *
47 * @a: Pointer to "struct tomoyo_acl_head".
48 * @b: Pointer to "struct tomoyo_acl_head".
49 *
50 * Returns true if @a == @b, false otherwise.
51 */
52static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a,
53 const struct tomoyo_acl_head *b)
54{
55 const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1),
56 head);
57 const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2),
58 head);
59
60 return tomoyo_same_ipaddr_union(&p1->address, &p2->address);
61}
62
63/**
64 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
46 * 65 *
47 * @param: Pointer to "struct tomoyo_acl_param". 66 * @param: Pointer to "struct tomoyo_acl_param".
48 * @type: Type of this group. 67 * @type: Type of this group.
@@ -77,6 +96,14 @@ int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
77 * tomoyo_put_number_union() is not needed because 96 * tomoyo_put_number_union() is not needed because
78 * param->data[0] != '@'. 97 * param->data[0] != '@'.
79 */ 98 */
99 } else {
100 struct tomoyo_address_group e = { };
101
102 if (param->data[0] == '@' ||
103 !tomoyo_parse_ipaddr_union(param, &e.address))
104 goto out;
105 error = tomoyo_update_policy(&e.head, sizeof(e), param,
106 tomoyo_same_address_group);
80 } 107 }
81out: 108out:
82 tomoyo_put_group(group); 109 tomoyo_put_group(group);
@@ -137,3 +164,35 @@ bool tomoyo_number_matches_group(const unsigned long min,
137 } 164 }
138 return matched; 165 return matched;
139} 166}
167
168/**
169 * tomoyo_address_matches_group - Check whether the given address matches members of the given address group.
170 *
171 * @is_ipv6: True if @address is an IPv6 address.
172 * @address: An IPv4 or IPv6 address.
173 * @group: Pointer to "struct tomoyo_address_group".
174 *
175 * Returns true if @address matches addresses in @group group, false otherwise.
176 *
177 * Caller holds tomoyo_read_lock().
178 */
179bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
180 const struct tomoyo_group *group)
181{
182 struct tomoyo_address_group *member;
183 bool matched = false;
184 const u8 size = is_ipv6 ? 16 : 4;
185
186 list_for_each_entry_rcu(member, &group->member_list, head.list) {
187 if (member->head.is_deleted)
188 continue;
189 if (member->address.is_ipv6 != is_ipv6)
190 continue;
191 if (memcmp(&member->address.ip[0], address, size) > 0 ||
192 memcmp(address, &member->address.ip[1], size) > 0)
193 continue;
194 matched = true;
195 break;
196 }
197 return matched;
198}
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 7a56051146c2..0e995716cc25 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -27,8 +27,6 @@ void tomoyo_warn_oom(const char *function)
27 panic("MAC Initialization failed.\n"); 27 panic("MAC Initialization failed.\n");
28} 28}
29 29
30/* Lock for protecting tomoyo_memory_used. */
31static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
32/* Memoy currently used by policy/audit log/query. */ 30/* Memoy currently used by policy/audit log/query. */
33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 31unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */ 32/* Memory quota for "policy"/"audit log"/"query". */
@@ -42,22 +40,19 @@ unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
42 * Returns true on success, false otherwise. 40 * Returns true on success, false otherwise.
43 * 41 *
44 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise. 42 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
43 *
44 * Caller holds tomoyo_policy_lock mutex.
45 */ 45 */
46bool tomoyo_memory_ok(void *ptr) 46bool tomoyo_memory_ok(void *ptr)
47{ 47{
48 if (ptr) { 48 if (ptr) {
49 const size_t s = ksize(ptr); 49 const size_t s = ksize(ptr);
50 bool result;
51 spin_lock(&tomoyo_policy_memory_lock);
52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s; 50 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
53 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] || 51 if (!tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <= 52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
55 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY]; 53 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY])
56 if (!result)
57 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
58 spin_unlock(&tomoyo_policy_memory_lock);
59 if (result)
60 return true; 54 return true;
55 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
61 } 56 }
62 tomoyo_warn_oom(__func__); 57 tomoyo_warn_oom(__func__);
63 return false; 58 return false;
@@ -71,6 +66,8 @@ bool tomoyo_memory_ok(void *ptr)
71 * 66 *
72 * Returns pointer to allocated memory on success, NULL otherwise. 67 * Returns pointer to allocated memory on success, NULL otherwise.
73 * @data is zero-cleared on success. 68 * @data is zero-cleared on success.
69 *
70 * Caller holds tomoyo_policy_lock mutex.
74 */ 71 */
75void *tomoyo_commit_ok(void *data, const unsigned int size) 72void *tomoyo_commit_ok(void *data, const unsigned int size)
76{ 73{
@@ -85,20 +82,6 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
85} 82}
86 83
87/** 84/**
88 * tomoyo_memory_free - Free memory for elements.
89 *
90 * @ptr: Pointer to allocated memory.
91 */
92void tomoyo_memory_free(void *ptr)
93{
94 size_t s = ksize(ptr);
95 spin_lock(&tomoyo_policy_memory_lock);
96 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
97 spin_unlock(&tomoyo_policy_memory_lock);
98 kfree(ptr);
99}
100
101/**
102 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group". 85 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
103 * 86 *
104 * @param: Pointer to "struct tomoyo_acl_param". 87 * @param: Pointer to "struct tomoyo_acl_param".
@@ -123,7 +106,8 @@ struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
123 goto out; 106 goto out;
124 list = &param->ns->group_list[idx]; 107 list = &param->ns->group_list[idx];
125 list_for_each_entry(group, list, head.list) { 108 list_for_each_entry(group, list, head.list) {
126 if (e.group_name != group->group_name) 109 if (e.group_name != group->group_name ||
110 atomic_read(&group->head.users) == TOMOYO_GC_IN_PROGRESS)
127 continue; 111 continue;
128 atomic_inc(&group->head.users); 112 atomic_inc(&group->head.users);
129 found = true; 113 found = true;
@@ -175,7 +159,8 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
175 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 159 if (mutex_lock_interruptible(&tomoyo_policy_lock))
176 return NULL; 160 return NULL;
177 list_for_each_entry(ptr, head, head.list) { 161 list_for_each_entry(ptr, head, head.list) {
178 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 162 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name) ||
163 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
179 continue; 164 continue;
180 atomic_inc(&ptr->head.users); 165 atomic_inc(&ptr->head.users);
181 goto out; 166 goto out;
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c
new file mode 100644
index 000000000000..97527710a72a
--- /dev/null
+++ b/security/tomoyo/network.c
@@ -0,0 +1,771 @@
1/*
2 * security/tomoyo/network.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/* Structure for holding inet domain socket's address. */
11struct tomoyo_inet_addr_info {
12 __be16 port; /* In network byte order. */
13 const __be32 *address; /* In network byte order. */
14 bool is_ipv6;
15};
16
17/* Structure for holding unix domain socket's address. */
18struct tomoyo_unix_addr_info {
19 u8 *addr; /* This may not be '\0' terminated string. */
20 unsigned int addr_len;
21};
22
23/* Structure for holding socket address. */
24struct tomoyo_addr_info {
25 u8 protocol;
26 u8 operation;
27 struct tomoyo_inet_addr_info inet;
28 struct tomoyo_unix_addr_info unix0;
29};
30
31/* String table for socket's protocols. */
32const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX] = {
33 [SOCK_STREAM] = "stream",
34 [SOCK_DGRAM] = "dgram",
35 [SOCK_RAW] = "raw",
36 [SOCK_SEQPACKET] = "seqpacket",
37 [0] = " ", /* Dummy for avoiding NULL pointer dereference. */
38 [4] = " ", /* Dummy for avoiding NULL pointer dereference. */
39};
40
41/**
42 * tomoyo_parse_ipaddr_union - Parse an IP address.
43 *
44 * @param: Pointer to "struct tomoyo_acl_param".
45 * @ptr: Pointer to "struct tomoyo_ipaddr_union".
46 *
47 * Returns true on success, false otherwise.
48 */
49bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
50 struct tomoyo_ipaddr_union *ptr)
51{
52 u8 * const min = ptr->ip[0].in6_u.u6_addr8;
53 u8 * const max = ptr->ip[1].in6_u.u6_addr8;
54 char *address = tomoyo_read_token(param);
55 const char *end;
56
57 if (!strchr(address, ':') &&
58 in4_pton(address, -1, min, '-', &end) > 0) {
59 ptr->is_ipv6 = false;
60 if (!*end)
61 ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
62 else if (*end++ != '-' ||
63 in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
64 return false;
65 return true;
66 }
67 if (in6_pton(address, -1, min, '-', &end) > 0) {
68 ptr->is_ipv6 = true;
69 if (!*end)
70 memmove(max, min, sizeof(u16) * 8);
71 else if (*end++ != '-' ||
72 in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
73 return false;
74 return true;
75 }
76 return false;
77}
78
79/**
80 * tomoyo_print_ipv4 - Print an IPv4 address.
81 *
82 * @buffer: Buffer to write to.
83 * @buffer_len: Size of @buffer.
84 * @min_ip: Pointer to __be32.
85 * @max_ip: Pointer to __be32.
86 *
87 * Returns nothing.
88 */
89static void tomoyo_print_ipv4(char *buffer, const unsigned int buffer_len,
90 const __be32 *min_ip, const __be32 *max_ip)
91{
92 snprintf(buffer, buffer_len, "%pI4%c%pI4", min_ip,
93 *min_ip == *max_ip ? '\0' : '-', max_ip);
94}
95
96/**
97 * tomoyo_print_ipv6 - Print an IPv6 address.
98 *
99 * @buffer: Buffer to write to.
100 * @buffer_len: Size of @buffer.
101 * @min_ip: Pointer to "struct in6_addr".
102 * @max_ip: Pointer to "struct in6_addr".
103 *
104 * Returns nothing.
105 */
106static void tomoyo_print_ipv6(char *buffer, const unsigned int buffer_len,
107 const struct in6_addr *min_ip,
108 const struct in6_addr *max_ip)
109{
110 snprintf(buffer, buffer_len, "%pI6c%c%pI6c", min_ip,
111 !memcmp(min_ip, max_ip, 16) ? '\0' : '-', max_ip);
112}
113
114/**
115 * tomoyo_print_ip - Print an IP address.
116 *
117 * @buf: Buffer to write to.
118 * @size: Size of @buf.
119 * @ptr: Pointer to "struct ipaddr_union".
120 *
121 * Returns nothing.
122 */
123void tomoyo_print_ip(char *buf, const unsigned int size,
124 const struct tomoyo_ipaddr_union *ptr)
125{
126 if (ptr->is_ipv6)
127 tomoyo_print_ipv6(buf, size, &ptr->ip[0], &ptr->ip[1]);
128 else
129 tomoyo_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0],
130 &ptr->ip[1].s6_addr32[0]);
131}
132
133/*
134 * Mapping table from "enum tomoyo_network_acl_index" to
135 * "enum tomoyo_mac_index" for inet domain socket.
136 */
137static const u8 tomoyo_inet2mac
138[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
139 [SOCK_STREAM] = {
140 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
141 [TOMOYO_NETWORK_LISTEN] =
142 TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
143 [TOMOYO_NETWORK_CONNECT] =
144 TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
145 },
146 [SOCK_DGRAM] = {
147 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
148 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
149 },
150 [SOCK_RAW] = {
151 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_RAW_BIND,
152 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_RAW_SEND,
153 },
154};
155
156/*
157 * Mapping table from "enum tomoyo_network_acl_index" to
158 * "enum tomoyo_mac_index" for unix domain socket.
159 */
160static const u8 tomoyo_unix2mac
161[TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
162 [SOCK_STREAM] = {
163 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
164 [TOMOYO_NETWORK_LISTEN] =
165 TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
166 [TOMOYO_NETWORK_CONNECT] =
167 TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
168 },
169 [SOCK_DGRAM] = {
170 [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
171 [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
172 },
173 [SOCK_SEQPACKET] = {
174 [TOMOYO_NETWORK_BIND] =
175 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
176 [TOMOYO_NETWORK_LISTEN] =
177 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
178 [TOMOYO_NETWORK_CONNECT] =
179 TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
180 },
181};
182
183/**
184 * tomoyo_same_inet_acl - Check for duplicated "struct tomoyo_inet_acl" entry.
185 *
186 * @a: Pointer to "struct tomoyo_acl_info".
187 * @b: Pointer to "struct tomoyo_acl_info".
188 *
189 * Returns true if @a == @b except permission bits, false otherwise.
190 */
191static bool tomoyo_same_inet_acl(const struct tomoyo_acl_info *a,
192 const struct tomoyo_acl_info *b)
193{
194 const struct tomoyo_inet_acl *p1 = container_of(a, typeof(*p1), head);
195 const struct tomoyo_inet_acl *p2 = container_of(b, typeof(*p2), head);
196
197 return p1->protocol == p2->protocol &&
198 tomoyo_same_ipaddr_union(&p1->address, &p2->address) &&
199 tomoyo_same_number_union(&p1->port, &p2->port);
200}
201
202/**
203 * tomoyo_same_unix_acl - Check for duplicated "struct tomoyo_unix_acl" entry.
204 *
205 * @a: Pointer to "struct tomoyo_acl_info".
206 * @b: Pointer to "struct tomoyo_acl_info".
207 *
208 * Returns true if @a == @b except permission bits, false otherwise.
209 */
210static bool tomoyo_same_unix_acl(const struct tomoyo_acl_info *a,
211 const struct tomoyo_acl_info *b)
212{
213 const struct tomoyo_unix_acl *p1 = container_of(a, typeof(*p1), head);
214 const struct tomoyo_unix_acl *p2 = container_of(b, typeof(*p2), head);
215
216 return p1->protocol == p2->protocol &&
217 tomoyo_same_name_union(&p1->name, &p2->name);
218}
219
220/**
221 * tomoyo_merge_inet_acl - Merge duplicated "struct tomoyo_inet_acl" entry.
222 *
223 * @a: Pointer to "struct tomoyo_acl_info".
224 * @b: Pointer to "struct tomoyo_acl_info".
225 * @is_delete: True for @a &= ~@b, false for @a |= @b.
226 *
227 * Returns true if @a is empty, false otherwise.
228 */
229static bool tomoyo_merge_inet_acl(struct tomoyo_acl_info *a,
230 struct tomoyo_acl_info *b,
231 const bool is_delete)
232{
233 u8 * const a_perm =
234 &container_of(a, struct tomoyo_inet_acl, head)->perm;
235 u8 perm = *a_perm;
236 const u8 b_perm = container_of(b, struct tomoyo_inet_acl, head)->perm;
237
238 if (is_delete)
239 perm &= ~b_perm;
240 else
241 perm |= b_perm;
242 *a_perm = perm;
243 return !perm;
244}
245
246/**
247 * tomoyo_merge_unix_acl - Merge duplicated "struct tomoyo_unix_acl" entry.
248 *
249 * @a: Pointer to "struct tomoyo_acl_info".
250 * @b: Pointer to "struct tomoyo_acl_info".
251 * @is_delete: True for @a &= ~@b, false for @a |= @b.
252 *
253 * Returns true if @a is empty, false otherwise.
254 */
255static bool tomoyo_merge_unix_acl(struct tomoyo_acl_info *a,
256 struct tomoyo_acl_info *b,
257 const bool is_delete)
258{
259 u8 * const a_perm =
260 &container_of(a, struct tomoyo_unix_acl, head)->perm;
261 u8 perm = *a_perm;
262 const u8 b_perm = container_of(b, struct tomoyo_unix_acl, head)->perm;
263
264 if (is_delete)
265 perm &= ~b_perm;
266 else
267 perm |= b_perm;
268 *a_perm = perm;
269 return !perm;
270}
271
272/**
273 * tomoyo_write_inet_network - Write "struct tomoyo_inet_acl" list.
274 *
275 * @param: Pointer to "struct tomoyo_acl_param".
276 *
277 * Returns 0 on success, negative value otherwise.
278 *
279 * Caller holds tomoyo_read_lock().
280 */
281int tomoyo_write_inet_network(struct tomoyo_acl_param *param)
282{
283 struct tomoyo_inet_acl e = { .head.type = TOMOYO_TYPE_INET_ACL };
284 int error = -EINVAL;
285 u8 type;
286 const char *protocol = tomoyo_read_token(param);
287 const char *operation = tomoyo_read_token(param);
288
289 for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
290 if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
291 break;
292 for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
293 if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
294 e.perm |= 1 << type;
295 if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
296 return -EINVAL;
297 if (param->data[0] == '@') {
298 param->data++;
299 e.address.group =
300 tomoyo_get_group(param, TOMOYO_ADDRESS_GROUP);
301 if (!e.address.group)
302 return -ENOMEM;
303 } else {
304 if (!tomoyo_parse_ipaddr_union(param, &e.address))
305 goto out;
306 }
307 if (!tomoyo_parse_number_union(param, &e.port) ||
308 e.port.values[1] > 65535)
309 goto out;
310 error = tomoyo_update_domain(&e.head, sizeof(e), param,
311 tomoyo_same_inet_acl,
312 tomoyo_merge_inet_acl);
313out:
314 tomoyo_put_group(e.address.group);
315 tomoyo_put_number_union(&e.port);
316 return error;
317}
318
319/**
320 * tomoyo_write_unix_network - Write "struct tomoyo_unix_acl" list.
321 *
322 * @param: Pointer to "struct tomoyo_acl_param".
323 *
324 * Returns 0 on success, negative value otherwise.
325 */
326int tomoyo_write_unix_network(struct tomoyo_acl_param *param)
327{
328 struct tomoyo_unix_acl e = { .head.type = TOMOYO_TYPE_UNIX_ACL };
329 int error;
330 u8 type;
331 const char *protocol = tomoyo_read_token(param);
332 const char *operation = tomoyo_read_token(param);
333
334 for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
335 if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
336 break;
337 for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
338 if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
339 e.perm |= 1 << type;
340 if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
341 return -EINVAL;
342 if (!tomoyo_parse_name_union(param, &e.name))
343 return -EINVAL;
344 error = tomoyo_update_domain(&e.head, sizeof(e), param,
345 tomoyo_same_unix_acl,
346 tomoyo_merge_unix_acl);
347 tomoyo_put_name_union(&e.name);
348 return error;
349}
350
351/**
352 * tomoyo_audit_net_log - Audit network log.
353 *
354 * @r: Pointer to "struct tomoyo_request_info".
355 * @family: Name of socket family ("inet" or "unix").
356 * @protocol: Name of protocol in @family.
357 * @operation: Name of socket operation.
358 * @address: Name of address.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
362static int tomoyo_audit_net_log(struct tomoyo_request_info *r,
363 const char *family, const u8 protocol,
364 const u8 operation, const char *address)
365{
366 return tomoyo_supervisor(r, "network %s %s %s %s\n", family,
367 tomoyo_proto_keyword[protocol],
368 tomoyo_socket_keyword[operation], address);
369}
370
371/**
372 * tomoyo_audit_inet_log - Audit INET network log.
373 *
374 * @r: Pointer to "struct tomoyo_request_info".
375 *
376 * Returns 0 on success, negative value otherwise.
377 */
378static int tomoyo_audit_inet_log(struct tomoyo_request_info *r)
379{
380 char buf[128];
381 int len;
382 const __be32 *address = r->param.inet_network.address;
383
384 if (r->param.inet_network.is_ipv6)
385 tomoyo_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
386 address, (const struct in6_addr *) address);
387 else
388 tomoyo_print_ipv4(buf, sizeof(buf), address, address);
389 len = strlen(buf);
390 snprintf(buf + len, sizeof(buf) - len, " %u",
391 r->param.inet_network.port);
392 return tomoyo_audit_net_log(r, "inet", r->param.inet_network.protocol,
393 r->param.inet_network.operation, buf);
394}
395
396/**
397 * tomoyo_audit_unix_log - Audit UNIX network log.
398 *
399 * @r: Pointer to "struct tomoyo_request_info".
400 *
401 * Returns 0 on success, negative value otherwise.
402 */
403static int tomoyo_audit_unix_log(struct tomoyo_request_info *r)
404{
405 return tomoyo_audit_net_log(r, "unix", r->param.unix_network.protocol,
406 r->param.unix_network.operation,
407 r->param.unix_network.address->name);
408}
409
410/**
411 * tomoyo_check_inet_acl - Check permission for inet domain socket operation.
412 *
413 * @r: Pointer to "struct tomoyo_request_info".
414 * @ptr: Pointer to "struct tomoyo_acl_info".
415 *
416 * Returns true if granted, false otherwise.
417 */
418static bool tomoyo_check_inet_acl(struct tomoyo_request_info *r,
419 const struct tomoyo_acl_info *ptr)
420{
421 const struct tomoyo_inet_acl *acl =
422 container_of(ptr, typeof(*acl), head);
423 const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
424
425 if (!(acl->perm & (1 << r->param.inet_network.operation)) ||
426 !tomoyo_compare_number_union(r->param.inet_network.port,
427 &acl->port))
428 return false;
429 if (acl->address.group)
430 return tomoyo_address_matches_group
431 (r->param.inet_network.is_ipv6,
432 r->param.inet_network.address, acl->address.group);
433 return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
434 memcmp(&acl->address.ip[0],
435 r->param.inet_network.address, size) <= 0 &&
436 memcmp(r->param.inet_network.address,
437 &acl->address.ip[1], size) <= 0;
438}
439
440/**
441 * tomoyo_check_unix_acl - Check permission for unix domain socket operation.
442 *
443 * @r: Pointer to "struct tomoyo_request_info".
444 * @ptr: Pointer to "struct tomoyo_acl_info".
445 *
446 * Returns true if granted, false otherwise.
447 */
448static bool tomoyo_check_unix_acl(struct tomoyo_request_info *r,
449 const struct tomoyo_acl_info *ptr)
450{
451 const struct tomoyo_unix_acl *acl =
452 container_of(ptr, typeof(*acl), head);
453
454 return (acl->perm & (1 << r->param.unix_network.operation)) &&
455 tomoyo_compare_name_union(r->param.unix_network.address,
456 &acl->name);
457}
458
459/**
460 * tomoyo_inet_entry - Check permission for INET network operation.
461 *
462 * @address: Pointer to "struct tomoyo_addr_info".
463 *
464 * Returns 0 on success, negative value otherwise.
465 */
466static int tomoyo_inet_entry(const struct tomoyo_addr_info *address)
467{
468 const int idx = tomoyo_read_lock();
469 struct tomoyo_request_info r;
470 int error = 0;
471 const u8 type = tomoyo_inet2mac[address->protocol][address->operation];
472
473 if (type && tomoyo_init_request_info(&r, NULL, type)
474 != TOMOYO_CONFIG_DISABLED) {
475 r.param_type = TOMOYO_TYPE_INET_ACL;
476 r.param.inet_network.protocol = address->protocol;
477 r.param.inet_network.operation = address->operation;
478 r.param.inet_network.is_ipv6 = address->inet.is_ipv6;
479 r.param.inet_network.address = address->inet.address;
480 r.param.inet_network.port = ntohs(address->inet.port);
481 do {
482 tomoyo_check_acl(&r, tomoyo_check_inet_acl);
483 error = tomoyo_audit_inet_log(&r);
484 } while (error == TOMOYO_RETRY_REQUEST);
485 }
486 tomoyo_read_unlock(idx);
487 return error;
488}
489
490/**
491 * tomoyo_check_inet_address - Check permission for inet domain socket's operation.
492 *
493 * @addr: Pointer to "struct sockaddr".
494 * @addr_len: Size of @addr.
495 * @port: Port number.
496 * @address: Pointer to "struct tomoyo_addr_info".
497 *
498 * Returns 0 on success, negative value otherwise.
499 */
500static int tomoyo_check_inet_address(const struct sockaddr *addr,
501 const unsigned int addr_len,
502 const u16 port,
503 struct tomoyo_addr_info *address)
504{
505 struct tomoyo_inet_addr_info *i = &address->inet;
506
507 switch (addr->sa_family) {
508 case AF_INET6:
509 if (addr_len < SIN6_LEN_RFC2133)
510 goto skip;
511 i->is_ipv6 = true;
512 i->address = (__be32 *)
513 ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
514 i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
515 break;
516 case AF_INET:
517 if (addr_len < sizeof(struct sockaddr_in))
518 goto skip;
519 i->is_ipv6 = false;
520 i->address = (__be32 *)
521 &((struct sockaddr_in *) addr)->sin_addr;
522 i->port = ((struct sockaddr_in *) addr)->sin_port;
523 break;
524 default:
525 goto skip;
526 }
527 if (address->protocol == SOCK_RAW)
528 i->port = htons(port);
529 return tomoyo_inet_entry(address);
530skip:
531 return 0;
532}
533
534/**
535 * tomoyo_unix_entry - Check permission for UNIX network operation.
536 *
537 * @address: Pointer to "struct tomoyo_addr_info".
538 *
539 * Returns 0 on success, negative value otherwise.
540 */
541static int tomoyo_unix_entry(const struct tomoyo_addr_info *address)
542{
543 const int idx = tomoyo_read_lock();
544 struct tomoyo_request_info r;
545 int error = 0;
546 const u8 type = tomoyo_unix2mac[address->protocol][address->operation];
547
548 if (type && tomoyo_init_request_info(&r, NULL, type)
549 != TOMOYO_CONFIG_DISABLED) {
550 char *buf = address->unix0.addr;
551 int len = address->unix0.addr_len - sizeof(sa_family_t);
552
553 if (len <= 0) {
554 buf = "anonymous";
555 len = 9;
556 } else if (buf[0]) {
557 len = strnlen(buf, len);
558 }
559 buf = tomoyo_encode2(buf, len);
560 if (buf) {
561 struct tomoyo_path_info addr;
562
563 addr.name = buf;
564 tomoyo_fill_path_info(&addr);
565 r.param_type = TOMOYO_TYPE_UNIX_ACL;
566 r.param.unix_network.protocol = address->protocol;
567 r.param.unix_network.operation = address->operation;
568 r.param.unix_network.address = &addr;
569 do {
570 tomoyo_check_acl(&r, tomoyo_check_unix_acl);
571 error = tomoyo_audit_unix_log(&r);
572 } while (error == TOMOYO_RETRY_REQUEST);
573 kfree(buf);
574 } else
575 error = -ENOMEM;
576 }
577 tomoyo_read_unlock(idx);
578 return error;
579}
580
581/**
582 * tomoyo_check_unix_address - Check permission for unix domain socket's operation.
583 *
584 * @addr: Pointer to "struct sockaddr".
585 * @addr_len: Size of @addr.
586 * @address: Pointer to "struct tomoyo_addr_info".
587 *
588 * Returns 0 on success, negative value otherwise.
589 */
590static int tomoyo_check_unix_address(struct sockaddr *addr,
591 const unsigned int addr_len,
592 struct tomoyo_addr_info *address)
593{
594 struct tomoyo_unix_addr_info *u = &address->unix0;
595
596 if (addr->sa_family != AF_UNIX)
597 return 0;
598 u->addr = ((struct sockaddr_un *) addr)->sun_path;
599 u->addr_len = addr_len;
600 return tomoyo_unix_entry(address);
601}
602
603/**
604 * tomoyo_kernel_service - Check whether I'm kernel service or not.
605 *
606 * Returns true if I'm kernel service, false otherwise.
607 */
608static bool tomoyo_kernel_service(void)
609{
610 /* Nothing to do if I am a kernel service. */
611 return segment_eq(get_fs(), KERNEL_DS);
612}
613
614/**
615 * tomoyo_sock_family - Get socket's family.
616 *
617 * @sk: Pointer to "struct sock".
618 *
619 * Returns one of PF_INET, PF_INET6, PF_UNIX or 0.
620 */
621static u8 tomoyo_sock_family(struct sock *sk)
622{
623 u8 family;
624
625 if (tomoyo_kernel_service())
626 return 0;
627 family = sk->sk_family;
628 switch (family) {
629 case PF_INET:
630 case PF_INET6:
631 case PF_UNIX:
632 return family;
633 default:
634 return 0;
635 }
636}
637
638/**
639 * tomoyo_socket_listen_permission - Check permission for listening a socket.
640 *
641 * @sock: Pointer to "struct socket".
642 *
643 * Returns 0 on success, negative value otherwise.
644 */
645int tomoyo_socket_listen_permission(struct socket *sock)
646{
647 struct tomoyo_addr_info address;
648 const u8 family = tomoyo_sock_family(sock->sk);
649 const unsigned int type = sock->type;
650 struct sockaddr_storage addr;
651 int addr_len;
652
653 if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
654 return 0;
655 {
656 const int error = sock->ops->getname(sock, (struct sockaddr *)
657 &addr, &addr_len, 0);
658
659 if (error)
660 return error;
661 }
662 address.protocol = type;
663 address.operation = TOMOYO_NETWORK_LISTEN;
664 if (family == PF_UNIX)
665 return tomoyo_check_unix_address((struct sockaddr *) &addr,
666 addr_len, &address);
667 return tomoyo_check_inet_address((struct sockaddr *) &addr, addr_len,
668 0, &address);
669}
670
671/**
672 * tomoyo_socket_connect_permission - Check permission for setting the remote address of a socket.
673 *
674 * @sock: Pointer to "struct socket".
675 * @addr: Pointer to "struct sockaddr".
676 * @addr_len: Size of @addr.
677 *
678 * Returns 0 on success, negative value otherwise.
679 */
680int tomoyo_socket_connect_permission(struct socket *sock,
681 struct sockaddr *addr, int addr_len)
682{
683 struct tomoyo_addr_info address;
684 const u8 family = tomoyo_sock_family(sock->sk);
685 const unsigned int type = sock->type;
686
687 if (!family)
688 return 0;
689 address.protocol = type;
690 switch (type) {
691 case SOCK_DGRAM:
692 case SOCK_RAW:
693 address.operation = TOMOYO_NETWORK_SEND;
694 break;
695 case SOCK_STREAM:
696 case SOCK_SEQPACKET:
697 address.operation = TOMOYO_NETWORK_CONNECT;
698 break;
699 default:
700 return 0;
701 }
702 if (family == PF_UNIX)
703 return tomoyo_check_unix_address(addr, addr_len, &address);
704 return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
705 &address);
706}
707
708/**
709 * tomoyo_socket_bind_permission - Check permission for setting the local address of a socket.
710 *
711 * @sock: Pointer to "struct socket".
712 * @addr: Pointer to "struct sockaddr".
713 * @addr_len: Size of @addr.
714 *
715 * Returns 0 on success, negative value otherwise.
716 */
717int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
718 int addr_len)
719{
720 struct tomoyo_addr_info address;
721 const u8 family = tomoyo_sock_family(sock->sk);
722 const unsigned int type = sock->type;
723
724 if (!family)
725 return 0;
726 switch (type) {
727 case SOCK_STREAM:
728 case SOCK_DGRAM:
729 case SOCK_RAW:
730 case SOCK_SEQPACKET:
731 address.protocol = type;
732 address.operation = TOMOYO_NETWORK_BIND;
733 break;
734 default:
735 return 0;
736 }
737 if (family == PF_UNIX)
738 return tomoyo_check_unix_address(addr, addr_len, &address);
739 return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
740 &address);
741}
742
743/**
744 * tomoyo_socket_sendmsg_permission - Check permission for sending a datagram.
745 *
746 * @sock: Pointer to "struct socket".
747 * @msg: Pointer to "struct msghdr".
748 * @size: Unused.
749 *
750 * Returns 0 on success, negative value otherwise.
751 */
752int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
753 int size)
754{
755 struct tomoyo_addr_info address;
756 const u8 family = tomoyo_sock_family(sock->sk);
757 const unsigned int type = sock->type;
758
759 if (!msg->msg_name || !family ||
760 (type != SOCK_DGRAM && type != SOCK_RAW))
761 return 0;
762 address.protocol = type;
763 address.operation = TOMOYO_NETWORK_SEND;
764 if (family == PF_UNIX)
765 return tomoyo_check_unix_address((struct sockaddr *)
766 msg->msg_name,
767 msg->msg_namelen, &address);
768 return tomoyo_check_inet_address((struct sockaddr *) msg->msg_name,
769 msg->msg_namelen,
770 sock->sk->sk_protocol, &address);
771}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 6c601bd300f3..738bbdf8d4c7 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -15,17 +15,19 @@
15#include "../../fs/internal.h" 15#include "../../fs/internal.h"
16 16
17/** 17/**
18 * tomoyo_encode: Convert binary string to ascii string. 18 * tomoyo_encode2 - Encode binary string to ascii string.
19 * 19 *
20 * @str: String in binary format. 20 * @str: String in binary format.
21 * @str_len: Size of @str in byte.
21 * 22 *
22 * Returns pointer to @str in ascii format on success, NULL otherwise. 23 * Returns pointer to @str in ascii format on success, NULL otherwise.
23 * 24 *
24 * This function uses kzalloc(), so caller must kfree() if this function 25 * This function uses kzalloc(), so caller must kfree() if this function
25 * didn't return NULL. 26 * didn't return NULL.
26 */ 27 */
27char *tomoyo_encode(const char *str) 28char *tomoyo_encode2(const char *str, int str_len)
28{ 29{
30 int i;
29 int len = 0; 31 int len = 0;
30 const char *p = str; 32 const char *p = str;
31 char *cp; 33 char *cp;
@@ -33,8 +35,9 @@ char *tomoyo_encode(const char *str)
33 35
34 if (!p) 36 if (!p)
35 return NULL; 37 return NULL;
36 while (*p) { 38 for (i = 0; i < str_len; i++) {
37 const unsigned char c = *p++; 39 const unsigned char c = p[i];
40
38 if (c == '\\') 41 if (c == '\\')
39 len += 2; 42 len += 2;
40 else if (c > ' ' && c < 127) 43 else if (c > ' ' && c < 127)
@@ -49,8 +52,8 @@ char *tomoyo_encode(const char *str)
49 return NULL; 52 return NULL;
50 cp0 = cp; 53 cp0 = cp;
51 p = str; 54 p = str;
52 while (*p) { 55 for (i = 0; i < str_len; i++) {
53 const unsigned char c = *p++; 56 const unsigned char c = p[i];
54 57
55 if (c == '\\') { 58 if (c == '\\') {
56 *cp++ = '\\'; 59 *cp++ = '\\';
@@ -68,6 +71,21 @@ char *tomoyo_encode(const char *str)
68} 71}
69 72
70/** 73/**
74 * tomoyo_encode - Encode binary string to ascii string.
75 *
76 * @str: String in binary format.
77 *
78 * Returns pointer to @str in ascii format on success, NULL otherwise.
79 *
80 * This function uses kzalloc(), so caller must kfree() if this function
81 * didn't return NULL.
82 */
83char *tomoyo_encode(const char *str)
84{
85 return str ? tomoyo_encode2(str, strlen(str)) : NULL;
86}
87
88/**
71 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root. 89 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
72 * 90 *
73 * @path: Pointer to "struct path". 91 * @path: Pointer to "struct path".
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index a49c3bfd4dd5..2672ac4f3beb 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -8,6 +8,124 @@
8#include "common.h" 8#include "common.h"
9 9
10/** 10/**
11 * tomoyo_check_task_acl - Check permission for task operation.
12 *
13 * @r: Pointer to "struct tomoyo_request_info".
14 * @ptr: Pointer to "struct tomoyo_acl_info".
15 *
16 * Returns true if granted, false otherwise.
17 */
18static bool tomoyo_check_task_acl(struct tomoyo_request_info *r,
19 const struct tomoyo_acl_info *ptr)
20{
21 const struct tomoyo_task_acl *acl = container_of(ptr, typeof(*acl),
22 head);
23 return !tomoyo_pathcmp(r->param.task.domainname, acl->domainname);
24}
25
26/**
27 * tomoyo_write_self - write() for /sys/kernel/security/tomoyo/self_domain interface.
28 *
29 * @file: Pointer to "struct file".
30 * @buf: Domainname to transit to.
31 * @count: Size of @buf.
32 * @ppos: Unused.
33 *
34 * Returns @count on success, negative value otherwise.
35 *
36 * If domain transition was permitted but the domain transition failed, this
37 * function returns error rather than terminating current thread with SIGKILL.
38 */
39static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
40 size_t count, loff_t *ppos)
41{
42 char *data;
43 int error;
44 if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
45 return -ENOMEM;
46 data = kzalloc(count + 1, GFP_NOFS);
47 if (!data)
48 return -ENOMEM;
49 if (copy_from_user(data, buf, count)) {
50 error = -EFAULT;
51 goto out;
52 }
53 tomoyo_normalize_line(data);
54 if (tomoyo_correct_domain(data)) {
55 const int idx = tomoyo_read_lock();
56 struct tomoyo_path_info name;
57 struct tomoyo_request_info r;
58 name.name = data;
59 tomoyo_fill_path_info(&name);
60 /* Check "task manual_domain_transition" permission. */
61 tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
62 r.param_type = TOMOYO_TYPE_MANUAL_TASK_ACL;
63 r.param.task.domainname = &name;
64 tomoyo_check_acl(&r, tomoyo_check_task_acl);
65 if (!r.granted)
66 error = -EPERM;
67 else {
68 struct tomoyo_domain_info *new_domain =
69 tomoyo_assign_domain(data, true);
70 if (!new_domain) {
71 error = -ENOENT;
72 } else {
73 struct cred *cred = prepare_creds();
74 if (!cred) {
75 error = -ENOMEM;
76 } else {
77 struct tomoyo_domain_info *old_domain =
78 cred->security;
79 cred->security = new_domain;
80 atomic_inc(&new_domain->users);
81 atomic_dec(&old_domain->users);
82 commit_creds(cred);
83 error = 0;
84 }
85 }
86 }
87 tomoyo_read_unlock(idx);
88 } else
89 error = -EINVAL;
90out:
91 kfree(data);
92 return error ? error : count;
93}
94
95/**
96 * tomoyo_read_self - read() for /sys/kernel/security/tomoyo/self_domain interface.
97 *
98 * @file: Pointer to "struct file".
99 * @buf: Domainname which current thread belongs to.
100 * @count: Size of @buf.
101 * @ppos: Bytes read by now.
102 *
103 * Returns read size on success, negative value otherwise.
104 */
105static ssize_t tomoyo_read_self(struct file *file, char __user *buf,
106 size_t count, loff_t *ppos)
107{
108 const char *domain = tomoyo_domain()->domainname->name;
109 loff_t len = strlen(domain);
110 loff_t pos = *ppos;
111 if (pos >= len || !count)
112 return 0;
113 len -= pos;
114 if (count < len)
115 len = count;
116 if (copy_to_user(buf, domain + pos, len))
117 return -EFAULT;
118 *ppos += len;
119 return len;
120}
121
122/* Operations for /sys/kernel/security/tomoyo/self_domain interface. */
123static const struct file_operations tomoyo_self_operations = {
124 .write = tomoyo_write_self,
125 .read = tomoyo_read_self,
126};
127
128/**
11 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 129 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
12 * 130 *
13 * @inode: Pointer to "struct inode". 131 * @inode: Pointer to "struct inode".
@@ -135,8 +253,6 @@ static int __init tomoyo_initerface_init(void)
135 TOMOYO_EXCEPTIONPOLICY); 253 TOMOYO_EXCEPTIONPOLICY);
136 tomoyo_create_entry("audit", 0400, tomoyo_dir, 254 tomoyo_create_entry("audit", 0400, tomoyo_dir,
137 TOMOYO_AUDIT); 255 TOMOYO_AUDIT);
138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
139 TOMOYO_SELFDOMAIN);
140 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 256 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
141 TOMOYO_PROCESS_STATUS); 257 TOMOYO_PROCESS_STATUS);
142 tomoyo_create_entry("stat", 0644, tomoyo_dir, 258 tomoyo_create_entry("stat", 0644, tomoyo_dir,
@@ -147,6 +263,9 @@ static int __init tomoyo_initerface_init(void)
147 TOMOYO_MANAGER); 263 TOMOYO_MANAGER);
148 tomoyo_create_entry("version", 0400, tomoyo_dir, 264 tomoyo_create_entry("version", 0400, tomoyo_dir,
149 TOMOYO_VERSION); 265 TOMOYO_VERSION);
266 securityfs_create_file("self_domain", 0666, tomoyo_dir, NULL,
267 &tomoyo_self_operations);
268 tomoyo_load_builtin_policy();
150 return 0; 269 return 0;
151} 270}
152 271
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index f776400a8f31..4b327b691745 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -442,6 +442,64 @@ static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path); 442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
443} 443}
444 444
445/**
446 * tomoyo_socket_listen - Check permission for listen().
447 *
448 * @sock: Pointer to "struct socket".
449 * @backlog: Backlog parameter.
450 *
451 * Returns 0 on success, negative value otherwise.
452 */
453static int tomoyo_socket_listen(struct socket *sock, int backlog)
454{
455 return tomoyo_socket_listen_permission(sock);
456}
457
458/**
459 * tomoyo_socket_connect - Check permission for connect().
460 *
461 * @sock: Pointer to "struct socket".
462 * @addr: Pointer to "struct sockaddr".
463 * @addr_len: Size of @addr.
464 *
465 * Returns 0 on success, negative value otherwise.
466 */
467static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
468 int addr_len)
469{
470 return tomoyo_socket_connect_permission(sock, addr, addr_len);
471}
472
473/**
474 * tomoyo_socket_bind - Check permission for bind().
475 *
476 * @sock: Pointer to "struct socket".
477 * @addr: Pointer to "struct sockaddr".
478 * @addr_len: Size of @addr.
479 *
480 * Returns 0 on success, negative value otherwise.
481 */
482static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
483 int addr_len)
484{
485 return tomoyo_socket_bind_permission(sock, addr, addr_len);
486}
487
488/**
489 * tomoyo_socket_sendmsg - Check permission for sendmsg().
490 *
491 * @sock: Pointer to "struct socket".
492 * @msg: Pointer to "struct msghdr".
493 * @size: Size of message.
494 *
495 * Returns 0 on success, negative value otherwise.
496 */
497static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
498 int size)
499{
500 return tomoyo_socket_sendmsg_permission(sock, msg, size);
501}
502
445/* 503/*
446 * tomoyo_security_ops is a "struct security_operations" which is used for 504 * tomoyo_security_ops is a "struct security_operations" which is used for
447 * registering TOMOYO. 505 * registering TOMOYO.
@@ -472,6 +530,10 @@ static struct security_operations tomoyo_security_ops = {
472 .sb_mount = tomoyo_sb_mount, 530 .sb_mount = tomoyo_sb_mount,
473 .sb_umount = tomoyo_sb_umount, 531 .sb_umount = tomoyo_sb_umount,
474 .sb_pivotroot = tomoyo_sb_pivotroot, 532 .sb_pivotroot = tomoyo_sb_pivotroot,
533 .socket_bind = tomoyo_socket_bind,
534 .socket_connect = tomoyo_socket_connect,
535 .socket_listen = tomoyo_socket_listen,
536 .socket_sendmsg = tomoyo_socket_sendmsg,
475}; 537};
476 538
477/* Lock for GC. */ 539/* Lock for GC. */
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index c36bd1107fc8..4a9b4b2eb755 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -42,6 +42,39 @@ const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE, 42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE, 43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE, 44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
45 /* CONFIG::network group */
46 [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] =
47 TOMOYO_MAC_CATEGORY_NETWORK,
48 [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] =
49 TOMOYO_MAC_CATEGORY_NETWORK,
50 [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] =
51 TOMOYO_MAC_CATEGORY_NETWORK,
52 [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] =
53 TOMOYO_MAC_CATEGORY_NETWORK,
54 [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] =
55 TOMOYO_MAC_CATEGORY_NETWORK,
56 [TOMOYO_MAC_NETWORK_INET_RAW_BIND] =
57 TOMOYO_MAC_CATEGORY_NETWORK,
58 [TOMOYO_MAC_NETWORK_INET_RAW_SEND] =
59 TOMOYO_MAC_CATEGORY_NETWORK,
60 [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] =
61 TOMOYO_MAC_CATEGORY_NETWORK,
62 [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] =
63 TOMOYO_MAC_CATEGORY_NETWORK,
64 [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] =
65 TOMOYO_MAC_CATEGORY_NETWORK,
66 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] =
67 TOMOYO_MAC_CATEGORY_NETWORK,
68 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] =
69 TOMOYO_MAC_CATEGORY_NETWORK,
70 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] =
71 TOMOYO_MAC_CATEGORY_NETWORK,
72 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] =
73 TOMOYO_MAC_CATEGORY_NETWORK,
74 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] =
75 TOMOYO_MAC_CATEGORY_NETWORK,
76 /* CONFIG::misc group */
77 [TOMOYO_MAC_ENVIRON] = TOMOYO_MAC_CATEGORY_MISC,
45}; 78};
46 79
47/** 80/**
@@ -126,6 +159,31 @@ char *tomoyo_read_token(struct tomoyo_acl_param *param)
126} 159}
127 160
128/** 161/**
162 * tomoyo_get_domainname - Read a domainname from a line.
163 *
164 * @param: Pointer to "struct tomoyo_acl_param".
165 *
166 * Returns a domainname on success, NULL otherwise.
167 */
168const struct tomoyo_path_info *tomoyo_get_domainname
169(struct tomoyo_acl_param *param)
170{
171 char *start = param->data;
172 char *pos = start;
173 while (*pos) {
174 if (*pos++ != ' ' || *pos++ == '/')
175 continue;
176 pos -= 2;
177 *pos++ = '\0';
178 break;
179 }
180 param->data = pos;
181 if (tomoyo_correct_domain(start))
182 return tomoyo_get_name(start);
183 return NULL;
184}
185
186/**
129 * tomoyo_parse_ulong - Parse an "unsigned long" value. 187 * tomoyo_parse_ulong - Parse an "unsigned long" value.
130 * 188 *
131 * @result: Pointer to "unsigned long". 189 * @result: Pointer to "unsigned long".
@@ -920,14 +978,17 @@ int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
920 const u8 index) 978 const u8 index)
921{ 979{
922 u8 mode; 980 u8 mode;
923 const u8 category = TOMOYO_MAC_CATEGORY_FILE; 981 struct tomoyo_profile *p;
982
924 if (!tomoyo_policy_loaded) 983 if (!tomoyo_policy_loaded)
925 return TOMOYO_CONFIG_DISABLED; 984 return TOMOYO_CONFIG_DISABLED;
926 mode = tomoyo_profile(ns, profile)->config[index]; 985 p = tomoyo_profile(ns, profile);
986 mode = p->config[index];
927 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 987 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
928 mode = tomoyo_profile(ns, profile)->config[category]; 988 mode = p->config[tomoyo_index2category[index]
989 + TOMOYO_MAX_MAC_INDEX];
929 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 990 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
930 mode = tomoyo_profile(ns, profile)->default_config; 991 mode = p->default_config;
931 return mode & 3; 992 return mode & 3;
932} 993}
933 994
@@ -996,6 +1057,17 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
996 perm = container_of(ptr, struct tomoyo_mkdev_acl, 1057 perm = container_of(ptr, struct tomoyo_mkdev_acl,
997 head)->perm; 1058 head)->perm;
998 break; 1059 break;
1060 case TOMOYO_TYPE_INET_ACL:
1061 perm = container_of(ptr, struct tomoyo_inet_acl,
1062 head)->perm;
1063 break;
1064 case TOMOYO_TYPE_UNIX_ACL:
1065 perm = container_of(ptr, struct tomoyo_unix_acl,
1066 head)->perm;
1067 break;
1068 case TOMOYO_TYPE_MANUAL_TASK_ACL:
1069 perm = 0;
1070 break;
999 default: 1071 default:
1000 perm = 1; 1072 perm = 1;
1001 } 1073 }