aboutsummaryrefslogtreecommitdiffstats
path: root/security
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 /security
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 ...
Diffstat (limited to 'security')
-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
72 files changed, 4164 insertions, 1201 deletions
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 }