aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 22:26:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 22:26:38 -0400
commit95b6886526bb510b8370b625a49bc0ab3b8ff10f (patch)
tree2862606224820d200be12d2092dcd26df1654b80 /security
parent22712200e175e0df5c7f9edfe6c6bf5c94c23b83 (diff)
parent29412f0f6a19e34336368f13eab848091c343952 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (54 commits) tpm_nsc: Fix bug when loading multiple TPM drivers tpm: Move tpm_tis_reenable_interrupts out of CONFIG_PNP block tpm: Fix compilation warning when CONFIG_PNP is not defined TOMOYO: Update kernel-doc. tpm: Fix a typo tpm_tis: Probing function for Intel iTPM bug tpm_tis: Fix the probing for interrupts tpm_tis: Delay ACPI S3 suspend while the TPM is busy tpm_tis: Re-enable interrupts upon (S3) resume tpm: Fix display of data in pubek sysfs entry tpm_tis: Add timeouts sysfs entry tpm: Adjust interface timeouts if they are too small tpm: Use interface timeouts returned from the TPM tpm_tis: Introduce durations sysfs entry tpm: Adjust the durations if they are too small tpm: Use durations returned from TPM TOMOYO: Enable conditional ACL. TOMOYO: Allow using argv[]/envp[] of execve() as conditions. TOMOYO: Allow using executable's realpath and symlink's target as conditions. TOMOYO: Allow using owner/group etc. of file objects as conditions. ... Fix up trivial conflict in security/tomoyo/realpath.c
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/domain.c2
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/ecryptfs_format.c81
-rw-r--r--security/keys/ecryptfs_format.h30
-rw-r--r--security/keys/encrypted.c251
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/tomoyo/Kconfig61
-rw-r--r--security/tomoyo/Makefile49
-rw-r--r--security/tomoyo/audit.c456
-rw-r--r--security/tomoyo/common.c1959
-rw-r--r--security/tomoyo/common.h1197
-rw-r--r--security/tomoyo/condition.c1035
-rw-r--r--security/tomoyo/domain.c630
-rw-r--r--security/tomoyo/file.c954
-rw-r--r--security/tomoyo/gc.c551
-rw-r--r--security/tomoyo/group.c61
-rw-r--r--security/tomoyo/load_policy.c80
-rw-r--r--security/tomoyo/memory.c173
-rw-r--r--security/tomoyo/mount.c176
-rw-r--r--security/tomoyo/realpath.c226
-rw-r--r--security/tomoyo/securityfs_if.c22
-rw-r--r--security/tomoyo/tomoyo.c238
-rw-r--r--security/tomoyo/util.c363
24 files changed, 5954 insertions, 2647 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 7312bf9f7afc..c1e18ba5bdc0 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -73,7 +73,6 @@ static int may_change_ptraced_domain(struct task_struct *task,
73 cred = get_task_cred(tracer); 73 cred = get_task_cred(tracer);
74 tracerp = aa_cred_profile(cred); 74 tracerp = aa_cred_profile(cred);
75 } 75 }
76 rcu_read_unlock();
77 76
78 /* not ptraced */ 77 /* not ptraced */
79 if (!tracer || unconfined(tracerp)) 78 if (!tracer || unconfined(tracerp))
@@ -82,6 +81,7 @@ static int may_change_ptraced_domain(struct task_struct *task,
82 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH); 81 error = aa_may_ptrace(tracer, tracerp, to_profile, PTRACE_MODE_ATTACH);
83 82
84out: 83out:
84 rcu_read_unlock();
85 if (cred) 85 if (cred)
86 put_cred(cred); 86 put_cred(cred);
87 87
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3d2fd141dff7..37832026e58a 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -127,7 +127,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
127 *inheritable = cred->cap_inheritable; 127 *inheritable = cred->cap_inheritable;
128 *permitted = cred->cap_permitted; 128 *permitted = cred->cap_permitted;
129 129
130 if (!unconfined(profile)) { 130 if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
131 *effective = cap_intersect(*effective, profile->caps.allow); 131 *effective = cap_intersect(*effective, profile->caps.allow);
132 *permitted = cap_intersect(*permitted, profile->caps.allow); 132 *permitted = cap_intersect(*permitted, profile->caps.allow);
133 } 133 }
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 1bf090a885fe..b34cc6ee6900 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) += encrypted.o 17obj-$(CONFIG_ENCRYPTED_KEYS) += ecryptfs_format.o encrypted.o
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/ecryptfs_format.c b/security/keys/ecryptfs_format.c
new file mode 100644
index 000000000000..6daa3b6ff9ed
--- /dev/null
+++ b/security/keys/ecryptfs_format.c
@@ -0,0 +1,81 @@
1/*
2 * ecryptfs_format.c: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#include <linux/module.h>
19#include "ecryptfs_format.h"
20
21u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
22{
23 return auth_tok->token.password.session_key_encryption_key;
24}
25EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
26
27/*
28 * ecryptfs_get_versions()
29 *
30 * Source code taken from the software 'ecryptfs-utils' version 83.
31 *
32 */
33void ecryptfs_get_versions(int *major, int *minor, int *file_version)
34{
35 *major = ECRYPTFS_VERSION_MAJOR;
36 *minor = ECRYPTFS_VERSION_MINOR;
37 if (file_version)
38 *file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
39}
40EXPORT_SYMBOL(ecryptfs_get_versions);
41
42/*
43 * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
44 *
45 * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
46 * The source code is inspired to the original function generate_payload()
47 * shipped with the software 'ecryptfs-utils' version 83.
48 *
49 */
50int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
51 const char *key_desc)
52{
53 int major, minor;
54
55 ecryptfs_get_versions(&major, &minor, NULL);
56 auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
57 | ((uint16_t)minor & 0x00FF));
58 auth_tok->token_type = ECRYPTFS_PASSWORD;
59 strncpy((char *)auth_tok->token.password.signature, key_desc,
60 ECRYPTFS_PASSWORD_SIG_SIZE);
61 auth_tok->token.password.session_key_encryption_key_bytes =
62 ECRYPTFS_MAX_KEY_BYTES;
63 /*
64 * Removed auth_tok->token.password.salt and
65 * auth_tok->token.password.session_key_encryption_key
66 * initialization from the original code
67 */
68 /* TODO: Make the hash parameterizable via policy */
69 auth_tok->token.password.flags |=
70 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
71 /* The kernel code will encrypt the session key. */
72 auth_tok->session_key.encrypted_key[0] = 0;
73 auth_tok->session_key.encrypted_key_size = 0;
74 /* Default; subject to change by kernel eCryptfs */
75 auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
76 auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
77 return 0;
78}
79EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
80
81MODULE_LICENSE("GPL");
diff --git a/security/keys/ecryptfs_format.h b/security/keys/ecryptfs_format.h
new file mode 100644
index 000000000000..40294de238bb
--- /dev/null
+++ b/security/keys/ecryptfs_format.h
@@ -0,0 +1,30 @@
1/*
2 * ecryptfs_format.h: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#ifndef __KEYS_ECRYPTFS_H
19#define __KEYS_ECRYPTFS_H
20
21#include <linux/ecryptfs.h>
22
23#define PGP_DIGEST_ALGO_SHA512 10
24
25u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
26void ecryptfs_get_versions(int *major, int *minor, int *file_version);
27int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
28 const char *key_desc);
29
30#endif /* __KEYS_ECRYPTFS_H */
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index b1cba5bf0a5e..e7eca9ec4c65 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2010 IBM Corporation 2 * Copyright (C) 2010 IBM Corporation
3 * Copyright (C) 2010 Politecnico di Torino, Italy
4 * TORSEC group -- http://security.polito.it
3 * 5 *
4 * Author: 6 * Authors:
5 * Mimi Zohar <zohar@us.ibm.com> 7 * Mimi Zohar <zohar@us.ibm.com>
8 * Roberto Sassu <roberto.sassu@polito.it>
6 * 9 *
7 * This program is free software; you can redistribute it and/or modify 10 * 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 11 * it under the terms of the GNU General Public License as published by
@@ -26,22 +29,27 @@
26#include <linux/rcupdate.h> 29#include <linux/rcupdate.h>
27#include <linux/scatterlist.h> 30#include <linux/scatterlist.h>
28#include <linux/crypto.h> 31#include <linux/crypto.h>
32#include <linux/ctype.h>
29#include <crypto/hash.h> 33#include <crypto/hash.h>
30#include <crypto/sha.h> 34#include <crypto/sha.h>
31#include <crypto/aes.h> 35#include <crypto/aes.h>
32 36
33#include "encrypted.h" 37#include "encrypted.h"
38#include "ecryptfs_format.h"
34 39
35static const char KEY_TRUSTED_PREFIX[] = "trusted:"; 40static const char KEY_TRUSTED_PREFIX[] = "trusted:";
36static const char KEY_USER_PREFIX[] = "user:"; 41static const char KEY_USER_PREFIX[] = "user:";
37static const char hash_alg[] = "sha256"; 42static const char hash_alg[] = "sha256";
38static const char hmac_alg[] = "hmac(sha256)"; 43static const char hmac_alg[] = "hmac(sha256)";
39static const char blkcipher_alg[] = "cbc(aes)"; 44static const char blkcipher_alg[] = "cbc(aes)";
45static const char key_format_default[] = "default";
46static const char key_format_ecryptfs[] = "ecryptfs";
40static unsigned int ivsize; 47static unsigned int ivsize;
41static int blksize; 48static int blksize;
42 49
43#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1) 50#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
44#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1) 51#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
52#define KEY_ECRYPTFS_DESC_LEN 16
45#define HASH_SIZE SHA256_DIGEST_SIZE 53#define HASH_SIZE SHA256_DIGEST_SIZE
46#define MAX_DATA_SIZE 4096 54#define MAX_DATA_SIZE 4096
47#define MIN_DATA_SIZE 20 55#define MIN_DATA_SIZE 20
@@ -58,6 +66,16 @@ enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update 66 Opt_err = -1, Opt_new, Opt_load, Opt_update
59}; 67};
60 68
69enum {
70 Opt_error = -1, Opt_default, Opt_ecryptfs
71};
72
73static const match_table_t key_format_tokens = {
74 {Opt_default, "default"},
75 {Opt_ecryptfs, "ecryptfs"},
76 {Opt_error, NULL}
77};
78
61static const match_table_t key_tokens = { 79static const match_table_t key_tokens = {
62 {Opt_new, "new"}, 80 {Opt_new, "new"},
63 {Opt_load, "load"}, 81 {Opt_load, "load"},
@@ -82,9 +100,37 @@ static int aes_get_sizes(void)
82} 100}
83 101
84/* 102/*
103 * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
104 *
105 * The description of a encrypted key with format 'ecryptfs' must contain
106 * exactly 16 hexadecimal characters.
107 *
108 */
109static int valid_ecryptfs_desc(const char *ecryptfs_desc)
110{
111 int i;
112
113 if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
114 pr_err("encrypted_key: key description must be %d hexadecimal "
115 "characters long\n", KEY_ECRYPTFS_DESC_LEN);
116 return -EINVAL;
117 }
118
119 for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
120 if (!isxdigit(ecryptfs_desc[i])) {
121 pr_err("encrypted_key: key description must contain "
122 "only hexadecimal characters\n");
123 return -EINVAL;
124 }
125 }
126
127 return 0;
128}
129
130/*
85 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key 131 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
86 * 132 *
87 * key-type:= "trusted:" | "encrypted:" 133 * key-type:= "trusted:" | "user:"
88 * desc:= master-key description 134 * desc:= master-key description
89 * 135 *
90 * Verify that 'key-type' is valid and that 'desc' exists. On key update, 136 * Verify that 'key-type' is valid and that 'desc' exists. On key update,
@@ -118,8 +164,9 @@ out:
118 * datablob_parse - parse the keyctl data 164 * datablob_parse - parse the keyctl data
119 * 165 *
120 * datablob format: 166 * datablob format:
121 * new <master-key name> <decrypted data length> 167 * new [<format>] <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data> 168 * load [<format>] <master-key name> <decrypted data length>
169 * <encrypted iv + data>
123 * update <new-master-key name> 170 * update <new-master-key name>
124 * 171 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token, 172 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,52 +174,95 @@ out:
127 * 174 *
128 * On success returns 0, otherwise -EINVAL. 175 * On success returns 0, otherwise -EINVAL.
129 */ 176 */
130static int datablob_parse(char *datablob, char **master_desc, 177static int datablob_parse(char *datablob, const char **format,
131 char **decrypted_datalen, char **hex_encoded_iv) 178 char **master_desc, char **decrypted_datalen,
179 char **hex_encoded_iv)
132{ 180{
133 substring_t args[MAX_OPT_ARGS]; 181 substring_t args[MAX_OPT_ARGS];
134 int ret = -EINVAL; 182 int ret = -EINVAL;
135 int key_cmd; 183 int key_cmd;
136 char *p; 184 int key_format;
185 char *p, *keyword;
186
187 keyword = strsep(&datablob, " \t");
188 if (!keyword) {
189 pr_info("encrypted_key: insufficient parameters specified\n");
190 return ret;
191 }
192 key_cmd = match_token(keyword, key_tokens, args);
137 193
194 /* Get optional format: default | ecryptfs */
138 p = strsep(&datablob, " \t"); 195 p = strsep(&datablob, " \t");
139 if (!p) 196 if (!p) {
197 pr_err("encrypted_key: insufficient parameters specified\n");
140 return ret; 198 return ret;
141 key_cmd = match_token(p, key_tokens, args); 199 }
142 200
143 *master_desc = strsep(&datablob, " \t"); 201 key_format = match_token(p, key_format_tokens, args);
144 if (!*master_desc) 202 switch (key_format) {
203 case Opt_ecryptfs:
204 case Opt_default:
205 *format = p;
206 *master_desc = strsep(&datablob, " \t");
207 break;
208 case Opt_error:
209 *master_desc = p;
210 break;
211 }
212
213 if (!*master_desc) {
214 pr_info("encrypted_key: master key parameter is missing\n");
145 goto out; 215 goto out;
216 }
146 217
147 if (valid_master_desc(*master_desc, NULL) < 0) 218 if (valid_master_desc(*master_desc, NULL) < 0) {
219 pr_info("encrypted_key: master key parameter \'%s\' "
220 "is invalid\n", *master_desc);
148 goto out; 221 goto out;
222 }
149 223
150 if (decrypted_datalen) { 224 if (decrypted_datalen) {
151 *decrypted_datalen = strsep(&datablob, " \t"); 225 *decrypted_datalen = strsep(&datablob, " \t");
152 if (!*decrypted_datalen) 226 if (!*decrypted_datalen) {
227 pr_info("encrypted_key: keylen parameter is missing\n");
153 goto out; 228 goto out;
229 }
154 } 230 }
155 231
156 switch (key_cmd) { 232 switch (key_cmd) {
157 case Opt_new: 233 case Opt_new:
158 if (!decrypted_datalen) 234 if (!decrypted_datalen) {
235 pr_info("encrypted_key: keyword \'%s\' not allowed "
236 "when called from .update method\n", keyword);
159 break; 237 break;
238 }
160 ret = 0; 239 ret = 0;
161 break; 240 break;
162 case Opt_load: 241 case Opt_load:
163 if (!decrypted_datalen) 242 if (!decrypted_datalen) {
243 pr_info("encrypted_key: keyword \'%s\' not allowed "
244 "when called from .update method\n", keyword);
164 break; 245 break;
246 }
165 *hex_encoded_iv = strsep(&datablob, " \t"); 247 *hex_encoded_iv = strsep(&datablob, " \t");
166 if (!*hex_encoded_iv) 248 if (!*hex_encoded_iv) {
249 pr_info("encrypted_key: hex blob is missing\n");
167 break; 250 break;
251 }
168 ret = 0; 252 ret = 0;
169 break; 253 break;
170 case Opt_update: 254 case Opt_update:
171 if (decrypted_datalen) 255 if (decrypted_datalen) {
256 pr_info("encrypted_key: keyword \'%s\' not allowed "
257 "when called from .instantiate method\n",
258 keyword);
172 break; 259 break;
260 }
173 ret = 0; 261 ret = 0;
174 break; 262 break;
175 case Opt_err: 263 case Opt_err:
264 pr_info("encrypted_key: keyword \'%s\' not recognized\n",
265 keyword);
176 break; 266 break;
177 } 267 }
178out: 268out:
@@ -197,8 +287,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
197 ascii_buf[asciiblob_len] = '\0'; 287 ascii_buf[asciiblob_len] = '\0';
198 288
199 /* copy datablob master_desc and datalen strings */ 289 /* copy datablob master_desc and datalen strings */
200 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, 290 len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
201 epayload->datalen); 291 epayload->master_desc, epayload->datalen);
202 292
203 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ 293 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
204 bufp = &ascii_buf[len]; 294 bufp = &ascii_buf[len];
@@ -378,11 +468,13 @@ static struct key *request_master_key(struct encrypted_key_payload *epayload,
378 } else 468 } else
379 goto out; 469 goto out;
380 470
381 if (IS_ERR(mkey)) 471 if (IS_ERR(mkey)) {
382 pr_info("encrypted_key: key %s not found", 472 pr_info("encrypted_key: key %s not found",
383 epayload->master_desc); 473 epayload->master_desc);
384 if (mkey) 474 goto out;
385 dump_master_key(*master_key, *master_keylen); 475 }
476
477 dump_master_key(*master_key, *master_keylen);
386out: 478out:
387 return mkey; 479 return mkey;
388} 480}
@@ -439,9 +531,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
439 if (ret < 0) 531 if (ret < 0)
440 goto out; 532 goto out;
441 533
442 digest = epayload->master_desc + epayload->datablob_len; 534 digest = epayload->format + epayload->datablob_len;
443 ret = calc_hmac(digest, derived_key, sizeof derived_key, 535 ret = calc_hmac(digest, derived_key, sizeof derived_key,
444 epayload->master_desc, epayload->datablob_len); 536 epayload->format, epayload->datablob_len);
445 if (!ret) 537 if (!ret)
446 dump_hmac(NULL, digest, HASH_SIZE); 538 dump_hmac(NULL, digest, HASH_SIZE);
447out: 539out:
@@ -450,26 +542,35 @@ out:
450 542
451/* verify HMAC before decrypting encrypted key */ 543/* verify HMAC before decrypting encrypted key */
452static int datablob_hmac_verify(struct encrypted_key_payload *epayload, 544static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
453 const u8 *master_key, size_t master_keylen) 545 const u8 *format, const u8 *master_key,
546 size_t master_keylen)
454{ 547{
455 u8 derived_key[HASH_SIZE]; 548 u8 derived_key[HASH_SIZE];
456 u8 digest[HASH_SIZE]; 549 u8 digest[HASH_SIZE];
457 int ret; 550 int ret;
551 char *p;
552 unsigned short len;
458 553
459 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); 554 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
460 if (ret < 0) 555 if (ret < 0)
461 goto out; 556 goto out;
462 557
463 ret = calc_hmac(digest, derived_key, sizeof derived_key, 558 len = epayload->datablob_len;
464 epayload->master_desc, epayload->datablob_len); 559 if (!format) {
560 p = epayload->master_desc;
561 len -= strlen(epayload->format) + 1;
562 } else
563 p = epayload->format;
564
565 ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
465 if (ret < 0) 566 if (ret < 0)
466 goto out; 567 goto out;
467 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, 568 ret = memcmp(digest, epayload->format + epayload->datablob_len,
468 sizeof digest); 569 sizeof digest);
469 if (ret) { 570 if (ret) {
470 ret = -EINVAL; 571 ret = -EINVAL;
471 dump_hmac("datablob", 572 dump_hmac("datablob",
472 epayload->master_desc + epayload->datablob_len, 573 epayload->format + epayload->datablob_len,
473 HASH_SIZE); 574 HASH_SIZE);
474 dump_hmac("calc", digest, HASH_SIZE); 575 dump_hmac("calc", digest, HASH_SIZE);
475 } 576 }
@@ -514,13 +615,16 @@ out:
514 615
515/* Allocate memory for decrypted key and datablob. */ 616/* Allocate memory for decrypted key and datablob. */
516static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, 617static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
618 const char *format,
517 const char *master_desc, 619 const char *master_desc,
518 const char *datalen) 620 const char *datalen)
519{ 621{
520 struct encrypted_key_payload *epayload = NULL; 622 struct encrypted_key_payload *epayload = NULL;
521 unsigned short datablob_len; 623 unsigned short datablob_len;
522 unsigned short decrypted_datalen; 624 unsigned short decrypted_datalen;
625 unsigned short payload_datalen;
523 unsigned int encrypted_datalen; 626 unsigned int encrypted_datalen;
627 unsigned int format_len;
524 long dlen; 628 long dlen;
525 int ret; 629 int ret;
526 630
@@ -528,29 +632,43 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
528 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) 632 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
529 return ERR_PTR(-EINVAL); 633 return ERR_PTR(-EINVAL);
530 634
635 format_len = (!format) ? strlen(key_format_default) : strlen(format);
531 decrypted_datalen = dlen; 636 decrypted_datalen = dlen;
637 payload_datalen = decrypted_datalen;
638 if (format && !strcmp(format, key_format_ecryptfs)) {
639 if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
640 pr_err("encrypted_key: keylen for the ecryptfs format "
641 "must be equal to %d bytes\n",
642 ECRYPTFS_MAX_KEY_BYTES);
643 return ERR_PTR(-EINVAL);
644 }
645 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
646 payload_datalen = sizeof(struct ecryptfs_auth_tok);
647 }
648
532 encrypted_datalen = roundup(decrypted_datalen, blksize); 649 encrypted_datalen = roundup(decrypted_datalen, blksize);
533 650
534 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 651 datablob_len = format_len + 1 + strlen(master_desc) + 1
535 + ivsize + 1 + encrypted_datalen; 652 + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
536 653
537 ret = key_payload_reserve(key, decrypted_datalen + datablob_len 654 ret = key_payload_reserve(key, payload_datalen + datablob_len
538 + HASH_SIZE + 1); 655 + HASH_SIZE + 1);
539 if (ret < 0) 656 if (ret < 0)
540 return ERR_PTR(ret); 657 return ERR_PTR(ret);
541 658
542 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + 659 epayload = kzalloc(sizeof(*epayload) + payload_datalen +
543 datablob_len + HASH_SIZE + 1, GFP_KERNEL); 660 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
544 if (!epayload) 661 if (!epayload)
545 return ERR_PTR(-ENOMEM); 662 return ERR_PTR(-ENOMEM);
546 663
664 epayload->payload_datalen = payload_datalen;
547 epayload->decrypted_datalen = decrypted_datalen; 665 epayload->decrypted_datalen = decrypted_datalen;
548 epayload->datablob_len = datablob_len; 666 epayload->datablob_len = datablob_len;
549 return epayload; 667 return epayload;
550} 668}
551 669
552static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 670static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
553 const char *hex_encoded_iv) 671 const char *format, const char *hex_encoded_iv)
554{ 672{
555 struct key *mkey; 673 struct key *mkey;
556 u8 derived_key[HASH_SIZE]; 674 u8 derived_key[HASH_SIZE];
@@ -571,14 +689,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
571 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 689 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
572 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 690 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
573 691
574 hmac = epayload->master_desc + epayload->datablob_len; 692 hmac = epayload->format + epayload->datablob_len;
575 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 693 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
576 694
577 mkey = request_master_key(epayload, &master_key, &master_keylen); 695 mkey = request_master_key(epayload, &master_key, &master_keylen);
578 if (IS_ERR(mkey)) 696 if (IS_ERR(mkey))
579 return PTR_ERR(mkey); 697 return PTR_ERR(mkey);
580 698
581 ret = datablob_hmac_verify(epayload, master_key, master_keylen); 699 ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
582 if (ret < 0) { 700 if (ret < 0) {
583 pr_err("encrypted_key: bad hmac (%d)\n", ret); 701 pr_err("encrypted_key: bad hmac (%d)\n", ret);
584 goto out; 702 goto out;
@@ -598,13 +716,28 @@ out:
598} 716}
599 717
600static void __ekey_init(struct encrypted_key_payload *epayload, 718static void __ekey_init(struct encrypted_key_payload *epayload,
601 const char *master_desc, const char *datalen) 719 const char *format, const char *master_desc,
720 const char *datalen)
602{ 721{
603 epayload->master_desc = epayload->decrypted_data 722 unsigned int format_len;
604 + epayload->decrypted_datalen; 723
724 format_len = (!format) ? strlen(key_format_default) : strlen(format);
725 epayload->format = epayload->payload_data + epayload->payload_datalen;
726 epayload->master_desc = epayload->format + format_len + 1;
605 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; 727 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
606 epayload->iv = epayload->datalen + strlen(datalen) + 1; 728 epayload->iv = epayload->datalen + strlen(datalen) + 1;
607 epayload->encrypted_data = epayload->iv + ivsize + 1; 729 epayload->encrypted_data = epayload->iv + ivsize + 1;
730 epayload->decrypted_data = epayload->payload_data;
731
732 if (!format)
733 memcpy(epayload->format, key_format_default, format_len);
734 else {
735 if (!strcmp(format, key_format_ecryptfs))
736 epayload->decrypted_data =
737 ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
738
739 memcpy(epayload->format, format, format_len);
740 }
608 741
609 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 742 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
610 memcpy(epayload->datalen, datalen, strlen(datalen)); 743 memcpy(epayload->datalen, datalen, strlen(datalen));
@@ -617,19 +750,29 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
617 * itself. For an old key, decrypt the hex encoded data. 750 * itself. For an old key, decrypt the hex encoded data.
618 */ 751 */
619static int encrypted_init(struct encrypted_key_payload *epayload, 752static int encrypted_init(struct encrypted_key_payload *epayload,
753 const char *key_desc, const char *format,
620 const char *master_desc, const char *datalen, 754 const char *master_desc, const char *datalen,
621 const char *hex_encoded_iv) 755 const char *hex_encoded_iv)
622{ 756{
623 int ret = 0; 757 int ret = 0;
624 758
625 __ekey_init(epayload, master_desc, datalen); 759 if (format && !strcmp(format, key_format_ecryptfs)) {
760 ret = valid_ecryptfs_desc(key_desc);
761 if (ret < 0)
762 return ret;
763
764 ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
765 key_desc);
766 }
767
768 __ekey_init(epayload, format, master_desc, datalen);
626 if (!hex_encoded_iv) { 769 if (!hex_encoded_iv) {
627 get_random_bytes(epayload->iv, ivsize); 770 get_random_bytes(epayload->iv, ivsize);
628 771
629 get_random_bytes(epayload->decrypted_data, 772 get_random_bytes(epayload->decrypted_data,
630 epayload->decrypted_datalen); 773 epayload->decrypted_datalen);
631 } else 774 } else
632 ret = encrypted_key_decrypt(epayload, hex_encoded_iv); 775 ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
633 return ret; 776 return ret;
634} 777}
635 778
@@ -646,6 +789,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
646{ 789{
647 struct encrypted_key_payload *epayload = NULL; 790 struct encrypted_key_payload *epayload = NULL;
648 char *datablob = NULL; 791 char *datablob = NULL;
792 const char *format = NULL;
649 char *master_desc = NULL; 793 char *master_desc = NULL;
650 char *decrypted_datalen = NULL; 794 char *decrypted_datalen = NULL;
651 char *hex_encoded_iv = NULL; 795 char *hex_encoded_iv = NULL;
@@ -659,18 +803,19 @@ static int encrypted_instantiate(struct key *key, const void *data,
659 return -ENOMEM; 803 return -ENOMEM;
660 datablob[datalen] = 0; 804 datablob[datalen] = 0;
661 memcpy(datablob, data, datalen); 805 memcpy(datablob, data, datalen);
662 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 806 ret = datablob_parse(datablob, &format, &master_desc,
663 &hex_encoded_iv); 807 &decrypted_datalen, &hex_encoded_iv);
664 if (ret < 0) 808 if (ret < 0)
665 goto out; 809 goto out;
666 810
667 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); 811 epayload = encrypted_key_alloc(key, format, master_desc,
812 decrypted_datalen);
668 if (IS_ERR(epayload)) { 813 if (IS_ERR(epayload)) {
669 ret = PTR_ERR(epayload); 814 ret = PTR_ERR(epayload);
670 goto out; 815 goto out;
671 } 816 }
672 ret = encrypted_init(epayload, master_desc, decrypted_datalen, 817 ret = encrypted_init(epayload, key->description, format, master_desc,
673 hex_encoded_iv); 818 decrypted_datalen, hex_encoded_iv);
674 if (ret < 0) { 819 if (ret < 0) {
675 kfree(epayload); 820 kfree(epayload);
676 goto out; 821 goto out;
@@ -706,6 +851,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
706 struct encrypted_key_payload *new_epayload; 851 struct encrypted_key_payload *new_epayload;
707 char *buf; 852 char *buf;
708 char *new_master_desc = NULL; 853 char *new_master_desc = NULL;
854 const char *format = NULL;
709 int ret = 0; 855 int ret = 0;
710 856
711 if (datalen <= 0 || datalen > 32767 || !data) 857 if (datalen <= 0 || datalen > 32767 || !data)
@@ -717,7 +863,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
717 863
718 buf[datalen] = 0; 864 buf[datalen] = 0;
719 memcpy(buf, data, datalen); 865 memcpy(buf, data, datalen);
720 ret = datablob_parse(buf, &new_master_desc, NULL, NULL); 866 ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
721 if (ret < 0) 867 if (ret < 0)
722 goto out; 868 goto out;
723 869
@@ -725,18 +871,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
725 if (ret < 0) 871 if (ret < 0)
726 goto out; 872 goto out;
727 873
728 new_epayload = encrypted_key_alloc(key, new_master_desc, 874 new_epayload = encrypted_key_alloc(key, epayload->format,
729 epayload->datalen); 875 new_master_desc, epayload->datalen);
730 if (IS_ERR(new_epayload)) { 876 if (IS_ERR(new_epayload)) {
731 ret = PTR_ERR(new_epayload); 877 ret = PTR_ERR(new_epayload);
732 goto out; 878 goto out;
733 } 879 }
734 880
735 __ekey_init(new_epayload, new_master_desc, epayload->datalen); 881 __ekey_init(new_epayload, epayload->format, new_master_desc,
882 epayload->datalen);
736 883
737 memcpy(new_epayload->iv, epayload->iv, ivsize); 884 memcpy(new_epayload->iv, epayload->iv, ivsize);
738 memcpy(new_epayload->decrypted_data, epayload->decrypted_data, 885 memcpy(new_epayload->payload_data, epayload->payload_data,
739 epayload->decrypted_datalen); 886 epayload->payload_datalen);
740 887
741 rcu_assign_pointer(key->payload.data, new_epayload); 888 rcu_assign_pointer(key->payload.data, new_epayload);
742 call_rcu(&epayload->rcu, encrypted_rcu_free); 889 call_rcu(&epayload->rcu, encrypted_rcu_free);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 6cff37529b80..60d4e3f5e4bb 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -251,6 +251,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
251 251
252 if (IS_ERR(authkey_ref)) { 252 if (IS_ERR(authkey_ref)) {
253 authkey = ERR_CAST(authkey_ref); 253 authkey = ERR_CAST(authkey_ref);
254 if (authkey == ERR_PTR(-EAGAIN))
255 authkey = ERR_PTR(-ENOKEY);
254 goto error; 256 goto error;
255 } 257 }
256 258
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index c8f385793235..7c7f8c16c10f 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -9,3 +9,64 @@ config SECURITY_TOMOYO
9 Required userspace tools and further information may be 9 Required userspace tools and further information may be
10 found at <http://tomoyo.sourceforge.jp/>. 10 found at <http://tomoyo.sourceforge.jp/>.
11 If you are unsure how to answer this question, answer N. 11 If you are unsure how to answer this question, answer N.
12
13config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY
14 int "Default maximal count for learning mode"
15 default 2048
16 range 0 2147483647
17 depends on SECURITY_TOMOYO
18 help
19 This is the default value for maximal ACL entries
20 that are automatically appended into policy at "learning mode".
21 Some programs access thousands of objects, so running
22 such programs in "learning mode" dulls the system response
23 and consumes much memory.
24 This is the safeguard for such programs.
25
26config SECURITY_TOMOYO_MAX_AUDIT_LOG
27 int "Default maximal count for audit log"
28 default 1024
29 range 0 2147483647
30 depends on SECURITY_TOMOYO
31 help
32 This is the default value for maximal entries for
33 audit logs that the kernel can hold on memory.
34 You can read the log via /sys/kernel/security/tomoyo/audit.
35 If you don't need audit logs, you may set this value to 0.
36
37config SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
38 bool "Activate without calling userspace policy loader."
39 default n
40 depends on SECURITY_TOMOYO
41 ---help---
42 Say Y here if you want to activate access control as soon as built-in
43 policy was loaded. This option will be useful for systems where
44 operations which can lead to the hijacking of the boot sequence are
45 needed before loading the policy. For example, you can activate
46 immediately after loading the fixed part of policy which will allow
47 only operations needed for mounting a partition which contains the
48 variant part of policy and verifying (e.g. running GPG check) and
49 loading the variant part of policy. Since you can start using
50 enforcing mode from the beginning, you can reduce the possibility of
51 hijacking the boot sequence.
52
53config SECURITY_TOMOYO_POLICY_LOADER
54 string "Location of userspace policy loader"
55 default "/sbin/tomoyo-init"
56 depends on SECURITY_TOMOYO
57 depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
58 ---help---
59 This is the default pathname of policy loader which is called before
60 activation. You can override this setting via TOMOYO_loader= kernel
61 command line option.
62
63config SECURITY_TOMOYO_ACTIVATION_TRIGGER
64 string "Trigger for calling userspace policy loader"
65 default "/sbin/init"
66 depends on SECURITY_TOMOYO
67 depends on !SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
68 ---help---
69 This is the default pathname of activation trigger.
70 You can override this setting via TOMOYO_trigger= kernel command line
71 option. For example, if you pass init=/bin/systemd option, you may
72 want to also pass TOMOYO_trigger=/bin/systemd option.
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index 91640e96bd06..95278b71fc21 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1 +1,48 @@
1obj-y = common.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 file.o gc.o group.o load_policy.o memory.o mount.o realpath.o securityfs_if.o tomoyo.o util.o
2
3$(obj)/policy/profile.conf:
4 @mkdir -p $(obj)/policy/
5 @echo Creating an empty policy/profile.conf
6 @touch $@
7
8$(obj)/policy/exception_policy.conf:
9 @mkdir -p $(obj)/policy/
10 @echo Creating a default policy/exception_policy.conf
11 @echo initialize_domain /sbin/modprobe from any >> $@
12 @echo initialize_domain /sbin/hotplug from any >> $@
13
14$(obj)/policy/domain_policy.conf:
15 @mkdir -p $(obj)/policy/
16 @echo Creating an empty policy/domain_policy.conf
17 @touch $@
18
19$(obj)/policy/manager.conf:
20 @mkdir -p $(obj)/policy/
21 @echo Creating an empty policy/manager.conf
22 @touch $@
23
24$(obj)/policy/stat.conf:
25 @mkdir -p $(obj)/policy/
26 @echo Creating an empty policy/stat.conf
27 @touch $@
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
30 @echo Generating built-in policy for TOMOYO 2.4.x.
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
33 @echo "\"\";" >> $@.tmp
34 @echo "static char tomoyo_builtin_exception_policy[] __initdata =" >> $@.tmp
35 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/exception_policy.conf >> $@.tmp
36 @echo "\"\";" >> $@.tmp
37 @echo "static char tomoyo_builtin_domain_policy[] __initdata =" >> $@.tmp
38 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/domain_policy.conf >> $@.tmp
39 @echo "\"\";" >> $@.tmp
40 @echo "static char tomoyo_builtin_manager[] __initdata =" >> $@.tmp
41 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/manager.conf >> $@.tmp
42 @echo "\"\";" >> $@.tmp
43 @echo "static char tomoyo_builtin_stat[] __initdata =" >> $@.tmp
44 @sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/"\1\\n"/' < $(obj)/policy/stat.conf >> $@.tmp
45 @echo "\"\";" >> $@.tmp
46 @mv $@.tmp $@
47
48$(obj)/common.o: $(obj)/builtin-policy.h
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
new file mode 100644
index 000000000000..5dbb1f7617c0
--- /dev/null
+++ b/security/tomoyo/audit.c
@@ -0,0 +1,456 @@
1/*
2 * security/tomoyo/audit.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/**
11 * tomoyo_print_bprm - Print "struct linux_binprm" for auditing.
12 *
13 * @bprm: Pointer to "struct linux_binprm".
14 * @dump: Pointer to "struct tomoyo_page_dump".
15 *
16 * Returns the contents of @bprm on success, NULL otherwise.
17 *
18 * This function uses kzalloc(), so caller must kfree() if this function
19 * didn't return NULL.
20 */
21static char *tomoyo_print_bprm(struct linux_binprm *bprm,
22 struct tomoyo_page_dump *dump)
23{
24 static const int tomoyo_buffer_len = 4096 * 2;
25 char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS);
26 char *cp;
27 char *last_start;
28 int len;
29 unsigned long pos = bprm->p;
30 int offset = pos % PAGE_SIZE;
31 int argv_count = bprm->argc;
32 int envp_count = bprm->envc;
33 bool truncated = false;
34 if (!buffer)
35 return NULL;
36 len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ ");
37 cp = buffer + len;
38 if (!argv_count) {
39 memmove(cp, "} envp[]={ ", 11);
40 cp += 11;
41 }
42 last_start = cp;
43 while (argv_count || envp_count) {
44 if (!tomoyo_dump_page(bprm, pos, dump))
45 goto out;
46 pos += PAGE_SIZE - offset;
47 /* Read. */
48 while (offset < PAGE_SIZE) {
49 const char *kaddr = dump->data;
50 const unsigned char c = kaddr[offset++];
51 if (cp == last_start)
52 *cp++ = '"';
53 if (cp >= buffer + tomoyo_buffer_len - 32) {
54 /* Reserve some room for "..." string. */
55 truncated = true;
56 } else if (c == '\\') {
57 *cp++ = '\\';
58 *cp++ = '\\';
59 } else if (c > ' ' && c < 127) {
60 *cp++ = c;
61 } else if (!c) {
62 *cp++ = '"';
63 *cp++ = ' ';
64 last_start = cp;
65 } else {
66 *cp++ = '\\';
67 *cp++ = (c >> 6) + '0';
68 *cp++ = ((c >> 3) & 7) + '0';
69 *cp++ = (c & 7) + '0';
70 }
71 if (c)
72 continue;
73 if (argv_count) {
74 if (--argv_count == 0) {
75 if (truncated) {
76 cp = last_start;
77 memmove(cp, "... ", 4);
78 cp += 4;
79 }
80 memmove(cp, "} envp[]={ ", 11);
81 cp += 11;
82 last_start = cp;
83 truncated = false;
84 }
85 } else if (envp_count) {
86 if (--envp_count == 0) {
87 if (truncated) {
88 cp = last_start;
89 memmove(cp, "... ", 4);
90 cp += 4;
91 }
92 }
93 }
94 if (!argv_count && !envp_count)
95 break;
96 }
97 offset = 0;
98 }
99 *cp++ = '}';
100 *cp = '\0';
101 return buffer;
102out:
103 snprintf(buffer, tomoyo_buffer_len - 1,
104 "argv[]={ ... } envp[]= { ... }");
105 return buffer;
106}
107
108/**
109 * tomoyo_filetype - Get string representation of file type.
110 *
111 * @mode: Mode value for stat().
112 *
113 * Returns file type string.
114 */
115static inline const char *tomoyo_filetype(const mode_t mode)
116{
117 switch (mode & S_IFMT) {
118 case S_IFREG:
119 case 0:
120 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
121 case S_IFDIR:
122 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
123 case S_IFLNK:
124 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
125 case S_IFIFO:
126 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
127 case S_IFSOCK:
128 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
129 case S_IFBLK:
130 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
131 case S_IFCHR:
132 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
133 }
134 return "unknown"; /* This should not happen. */
135}
136
137/**
138 * tomoyo_print_header - Get header line of audit log.
139 *
140 * @r: Pointer to "struct tomoyo_request_info".
141 *
142 * Returns string representation.
143 *
144 * This function uses kmalloc(), so caller must kfree() if this function
145 * didn't return NULL.
146 */
147static char *tomoyo_print_header(struct tomoyo_request_info *r)
148{
149 struct tomoyo_time stamp;
150 const pid_t gpid = task_pid_nr(current);
151 struct tomoyo_obj_info *obj = r->obj;
152 static const int tomoyo_buffer_len = 4096;
153 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
154 int pos;
155 u8 i;
156 if (!buffer)
157 return NULL;
158 {
159 struct timeval tv;
160 do_gettimeofday(&tv);
161 tomoyo_convert_time(tv.tv_sec, &stamp);
162 }
163 pos = snprintf(buffer, tomoyo_buffer_len - 1,
164 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
165 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
166 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
167 "fsuid=%u fsgid=%u }", stamp.year, stamp.month,
168 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
169 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
170 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
171 current_uid(), current_gid(), current_euid(),
172 current_egid(), current_suid(), current_sgid(),
173 current_fsuid(), current_fsgid());
174 if (!obj)
175 goto no_obj_info;
176 if (!obj->validate_done) {
177 tomoyo_get_attributes(obj);
178 obj->validate_done = true;
179 }
180 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
181 struct tomoyo_mini_stat *stat;
182 unsigned int dev;
183 mode_t mode;
184 if (!obj->stat_valid[i])
185 continue;
186 stat = &obj->stat[i];
187 dev = stat->dev;
188 mode = stat->mode;
189 if (i & 1) {
190 pos += snprintf(buffer + pos,
191 tomoyo_buffer_len - 1 - pos,
192 " path%u.parent={ uid=%u gid=%u "
193 "ino=%lu perm=0%o }", (i >> 1) + 1,
194 stat->uid, stat->gid, (unsigned long)
195 stat->ino, stat->mode & S_IALLUGO);
196 continue;
197 }
198 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
199 " path%u={ uid=%u gid=%u ino=%lu major=%u"
200 " minor=%u perm=0%o type=%s", (i >> 1) + 1,
201 stat->uid, stat->gid, (unsigned long)
202 stat->ino, MAJOR(dev), MINOR(dev),
203 mode & S_IALLUGO, tomoyo_filetype(mode));
204 if (S_ISCHR(mode) || S_ISBLK(mode)) {
205 dev = stat->rdev;
206 pos += snprintf(buffer + pos,
207 tomoyo_buffer_len - 1 - pos,
208 " dev_major=%u dev_minor=%u",
209 MAJOR(dev), MINOR(dev));
210 }
211 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
212 " }");
213 }
214no_obj_info:
215 if (pos < tomoyo_buffer_len - 1)
216 return buffer;
217 kfree(buffer);
218 return NULL;
219}
220
221/**
222 * tomoyo_init_log - Allocate buffer for audit logs.
223 *
224 * @r: Pointer to "struct tomoyo_request_info".
225 * @len: Buffer size needed for @fmt and @args.
226 * @fmt: The printf()'s format string.
227 * @args: va_list structure for @fmt.
228 *
229 * Returns pointer to allocated memory.
230 *
231 * This function uses kzalloc(), so caller must kfree() if this function
232 * didn't return NULL.
233 */
234char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
235 va_list args)
236{
237 char *buf = NULL;
238 char *bprm_info = NULL;
239 const char *header = NULL;
240 char *realpath = NULL;
241 const char *symlink = NULL;
242 int pos;
243 const char *domainname = r->domain->domainname->name;
244 header = tomoyo_print_header(r);
245 if (!header)
246 return NULL;
247 /* +10 is for '\n' etc. and '\0'. */
248 len += strlen(domainname) + strlen(header) + 10;
249 if (r->ee) {
250 struct file *file = r->ee->bprm->file;
251 realpath = tomoyo_realpath_from_path(&file->f_path);
252 bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump);
253 if (!realpath || !bprm_info)
254 goto out;
255 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
256 len += strlen(realpath) + 80 + strlen(bprm_info);
257 } else if (r->obj && r->obj->symlink_target) {
258 symlink = r->obj->symlink_target->name;
259 /* +18 is for " symlink.target=\"%s\"" */
260 len += 18 + strlen(symlink);
261 }
262 len = tomoyo_round2(len);
263 buf = kzalloc(len, GFP_NOFS);
264 if (!buf)
265 goto out;
266 len--;
267 pos = snprintf(buf, len, "%s", header);
268 if (realpath) {
269 struct linux_binprm *bprm = r->ee->bprm;
270 pos += snprintf(buf + pos, len - pos,
271 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
272 realpath, bprm->argc, bprm->envc, bprm_info);
273 } else if (symlink)
274 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
275 symlink);
276 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
277 vsnprintf(buf + pos, len - pos, fmt, args);
278out:
279 kfree(realpath);
280 kfree(bprm_info);
281 kfree(header);
282 return buf;
283}
284
285/* Wait queue for /sys/kernel/security/tomoyo/audit. */
286static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
287
288/* Structure for audit log. */
289struct tomoyo_log {
290 struct list_head list;
291 char *log;
292 int size;
293};
294
295/* The list for "struct tomoyo_log". */
296static LIST_HEAD(tomoyo_log);
297
298/* Lock for "struct list_head tomoyo_log". */
299static DEFINE_SPINLOCK(tomoyo_log_lock);
300
301/* Length of "stuct list_head tomoyo_log". */
302static unsigned int tomoyo_log_count;
303
304/**
305 * tomoyo_get_audit - Get audit mode.
306 *
307 * @ns: Pointer to "struct tomoyo_policy_namespace".
308 * @profile: Profile number.
309 * @index: Index number of functionality.
310 * @is_granted: True if granted log, false otherwise.
311 *
312 * Returns true if this request should be audited, false otherwise.
313 */
314static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
315 const u8 profile, const u8 index,
316 const bool is_granted)
317{
318 u8 mode;
319 const u8 category = tomoyo_index2category[index] +
320 TOMOYO_MAX_MAC_INDEX;
321 struct tomoyo_profile *p;
322 if (!tomoyo_policy_loaded)
323 return false;
324 p = tomoyo_profile(ns, profile);
325 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
326 return false;
327 mode = p->config[index];
328 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
329 mode = p->config[category];
330 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
331 mode = p->default_config;
332 if (is_granted)
333 return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
334 return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
335}
336
337/**
338 * tomoyo_write_log2 - Write an audit log.
339 *
340 * @r: Pointer to "struct tomoyo_request_info".
341 * @len: Buffer size needed for @fmt and @args.
342 * @fmt: The printf()'s format string.
343 * @args: va_list structure for @fmt.
344 *
345 * Returns nothing.
346 */
347void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
348 va_list args)
349{
350 char *buf;
351 struct tomoyo_log *entry;
352 bool quota_exceeded = false;
353 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
354 goto out;
355 buf = tomoyo_init_log(r, len, fmt, args);
356 if (!buf)
357 goto out;
358 entry = kzalloc(sizeof(*entry), GFP_NOFS);
359 if (!entry) {
360 kfree(buf);
361 goto out;
362 }
363 entry->log = buf;
364 len = tomoyo_round2(strlen(buf) + 1);
365 /*
366 * The entry->size is used for memory quota checks.
367 * Don't go beyond strlen(entry->log).
368 */
369 entry->size = len + tomoyo_round2(sizeof(*entry));
370 spin_lock(&tomoyo_log_lock);
371 if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
372 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
373 tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
374 quota_exceeded = true;
375 } else {
376 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
377 list_add_tail(&entry->list, &tomoyo_log);
378 tomoyo_log_count++;
379 }
380 spin_unlock(&tomoyo_log_lock);
381 if (quota_exceeded) {
382 kfree(buf);
383 kfree(entry);
384 goto out;
385 }
386 wake_up(&tomoyo_log_wait);
387out:
388 return;
389}
390
391/**
392 * tomoyo_write_log - Write an audit log.
393 *
394 * @r: Pointer to "struct tomoyo_request_info".
395 * @fmt: The printf()'s format string, followed by parameters.
396 *
397 * Returns nothing.
398 */
399void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
400{
401 va_list args;
402 int len;
403 va_start(args, fmt);
404 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
405 va_end(args);
406 va_start(args, fmt);
407 tomoyo_write_log2(r, len, fmt, args);
408 va_end(args);
409}
410
411/**
412 * tomoyo_read_log - Read an audit log.
413 *
414 * @head: Pointer to "struct tomoyo_io_buffer".
415 *
416 * Returns nothing.
417 */
418void tomoyo_read_log(struct tomoyo_io_buffer *head)
419{
420 struct tomoyo_log *ptr = NULL;
421 if (head->r.w_pos)
422 return;
423 kfree(head->read_buf);
424 head->read_buf = NULL;
425 spin_lock(&tomoyo_log_lock);
426 if (!list_empty(&tomoyo_log)) {
427 ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
428 list_del(&ptr->list);
429 tomoyo_log_count--;
430 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
431 }
432 spin_unlock(&tomoyo_log_lock);
433 if (ptr) {
434 head->read_buf = ptr->log;
435 head->r.w[head->r.w_pos++] = head->read_buf;
436 kfree(ptr);
437 }
438}
439
440/**
441 * tomoyo_poll_log - Wait for an audit log.
442 *
443 * @file: Pointer to "struct file".
444 * @wait: Pointer to "poll_table".
445 *
446 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
447 */
448int tomoyo_poll_log(struct file *file, poll_table *wait)
449{
450 if (tomoyo_log_count)
451 return POLLIN | POLLRDNORM;
452 poll_wait(file, &tomoyo_log_wait, wait);
453 if (tomoyo_log_count)
454 return POLLIN | POLLRDNORM;
455 return 0;
456}
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a0d09e56874b..c8439cf2a448 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/common.c 2 * security/tomoyo/common.c
3 * 3 *
4 * Common functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/uaccess.h> 7#include <linux/uaccess.h>
@@ -11,54 +9,131 @@
11#include <linux/security.h> 9#include <linux/security.h>
12#include "common.h" 10#include "common.h"
13 11
14static struct tomoyo_profile tomoyo_default_profile = { 12/* String table for operation mode. */
15 .learning = &tomoyo_default_profile.preference, 13const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
16 .permissive = &tomoyo_default_profile.preference, 14 [TOMOYO_CONFIG_DISABLED] = "disabled",
17 .enforcing = &tomoyo_default_profile.preference, 15 [TOMOYO_CONFIG_LEARNING] = "learning",
18 .preference.enforcing_verbose = true, 16 [TOMOYO_CONFIG_PERMISSIVE] = "permissive",
19 .preference.learning_max_entry = 2048, 17 [TOMOYO_CONFIG_ENFORCING] = "enforcing"
20 .preference.learning_verbose = false,
21 .preference.permissive_verbose = true
22}; 18};
23 19
24/* Profile version. Currently only 20090903 is defined. */ 20/* String table for /sys/kernel/security/tomoyo/profile */
25static unsigned int tomoyo_profile_version; 21const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
22 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
23 [TOMOYO_MAC_FILE_EXECUTE] = "execute",
24 [TOMOYO_MAC_FILE_OPEN] = "open",
25 [TOMOYO_MAC_FILE_CREATE] = "create",
26 [TOMOYO_MAC_FILE_UNLINK] = "unlink",
27 [TOMOYO_MAC_FILE_GETATTR] = "getattr",
28 [TOMOYO_MAC_FILE_MKDIR] = "mkdir",
29 [TOMOYO_MAC_FILE_RMDIR] = "rmdir",
30 [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo",
31 [TOMOYO_MAC_FILE_MKSOCK] = "mksock",
32 [TOMOYO_MAC_FILE_TRUNCATE] = "truncate",
33 [TOMOYO_MAC_FILE_SYMLINK] = "symlink",
34 [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock",
35 [TOMOYO_MAC_FILE_MKCHAR] = "mkchar",
36 [TOMOYO_MAC_FILE_LINK] = "link",
37 [TOMOYO_MAC_FILE_RENAME] = "rename",
38 [TOMOYO_MAC_FILE_CHMOD] = "chmod",
39 [TOMOYO_MAC_FILE_CHOWN] = "chown",
40 [TOMOYO_MAC_FILE_CHGRP] = "chgrp",
41 [TOMOYO_MAC_FILE_IOCTL] = "ioctl",
42 [TOMOYO_MAC_FILE_CHROOT] = "chroot",
43 [TOMOYO_MAC_FILE_MOUNT] = "mount",
44 [TOMOYO_MAC_FILE_UMOUNT] = "unmount",
45 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
46 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
47};
26 48
27/* Profile table. Memory is allocated as needed. */ 49/* String table for conditions. */
28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; 50const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
51 [TOMOYO_TASK_UID] = "task.uid",
52 [TOMOYO_TASK_EUID] = "task.euid",
53 [TOMOYO_TASK_SUID] = "task.suid",
54 [TOMOYO_TASK_FSUID] = "task.fsuid",
55 [TOMOYO_TASK_GID] = "task.gid",
56 [TOMOYO_TASK_EGID] = "task.egid",
57 [TOMOYO_TASK_SGID] = "task.sgid",
58 [TOMOYO_TASK_FSGID] = "task.fsgid",
59 [TOMOYO_TASK_PID] = "task.pid",
60 [TOMOYO_TASK_PPID] = "task.ppid",
61 [TOMOYO_EXEC_ARGC] = "exec.argc",
62 [TOMOYO_EXEC_ENVC] = "exec.envc",
63 [TOMOYO_TYPE_IS_SOCKET] = "socket",
64 [TOMOYO_TYPE_IS_SYMLINK] = "symlink",
65 [TOMOYO_TYPE_IS_FILE] = "file",
66 [TOMOYO_TYPE_IS_BLOCK_DEV] = "block",
67 [TOMOYO_TYPE_IS_DIRECTORY] = "directory",
68 [TOMOYO_TYPE_IS_CHAR_DEV] = "char",
69 [TOMOYO_TYPE_IS_FIFO] = "fifo",
70 [TOMOYO_MODE_SETUID] = "setuid",
71 [TOMOYO_MODE_SETGID] = "setgid",
72 [TOMOYO_MODE_STICKY] = "sticky",
73 [TOMOYO_MODE_OWNER_READ] = "owner_read",
74 [TOMOYO_MODE_OWNER_WRITE] = "owner_write",
75 [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute",
76 [TOMOYO_MODE_GROUP_READ] = "group_read",
77 [TOMOYO_MODE_GROUP_WRITE] = "group_write",
78 [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute",
79 [TOMOYO_MODE_OTHERS_READ] = "others_read",
80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
82 [TOMOYO_EXEC_REALPATH] = "exec.realpath",
83 [TOMOYO_SYMLINK_TARGET] = "symlink.target",
84 [TOMOYO_PATH1_UID] = "path1.uid",
85 [TOMOYO_PATH1_GID] = "path1.gid",
86 [TOMOYO_PATH1_INO] = "path1.ino",
87 [TOMOYO_PATH1_MAJOR] = "path1.major",
88 [TOMOYO_PATH1_MINOR] = "path1.minor",
89 [TOMOYO_PATH1_PERM] = "path1.perm",
90 [TOMOYO_PATH1_TYPE] = "path1.type",
91 [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major",
92 [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor",
93 [TOMOYO_PATH2_UID] = "path2.uid",
94 [TOMOYO_PATH2_GID] = "path2.gid",
95 [TOMOYO_PATH2_INO] = "path2.ino",
96 [TOMOYO_PATH2_MAJOR] = "path2.major",
97 [TOMOYO_PATH2_MINOR] = "path2.minor",
98 [TOMOYO_PATH2_PERM] = "path2.perm",
99 [TOMOYO_PATH2_TYPE] = "path2.type",
100 [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major",
101 [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor",
102 [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid",
103 [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid",
104 [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino",
105 [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm",
106 [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid",
107 [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid",
108 [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino",
109 [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm",
110};
29 111
30/* String table for functionality that takes 4 modes. */ 112/* String table for PREFERENCE keyword. */
31static const char *tomoyo_mode[4] = { 113static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
32 "disabled", "learning", "permissive", "enforcing" 114 [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log",
115 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
33}; 116};
34 117
35/* String table for /sys/kernel/security/tomoyo/profile */ 118/* String table for path operation. */
36static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 119const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
37 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 120 [TOMOYO_TYPE_EXECUTE] = "execute",
38 [TOMOYO_MAC_FILE_EXECUTE] = "file::execute", 121 [TOMOYO_TYPE_READ] = "read",
39 [TOMOYO_MAC_FILE_OPEN] = "file::open", 122 [TOMOYO_TYPE_WRITE] = "write",
40 [TOMOYO_MAC_FILE_CREATE] = "file::create", 123 [TOMOYO_TYPE_APPEND] = "append",
41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink", 124 [TOMOYO_TYPE_UNLINK] = "unlink",
42 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir", 125 [TOMOYO_TYPE_GETATTR] = "getattr",
43 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir", 126 [TOMOYO_TYPE_RMDIR] = "rmdir",
44 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo", 127 [TOMOYO_TYPE_TRUNCATE] = "truncate",
45 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock", 128 [TOMOYO_TYPE_SYMLINK] = "symlink",
46 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate", 129 [TOMOYO_TYPE_CHROOT] = "chroot",
47 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink", 130 [TOMOYO_TYPE_UMOUNT] = "unmount",
48 [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite", 131};
49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock", 132
50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar", 133/* String table for categories. */
51 [TOMOYO_MAC_FILE_LINK] = "file::link", 134static const char * const tomoyo_category_keywords
52 [TOMOYO_MAC_FILE_RENAME] = "file::rename", 135[TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
53 [TOMOYO_MAC_FILE_CHMOD] = "file::chmod", 136 [TOMOYO_MAC_CATEGORY_FILE] = "file",
54 [TOMOYO_MAC_FILE_CHOWN] = "file::chown",
55 [TOMOYO_MAC_FILE_CHGRP] = "file::chgrp",
56 [TOMOYO_MAC_FILE_IOCTL] = "file::ioctl",
57 [TOMOYO_MAC_FILE_CHROOT] = "file::chroot",
58 [TOMOYO_MAC_FILE_MOUNT] = "file::mount",
59 [TOMOYO_MAC_FILE_UMOUNT] = "file::umount",
60 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "file::pivot_root",
61 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
62}; 137};
63 138
64/* Permit policy management by non-root user? */ 139/* Permit policy management by non-root user? */
@@ -71,11 +146,20 @@ static bool tomoyo_manage_by_non_root;
71 * 146 *
72 * @value: Bool value. 147 * @value: Bool value.
73 */ 148 */
74static const char *tomoyo_yesno(const unsigned int value) 149const char *tomoyo_yesno(const unsigned int value)
75{ 150{
76 return value ? "yes" : "no"; 151 return value ? "yes" : "no";
77} 152}
78 153
154/**
155 * tomoyo_addprintf - strncat()-like-snprintf().
156 *
157 * @buffer: Buffer to write to. Must be '\0'-terminated.
158 * @len: Size of @buffer.
159 * @fmt: The printf()'s format string, followed by parameters.
160 *
161 * Returns nothing.
162 */
79static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) 163static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
80{ 164{
81 va_list args; 165 va_list args;
@@ -96,7 +180,7 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
96{ 180{
97 while (head->r.w_pos) { 181 while (head->r.w_pos) {
98 const char *w = head->r.w[0]; 182 const char *w = head->r.w[0];
99 int len = strlen(w); 183 size_t len = strlen(w);
100 if (len) { 184 if (len) {
101 if (len > head->read_user_buf_avail) 185 if (len > head->read_user_buf_avail)
102 len = head->read_user_buf_avail; 186 len = head->read_user_buf_avail;
@@ -111,7 +195,7 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
111 head->r.w[0] = w; 195 head->r.w[0] = w;
112 if (*w) 196 if (*w)
113 return false; 197 return false;
114 /* Add '\0' for query. */ 198 /* Add '\0' for audit logs and query. */
115 if (head->poll) { 199 if (head->poll) {
116 if (!head->read_user_buf_avail || 200 if (!head->read_user_buf_avail ||
117 copy_to_user(head->read_user_buf, "", 1)) 201 copy_to_user(head->read_user_buf, "", 1))
@@ -155,8 +239,8 @@ static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
155void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 239void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
156{ 240{
157 va_list args; 241 va_list args;
158 int len; 242 size_t len;
159 int pos = head->r.avail; 243 size_t pos = head->r.avail;
160 int size = head->readbuf_size - pos; 244 int size = head->readbuf_size - pos;
161 if (size <= 0) 245 if (size <= 0)
162 return; 246 return;
@@ -171,11 +255,25 @@ void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
171 tomoyo_set_string(head, head->read_buf + pos); 255 tomoyo_set_string(head, head->read_buf + pos);
172} 256}
173 257
258/**
259 * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure.
260 *
261 * @head: Pointer to "struct tomoyo_io_buffer".
262 *
263 * Returns nothing.
264 */
174static void tomoyo_set_space(struct tomoyo_io_buffer *head) 265static void tomoyo_set_space(struct tomoyo_io_buffer *head)
175{ 266{
176 tomoyo_set_string(head, " "); 267 tomoyo_set_string(head, " ");
177} 268}
178 269
270/**
271 * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure.
272 *
273 * @head: Pointer to "struct tomoyo_io_buffer".
274 *
275 * Returns nothing.
276 */
179static bool tomoyo_set_lf(struct tomoyo_io_buffer *head) 277static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
180{ 278{
181 tomoyo_set_string(head, "\n"); 279 tomoyo_set_string(head, "\n");
@@ -183,6 +281,62 @@ static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
183} 281}
184 282
185/** 283/**
284 * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure.
285 *
286 * @head: Pointer to "struct tomoyo_io_buffer".
287 *
288 * Returns nothing.
289 */
290static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
291{
292 tomoyo_set_string(head, "/");
293}
294
295/* List of namespaces. */
296LIST_HEAD(tomoyo_namespace_list);
297/* True if namespace other than tomoyo_kernel_namespace is defined. */
298static bool tomoyo_namespace_enabled;
299
300/**
301 * tomoyo_init_policy_namespace - Initialize namespace.
302 *
303 * @ns: Pointer to "struct tomoyo_policy_namespace".
304 *
305 * Returns nothing.
306 */
307void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
308{
309 unsigned int idx;
310 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
311 INIT_LIST_HEAD(&ns->acl_group[idx]);
312 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
313 INIT_LIST_HEAD(&ns->group_list[idx]);
314 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
315 INIT_LIST_HEAD(&ns->policy_list[idx]);
316 ns->profile_version = 20100903;
317 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
318 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
319}
320
321/**
322 * tomoyo_print_namespace - Print namespace header.
323 *
324 * @head: Pointer to "struct tomoyo_io_buffer".
325 *
326 * Returns nothing.
327 */
328static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
329{
330 if (!tomoyo_namespace_enabled)
331 return;
332 tomoyo_set_string(head,
333 container_of(head->r.ns,
334 struct tomoyo_policy_namespace,
335 namespace_list)->name);
336 tomoyo_set_space(head);
337}
338
339/**
186 * tomoyo_print_name_union - Print a tomoyo_name_union. 340 * tomoyo_print_name_union - Print a tomoyo_name_union.
187 * 341 *
188 * @head: Pointer to "struct tomoyo_io_buffer". 342 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -192,7 +346,7 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
192 const struct tomoyo_name_union *ptr) 346 const struct tomoyo_name_union *ptr)
193{ 347{
194 tomoyo_set_space(head); 348 tomoyo_set_space(head);
195 if (ptr->is_group) { 349 if (ptr->group) {
196 tomoyo_set_string(head, "@"); 350 tomoyo_set_string(head, "@");
197 tomoyo_set_string(head, ptr->group->group_name->name); 351 tomoyo_set_string(head, ptr->group->group_name->name);
198 } else { 352 } else {
@@ -201,24 +355,46 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
201} 355}
202 356
203/** 357/**
204 * tomoyo_print_number_union - Print a tomoyo_number_union. 358 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
205 * 359 *
206 * @head: Pointer to "struct tomoyo_io_buffer". 360 * @head: Pointer to "struct tomoyo_io_buffer".
207 * @ptr: Pointer to "struct tomoyo_number_union". 361 * @ptr: Pointer to "struct tomoyo_name_union".
362 *
363 * Returns nothing.
208 */ 364 */
209static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, 365static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
210 const struct tomoyo_number_union *ptr) 366 const struct tomoyo_name_union *ptr)
211{ 367{
212 tomoyo_set_space(head); 368 if (ptr->group) {
213 if (ptr->is_group) { 369 tomoyo_set_string(head, "@");
370 tomoyo_set_string(head, ptr->group->group_name->name);
371 } else {
372 tomoyo_set_string(head, "\"");
373 tomoyo_set_string(head, ptr->filename->name);
374 tomoyo_set_string(head, "\"");
375 }
376}
377
378/**
379 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
380 *
381 * @head: Pointer to "struct tomoyo_io_buffer".
382 * @ptr: Pointer to "struct tomoyo_number_union".
383 *
384 * Returns nothing.
385 */
386static void tomoyo_print_number_union_nospace
387(struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr)
388{
389 if (ptr->group) {
214 tomoyo_set_string(head, "@"); 390 tomoyo_set_string(head, "@");
215 tomoyo_set_string(head, ptr->group->group_name->name); 391 tomoyo_set_string(head, ptr->group->group_name->name);
216 } else { 392 } else {
217 int i; 393 int i;
218 unsigned long min = ptr->values[0]; 394 unsigned long min = ptr->values[0];
219 const unsigned long max = ptr->values[1]; 395 const unsigned long max = ptr->values[1];
220 u8 min_type = ptr->min_type; 396 u8 min_type = ptr->value_type[0];
221 const u8 max_type = ptr->max_type; 397 const u8 max_type = ptr->value_type[1];
222 char buffer[128]; 398 char buffer[128];
223 buffer[0] = '\0'; 399 buffer[0] = '\0';
224 for (i = 0; i < 2; i++) { 400 for (i = 0; i < 2; i++) {
@@ -232,8 +408,8 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
232 "0%lo", min); 408 "0%lo", min);
233 break; 409 break;
234 default: 410 default:
235 tomoyo_addprintf(buffer, sizeof(buffer), 411 tomoyo_addprintf(buffer, sizeof(buffer), "%lu",
236 "%lu", min); 412 min);
237 break; 413 break;
238 } 414 }
239 if (min == max && min_type == max_type) 415 if (min == max && min_type == max_type)
@@ -247,35 +423,53 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
247} 423}
248 424
249/** 425/**
426 * tomoyo_print_number_union - Print a tomoyo_number_union.
427 *
428 * @head: Pointer to "struct tomoyo_io_buffer".
429 * @ptr: Pointer to "struct tomoyo_number_union".
430 *
431 * Returns nothing.
432 */
433static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
434 const struct tomoyo_number_union *ptr)
435{
436 tomoyo_set_space(head);
437 tomoyo_print_number_union_nospace(head, ptr);
438}
439
440/**
250 * tomoyo_assign_profile - Create a new profile. 441 * tomoyo_assign_profile - Create a new profile.
251 * 442 *
443 * @ns: Pointer to "struct tomoyo_policy_namespace".
252 * @profile: Profile number to create. 444 * @profile: Profile number to create.
253 * 445 *
254 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 446 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
255 */ 447 */
256static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile) 448static struct tomoyo_profile *tomoyo_assign_profile
449(struct tomoyo_policy_namespace *ns, const unsigned int profile)
257{ 450{
258 struct tomoyo_profile *ptr; 451 struct tomoyo_profile *ptr;
259 struct tomoyo_profile *entry; 452 struct tomoyo_profile *entry;
260 if (profile >= TOMOYO_MAX_PROFILES) 453 if (profile >= TOMOYO_MAX_PROFILES)
261 return NULL; 454 return NULL;
262 ptr = tomoyo_profile_ptr[profile]; 455 ptr = ns->profile_ptr[profile];
263 if (ptr) 456 if (ptr)
264 return ptr; 457 return ptr;
265 entry = kzalloc(sizeof(*entry), GFP_NOFS); 458 entry = kzalloc(sizeof(*entry), GFP_NOFS);
266 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 459 if (mutex_lock_interruptible(&tomoyo_policy_lock))
267 goto out; 460 goto out;
268 ptr = tomoyo_profile_ptr[profile]; 461 ptr = ns->profile_ptr[profile];
269 if (!ptr && tomoyo_memory_ok(entry)) { 462 if (!ptr && tomoyo_memory_ok(entry)) {
270 ptr = entry; 463 ptr = entry;
271 ptr->learning = &tomoyo_default_profile.preference; 464 ptr->default_config = TOMOYO_CONFIG_DISABLED |
272 ptr->permissive = &tomoyo_default_profile.preference; 465 TOMOYO_CONFIG_WANT_GRANT_LOG |
273 ptr->enforcing = &tomoyo_default_profile.preference; 466 TOMOYO_CONFIG_WANT_REJECT_LOG;
274 ptr->default_config = TOMOYO_CONFIG_DISABLED;
275 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 467 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
276 sizeof(ptr->config)); 468 sizeof(ptr->config));
469 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024;
470 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
277 mb(); /* Avoid out-of-order execution. */ 471 mb(); /* Avoid out-of-order execution. */
278 tomoyo_profile_ptr[profile] = ptr; 472 ns->profile_ptr[profile] = ptr;
279 entry = NULL; 473 entry = NULL;
280 } 474 }
281 mutex_unlock(&tomoyo_policy_lock); 475 mutex_unlock(&tomoyo_policy_lock);
@@ -287,19 +481,29 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
287/** 481/**
288 * tomoyo_profile - Find a profile. 482 * tomoyo_profile - Find a profile.
289 * 483 *
484 * @ns: Pointer to "struct tomoyo_policy_namespace".
290 * @profile: Profile number to find. 485 * @profile: Profile number to find.
291 * 486 *
292 * Returns pointer to "struct tomoyo_profile". 487 * Returns pointer to "struct tomoyo_profile".
293 */ 488 */
294struct tomoyo_profile *tomoyo_profile(const u8 profile) 489struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
490 const u8 profile)
295{ 491{
296 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile]; 492 static struct tomoyo_profile tomoyo_null_profile;
297 if (!tomoyo_policy_loaded) 493 struct tomoyo_profile *ptr = ns->profile_ptr[profile];
298 return &tomoyo_default_profile; 494 if (!ptr)
299 BUG_ON(!ptr); 495 ptr = &tomoyo_null_profile;
300 return ptr; 496 return ptr;
301} 497}
302 498
499/**
500 * tomoyo_find_yesno - Find values for specified keyword.
501 *
502 * @string: String to check.
503 * @find: Name of keyword.
504 *
505 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
506 */
303static s8 tomoyo_find_yesno(const char *string, const char *find) 507static s8 tomoyo_find_yesno(const char *string, const char *find)
304{ 508{
305 const char *cp = strstr(string, find); 509 const char *cp = strstr(string, find);
@@ -313,18 +517,15 @@ static s8 tomoyo_find_yesno(const char *string, const char *find)
313 return -1; 517 return -1;
314} 518}
315 519
316static void tomoyo_set_bool(bool *b, const char *string, const char *find) 520/**
317{ 521 * tomoyo_set_uint - Set value for specified preference.
318 switch (tomoyo_find_yesno(string, find)) { 522 *
319 case 1: 523 * @i: Pointer to "unsigned int".
320 *b = true; 524 * @string: String to check.
321 break; 525 * @find: Name of keyword.
322 case 0: 526 *
323 *b = false; 527 * Returns nothing.
324 break; 528 */
325 }
326}
327
328static void tomoyo_set_uint(unsigned int *i, const char *string, 529static void tomoyo_set_uint(unsigned int *i, const char *string,
329 const char *find) 530 const char *find)
330{ 531{
@@ -333,51 +534,16 @@ static void tomoyo_set_uint(unsigned int *i, const char *string,
333 sscanf(cp + strlen(find), "=%u", i); 534 sscanf(cp + strlen(find), "=%u", i);
334} 535}
335 536
336static void tomoyo_set_pref(const char *name, const char *value, 537/**
337 const bool use_default, 538 * tomoyo_set_mode - Set mode for specified profile.
338 struct tomoyo_profile *profile) 539 *
339{ 540 * @name: Name of functionality.
340 struct tomoyo_preference **pref; 541 * @value: Mode for @name.
341 bool *verbose; 542 * @profile: Pointer to "struct tomoyo_profile".
342 if (!strcmp(name, "enforcing")) { 543 *
343 if (use_default) { 544 * Returns 0 on success, negative value otherwise.
344 pref = &profile->enforcing; 545 */
345 goto set_default;
346 }
347 profile->enforcing = &profile->preference;
348 verbose = &profile->preference.enforcing_verbose;
349 goto set_verbose;
350 }
351 if (!strcmp(name, "permissive")) {
352 if (use_default) {
353 pref = &profile->permissive;
354 goto set_default;
355 }
356 profile->permissive = &profile->preference;
357 verbose = &profile->preference.permissive_verbose;
358 goto set_verbose;
359 }
360 if (!strcmp(name, "learning")) {
361 if (use_default) {
362 pref = &profile->learning;
363 goto set_default;
364 }
365 profile->learning = &profile->preference;
366 tomoyo_set_uint(&profile->preference.learning_max_entry, value,
367 "max_entry");
368 verbose = &profile->preference.learning_verbose;
369 goto set_verbose;
370 }
371 return;
372 set_default:
373 *pref = &tomoyo_default_profile.preference;
374 return;
375 set_verbose:
376 tomoyo_set_bool(verbose, value, "verbose");
377}
378
379static int tomoyo_set_mode(char *name, const char *value, 546static int tomoyo_set_mode(char *name, const char *value,
380 const bool use_default,
381 struct tomoyo_profile *profile) 547 struct tomoyo_profile *profile)
382{ 548{
383 u8 i; 549 u8 i;
@@ -389,7 +555,17 @@ static int tomoyo_set_mode(char *name, const char *value,
389 config = 0; 555 config = 0;
390 for (i = 0; i < TOMOYO_MAX_MAC_INDEX 556 for (i = 0; i < TOMOYO_MAX_MAC_INDEX
391 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { 557 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
392 if (strcmp(name, tomoyo_mac_keywords[i])) 558 int len = 0;
559 if (i < TOMOYO_MAX_MAC_INDEX) {
560 const u8 c = tomoyo_index2category[i];
561 const char *category =
562 tomoyo_category_keywords[c];
563 len = strlen(category);
564 if (strncmp(name, category, len) ||
565 name[len++] != ':' || name[len++] != ':')
566 continue;
567 }
568 if (strcmp(name + len, tomoyo_mac_keywords[i]))
393 continue; 569 continue;
394 config = profile->config[i]; 570 config = profile->config[i];
395 break; 571 break;
@@ -399,7 +575,7 @@ static int tomoyo_set_mode(char *name, const char *value,
399 } else { 575 } else {
400 return -EINVAL; 576 return -EINVAL;
401 } 577 }
402 if (use_default) { 578 if (strstr(value, "use_default")) {
403 config = TOMOYO_CONFIG_USE_DEFAULT; 579 config = TOMOYO_CONFIG_USE_DEFAULT;
404 } else { 580 } else {
405 u8 mode; 581 u8 mode;
@@ -410,6 +586,24 @@ static int tomoyo_set_mode(char *name, const char *value,
410 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. 586 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
411 */ 587 */
412 config = (config & ~7) | mode; 588 config = (config & ~7) | mode;
589 if (config != TOMOYO_CONFIG_USE_DEFAULT) {
590 switch (tomoyo_find_yesno(value, "grant_log")) {
591 case 1:
592 config |= TOMOYO_CONFIG_WANT_GRANT_LOG;
593 break;
594 case 0:
595 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG;
596 break;
597 }
598 switch (tomoyo_find_yesno(value, "reject_log")) {
599 case 1:
600 config |= TOMOYO_CONFIG_WANT_REJECT_LOG;
601 break;
602 case 0:
603 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG;
604 break;
605 }
606 }
413 } 607 }
414 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 608 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
415 profile->config[i] = config; 609 profile->config[i] = config;
@@ -429,34 +623,22 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
429{ 623{
430 char *data = head->write_buf; 624 char *data = head->write_buf;
431 unsigned int i; 625 unsigned int i;
432 bool use_default = false;
433 char *cp; 626 char *cp;
434 struct tomoyo_profile *profile; 627 struct tomoyo_profile *profile;
435 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1) 628 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
629 == 1)
436 return 0; 630 return 0;
437 i = simple_strtoul(data, &cp, 10); 631 i = simple_strtoul(data, &cp, 10);
438 if (data == cp) { 632 if (*cp != '-')
439 profile = &tomoyo_default_profile; 633 return -EINVAL;
440 } else { 634 data = cp + 1;
441 if (*cp != '-') 635 profile = tomoyo_assign_profile(head->w.ns, i);
442 return -EINVAL; 636 if (!profile)
443 data = cp + 1; 637 return -EINVAL;
444 profile = tomoyo_assign_profile(i);
445 if (!profile)
446 return -EINVAL;
447 }
448 cp = strchr(data, '='); 638 cp = strchr(data, '=');
449 if (!cp) 639 if (!cp)
450 return -EINVAL; 640 return -EINVAL;
451 *cp++ = '\0'; 641 *cp++ = '\0';
452 if (profile != &tomoyo_default_profile)
453 use_default = strstr(cp, "use_default") != NULL;
454 if (tomoyo_str_starts(&data, "PREFERENCE::")) {
455 tomoyo_set_pref(data, cp, use_default, profile);
456 return 0;
457 }
458 if (profile == &tomoyo_default_profile)
459 return -EINVAL;
460 if (!strcmp(data, "COMMENT")) { 642 if (!strcmp(data, "COMMENT")) {
461 static DEFINE_SPINLOCK(lock); 643 static DEFINE_SPINLOCK(lock);
462 const struct tomoyo_path_info *new_comment 644 const struct tomoyo_path_info *new_comment
@@ -471,77 +653,62 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
471 tomoyo_put_name(old_comment); 653 tomoyo_put_name(old_comment);
472 return 0; 654 return 0;
473 } 655 }
474 return tomoyo_set_mode(data, cp, use_default, profile); 656 if (!strcmp(data, "PREFERENCE")) {
475} 657 for (i = 0; i < TOMOYO_MAX_PREF; i++)
476 658 tomoyo_set_uint(&profile->pref[i], cp,
477static void tomoyo_print_preference(struct tomoyo_io_buffer *head, 659 tomoyo_pref_keywords[i]);
478 const int idx) 660 return 0;
479{
480 struct tomoyo_preference *pref = &tomoyo_default_profile.preference;
481 const struct tomoyo_profile *profile = idx >= 0 ?
482 tomoyo_profile_ptr[idx] : NULL;
483 char buffer[16] = "";
484 if (profile) {
485 buffer[sizeof(buffer) - 1] = '\0';
486 snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
487 }
488 if (profile) {
489 pref = profile->learning;
490 if (pref == &tomoyo_default_profile.preference)
491 goto skip1;
492 }
493 tomoyo_io_printf(head, "%sPREFERENCE::%s={ "
494 "verbose=%s max_entry=%u }\n",
495 buffer, "learning",
496 tomoyo_yesno(pref->learning_verbose),
497 pref->learning_max_entry);
498 skip1:
499 if (profile) {
500 pref = profile->permissive;
501 if (pref == &tomoyo_default_profile.preference)
502 goto skip2;
503 }
504 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
505 buffer, "permissive",
506 tomoyo_yesno(pref->permissive_verbose));
507 skip2:
508 if (profile) {
509 pref = profile->enforcing;
510 if (pref == &tomoyo_default_profile.preference)
511 return;
512 } 661 }
513 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n", 662 return tomoyo_set_mode(data, cp, profile);
514 buffer, "enforcing",
515 tomoyo_yesno(pref->enforcing_verbose));
516} 663}
517 664
665/**
666 * tomoyo_print_config - Print mode for specified functionality.
667 *
668 * @head: Pointer to "struct tomoyo_io_buffer".
669 * @config: Mode for that functionality.
670 *
671 * Returns nothing.
672 *
673 * Caller prints functionality's name.
674 */
518static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 675static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
519{ 676{
520 tomoyo_io_printf(head, "={ mode=%s }\n", tomoyo_mode[config & 3]); 677 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
678 tomoyo_mode[config & 3],
679 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_GRANT_LOG),
680 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_REJECT_LOG));
521} 681}
522 682
523/** 683/**
524 * tomoyo_read_profile - Read profile table. 684 * tomoyo_read_profile - Read profile table.
525 * 685 *
526 * @head: Pointer to "struct tomoyo_io_buffer". 686 * @head: Pointer to "struct tomoyo_io_buffer".
687 *
688 * Returns nothing.
527 */ 689 */
528static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 690static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
529{ 691{
530 u8 index; 692 u8 index;
693 struct tomoyo_policy_namespace *ns =
694 container_of(head->r.ns, typeof(*ns), namespace_list);
531 const struct tomoyo_profile *profile; 695 const struct tomoyo_profile *profile;
696 if (head->r.eof)
697 return;
532 next: 698 next:
533 index = head->r.index; 699 index = head->r.index;
534 profile = tomoyo_profile_ptr[index]; 700 profile = ns->profile_ptr[index];
535 switch (head->r.step) { 701 switch (head->r.step) {
536 case 0: 702 case 0:
537 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); 703 tomoyo_print_namespace(head);
538 tomoyo_print_preference(head, -1); 704 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
705 ns->profile_version);
539 head->r.step++; 706 head->r.step++;
540 break; 707 break;
541 case 1: 708 case 1:
542 for ( ; head->r.index < TOMOYO_MAX_PROFILES; 709 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
543 head->r.index++) 710 head->r.index++)
544 if (tomoyo_profile_ptr[head->r.index]) 711 if (ns->profile_ptr[head->r.index])
545 break; 712 break;
546 if (head->r.index == TOMOYO_MAX_PROFILES) 713 if (head->r.index == TOMOYO_MAX_PROFILES)
547 return; 714 return;
@@ -549,16 +716,25 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
549 break; 716 break;
550 case 2: 717 case 2:
551 { 718 {
719 u8 i;
552 const struct tomoyo_path_info *comment = 720 const struct tomoyo_path_info *comment =
553 profile->comment; 721 profile->comment;
722 tomoyo_print_namespace(head);
554 tomoyo_io_printf(head, "%u-COMMENT=", index); 723 tomoyo_io_printf(head, "%u-COMMENT=", index);
555 tomoyo_set_string(head, comment ? comment->name : ""); 724 tomoyo_set_string(head, comment ? comment->name : "");
556 tomoyo_set_lf(head); 725 tomoyo_set_lf(head);
726 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
727 for (i = 0; i < TOMOYO_MAX_PREF; i++)
728 tomoyo_io_printf(head, "%s=%u ",
729 tomoyo_pref_keywords[i],
730 profile->pref[i]);
731 tomoyo_set_string(head, "}\n");
557 head->r.step++; 732 head->r.step++;
558 } 733 }
559 break; 734 break;
560 case 3: 735 case 3:
561 { 736 {
737 tomoyo_print_namespace(head);
562 tomoyo_io_printf(head, "%u-%s", index, "CONFIG"); 738 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
563 tomoyo_print_config(head, profile->default_config); 739 tomoyo_print_config(head, profile->default_config);
564 head->r.bit = 0; 740 head->r.bit = 0;
@@ -572,15 +748,22 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
572 const u8 config = profile->config[i]; 748 const u8 config = profile->config[i];
573 if (config == TOMOYO_CONFIG_USE_DEFAULT) 749 if (config == TOMOYO_CONFIG_USE_DEFAULT)
574 continue; 750 continue;
575 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::", 751 tomoyo_print_namespace(head);
576 tomoyo_mac_keywords[i]); 752 if (i < TOMOYO_MAX_MAC_INDEX)
753 tomoyo_io_printf(head, "%u-CONFIG::%s::%s",
754 index,
755 tomoyo_category_keywords
756 [tomoyo_index2category[i]],
757 tomoyo_mac_keywords[i]);
758 else
759 tomoyo_io_printf(head, "%u-CONFIG::%s", index,
760 tomoyo_mac_keywords[i]);
577 tomoyo_print_config(head, config); 761 tomoyo_print_config(head, config);
578 head->r.bit++; 762 head->r.bit++;
579 break; 763 break;
580 } 764 }
581 if (head->r.bit == TOMOYO_MAX_MAC_INDEX 765 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
582 + TOMOYO_MAX_MAC_CATEGORY_INDEX) { 766 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
583 tomoyo_print_preference(head, index);
584 head->r.index++; 767 head->r.index++;
585 head->r.step = 1; 768 head->r.step = 1;
586 } 769 }
@@ -590,6 +773,14 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
590 goto next; 773 goto next;
591} 774}
592 775
776/**
777 * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry.
778 *
779 * @a: Pointer to "struct tomoyo_acl_head".
780 * @b: Pointer to "struct tomoyo_acl_head".
781 *
782 * Returns true if @a == @b, false otherwise.
783 */
593static bool tomoyo_same_manager(const struct tomoyo_acl_head *a, 784static bool tomoyo_same_manager(const struct tomoyo_acl_head *a,
594 const struct tomoyo_acl_head *b) 785 const struct tomoyo_acl_head *b)
595{ 786{
@@ -611,8 +802,13 @@ static int tomoyo_update_manager_entry(const char *manager,
611 const bool is_delete) 802 const bool is_delete)
612{ 803{
613 struct tomoyo_manager e = { }; 804 struct tomoyo_manager e = { };
614 int error; 805 struct tomoyo_acl_param param = {
615 806 /* .ns = &tomoyo_kernel_namespace, */
807 .is_delete = is_delete,
808 .list = &tomoyo_kernel_namespace.
809 policy_list[TOMOYO_ID_MANAGER],
810 };
811 int error = is_delete ? -ENOENT : -ENOMEM;
616 if (tomoyo_domain_def(manager)) { 812 if (tomoyo_domain_def(manager)) {
617 if (!tomoyo_correct_domain(manager)) 813 if (!tomoyo_correct_domain(manager))
618 return -EINVAL; 814 return -EINVAL;
@@ -622,12 +818,11 @@ static int tomoyo_update_manager_entry(const char *manager,
622 return -EINVAL; 818 return -EINVAL;
623 } 819 }
624 e.manager = tomoyo_get_name(manager); 820 e.manager = tomoyo_get_name(manager);
625 if (!e.manager) 821 if (e.manager) {
626 return -ENOMEM; 822 error = tomoyo_update_policy(&e.head, sizeof(e), &param,
627 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 823 tomoyo_same_manager);
628 &tomoyo_policy_list[TOMOYO_ID_MANAGER], 824 tomoyo_put_name(e.manager);
629 tomoyo_same_manager); 825 }
630 tomoyo_put_name(e.manager);
631 return error; 826 return error;
632} 827}
633 828
@@ -643,13 +838,12 @@ static int tomoyo_update_manager_entry(const char *manager,
643static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 838static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
644{ 839{
645 char *data = head->write_buf; 840 char *data = head->write_buf;
646 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
647 841
648 if (!strcmp(data, "manage_by_non_root")) { 842 if (!strcmp(data, "manage_by_non_root")) {
649 tomoyo_manage_by_non_root = !is_delete; 843 tomoyo_manage_by_non_root = !head->w.is_delete;
650 return 0; 844 return 0;
651 } 845 }
652 return tomoyo_update_manager_entry(data, is_delete); 846 return tomoyo_update_manager_entry(data, head->w.is_delete);
653} 847}
654 848
655/** 849/**
@@ -663,8 +857,8 @@ static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
663{ 857{
664 if (head->r.eof) 858 if (head->r.eof)
665 return; 859 return;
666 list_for_each_cookie(head->r.acl, 860 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
667 &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { 861 policy_list[TOMOYO_ID_MANAGER]) {
668 struct tomoyo_manager *ptr = 862 struct tomoyo_manager *ptr =
669 list_entry(head->r.acl, typeof(*ptr), head.list); 863 list_entry(head->r.acl, typeof(*ptr), head.list);
670 if (ptr->head.is_deleted) 864 if (ptr->head.is_deleted)
@@ -697,8 +891,8 @@ static bool tomoyo_manager(void)
697 return true; 891 return true;
698 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 892 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
699 return false; 893 return false;
700 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 894 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
701 head.list) { 895 policy_list[TOMOYO_ID_MANAGER], head.list) {
702 if (!ptr->head.is_deleted && ptr->is_domain 896 if (!ptr->head.is_deleted && ptr->is_domain
703 && !tomoyo_pathcmp(domainname, ptr->manager)) { 897 && !tomoyo_pathcmp(domainname, ptr->manager)) {
704 found = true; 898 found = true;
@@ -710,8 +904,8 @@ static bool tomoyo_manager(void)
710 exe = tomoyo_get_exe(); 904 exe = tomoyo_get_exe();
711 if (!exe) 905 if (!exe)
712 return false; 906 return false;
713 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 907 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
714 head.list) { 908 policy_list[TOMOYO_ID_MANAGER], head.list) {
715 if (!ptr->head.is_deleted && !ptr->is_domain 909 if (!ptr->head.is_deleted && !ptr->is_domain
716 && !strcmp(exe, ptr->manager->name)) { 910 && !strcmp(exe, ptr->manager->name)) {
717 found = true; 911 found = true;
@@ -732,7 +926,7 @@ static bool tomoyo_manager(void)
732} 926}
733 927
734/** 928/**
735 * tomoyo_select_one - Parse select command. 929 * tomoyo_select_domain - Parse select command.
736 * 930 *
737 * @head: Pointer to "struct tomoyo_io_buffer". 931 * @head: Pointer to "struct tomoyo_io_buffer".
738 * @data: String to parse. 932 * @data: String to parse.
@@ -741,16 +935,15 @@ static bool tomoyo_manager(void)
741 * 935 *
742 * Caller holds tomoyo_read_lock(). 936 * Caller holds tomoyo_read_lock().
743 */ 937 */
744static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data) 938static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
939 const char *data)
745{ 940{
746 unsigned int pid; 941 unsigned int pid;
747 struct tomoyo_domain_info *domain = NULL; 942 struct tomoyo_domain_info *domain = NULL;
748 bool global_pid = false; 943 bool global_pid = false;
749 944 if (strncmp(data, "select ", 7))
750 if (!strcmp(data, "allow_execute")) { 945 return false;
751 head->r.print_execute_only = true; 946 data += 7;
752 return true;
753 }
754 if (sscanf(data, "pid=%u", &pid) == 1 || 947 if (sscanf(data, "pid=%u", &pid) == 1 ||
755 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 948 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
756 struct task_struct *p; 949 struct task_struct *p;
@@ -769,7 +962,7 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
769 domain = tomoyo_find_domain(data + 7); 962 domain = tomoyo_find_domain(data + 7);
770 } else 963 } else
771 return false; 964 return false;
772 head->write_var1 = domain; 965 head->w.domain = domain;
773 /* Accessing read_buf is safe because head->io_sem is held. */ 966 /* Accessing read_buf is safe because head->io_sem is held. */
774 if (!head->read_buf) 967 if (!head->read_buf)
775 return true; /* Do nothing if open(O_WRONLY). */ 968 return true; /* Do nothing if open(O_WRONLY). */
@@ -821,20 +1014,47 @@ static int tomoyo_delete_domain(char *domainname)
821/** 1014/**
822 * tomoyo_write_domain2 - Write domain policy. 1015 * tomoyo_write_domain2 - Write domain policy.
823 * 1016 *
824 * @head: Pointer to "struct tomoyo_io_buffer". 1017 * @ns: Pointer to "struct tomoyo_policy_namespace".
1018 * @list: Pointer to "struct list_head".
1019 * @data: Policy to be interpreted.
1020 * @is_delete: True if it is a delete request.
825 * 1021 *
826 * Returns 0 on success, negative value otherwise. 1022 * Returns 0 on success, negative value otherwise.
827 * 1023 *
828 * Caller holds tomoyo_read_lock(). 1024 * Caller holds tomoyo_read_lock().
829 */ 1025 */
830static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain, 1026static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
1027 struct list_head *list, char *data,
831 const bool is_delete) 1028 const bool is_delete)
832{ 1029{
833 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT)) 1030 struct tomoyo_acl_param param = {
834 return tomoyo_write_mount(data, domain, is_delete); 1031 .ns = ns,
835 return tomoyo_write_file(data, domain, is_delete); 1032 .list = list,
1033 .data = data,
1034 .is_delete = is_delete,
1035 };
1036 static const struct {
1037 const char *keyword;
1038 int (*write) (struct tomoyo_acl_param *);
1039 } tomoyo_callback[1] = {
1040 { "file ", tomoyo_write_file },
1041 };
1042 u8 i;
1043 for (i = 0; i < 1; i++) {
1044 if (!tomoyo_str_starts(&param.data,
1045 tomoyo_callback[i].keyword))
1046 continue;
1047 return tomoyo_callback[i].write(&param);
1048 }
1049 return -EINVAL;
836} 1050}
837 1051
1052/* String table for domain flags. */
1053const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = {
1054 [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n",
1055 [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n",
1056};
1057
838/** 1058/**
839 * tomoyo_write_domain - Write domain policy. 1059 * tomoyo_write_domain - Write domain policy.
840 * 1060 *
@@ -847,69 +1067,198 @@ static int tomoyo_write_domain2(char *data, struct tomoyo_domain_info *domain,
847static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 1067static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
848{ 1068{
849 char *data = head->write_buf; 1069 char *data = head->write_buf;
850 struct tomoyo_domain_info *domain = head->write_var1; 1070 struct tomoyo_policy_namespace *ns;
851 bool is_delete = false; 1071 struct tomoyo_domain_info *domain = head->w.domain;
852 bool is_select = false; 1072 const bool is_delete = head->w.is_delete;
1073 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
853 unsigned int profile; 1074 unsigned int profile;
854 1075 if (*data == '<') {
855 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
856 is_delete = true;
857 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
858 is_select = true;
859 if (is_select && tomoyo_select_one(head, data))
860 return 0;
861 /* Don't allow updating policies by non manager programs. */
862 if (!tomoyo_manager())
863 return -EPERM;
864 if (tomoyo_domain_def(data)) {
865 domain = NULL; 1076 domain = NULL;
866 if (is_delete) 1077 if (is_delete)
867 tomoyo_delete_domain(data); 1078 tomoyo_delete_domain(data);
868 else if (is_select) 1079 else if (is_select)
869 domain = tomoyo_find_domain(data); 1080 domain = tomoyo_find_domain(data);
870 else 1081 else
871 domain = tomoyo_assign_domain(data, 0); 1082 domain = tomoyo_assign_domain(data, false);
872 head->write_var1 = domain; 1083 head->w.domain = domain;
873 return 0; 1084 return 0;
874 } 1085 }
875 if (!domain) 1086 if (!domain)
876 return -EINVAL; 1087 return -EINVAL;
877 1088 ns = domain->ns;
878 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1 1089 if (sscanf(data, "use_profile %u", &profile) == 1
879 && profile < TOMOYO_MAX_PROFILES) { 1090 && profile < TOMOYO_MAX_PROFILES) {
880 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 1091 if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
881 domain->profile = (u8) profile; 1092 domain->profile = (u8) profile;
882 return 0; 1093 return 0;
883 } 1094 }
884 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1095 if (sscanf(data, "use_group %u\n", &profile) == 1
885 domain->ignore_global_allow_read = !is_delete; 1096 && profile < TOMOYO_MAX_ACL_GROUPS) {
1097 if (!is_delete)
1098 domain->group = (u8) profile;
886 return 0; 1099 return 0;
887 } 1100 }
888 if (!strcmp(data, TOMOYO_KEYWORD_QUOTA_EXCEEDED)) { 1101 for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) {
889 domain->quota_warned = !is_delete; 1102 const char *cp = tomoyo_dif[profile];
890 return 0; 1103 if (strncmp(data, cp, strlen(cp) - 1))
891 } 1104 continue;
892 if (!strcmp(data, TOMOYO_KEYWORD_TRANSITION_FAILED)) { 1105 domain->flags[profile] = !is_delete;
893 domain->transition_failed = !is_delete;
894 return 0; 1106 return 0;
895 } 1107 }
896 return tomoyo_write_domain2(data, domain, is_delete); 1108 return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
1109 is_delete);
897} 1110}
898 1111
899/** 1112/**
900 * tomoyo_fns - Find next set bit. 1113 * tomoyo_print_condition - Print condition part.
901 * 1114 *
902 * @perm: 8 bits value. 1115 * @head: Pointer to "struct tomoyo_io_buffer".
903 * @bit: First bit to find. 1116 * @cond: Pointer to "struct tomoyo_condition".
904 * 1117 *
905 * Returns next on-bit on success, 8 otherwise. 1118 * Returns true on success, false otherwise.
906 */ 1119 */
907static u8 tomoyo_fns(const u8 perm, u8 bit) 1120static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1121 const struct tomoyo_condition *cond)
908{ 1122{
909 for ( ; bit < 8; bit++) 1123 switch (head->r.cond_step) {
910 if (perm & (1 << bit)) 1124 case 0:
1125 head->r.cond_index = 0;
1126 head->r.cond_step++;
1127 /* fall through */
1128 case 1:
1129 {
1130 const u16 condc = cond->condc;
1131 const struct tomoyo_condition_element *condp =
1132 (typeof(condp)) (cond + 1);
1133 const struct tomoyo_number_union *numbers_p =
1134 (typeof(numbers_p)) (condp + condc);
1135 const struct tomoyo_name_union *names_p =
1136 (typeof(names_p))
1137 (numbers_p + cond->numbers_count);
1138 const struct tomoyo_argv *argv =
1139 (typeof(argv)) (names_p + cond->names_count);
1140 const struct tomoyo_envp *envp =
1141 (typeof(envp)) (argv + cond->argc);
1142 u16 skip;
1143 for (skip = 0; skip < head->r.cond_index; skip++) {
1144 const u8 left = condp->left;
1145 const u8 right = condp->right;
1146 condp++;
1147 switch (left) {
1148 case TOMOYO_ARGV_ENTRY:
1149 argv++;
1150 continue;
1151 case TOMOYO_ENVP_ENTRY:
1152 envp++;
1153 continue;
1154 case TOMOYO_NUMBER_UNION:
1155 numbers_p++;
1156 break;
1157 }
1158 switch (right) {
1159 case TOMOYO_NAME_UNION:
1160 names_p++;
1161 break;
1162 case TOMOYO_NUMBER_UNION:
1163 numbers_p++;
1164 break;
1165 }
1166 }
1167 while (head->r.cond_index < condc) {
1168 const u8 match = condp->equals;
1169 const u8 left = condp->left;
1170 const u8 right = condp->right;
1171 if (!tomoyo_flush(head))
1172 return false;
1173 condp++;
1174 head->r.cond_index++;
1175 tomoyo_set_space(head);
1176 switch (left) {
1177 case TOMOYO_ARGV_ENTRY:
1178 tomoyo_io_printf(head,
1179 "exec.argv[%lu]%s=\"",
1180 argv->index, argv->
1181 is_not ? "!" : "");
1182 tomoyo_set_string(head,
1183 argv->value->name);
1184 tomoyo_set_string(head, "\"");
1185 argv++;
1186 continue;
1187 case TOMOYO_ENVP_ENTRY:
1188 tomoyo_set_string(head,
1189 "exec.envp[\"");
1190 tomoyo_set_string(head,
1191 envp->name->name);
1192 tomoyo_io_printf(head, "\"]%s=", envp->
1193 is_not ? "!" : "");
1194 if (envp->value) {
1195 tomoyo_set_string(head, "\"");
1196 tomoyo_set_string(head, envp->
1197 value->name);
1198 tomoyo_set_string(head, "\"");
1199 } else {
1200 tomoyo_set_string(head,
1201 "NULL");
1202 }
1203 envp++;
1204 continue;
1205 case TOMOYO_NUMBER_UNION:
1206 tomoyo_print_number_union_nospace
1207 (head, numbers_p++);
1208 break;
1209 default:
1210 tomoyo_set_string(head,
1211 tomoyo_condition_keyword[left]);
1212 break;
1213 }
1214 tomoyo_set_string(head, match ? "=" : "!=");
1215 switch (right) {
1216 case TOMOYO_NAME_UNION:
1217 tomoyo_print_name_union_quoted
1218 (head, names_p++);
1219 break;
1220 case TOMOYO_NUMBER_UNION:
1221 tomoyo_print_number_union_nospace
1222 (head, numbers_p++);
1223 break;
1224 default:
1225 tomoyo_set_string(head,
1226 tomoyo_condition_keyword[right]);
1227 break;
1228 }
1229 }
1230 }
1231 head->r.cond_step++;
1232 /* fall through */
1233 case 2:
1234 if (!tomoyo_flush(head))
911 break; 1235 break;
912 return bit; 1236 head->r.cond_step++;
1237 /* fall through */
1238 case 3:
1239 tomoyo_set_lf(head);
1240 return true;
1241 }
1242 return false;
1243}
1244
1245/**
1246 * tomoyo_set_group - Print "acl_group " header keyword and category name.
1247 *
1248 * @head: Pointer to "struct tomoyo_io_buffer".
1249 * @category: Category name.
1250 *
1251 * Returns nothing.
1252 */
1253static void tomoyo_set_group(struct tomoyo_io_buffer *head,
1254 const char *category)
1255{
1256 if (head->type == TOMOYO_EXCEPTIONPOLICY) {
1257 tomoyo_print_namespace(head);
1258 tomoyo_io_printf(head, "acl_group %u ",
1259 head->r.acl_group_index);
1260 }
1261 tomoyo_set_string(head, category);
913} 1262}
914 1263
915/** 1264/**
@@ -924,63 +1273,96 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
924 struct tomoyo_acl_info *acl) 1273 struct tomoyo_acl_info *acl)
925{ 1274{
926 const u8 acl_type = acl->type; 1275 const u8 acl_type = acl->type;
1276 bool first = true;
927 u8 bit; 1277 u8 bit;
928 1278
1279 if (head->r.print_cond_part)
1280 goto print_cond_part;
929 if (acl->is_deleted) 1281 if (acl->is_deleted)
930 return true; 1282 return true;
931 next:
932 bit = head->r.bit;
933 if (!tomoyo_flush(head)) 1283 if (!tomoyo_flush(head))
934 return false; 1284 return false;
935 else if (acl_type == TOMOYO_TYPE_PATH_ACL) { 1285 else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
936 struct tomoyo_path_acl *ptr = 1286 struct tomoyo_path_acl *ptr =
937 container_of(acl, typeof(*ptr), head); 1287 container_of(acl, typeof(*ptr), head);
938 const u16 perm = ptr->perm; 1288 const u16 perm = ptr->perm;
939 for ( ; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 1289 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
940 if (!(perm & (1 << bit))) 1290 if (!(perm & (1 << bit)))
941 continue; 1291 continue;
942 if (head->r.print_execute_only && 1292 if (head->r.print_transition_related_only &&
943 bit != TOMOYO_TYPE_EXECUTE) 1293 bit != TOMOYO_TYPE_EXECUTE)
944 continue; 1294 continue;
945 /* Print "read/write" instead of "read" and "write". */ 1295 if (first) {
946 if ((bit == TOMOYO_TYPE_READ || 1296 tomoyo_set_group(head, "file ");
947 bit == TOMOYO_TYPE_WRITE) 1297 first = false;
948 && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) 1298 } else {
949 continue; 1299 tomoyo_set_slash(head);
950 break; 1300 }
1301 tomoyo_set_string(head, tomoyo_path_keyword[bit]);
951 } 1302 }
952 if (bit >= TOMOYO_MAX_PATH_OPERATION) 1303 if (first)
953 goto done; 1304 return true;
954 tomoyo_io_printf(head, "allow_%s", tomoyo_path_keyword[bit]);
955 tomoyo_print_name_union(head, &ptr->name); 1305 tomoyo_print_name_union(head, &ptr->name);
956 } else if (head->r.print_execute_only) { 1306 } else if (head->r.print_transition_related_only) {
957 return true; 1307 return true;
958 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1308 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
959 struct tomoyo_path2_acl *ptr = 1309 struct tomoyo_path2_acl *ptr =
960 container_of(acl, typeof(*ptr), head); 1310 container_of(acl, typeof(*ptr), head);
961 bit = tomoyo_fns(ptr->perm, bit); 1311 const u8 perm = ptr->perm;
962 if (bit >= TOMOYO_MAX_PATH2_OPERATION) 1312 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
963 goto done; 1313 if (!(perm & (1 << bit)))
964 tomoyo_io_printf(head, "allow_%s", tomoyo_path2_keyword[bit]); 1314 continue;
1315 if (first) {
1316 tomoyo_set_group(head, "file ");
1317 first = false;
1318 } else {
1319 tomoyo_set_slash(head);
1320 }
1321 tomoyo_set_string(head, tomoyo_mac_keywords
1322 [tomoyo_pp2mac[bit]]);
1323 }
1324 if (first)
1325 return true;
965 tomoyo_print_name_union(head, &ptr->name1); 1326 tomoyo_print_name_union(head, &ptr->name1);
966 tomoyo_print_name_union(head, &ptr->name2); 1327 tomoyo_print_name_union(head, &ptr->name2);
967 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { 1328 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
968 struct tomoyo_path_number_acl *ptr = 1329 struct tomoyo_path_number_acl *ptr =
969 container_of(acl, typeof(*ptr), head); 1330 container_of(acl, typeof(*ptr), head);
970 bit = tomoyo_fns(ptr->perm, bit); 1331 const u8 perm = ptr->perm;
971 if (bit >= TOMOYO_MAX_PATH_NUMBER_OPERATION) 1332 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) {
972 goto done; 1333 if (!(perm & (1 << bit)))
973 tomoyo_io_printf(head, "allow_%s", 1334 continue;
974 tomoyo_path_number_keyword[bit]); 1335 if (first) {
1336 tomoyo_set_group(head, "file ");
1337 first = false;
1338 } else {
1339 tomoyo_set_slash(head);
1340 }
1341 tomoyo_set_string(head, tomoyo_mac_keywords
1342 [tomoyo_pn2mac[bit]]);
1343 }
1344 if (first)
1345 return true;
975 tomoyo_print_name_union(head, &ptr->name); 1346 tomoyo_print_name_union(head, &ptr->name);
976 tomoyo_print_number_union(head, &ptr->number); 1347 tomoyo_print_number_union(head, &ptr->number);
977 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { 1348 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
978 struct tomoyo_mkdev_acl *ptr = 1349 struct tomoyo_mkdev_acl *ptr =
979 container_of(acl, typeof(*ptr), head); 1350 container_of(acl, typeof(*ptr), head);
980 bit = tomoyo_fns(ptr->perm, bit); 1351 const u8 perm = ptr->perm;
981 if (bit >= TOMOYO_MAX_MKDEV_OPERATION) 1352 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) {
982 goto done; 1353 if (!(perm & (1 << bit)))
983 tomoyo_io_printf(head, "allow_%s", tomoyo_mkdev_keyword[bit]); 1354 continue;
1355 if (first) {
1356 tomoyo_set_group(head, "file ");
1357 first = false;
1358 } else {
1359 tomoyo_set_slash(head);
1360 }
1361 tomoyo_set_string(head, tomoyo_mac_keywords
1362 [tomoyo_pnnn2mac[bit]]);
1363 }
1364 if (first)
1365 return true;
984 tomoyo_print_name_union(head, &ptr->name); 1366 tomoyo_print_name_union(head, &ptr->name);
985 tomoyo_print_number_union(head, &ptr->mode); 1367 tomoyo_print_number_union(head, &ptr->mode);
986 tomoyo_print_number_union(head, &ptr->major); 1368 tomoyo_print_number_union(head, &ptr->major);
@@ -988,35 +1370,41 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
988 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 1370 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
989 struct tomoyo_mount_acl *ptr = 1371 struct tomoyo_mount_acl *ptr =
990 container_of(acl, typeof(*ptr), head); 1372 container_of(acl, typeof(*ptr), head);
991 tomoyo_io_printf(head, "allow_mount"); 1373 tomoyo_set_group(head, "file mount");
992 tomoyo_print_name_union(head, &ptr->dev_name); 1374 tomoyo_print_name_union(head, &ptr->dev_name);
993 tomoyo_print_name_union(head, &ptr->dir_name); 1375 tomoyo_print_name_union(head, &ptr->dir_name);
994 tomoyo_print_name_union(head, &ptr->fs_type); 1376 tomoyo_print_name_union(head, &ptr->fs_type);
995 tomoyo_print_number_union(head, &ptr->flags); 1377 tomoyo_print_number_union(head, &ptr->flags);
996 } 1378 }
997 head->r.bit = bit + 1; 1379 if (acl->cond) {
998 tomoyo_io_printf(head, "\n"); 1380 head->r.print_cond_part = true;
999 if (acl_type != TOMOYO_TYPE_MOUNT_ACL) 1381 head->r.cond_step = 0;
1000 goto next; 1382 if (!tomoyo_flush(head))
1001 done: 1383 return false;
1002 head->r.bit = 0; 1384print_cond_part:
1385 if (!tomoyo_print_condition(head, acl->cond))
1386 return false;
1387 head->r.print_cond_part = false;
1388 } else {
1389 tomoyo_set_lf(head);
1390 }
1003 return true; 1391 return true;
1004} 1392}
1005 1393
1006/** 1394/**
1007 * tomoyo_read_domain2 - Read domain policy. 1395 * tomoyo_read_domain2 - Read domain policy.
1008 * 1396 *
1009 * @head: Pointer to "struct tomoyo_io_buffer". 1397 * @head: Pointer to "struct tomoyo_io_buffer".
1010 * @domain: Pointer to "struct tomoyo_domain_info". 1398 * @list: Pointer to "struct list_head".
1011 * 1399 *
1012 * Caller holds tomoyo_read_lock(). 1400 * Caller holds tomoyo_read_lock().
1013 * 1401 *
1014 * Returns true on success, false otherwise. 1402 * Returns true on success, false otherwise.
1015 */ 1403 */
1016static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, 1404static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
1017 struct tomoyo_domain_info *domain) 1405 struct list_head *list)
1018{ 1406{
1019 list_for_each_cookie(head->r.acl, &domain->acl_info_list) { 1407 list_for_each_cookie(head->r.acl, list) {
1020 struct tomoyo_acl_info *ptr = 1408 struct tomoyo_acl_info *ptr =
1021 list_entry(head->r.acl, typeof(*ptr), list); 1409 list_entry(head->r.acl, typeof(*ptr), list);
1022 if (!tomoyo_print_entry(head, ptr)) 1410 if (!tomoyo_print_entry(head, ptr))
@@ -1041,6 +1429,7 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1041 struct tomoyo_domain_info *domain = 1429 struct tomoyo_domain_info *domain =
1042 list_entry(head->r.domain, typeof(*domain), list); 1430 list_entry(head->r.domain, typeof(*domain), list);
1043 switch (head->r.step) { 1431 switch (head->r.step) {
1432 u8 i;
1044 case 0: 1433 case 0:
1045 if (domain->is_deleted && 1434 if (domain->is_deleted &&
1046 !head->r.print_this_domain_only) 1435 !head->r.print_this_domain_only)
@@ -1048,22 +1437,18 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1048 /* Print domainname and flags. */ 1437 /* Print domainname and flags. */
1049 tomoyo_set_string(head, domain->domainname->name); 1438 tomoyo_set_string(head, domain->domainname->name);
1050 tomoyo_set_lf(head); 1439 tomoyo_set_lf(head);
1051 tomoyo_io_printf(head, 1440 tomoyo_io_printf(head, "use_profile %u\n",
1052 TOMOYO_KEYWORD_USE_PROFILE "%u\n",
1053 domain->profile); 1441 domain->profile);
1054 if (domain->quota_warned) 1442 tomoyo_io_printf(head, "use_group %u\n",
1055 tomoyo_set_string(head, "quota_exceeded\n"); 1443 domain->group);
1056 if (domain->transition_failed) 1444 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
1057 tomoyo_set_string(head, "transition_failed\n"); 1445 if (domain->flags[i])
1058 if (domain->ignore_global_allow_read) 1446 tomoyo_set_string(head, tomoyo_dif[i]);
1059 tomoyo_set_string(head,
1060 TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
1061 "\n");
1062 head->r.step++; 1447 head->r.step++;
1063 tomoyo_set_lf(head); 1448 tomoyo_set_lf(head);
1064 /* fall through */ 1449 /* fall through */
1065 case 1: 1450 case 1:
1066 if (!tomoyo_read_domain2(head, domain)) 1451 if (!tomoyo_read_domain2(head, &domain->acl_info_list))
1067 return; 1452 return;
1068 head->r.step++; 1453 head->r.step++;
1069 if (!tomoyo_set_lf(head)) 1454 if (!tomoyo_set_lf(head))
@@ -1080,73 +1465,6 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1080} 1465}
1081 1466
1082/** 1467/**
1083 * tomoyo_write_domain_profile - Assign profile for specified domain.
1084 *
1085 * @head: Pointer to "struct tomoyo_io_buffer".
1086 *
1087 * Returns 0 on success, -EINVAL otherwise.
1088 *
1089 * This is equivalent to doing
1090 *
1091 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1092 * /usr/sbin/tomoyo-loadpolicy -d
1093 *
1094 * Caller holds tomoyo_read_lock().
1095 */
1096static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1097{
1098 char *data = head->write_buf;
1099 char *cp = strchr(data, ' ');
1100 struct tomoyo_domain_info *domain;
1101 unsigned long profile;
1102
1103 if (!cp)
1104 return -EINVAL;
1105 *cp = '\0';
1106 domain = tomoyo_find_domain(cp + 1);
1107 if (strict_strtoul(data, 10, &profile))
1108 return -EINVAL;
1109 if (domain && profile < TOMOYO_MAX_PROFILES
1110 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
1111 domain->profile = (u8) profile;
1112 return 0;
1113}
1114
1115/**
1116 * tomoyo_read_domain_profile - Read only domainname and profile.
1117 *
1118 * @head: Pointer to "struct tomoyo_io_buffer".
1119 *
1120 * Returns list of profile number and domainname pairs.
1121 *
1122 * This is equivalent to doing
1123 *
1124 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy |
1125 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1126 * domainname = $0; } else if ( $1 == "use_profile" ) {
1127 * print $2 " " domainname; domainname = ""; } } ; '
1128 *
1129 * Caller holds tomoyo_read_lock().
1130 */
1131static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1132{
1133 if (head->r.eof)
1134 return;
1135 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
1136 struct tomoyo_domain_info *domain =
1137 list_entry(head->r.domain, typeof(*domain), list);
1138 if (domain->is_deleted)
1139 continue;
1140 if (!tomoyo_flush(head))
1141 return;
1142 tomoyo_io_printf(head, "%u ", domain->profile);
1143 tomoyo_set_string(head, domain->domainname->name);
1144 tomoyo_set_lf(head);
1145 }
1146 head->r.eof = true;
1147}
1148
1149/**
1150 * tomoyo_write_pid: Specify PID to obtain domainname. 1468 * tomoyo_write_pid: Specify PID to obtain domainname.
1151 * 1469 *
1152 * @head: Pointer to "struct tomoyo_io_buffer". 1470 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1204,18 +1522,20 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1204 tomoyo_set_string(head, domain->domainname->name); 1522 tomoyo_set_string(head, domain->domainname->name);
1205} 1523}
1206 1524
1525/* String table for domain transition control keywords. */
1207static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1526static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1208 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] 1527 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
1209 = TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN, 1528 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
1210 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] 1529 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1211 = TOMOYO_KEYWORD_INITIALIZE_DOMAIN, 1530 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
1212 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = TOMOYO_KEYWORD_NO_KEEP_DOMAIN, 1531 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
1213 [TOMOYO_TRANSITION_CONTROL_KEEP] = TOMOYO_KEYWORD_KEEP_DOMAIN 1532 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ",
1214}; 1533};
1215 1534
1535/* String table for grouping keywords. */
1216static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1536static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1217 [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP, 1537 [TOMOYO_PATH_GROUP] = "path_group ",
1218 [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP 1538 [TOMOYO_NUMBER_GROUP] = "number_group ",
1219}; 1539};
1220 1540
1221/** 1541/**
@@ -1229,29 +1549,30 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1229 */ 1549 */
1230static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1550static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1231{ 1551{
1232 char *data = head->write_buf; 1552 const bool is_delete = head->w.is_delete;
1233 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1553 struct tomoyo_acl_param param = {
1234 u8 i; 1554 .ns = head->w.ns,
1235 static const struct { 1555 .is_delete = is_delete,
1236 const char *keyword; 1556 .data = head->write_buf,
1237 int (*write) (char *, const bool);
1238 } tomoyo_callback[4] = {
1239 { TOMOYO_KEYWORD_AGGREGATOR, tomoyo_write_aggregator },
1240 { TOMOYO_KEYWORD_FILE_PATTERN, tomoyo_write_pattern },
1241 { TOMOYO_KEYWORD_DENY_REWRITE, tomoyo_write_no_rewrite },
1242 { TOMOYO_KEYWORD_ALLOW_READ, tomoyo_write_globally_readable },
1243 }; 1557 };
1244 1558 u8 i;
1559 if (tomoyo_str_starts(&param.data, "aggregator "))
1560 return tomoyo_write_aggregator(&param);
1245 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1561 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
1246 if (tomoyo_str_starts(&data, tomoyo_transition_type[i])) 1562 if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
1247 return tomoyo_write_transition_control(data, is_delete, 1563 return tomoyo_write_transition_control(&param, i);
1248 i);
1249 for (i = 0; i < 4; i++)
1250 if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword))
1251 return tomoyo_callback[i].write(data, is_delete);
1252 for (i = 0; i < TOMOYO_MAX_GROUP; i++) 1564 for (i = 0; i < TOMOYO_MAX_GROUP; i++)
1253 if (tomoyo_str_starts(&data, tomoyo_group_name[i])) 1565 if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
1254 return tomoyo_write_group(data, is_delete, i); 1566 return tomoyo_write_group(&param, i);
1567 if (tomoyo_str_starts(&param.data, "acl_group ")) {
1568 unsigned int group;
1569 char *data;
1570 group = simple_strtoul(param.data, &data, 10);
1571 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1572 return tomoyo_write_domain2
1573 (head->w.ns, &head->w.ns->acl_group[group],
1574 data, is_delete);
1575 }
1255 return -EINVAL; 1576 return -EINVAL;
1256} 1577}
1257 1578
@@ -1267,9 +1588,12 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1267 */ 1588 */
1268static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1589static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1269{ 1590{
1270 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) { 1591 struct tomoyo_policy_namespace *ns =
1592 container_of(head->r.ns, typeof(*ns), namespace_list);
1593 struct list_head *list = &ns->group_list[idx];
1594 list_for_each_cookie(head->r.group, list) {
1271 struct tomoyo_group *group = 1595 struct tomoyo_group *group =
1272 list_entry(head->r.group, typeof(*group), list); 1596 list_entry(head->r.group, typeof(*group), head.list);
1273 list_for_each_cookie(head->r.acl, &group->member_list) { 1597 list_for_each_cookie(head->r.acl, &group->member_list) {
1274 struct tomoyo_acl_head *ptr = 1598 struct tomoyo_acl_head *ptr =
1275 list_entry(head->r.acl, typeof(*ptr), list); 1599 list_entry(head->r.acl, typeof(*ptr), list);
@@ -1277,6 +1601,7 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1277 continue; 1601 continue;
1278 if (!tomoyo_flush(head)) 1602 if (!tomoyo_flush(head))
1279 return false; 1603 return false;
1604 tomoyo_print_namespace(head);
1280 tomoyo_set_string(head, tomoyo_group_name[idx]); 1605 tomoyo_set_string(head, tomoyo_group_name[idx]);
1281 tomoyo_set_string(head, group->group_name->name); 1606 tomoyo_set_string(head, group->group_name->name);
1282 if (idx == TOMOYO_PATH_GROUP) { 1607 if (idx == TOMOYO_PATH_GROUP) {
@@ -1310,7 +1635,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1310 */ 1635 */
1311static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1636static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1312{ 1637{
1313 list_for_each_cookie(head->r.acl, &tomoyo_policy_list[idx]) { 1638 struct tomoyo_policy_namespace *ns =
1639 container_of(head->r.ns, typeof(*ns), namespace_list);
1640 struct list_head *list = &ns->policy_list[idx];
1641 list_for_each_cookie(head->r.acl, list) {
1314 struct tomoyo_acl_head *acl = 1642 struct tomoyo_acl_head *acl =
1315 container_of(head->r.acl, typeof(*acl), list); 1643 container_of(head->r.acl, typeof(*acl), list);
1316 if (acl->is_deleted) 1644 if (acl->is_deleted)
@@ -1322,35 +1650,23 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1322 { 1650 {
1323 struct tomoyo_transition_control *ptr = 1651 struct tomoyo_transition_control *ptr =
1324 container_of(acl, typeof(*ptr), head); 1652 container_of(acl, typeof(*ptr), head);
1325 tomoyo_set_string(head, 1653 tomoyo_print_namespace(head);
1326 tomoyo_transition_type 1654 tomoyo_set_string(head, tomoyo_transition_type
1327 [ptr->type]); 1655 [ptr->type]);
1328 if (ptr->program) 1656 tomoyo_set_string(head, ptr->program ?
1329 tomoyo_set_string(head, 1657 ptr->program->name : "any");
1330 ptr->program->name); 1658 tomoyo_set_string(head, " from ");
1331 if (ptr->program && ptr->domainname) 1659 tomoyo_set_string(head, ptr->domainname ?
1332 tomoyo_set_string(head, " from "); 1660 ptr->domainname->name :
1333 if (ptr->domainname) 1661 "any");
1334 tomoyo_set_string(head,
1335 ptr->domainname->
1336 name);
1337 }
1338 break;
1339 case TOMOYO_ID_GLOBALLY_READABLE:
1340 {
1341 struct tomoyo_readable_file *ptr =
1342 container_of(acl, typeof(*ptr), head);
1343 tomoyo_set_string(head,
1344 TOMOYO_KEYWORD_ALLOW_READ);
1345 tomoyo_set_string(head, ptr->filename->name);
1346 } 1662 }
1347 break; 1663 break;
1348 case TOMOYO_ID_AGGREGATOR: 1664 case TOMOYO_ID_AGGREGATOR:
1349 { 1665 {
1350 struct tomoyo_aggregator *ptr = 1666 struct tomoyo_aggregator *ptr =
1351 container_of(acl, typeof(*ptr), head); 1667 container_of(acl, typeof(*ptr), head);
1352 tomoyo_set_string(head, 1668 tomoyo_print_namespace(head);
1353 TOMOYO_KEYWORD_AGGREGATOR); 1669 tomoyo_set_string(head, "aggregator ");
1354 tomoyo_set_string(head, 1670 tomoyo_set_string(head,
1355 ptr->original_name->name); 1671 ptr->original_name->name);
1356 tomoyo_set_space(head); 1672 tomoyo_set_space(head);
@@ -1358,24 +1674,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1358 ptr->aggregated_name->name); 1674 ptr->aggregated_name->name);
1359 } 1675 }
1360 break; 1676 break;
1361 case TOMOYO_ID_PATTERN:
1362 {
1363 struct tomoyo_no_pattern *ptr =
1364 container_of(acl, typeof(*ptr), head);
1365 tomoyo_set_string(head,
1366 TOMOYO_KEYWORD_FILE_PATTERN);
1367 tomoyo_set_string(head, ptr->pattern->name);
1368 }
1369 break;
1370 case TOMOYO_ID_NO_REWRITE:
1371 {
1372 struct tomoyo_no_rewrite *ptr =
1373 container_of(acl, typeof(*ptr), head);
1374 tomoyo_set_string(head,
1375 TOMOYO_KEYWORD_DENY_REWRITE);
1376 tomoyo_set_string(head, ptr->pattern->name);
1377 }
1378 break;
1379 default: 1677 default:
1380 continue; 1678 continue;
1381 } 1679 }
@@ -1394,6 +1692,8 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1394 */ 1692 */
1395static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1693static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1396{ 1694{
1695 struct tomoyo_policy_namespace *ns =
1696 container_of(head->r.ns, typeof(*ns), namespace_list);
1397 if (head->r.eof) 1697 if (head->r.eof)
1398 return; 1698 return;
1399 while (head->r.step < TOMOYO_MAX_POLICY && 1699 while (head->r.step < TOMOYO_MAX_POLICY &&
@@ -1406,95 +1706,40 @@ static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1406 head->r.step++; 1706 head->r.step++;
1407 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) 1707 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1408 return; 1708 return;
1709 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP
1710 + TOMOYO_MAX_ACL_GROUPS) {
1711 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1712 - TOMOYO_MAX_GROUP;
1713 if (!tomoyo_read_domain2(head, &ns->acl_group
1714 [head->r.acl_group_index]))
1715 return;
1716 head->r.step++;
1717 }
1409 head->r.eof = true; 1718 head->r.eof = true;
1410} 1719}
1411 1720
1412/** 1721/* Wait queue for kernel -> userspace notification. */
1413 * tomoyo_print_header - Get header line of audit log.
1414 *
1415 * @r: Pointer to "struct tomoyo_request_info".
1416 *
1417 * Returns string representation.
1418 *
1419 * This function uses kmalloc(), so caller must kfree() if this function
1420 * didn't return NULL.
1421 */
1422static char *tomoyo_print_header(struct tomoyo_request_info *r)
1423{
1424 struct timeval tv;
1425 const pid_t gpid = task_pid_nr(current);
1426 static const int tomoyo_buffer_len = 4096;
1427 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
1428 pid_t ppid;
1429 if (!buffer)
1430 return NULL;
1431 do_gettimeofday(&tv);
1432 rcu_read_lock();
1433 ppid = task_tgid_vnr(current->real_parent);
1434 rcu_read_unlock();
1435 snprintf(buffer, tomoyo_buffer_len - 1,
1436 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
1437 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
1438 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
1439 tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
1440 task_tgid_vnr(current), ppid,
1441 current_uid(), current_gid(), current_euid(),
1442 current_egid(), current_suid(), current_sgid(),
1443 current_fsuid(), current_fsgid());
1444 return buffer;
1445}
1446
1447/**
1448 * tomoyo_init_audit_log - Allocate buffer for audit logs.
1449 *
1450 * @len: Required size.
1451 * @r: Pointer to "struct tomoyo_request_info".
1452 *
1453 * Returns pointer to allocated memory.
1454 *
1455 * The @len is updated to add the header lines' size on success.
1456 *
1457 * This function uses kzalloc(), so caller must kfree() if this function
1458 * didn't return NULL.
1459 */
1460static char *tomoyo_init_audit_log(int *len, struct tomoyo_request_info *r)
1461{
1462 char *buf = NULL;
1463 const char *header;
1464 const char *domainname;
1465 if (!r->domain)
1466 r->domain = tomoyo_domain();
1467 domainname = r->domain->domainname->name;
1468 header = tomoyo_print_header(r);
1469 if (!header)
1470 return NULL;
1471 *len += strlen(domainname) + strlen(header) + 10;
1472 buf = kzalloc(*len, GFP_NOFS);
1473 if (buf)
1474 snprintf(buf, (*len) - 1, "%s\n%s\n", header, domainname);
1475 kfree(header);
1476 return buf;
1477}
1478
1479/* Wait queue for tomoyo_query_list. */
1480static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait); 1722static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
1481 1723/* Wait queue for userspace -> kernel notification. */
1482/* Lock for manipulating tomoyo_query_list. */ 1724static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait);
1483static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1484 1725
1485/* Structure for query. */ 1726/* Structure for query. */
1486struct tomoyo_query { 1727struct tomoyo_query {
1487 struct list_head list; 1728 struct list_head list;
1488 char *query; 1729 char *query;
1489 int query_len; 1730 size_t query_len;
1490 unsigned int serial; 1731 unsigned int serial;
1491 int timer; 1732 u8 timer;
1492 int answer; 1733 u8 answer;
1734 u8 retry;
1493}; 1735};
1494 1736
1495/* The list for "struct tomoyo_query". */ 1737/* The list for "struct tomoyo_query". */
1496static LIST_HEAD(tomoyo_query_list); 1738static LIST_HEAD(tomoyo_query_list);
1497 1739
1740/* Lock for manipulating tomoyo_query_list. */
1741static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1742
1498/* 1743/*
1499 * Number of "struct file" referring /sys/kernel/security/tomoyo/query 1744 * Number of "struct file" referring /sys/kernel/security/tomoyo/query
1500 * interface. 1745 * interface.
@@ -1502,10 +1747,82 @@ static LIST_HEAD(tomoyo_query_list);
1502static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1747static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1503 1748
1504/** 1749/**
1750 * tomoyo_truncate - Truncate a line.
1751 *
1752 * @str: String to truncate.
1753 *
1754 * Returns length of truncated @str.
1755 */
1756static int tomoyo_truncate(char *str)
1757{
1758 char *start = str;
1759 while (*(unsigned char *) str > (unsigned char) ' ')
1760 str++;
1761 *str = '\0';
1762 return strlen(start) + 1;
1763}
1764
1765/**
1766 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1767 *
1768 * @domain: Pointer to "struct tomoyo_domain_info".
1769 * @header: Lines containing ACL.
1770 *
1771 * Returns nothing.
1772 */
1773static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1774{
1775 char *buffer;
1776 char *realpath = NULL;
1777 char *argv0 = NULL;
1778 char *symlink = NULL;
1779 char *cp = strchr(header, '\n');
1780 int len;
1781 if (!cp)
1782 return;
1783 cp = strchr(cp + 1, '\n');
1784 if (!cp)
1785 return;
1786 *cp++ = '\0';
1787 len = strlen(cp) + 1;
1788 /* strstr() will return NULL if ordering is wrong. */
1789 if (*cp == 'f') {
1790 argv0 = strstr(header, " argv[]={ \"");
1791 if (argv0) {
1792 argv0 += 10;
1793 len += tomoyo_truncate(argv0) + 14;
1794 }
1795 realpath = strstr(header, " exec={ realpath=\"");
1796 if (realpath) {
1797 realpath += 8;
1798 len += tomoyo_truncate(realpath) + 6;
1799 }
1800 symlink = strstr(header, " symlink.target=\"");
1801 if (symlink)
1802 len += tomoyo_truncate(symlink + 1) + 1;
1803 }
1804 buffer = kmalloc(len, GFP_NOFS);
1805 if (!buffer)
1806 return;
1807 snprintf(buffer, len - 1, "%s", cp);
1808 if (realpath)
1809 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
1810 if (argv0)
1811 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
1812 if (symlink)
1813 tomoyo_addprintf(buffer, len, "%s", symlink);
1814 tomoyo_normalize_line(buffer);
1815 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1816 false))
1817 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
1818 kfree(buffer);
1819}
1820
1821/**
1505 * tomoyo_supervisor - Ask for the supervisor's decision. 1822 * tomoyo_supervisor - Ask for the supervisor's decision.
1506 * 1823 *
1507 * @r: Pointer to "struct tomoyo_request_info". 1824 * @r: Pointer to "struct tomoyo_request_info".
1508 * @fmt: The printf()'s format string, followed by parameters. 1825 * @fmt: The printf()'s format string, followed by parameters.
1509 * 1826 *
1510 * Returns 0 if the supervisor decided to permit the access request which 1827 * Returns 0 if the supervisor decided to permit the access request which
1511 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the 1828 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
@@ -1515,88 +1832,79 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1515int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 1832int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1516{ 1833{
1517 va_list args; 1834 va_list args;
1518 int error = -EPERM; 1835 int error;
1519 int pos;
1520 int len; 1836 int len;
1521 static unsigned int tomoyo_serial; 1837 static unsigned int tomoyo_serial;
1522 struct tomoyo_query *entry = NULL; 1838 struct tomoyo_query entry = { };
1523 bool quota_exceeded = false; 1839 bool quota_exceeded = false;
1524 char *header; 1840 va_start(args, fmt);
1841 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
1842 va_end(args);
1843 /* Write /sys/kernel/security/tomoyo/audit. */
1844 va_start(args, fmt);
1845 tomoyo_write_log2(r, len, fmt, args);
1846 va_end(args);
1847 /* Nothing more to do if granted. */
1848 if (r->granted)
1849 return 0;
1850 if (r->mode)
1851 tomoyo_update_stat(r->mode);
1525 switch (r->mode) { 1852 switch (r->mode) {
1526 char *buffer; 1853 case TOMOYO_CONFIG_ENFORCING:
1854 error = -EPERM;
1855 if (atomic_read(&tomoyo_query_observers))
1856 break;
1857 goto out;
1527 case TOMOYO_CONFIG_LEARNING: 1858 case TOMOYO_CONFIG_LEARNING:
1528 if (!tomoyo_domain_quota_is_ok(r)) 1859 error = 0;
1529 return 0; 1860 /* Check max_learning_entry parameter. */
1530 va_start(args, fmt); 1861 if (tomoyo_domain_quota_is_ok(r))
1531 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4; 1862 break;
1532 va_end(args);
1533 buffer = kmalloc(len, GFP_NOFS);
1534 if (!buffer)
1535 return 0;
1536 va_start(args, fmt);
1537 vsnprintf(buffer, len - 1, fmt, args);
1538 va_end(args);
1539 tomoyo_normalize_line(buffer);
1540 tomoyo_write_domain2(buffer, r->domain, false);
1541 kfree(buffer);
1542 /* fall through */ 1863 /* fall through */
1543 case TOMOYO_CONFIG_PERMISSIVE: 1864 default:
1544 return 0; 1865 return 0;
1545 } 1866 }
1546 if (!r->domain) 1867 /* Get message. */
1547 r->domain = tomoyo_domain();
1548 if (!atomic_read(&tomoyo_query_observers))
1549 return -EPERM;
1550 va_start(args, fmt); 1868 va_start(args, fmt);
1551 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32; 1869 entry.query = tomoyo_init_log(r, len, fmt, args);
1552 va_end(args); 1870 va_end(args);
1553 header = tomoyo_init_audit_log(&len, r); 1871 if (!entry.query)
1554 if (!header)
1555 goto out; 1872 goto out;
1556 entry = kzalloc(sizeof(*entry), GFP_NOFS); 1873 entry.query_len = strlen(entry.query) + 1;
1557 if (!entry) 1874 if (!error) {
1875 tomoyo_add_entry(r->domain, entry.query);
1558 goto out; 1876 goto out;
1559 entry->query = kzalloc(len, GFP_NOFS); 1877 }
1560 if (!entry->query) 1878 len = tomoyo_round2(entry.query_len);
1561 goto out;
1562 len = ksize(entry->query);
1563 spin_lock(&tomoyo_query_list_lock); 1879 spin_lock(&tomoyo_query_list_lock);
1564 if (tomoyo_quota_for_query && tomoyo_query_memory_size + len + 1880 if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
1565 sizeof(*entry) >= tomoyo_quota_for_query) { 1881 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
1882 >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
1566 quota_exceeded = true; 1883 quota_exceeded = true;
1567 } else { 1884 } else {
1568 tomoyo_query_memory_size += len + sizeof(*entry); 1885 entry.serial = tomoyo_serial++;
1569 entry->serial = tomoyo_serial++; 1886 entry.retry = r->retry;
1887 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
1888 list_add_tail(&entry.list, &tomoyo_query_list);
1570 } 1889 }
1571 spin_unlock(&tomoyo_query_list_lock); 1890 spin_unlock(&tomoyo_query_list_lock);
1572 if (quota_exceeded) 1891 if (quota_exceeded)
1573 goto out; 1892 goto out;
1574 pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
1575 entry->serial, r->retry, header);
1576 kfree(header);
1577 header = NULL;
1578 va_start(args, fmt);
1579 vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
1580 entry->query_len = strlen(entry->query) + 1;
1581 va_end(args);
1582 spin_lock(&tomoyo_query_list_lock);
1583 list_add_tail(&entry->list, &tomoyo_query_list);
1584 spin_unlock(&tomoyo_query_list_lock);
1585 /* Give 10 seconds for supervisor's opinion. */ 1893 /* Give 10 seconds for supervisor's opinion. */
1586 for (entry->timer = 0; 1894 while (entry.timer < 10) {
1587 atomic_read(&tomoyo_query_observers) && entry->timer < 100; 1895 wake_up_all(&tomoyo_query_wait);
1588 entry->timer++) { 1896 if (wait_event_interruptible_timeout
1589 wake_up(&tomoyo_query_wait); 1897 (tomoyo_answer_wait, entry.answer ||
1590 set_current_state(TASK_INTERRUPTIBLE); 1898 !atomic_read(&tomoyo_query_observers), HZ))
1591 schedule_timeout(HZ / 10);
1592 if (entry->answer)
1593 break; 1899 break;
1900 else
1901 entry.timer++;
1594 } 1902 }
1595 spin_lock(&tomoyo_query_list_lock); 1903 spin_lock(&tomoyo_query_list_lock);
1596 list_del(&entry->list); 1904 list_del(&entry.list);
1597 tomoyo_query_memory_size -= len + sizeof(*entry); 1905 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
1598 spin_unlock(&tomoyo_query_list_lock); 1906 spin_unlock(&tomoyo_query_list_lock);
1599 switch (entry->answer) { 1907 switch (entry.answer) {
1600 case 3: /* Asked to retry by administrator. */ 1908 case 3: /* Asked to retry by administrator. */
1601 error = TOMOYO_RETRY_REQUEST; 1909 error = TOMOYO_RETRY_REQUEST;
1602 r->retry++; 1910 r->retry++;
@@ -1605,18 +1913,12 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1605 /* Granted by administrator. */ 1913 /* Granted by administrator. */
1606 error = 0; 1914 error = 0;
1607 break; 1915 break;
1608 case 0:
1609 /* Timed out. */
1610 break;
1611 default: 1916 default:
1612 /* Rejected by administrator. */ 1917 /* Timed out or rejected by administrator. */
1613 break; 1918 break;
1614 } 1919 }
1615 out: 1920out:
1616 if (entry) 1921 kfree(entry.query);
1617 kfree(entry->query);
1618 kfree(entry);
1619 kfree(header);
1620 return error; 1922 return error;
1621} 1923}
1622 1924
@@ -1663,8 +1965,8 @@ static int tomoyo_poll_query(struct file *file, poll_table *wait)
1663static void tomoyo_read_query(struct tomoyo_io_buffer *head) 1965static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1664{ 1966{
1665 struct list_head *tmp; 1967 struct list_head *tmp;
1666 int pos = 0; 1968 unsigned int pos = 0;
1667 int len = 0; 1969 size_t len = 0;
1668 char *buf; 1970 char *buf;
1669 if (head->r.w_pos) 1971 if (head->r.w_pos)
1670 return; 1972 return;
@@ -1687,7 +1989,7 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1687 head->r.query_index = 0; 1989 head->r.query_index = 0;
1688 return; 1990 return;
1689 } 1991 }
1690 buf = kzalloc(len, GFP_NOFS); 1992 buf = kzalloc(len + 32, GFP_NOFS);
1691 if (!buf) 1993 if (!buf)
1692 return; 1994 return;
1693 pos = 0; 1995 pos = 0;
@@ -1703,7 +2005,8 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1703 * can change, but I don't care. 2005 * can change, but I don't care.
1704 */ 2006 */
1705 if (len == ptr->query_len) 2007 if (len == ptr->query_len)
1706 memmove(buf, ptr->query, len); 2008 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
2009 ptr->retry, ptr->query);
1707 break; 2010 break;
1708 } 2011 }
1709 spin_unlock(&tomoyo_query_list_lock); 2012 spin_unlock(&tomoyo_query_list_lock);
@@ -1760,7 +2063,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1760static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2063static void tomoyo_read_version(struct tomoyo_io_buffer *head)
1761{ 2064{
1762 if (!head->r.eof) { 2065 if (!head->r.eof) {
1763 tomoyo_io_printf(head, "2.3.0"); 2066 tomoyo_io_printf(head, "2.4.0");
1764 head->r.eof = true; 2067 head->r.eof = true;
1765 } 2068 }
1766} 2069}
@@ -1785,15 +2088,111 @@ static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1785 } 2088 }
1786} 2089}
1787 2090
2091/* String table for /sys/kernel/security/tomoyo/stat interface. */
2092static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
2093 [TOMOYO_STAT_POLICY_UPDATES] = "update:",
2094 [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
2095 [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
2096 [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
2097};
2098
2099/* String table for /sys/kernel/security/tomoyo/stat interface. */
2100static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
2101 [TOMOYO_MEMORY_POLICY] = "policy:",
2102 [TOMOYO_MEMORY_AUDIT] = "audit log:",
2103 [TOMOYO_MEMORY_QUERY] = "query message:",
2104};
2105
2106/* Timestamp counter for last updated. */
2107static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
2108/* Counter for number of updates. */
2109static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
2110
2111/**
2112 * tomoyo_update_stat - Update statistic counters.
2113 *
2114 * @index: Index for policy type.
2115 *
2116 * Returns nothing.
2117 */
2118void tomoyo_update_stat(const u8 index)
2119{
2120 struct timeval tv;
2121 do_gettimeofday(&tv);
2122 /*
2123 * I don't use atomic operations because race condition is not fatal.
2124 */
2125 tomoyo_stat_updated[index]++;
2126 tomoyo_stat_modified[index] = tv.tv_sec;
2127}
2128
2129/**
2130 * tomoyo_read_stat - Read statistic data.
2131 *
2132 * @head: Pointer to "struct tomoyo_io_buffer".
2133 *
2134 * Returns nothing.
2135 */
2136static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
2137{
2138 u8 i;
2139 unsigned int total = 0;
2140 if (head->r.eof)
2141 return;
2142 for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
2143 tomoyo_io_printf(head, "Policy %-30s %10u",
2144 tomoyo_policy_headers[i],
2145 tomoyo_stat_updated[i]);
2146 if (tomoyo_stat_modified[i]) {
2147 struct tomoyo_time stamp;
2148 tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
2149 tomoyo_io_printf(head, " (Last: %04u/%02u/%02u "
2150 "%02u:%02u:%02u)",
2151 stamp.year, stamp.month, stamp.day,
2152 stamp.hour, stamp.min, stamp.sec);
2153 }
2154 tomoyo_set_lf(head);
2155 }
2156 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
2157 unsigned int used = tomoyo_memory_used[i];
2158 total += used;
2159 tomoyo_io_printf(head, "Memory used by %-22s %10u",
2160 tomoyo_memory_headers[i], used);
2161 used = tomoyo_memory_quota[i];
2162 if (used)
2163 tomoyo_io_printf(head, " (Quota: %10u)", used);
2164 tomoyo_set_lf(head);
2165 }
2166 tomoyo_io_printf(head, "Total memory used: %10u\n",
2167 total);
2168 head->r.eof = true;
2169}
2170
2171/**
2172 * tomoyo_write_stat - Set memory quota.
2173 *
2174 * @head: Pointer to "struct tomoyo_io_buffer".
2175 *
2176 * Returns 0.
2177 */
2178static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
2179{
2180 char *data = head->write_buf;
2181 u8 i;
2182 if (tomoyo_str_starts(&data, "Memory used by "))
2183 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
2184 if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
2185 sscanf(data, "%u", &tomoyo_memory_quota[i]);
2186 return 0;
2187}
2188
1788/** 2189/**
1789 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 2190 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
1790 * 2191 *
1791 * @type: Type of interface. 2192 * @type: Type of interface.
1792 * @file: Pointer to "struct file". 2193 * @file: Pointer to "struct file".
1793 * 2194 *
1794 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 2195 * Returns 0 on success, negative value otherwise.
1795 *
1796 * Caller acquires tomoyo_read_lock().
1797 */ 2196 */
1798int tomoyo_open_control(const u8 type, struct file *file) 2197int tomoyo_open_control(const u8 type, struct file *file)
1799{ 2198{
@@ -1814,15 +2213,15 @@ int tomoyo_open_control(const u8 type, struct file *file)
1814 head->write = tomoyo_write_exception; 2213 head->write = tomoyo_write_exception;
1815 head->read = tomoyo_read_exception; 2214 head->read = tomoyo_read_exception;
1816 break; 2215 break;
2216 case TOMOYO_AUDIT:
2217 /* /sys/kernel/security/tomoyo/audit */
2218 head->poll = tomoyo_poll_log;
2219 head->read = tomoyo_read_log;
2220 break;
1817 case TOMOYO_SELFDOMAIN: 2221 case TOMOYO_SELFDOMAIN:
1818 /* /sys/kernel/security/tomoyo/self_domain */ 2222 /* /sys/kernel/security/tomoyo/self_domain */
1819 head->read = tomoyo_read_self_domain; 2223 head->read = tomoyo_read_self_domain;
1820 break; 2224 break;
1821 case TOMOYO_DOMAIN_STATUS:
1822 /* /sys/kernel/security/tomoyo/.domain_status */
1823 head->write = tomoyo_write_domain_profile;
1824 head->read = tomoyo_read_domain_profile;
1825 break;
1826 case TOMOYO_PROCESS_STATUS: 2225 case TOMOYO_PROCESS_STATUS:
1827 /* /sys/kernel/security/tomoyo/.process_status */ 2226 /* /sys/kernel/security/tomoyo/.process_status */
1828 head->write = tomoyo_write_pid; 2227 head->write = tomoyo_write_pid;
@@ -1833,11 +2232,11 @@ int tomoyo_open_control(const u8 type, struct file *file)
1833 head->read = tomoyo_read_version; 2232 head->read = tomoyo_read_version;
1834 head->readbuf_size = 128; 2233 head->readbuf_size = 128;
1835 break; 2234 break;
1836 case TOMOYO_MEMINFO: 2235 case TOMOYO_STAT:
1837 /* /sys/kernel/security/tomoyo/meminfo */ 2236 /* /sys/kernel/security/tomoyo/stat */
1838 head->write = tomoyo_write_memory_quota; 2237 head->write = tomoyo_write_stat;
1839 head->read = tomoyo_read_memory_counter; 2238 head->read = tomoyo_read_stat;
1840 head->readbuf_size = 512; 2239 head->readbuf_size = 1024;
1841 break; 2240 break;
1842 case TOMOYO_PROFILE: 2241 case TOMOYO_PROFILE:
1843 /* /sys/kernel/security/tomoyo/profile */ 2242 /* /sys/kernel/security/tomoyo/profile */
@@ -1887,26 +2286,16 @@ int tomoyo_open_control(const u8 type, struct file *file)
1887 return -ENOMEM; 2286 return -ENOMEM;
1888 } 2287 }
1889 } 2288 }
1890 if (type != TOMOYO_QUERY)
1891 head->reader_idx = tomoyo_read_lock();
1892 file->private_data = head;
1893 /*
1894 * Call the handler now if the file is
1895 * /sys/kernel/security/tomoyo/self_domain
1896 * so that the user can use
1897 * cat < /sys/kernel/security/tomoyo/self_domain"
1898 * to know the current process's domainname.
1899 */
1900 if (type == TOMOYO_SELFDOMAIN)
1901 tomoyo_read_control(file, NULL, 0);
1902 /* 2289 /*
1903 * If the file is /sys/kernel/security/tomoyo/query , increment the 2290 * If the file is /sys/kernel/security/tomoyo/query , increment the
1904 * observer counter. 2291 * observer counter.
1905 * The obserber counter is used by tomoyo_supervisor() to see if 2292 * The obserber counter is used by tomoyo_supervisor() to see if
1906 * there is some process monitoring /sys/kernel/security/tomoyo/query. 2293 * there is some process monitoring /sys/kernel/security/tomoyo/query.
1907 */ 2294 */
1908 else if (type == TOMOYO_QUERY) 2295 if (type == TOMOYO_QUERY)
1909 atomic_inc(&tomoyo_query_observers); 2296 atomic_inc(&tomoyo_query_observers);
2297 file->private_data = head;
2298 tomoyo_notify_gc(head, true);
1910 return 0; 2299 return 0;
1911} 2300}
1912 2301
@@ -1917,7 +2306,8 @@ int tomoyo_open_control(const u8 type, struct file *file)
1917 * @wait: Pointer to "poll_table". 2306 * @wait: Pointer to "poll_table".
1918 * 2307 *
1919 * Waits for read readiness. 2308 * Waits for read readiness.
1920 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd . 2309 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and
2310 * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd.
1921 */ 2311 */
1922int tomoyo_poll_control(struct file *file, poll_table *wait) 2312int tomoyo_poll_control(struct file *file, poll_table *wait)
1923{ 2313{
@@ -1928,21 +2318,58 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1928} 2318}
1929 2319
1930/** 2320/**
2321 * tomoyo_set_namespace_cursor - Set namespace to read.
2322 *
2323 * @head: Pointer to "struct tomoyo_io_buffer".
2324 *
2325 * Returns nothing.
2326 */
2327static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
2328{
2329 struct list_head *ns;
2330 if (head->type != TOMOYO_EXCEPTIONPOLICY &&
2331 head->type != TOMOYO_PROFILE)
2332 return;
2333 /*
2334 * If this is the first read, or reading previous namespace finished
2335 * and has more namespaces to read, update the namespace cursor.
2336 */
2337 ns = head->r.ns;
2338 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
2339 /* Clearing is OK because tomoyo_flush() returned true. */
2340 memset(&head->r, 0, sizeof(head->r));
2341 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
2342 }
2343}
2344
2345/**
2346 * tomoyo_has_more_namespace - Check for unread namespaces.
2347 *
2348 * @head: Pointer to "struct tomoyo_io_buffer".
2349 *
2350 * Returns true if we have more entries to print, false otherwise.
2351 */
2352static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2353{
2354 return (head->type == TOMOYO_EXCEPTIONPOLICY ||
2355 head->type == TOMOYO_PROFILE) && head->r.eof &&
2356 head->r.ns->next != &tomoyo_namespace_list;
2357}
2358
2359/**
1931 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2360 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1932 * 2361 *
1933 * @file: Pointer to "struct file". 2362 * @head: Pointer to "struct tomoyo_io_buffer".
1934 * @buffer: Poiner to buffer to write to. 2363 * @buffer: Poiner to buffer to write to.
1935 * @buffer_len: Size of @buffer. 2364 * @buffer_len: Size of @buffer.
1936 * 2365 *
1937 * Returns bytes read on success, negative value otherwise. 2366 * Returns bytes read on success, negative value otherwise.
1938 *
1939 * Caller holds tomoyo_read_lock().
1940 */ 2367 */
1941int tomoyo_read_control(struct file *file, char __user *buffer, 2368ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
1942 const int buffer_len) 2369 const int buffer_len)
1943{ 2370{
1944 int len; 2371 int len;
1945 struct tomoyo_io_buffer *head = file->private_data; 2372 int idx;
1946 2373
1947 if (!head->read) 2374 if (!head->read)
1948 return -ENOSYS; 2375 return -ENOSYS;
@@ -1950,64 +2377,156 @@ int tomoyo_read_control(struct file *file, char __user *buffer,
1950 return -EINTR; 2377 return -EINTR;
1951 head->read_user_buf = buffer; 2378 head->read_user_buf = buffer;
1952 head->read_user_buf_avail = buffer_len; 2379 head->read_user_buf_avail = buffer_len;
2380 idx = tomoyo_read_lock();
1953 if (tomoyo_flush(head)) 2381 if (tomoyo_flush(head))
1954 /* Call the policy handler. */ 2382 /* Call the policy handler. */
1955 head->read(head); 2383 do {
1956 tomoyo_flush(head); 2384 tomoyo_set_namespace_cursor(head);
2385 head->read(head);
2386 } while (tomoyo_flush(head) &&
2387 tomoyo_has_more_namespace(head));
2388 tomoyo_read_unlock(idx);
1957 len = head->read_user_buf - buffer; 2389 len = head->read_user_buf - buffer;
1958 mutex_unlock(&head->io_sem); 2390 mutex_unlock(&head->io_sem);
1959 return len; 2391 return len;
1960} 2392}
1961 2393
1962/** 2394/**
2395 * tomoyo_parse_policy - Parse a policy line.
2396 *
2397 * @head: Poiter to "struct tomoyo_io_buffer".
2398 * @line: Line to parse.
2399 *
2400 * Returns 0 on success, negative value otherwise.
2401 *
2402 * Caller holds tomoyo_read_lock().
2403 */
2404static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2405{
2406 /* Delete request? */
2407 head->w.is_delete = !strncmp(line, "delete ", 7);
2408 if (head->w.is_delete)
2409 memmove(line, line + 7, strlen(line + 7) + 1);
2410 /* Selecting namespace to update. */
2411 if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2412 head->type == TOMOYO_PROFILE) {
2413 if (*line == '<') {
2414 char *cp = strchr(line, ' ');
2415 if (cp) {
2416 *cp++ = '\0';
2417 head->w.ns = tomoyo_assign_namespace(line);
2418 memmove(line, cp, strlen(cp) + 1);
2419 } else
2420 head->w.ns = NULL;
2421 } else
2422 head->w.ns = &tomoyo_kernel_namespace;
2423 /* Don't allow updating if namespace is invalid. */
2424 if (!head->w.ns)
2425 return -ENOENT;
2426 }
2427 /* Do the update. */
2428 return head->write(head);
2429}
2430
2431/**
1963 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2432 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1964 * 2433 *
1965 * @file: Pointer to "struct file". 2434 * @head: Pointer to "struct tomoyo_io_buffer".
1966 * @buffer: Pointer to buffer to read from. 2435 * @buffer: Pointer to buffer to read from.
1967 * @buffer_len: Size of @buffer. 2436 * @buffer_len: Size of @buffer.
1968 * 2437 *
1969 * Returns @buffer_len on success, negative value otherwise. 2438 * Returns @buffer_len on success, negative value otherwise.
1970 *
1971 * Caller holds tomoyo_read_lock().
1972 */ 2439 */
1973int tomoyo_write_control(struct file *file, const char __user *buffer, 2440ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
1974 const int buffer_len) 2441 const char __user *buffer, const int buffer_len)
1975{ 2442{
1976 struct tomoyo_io_buffer *head = file->private_data;
1977 int error = buffer_len; 2443 int error = buffer_len;
1978 int avail_len = buffer_len; 2444 size_t avail_len = buffer_len;
1979 char *cp0 = head->write_buf; 2445 char *cp0 = head->write_buf;
1980 2446 int idx;
1981 if (!head->write) 2447 if (!head->write)
1982 return -ENOSYS; 2448 return -ENOSYS;
1983 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2449 if (!access_ok(VERIFY_READ, buffer, buffer_len))
1984 return -EFAULT; 2450 return -EFAULT;
1985 /* Don't allow updating policies by non manager programs. */
1986 if (head->write != tomoyo_write_pid &&
1987 head->write != tomoyo_write_domain && !tomoyo_manager())
1988 return -EPERM;
1989 if (mutex_lock_interruptible(&head->io_sem)) 2451 if (mutex_lock_interruptible(&head->io_sem))
1990 return -EINTR; 2452 return -EINTR;
2453 idx = tomoyo_read_lock();
1991 /* Read a line and dispatch it to the policy handler. */ 2454 /* Read a line and dispatch it to the policy handler. */
1992 while (avail_len > 0) { 2455 while (avail_len > 0) {
1993 char c; 2456 char c;
1994 if (head->write_avail >= head->writebuf_size - 1) { 2457 if (head->w.avail >= head->writebuf_size - 1) {
1995 error = -ENOMEM; 2458 const int len = head->writebuf_size * 2;
1996 break; 2459 char *cp = kzalloc(len, GFP_NOFS);
1997 } else if (get_user(c, buffer)) { 2460 if (!cp) {
2461 error = -ENOMEM;
2462 break;
2463 }
2464 memmove(cp, cp0, head->w.avail);
2465 kfree(cp0);
2466 head->write_buf = cp;
2467 cp0 = cp;
2468 head->writebuf_size = len;
2469 }
2470 if (get_user(c, buffer)) {
1998 error = -EFAULT; 2471 error = -EFAULT;
1999 break; 2472 break;
2000 } 2473 }
2001 buffer++; 2474 buffer++;
2002 avail_len--; 2475 avail_len--;
2003 cp0[head->write_avail++] = c; 2476 cp0[head->w.avail++] = c;
2004 if (c != '\n') 2477 if (c != '\n')
2005 continue; 2478 continue;
2006 cp0[head->write_avail - 1] = '\0'; 2479 cp0[head->w.avail - 1] = '\0';
2007 head->write_avail = 0; 2480 head->w.avail = 0;
2008 tomoyo_normalize_line(cp0); 2481 tomoyo_normalize_line(cp0);
2009 head->write(head); 2482 if (!strcmp(cp0, "reset")) {
2483 head->w.ns = &tomoyo_kernel_namespace;
2484 head->w.domain = NULL;
2485 memset(&head->r, 0, sizeof(head->r));
2486 continue;
2487 }
2488 /* Don't allow updating policies by non manager programs. */
2489 switch (head->type) {
2490 case TOMOYO_PROCESS_STATUS:
2491 /* This does not write anything. */
2492 break;
2493 case TOMOYO_DOMAINPOLICY:
2494 if (tomoyo_select_domain(head, cp0))
2495 continue;
2496 /* fall through */
2497 case TOMOYO_EXCEPTIONPOLICY:
2498 if (!strcmp(cp0, "select transition_only")) {
2499 head->r.print_transition_related_only = true;
2500 continue;
2501 }
2502 /* fall through */
2503 default:
2504 if (!tomoyo_manager()) {
2505 error = -EPERM;
2506 goto out;
2507 }
2508 }
2509 switch (tomoyo_parse_policy(head, cp0)) {
2510 case -EPERM:
2511 error = -EPERM;
2512 goto out;
2513 case 0:
2514 switch (head->type) {
2515 case TOMOYO_DOMAINPOLICY:
2516 case TOMOYO_EXCEPTIONPOLICY:
2517 case TOMOYO_STAT:
2518 case TOMOYO_PROFILE:
2519 case TOMOYO_MANAGER:
2520 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2521 break;
2522 default:
2523 break;
2524 }
2525 break;
2526 }
2010 } 2527 }
2528out:
2529 tomoyo_read_unlock(idx);
2011 mutex_unlock(&head->io_sem); 2530 mutex_unlock(&head->io_sem);
2012 return error; 2531 return error;
2013} 2532}
@@ -2015,35 +2534,20 @@ int tomoyo_write_control(struct file *file, const char __user *buffer,
2015/** 2534/**
2016 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2535 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2017 * 2536 *
2018 * @file: Pointer to "struct file". 2537 * @head: Pointer to "struct tomoyo_io_buffer".
2019 *
2020 * Releases memory and returns 0.
2021 * 2538 *
2022 * Caller looses tomoyo_read_lock(). 2539 * Returns 0.
2023 */ 2540 */
2024int tomoyo_close_control(struct file *file) 2541int tomoyo_close_control(struct tomoyo_io_buffer *head)
2025{ 2542{
2026 struct tomoyo_io_buffer *head = file->private_data;
2027 const bool is_write = !!head->write_buf;
2028
2029 /* 2543 /*
2030 * If the file is /sys/kernel/security/tomoyo/query , decrement the 2544 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2031 * observer counter. 2545 * observer counter.
2032 */ 2546 */
2033 if (head->type == TOMOYO_QUERY) 2547 if (head->type == TOMOYO_QUERY &&
2034 atomic_dec(&tomoyo_query_observers); 2548 atomic_dec_and_test(&tomoyo_query_observers))
2035 else 2549 wake_up_all(&tomoyo_answer_wait);
2036 tomoyo_read_unlock(head->reader_idx); 2550 tomoyo_notify_gc(head, false);
2037 /* Release memory used for policy I/O. */
2038 kfree(head->read_buf);
2039 head->read_buf = NULL;
2040 kfree(head->write_buf);
2041 head->write_buf = NULL;
2042 kfree(head);
2043 head = NULL;
2044 file->private_data = NULL;
2045 if (is_write)
2046 tomoyo_run_gc();
2047 return 0; 2551 return 0;
2048} 2552}
2049 2553
@@ -2055,27 +2559,90 @@ void tomoyo_check_profile(void)
2055 struct tomoyo_domain_info *domain; 2559 struct tomoyo_domain_info *domain;
2056 const int idx = tomoyo_read_lock(); 2560 const int idx = tomoyo_read_lock();
2057 tomoyo_policy_loaded = true; 2561 tomoyo_policy_loaded = true;
2058 /* Check all profiles currently assigned to domains are defined. */ 2562 printk(KERN_INFO "TOMOYO: 2.4.0\n");
2059 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2563 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2060 const u8 profile = domain->profile; 2564 const u8 profile = domain->profile;
2061 if (tomoyo_profile_ptr[profile]) 2565 const struct tomoyo_policy_namespace *ns = domain->ns;
2566 if (ns->profile_version != 20100903)
2567 printk(KERN_ERR
2568 "Profile version %u is not supported.\n",
2569 ns->profile_version);
2570 else if (!ns->profile_ptr[profile])
2571 printk(KERN_ERR
2572 "Profile %u (used by '%s') is not defined.\n",
2573 profile, domain->domainname->name);
2574 else
2062 continue; 2575 continue;
2063 printk(KERN_ERR "You need to define profile %u before using it.\n", 2576 printk(KERN_ERR
2064 profile); 2577 "Userland tools for TOMOYO 2.4 must be installed and "
2065 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ " 2578 "policy must be initialized.\n");
2579 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ "
2066 "for more information.\n"); 2580 "for more information.\n");
2067 panic("Profile %u (used by '%s') not defined.\n", 2581 panic("STOP!");
2068 profile, domain->domainname->name);
2069 } 2582 }
2070 tomoyo_read_unlock(idx); 2583 tomoyo_read_unlock(idx);
2071 if (tomoyo_profile_version != 20090903) {
2072 printk(KERN_ERR "You need to install userland programs for "
2073 "TOMOYO 2.3 and initialize policy configuration.\n");
2074 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ "
2075 "for more information.\n");
2076 panic("Profile version %u is not supported.\n",
2077 tomoyo_profile_version);
2078 }
2079 printk(KERN_INFO "TOMOYO: 2.3.0\n");
2080 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2584 printk(KERN_INFO "Mandatory Access Control activated.\n");
2081} 2585}
2586
2587/**
2588 * tomoyo_load_builtin_policy - Load built-in policy.
2589 *
2590 * Returns nothing.
2591 */
2592void __init tomoyo_load_builtin_policy(void)
2593{
2594 /*
2595 * This include file is manually created and contains built-in policy
2596 * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
2597 * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
2598 * "tomoyo_builtin_stat" in the form of "static char [] __initdata".
2599 */
2600#include "builtin-policy.h"
2601 u8 i;
2602 const int idx = tomoyo_read_lock();
2603 for (i = 0; i < 5; i++) {
2604 struct tomoyo_io_buffer head = { };
2605 char *start = "";
2606 switch (i) {
2607 case 0:
2608 start = tomoyo_builtin_profile;
2609 head.type = TOMOYO_PROFILE;
2610 head.write = tomoyo_write_profile;
2611 break;
2612 case 1:
2613 start = tomoyo_builtin_exception_policy;
2614 head.type = TOMOYO_EXCEPTIONPOLICY;
2615 head.write = tomoyo_write_exception;
2616 break;
2617 case 2:
2618 start = tomoyo_builtin_domain_policy;
2619 head.type = TOMOYO_DOMAINPOLICY;
2620 head.write = tomoyo_write_domain;
2621 break;
2622 case 3:
2623 start = tomoyo_builtin_manager;
2624 head.type = TOMOYO_MANAGER;
2625 head.write = tomoyo_write_manager;
2626 break;
2627 case 4:
2628 start = tomoyo_builtin_stat;
2629 head.type = TOMOYO_STAT;
2630 head.write = tomoyo_write_stat;
2631 break;
2632 }
2633 while (1) {
2634 char *end = strchr(start, '\n');
2635 if (!end)
2636 break;
2637 *end = '\0';
2638 tomoyo_normalize_line(start);
2639 head.write_buf = start;
2640 tomoyo_parse_policy(&head, start);
2641 start = end + 1;
2642 }
2643 }
2644 tomoyo_read_unlock(idx);
2645#ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
2646 tomoyo_check_profile();
2647#endif
2648}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 7c66bd898782..f7fbaa66e443 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -21,7 +21,8 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/cred.h> 22#include <linux/cred.h>
23#include <linux/poll.h> 23#include <linux/poll.h>
24struct linux_binprm; 24#include <linux/binfmts.h>
25#include <linux/highmem.h>
25 26
26/********** Constants definitions. **********/ 27/********** Constants definitions. **********/
27 28
@@ -38,66 +39,149 @@ struct linux_binprm;
38/* Profile number is an integer between 0 and 255. */ 39/* Profile number is an integer between 0 and 255. */
39#define TOMOYO_MAX_PROFILES 256 40#define TOMOYO_MAX_PROFILES 256
40 41
42/* Group number is an integer between 0 and 255. */
43#define TOMOYO_MAX_ACL_GROUPS 256
44
45/* Index numbers for "struct tomoyo_condition". */
46enum tomoyo_conditions_index {
47 TOMOYO_TASK_UID, /* current_uid() */
48 TOMOYO_TASK_EUID, /* current_euid() */
49 TOMOYO_TASK_SUID, /* current_suid() */
50 TOMOYO_TASK_FSUID, /* current_fsuid() */
51 TOMOYO_TASK_GID, /* current_gid() */
52 TOMOYO_TASK_EGID, /* current_egid() */
53 TOMOYO_TASK_SGID, /* current_sgid() */
54 TOMOYO_TASK_FSGID, /* current_fsgid() */
55 TOMOYO_TASK_PID, /* sys_getpid() */
56 TOMOYO_TASK_PPID, /* sys_getppid() */
57 TOMOYO_EXEC_ARGC, /* "struct linux_binprm *"->argc */
58 TOMOYO_EXEC_ENVC, /* "struct linux_binprm *"->envc */
59 TOMOYO_TYPE_IS_SOCKET, /* S_IFSOCK */
60 TOMOYO_TYPE_IS_SYMLINK, /* S_IFLNK */
61 TOMOYO_TYPE_IS_FILE, /* S_IFREG */
62 TOMOYO_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
63 TOMOYO_TYPE_IS_DIRECTORY, /* S_IFDIR */
64 TOMOYO_TYPE_IS_CHAR_DEV, /* S_IFCHR */
65 TOMOYO_TYPE_IS_FIFO, /* S_IFIFO */
66 TOMOYO_MODE_SETUID, /* S_ISUID */
67 TOMOYO_MODE_SETGID, /* S_ISGID */
68 TOMOYO_MODE_STICKY, /* S_ISVTX */
69 TOMOYO_MODE_OWNER_READ, /* S_IRUSR */
70 TOMOYO_MODE_OWNER_WRITE, /* S_IWUSR */
71 TOMOYO_MODE_OWNER_EXECUTE, /* S_IXUSR */
72 TOMOYO_MODE_GROUP_READ, /* S_IRGRP */
73 TOMOYO_MODE_GROUP_WRITE, /* S_IWGRP */
74 TOMOYO_MODE_GROUP_EXECUTE, /* S_IXGRP */
75 TOMOYO_MODE_OTHERS_READ, /* S_IROTH */
76 TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */
77 TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */
78 TOMOYO_EXEC_REALPATH,
79 TOMOYO_SYMLINK_TARGET,
80 TOMOYO_PATH1_UID,
81 TOMOYO_PATH1_GID,
82 TOMOYO_PATH1_INO,
83 TOMOYO_PATH1_MAJOR,
84 TOMOYO_PATH1_MINOR,
85 TOMOYO_PATH1_PERM,
86 TOMOYO_PATH1_TYPE,
87 TOMOYO_PATH1_DEV_MAJOR,
88 TOMOYO_PATH1_DEV_MINOR,
89 TOMOYO_PATH2_UID,
90 TOMOYO_PATH2_GID,
91 TOMOYO_PATH2_INO,
92 TOMOYO_PATH2_MAJOR,
93 TOMOYO_PATH2_MINOR,
94 TOMOYO_PATH2_PERM,
95 TOMOYO_PATH2_TYPE,
96 TOMOYO_PATH2_DEV_MAJOR,
97 TOMOYO_PATH2_DEV_MINOR,
98 TOMOYO_PATH1_PARENT_UID,
99 TOMOYO_PATH1_PARENT_GID,
100 TOMOYO_PATH1_PARENT_INO,
101 TOMOYO_PATH1_PARENT_PERM,
102 TOMOYO_PATH2_PARENT_UID,
103 TOMOYO_PATH2_PARENT_GID,
104 TOMOYO_PATH2_PARENT_INO,
105 TOMOYO_PATH2_PARENT_PERM,
106 TOMOYO_MAX_CONDITION_KEYWORD,
107 TOMOYO_NUMBER_UNION,
108 TOMOYO_NAME_UNION,
109 TOMOYO_ARGV_ENTRY,
110 TOMOYO_ENVP_ENTRY,
111};
112
113
114/* Index numbers for stat(). */
115enum tomoyo_path_stat_index {
116 /* Do not change this order. */
117 TOMOYO_PATH1,
118 TOMOYO_PATH1_PARENT,
119 TOMOYO_PATH2,
120 TOMOYO_PATH2_PARENT,
121 TOMOYO_MAX_PATH_STAT
122};
123
124/* Index numbers for operation mode. */
41enum tomoyo_mode_index { 125enum tomoyo_mode_index {
42 TOMOYO_CONFIG_DISABLED, 126 TOMOYO_CONFIG_DISABLED,
43 TOMOYO_CONFIG_LEARNING, 127 TOMOYO_CONFIG_LEARNING,
44 TOMOYO_CONFIG_PERMISSIVE, 128 TOMOYO_CONFIG_PERMISSIVE,
45 TOMOYO_CONFIG_ENFORCING, 129 TOMOYO_CONFIG_ENFORCING,
46 TOMOYO_CONFIG_USE_DEFAULT = 255 130 TOMOYO_CONFIG_MAX_MODE,
131 TOMOYO_CONFIG_WANT_REJECT_LOG = 64,
132 TOMOYO_CONFIG_WANT_GRANT_LOG = 128,
133 TOMOYO_CONFIG_USE_DEFAULT = 255,
47}; 134};
48 135
136/* Index numbers for entry type. */
49enum tomoyo_policy_id { 137enum tomoyo_policy_id {
50 TOMOYO_ID_GROUP, 138 TOMOYO_ID_GROUP,
51 TOMOYO_ID_PATH_GROUP, 139 TOMOYO_ID_PATH_GROUP,
52 TOMOYO_ID_NUMBER_GROUP, 140 TOMOYO_ID_NUMBER_GROUP,
53 TOMOYO_ID_TRANSITION_CONTROL, 141 TOMOYO_ID_TRANSITION_CONTROL,
54 TOMOYO_ID_AGGREGATOR, 142 TOMOYO_ID_AGGREGATOR,
55 TOMOYO_ID_GLOBALLY_READABLE,
56 TOMOYO_ID_PATTERN,
57 TOMOYO_ID_NO_REWRITE,
58 TOMOYO_ID_MANAGER, 143 TOMOYO_ID_MANAGER,
144 TOMOYO_ID_CONDITION,
59 TOMOYO_ID_NAME, 145 TOMOYO_ID_NAME,
60 TOMOYO_ID_ACL, 146 TOMOYO_ID_ACL,
61 TOMOYO_ID_DOMAIN, 147 TOMOYO_ID_DOMAIN,
62 TOMOYO_MAX_POLICY 148 TOMOYO_MAX_POLICY
63}; 149};
64 150
151/* Index numbers for domain's attributes. */
152enum tomoyo_domain_info_flags_index {
153 /* Quota warnning flag. */
154 TOMOYO_DIF_QUOTA_WARNED,
155 /*
156 * This domain was unable to create a new domain at
157 * tomoyo_find_next_domain() because the name of the domain to be
158 * created was too long or it could not allocate memory.
159 * More than one process continued execve() without domain transition.
160 */
161 TOMOYO_DIF_TRANSITION_FAILED,
162 TOMOYO_MAX_DOMAIN_INFO_FLAGS
163};
164
165/* Index numbers for group entries. */
65enum tomoyo_group_id { 166enum tomoyo_group_id {
66 TOMOYO_PATH_GROUP, 167 TOMOYO_PATH_GROUP,
67 TOMOYO_NUMBER_GROUP, 168 TOMOYO_NUMBER_GROUP,
68 TOMOYO_MAX_GROUP 169 TOMOYO_MAX_GROUP
69}; 170};
70 171
71/* Keywords for ACLs. */ 172/* Index numbers for type of numeric values. */
72#define TOMOYO_KEYWORD_AGGREGATOR "aggregator " 173enum tomoyo_value_type {
73#define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount " 174 TOMOYO_VALUE_TYPE_INVALID,
74#define TOMOYO_KEYWORD_ALLOW_READ "allow_read " 175 TOMOYO_VALUE_TYPE_DECIMAL,
75#define TOMOYO_KEYWORD_DELETE "delete " 176 TOMOYO_VALUE_TYPE_OCTAL,
76#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite " 177 TOMOYO_VALUE_TYPE_HEXADECIMAL,
77#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern " 178};
78#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
79#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
80#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
81#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
82#define TOMOYO_KEYWORD_PATH_GROUP "path_group "
83#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group "
84#define TOMOYO_KEYWORD_SELECT "select "
85#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
86#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
87#define TOMOYO_KEYWORD_QUOTA_EXCEEDED "quota_exceeded"
88#define TOMOYO_KEYWORD_TRANSITION_FAILED "transition_failed"
89/* A domain definition starts with <kernel>. */
90#define TOMOYO_ROOT_NAME "<kernel>"
91#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
92
93/* Value type definition. */
94#define TOMOYO_VALUE_TYPE_INVALID 0
95#define TOMOYO_VALUE_TYPE_DECIMAL 1
96#define TOMOYO_VALUE_TYPE_OCTAL 2
97#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3
98 179
180/* Index numbers for domain transition control keywords. */
99enum tomoyo_transition_type { 181enum tomoyo_transition_type {
100 /* Do not change this order, */ 182 /* Do not change this order, */
183 TOMOYO_TRANSITION_CONTROL_NO_RESET,
184 TOMOYO_TRANSITION_CONTROL_RESET,
101 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE, 185 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
102 TOMOYO_TRANSITION_CONTROL_INITIALIZE, 186 TOMOYO_TRANSITION_CONTROL_INITIALIZE,
103 TOMOYO_TRANSITION_CONTROL_NO_KEEP, 187 TOMOYO_TRANSITION_CONTROL_NO_KEEP,
@@ -114,35 +198,29 @@ enum tomoyo_acl_entry_type_index {
114 TOMOYO_TYPE_MOUNT_ACL, 198 TOMOYO_TYPE_MOUNT_ACL,
115}; 199};
116 200
117/* Index numbers for File Controls. */ 201/* Index numbers for access controls with one pathname. */
118
119/*
120 * TOMOYO_TYPE_READ_WRITE is special. TOMOYO_TYPE_READ_WRITE is automatically
121 * set if both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are set.
122 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically set if
123 * TOMOYO_TYPE_READ_WRITE is set.
124 * TOMOYO_TYPE_READ_WRITE is automatically cleared if either TOMOYO_TYPE_READ
125 * or TOMOYO_TYPE_WRITE is cleared.
126 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically cleared if
127 * TOMOYO_TYPE_READ_WRITE is cleared.
128 */
129
130enum tomoyo_path_acl_index { 202enum tomoyo_path_acl_index {
131 TOMOYO_TYPE_READ_WRITE,
132 TOMOYO_TYPE_EXECUTE, 203 TOMOYO_TYPE_EXECUTE,
133 TOMOYO_TYPE_READ, 204 TOMOYO_TYPE_READ,
134 TOMOYO_TYPE_WRITE, 205 TOMOYO_TYPE_WRITE,
206 TOMOYO_TYPE_APPEND,
135 TOMOYO_TYPE_UNLINK, 207 TOMOYO_TYPE_UNLINK,
208 TOMOYO_TYPE_GETATTR,
136 TOMOYO_TYPE_RMDIR, 209 TOMOYO_TYPE_RMDIR,
137 TOMOYO_TYPE_TRUNCATE, 210 TOMOYO_TYPE_TRUNCATE,
138 TOMOYO_TYPE_SYMLINK, 211 TOMOYO_TYPE_SYMLINK,
139 TOMOYO_TYPE_REWRITE,
140 TOMOYO_TYPE_CHROOT, 212 TOMOYO_TYPE_CHROOT,
141 TOMOYO_TYPE_UMOUNT, 213 TOMOYO_TYPE_UMOUNT,
142 TOMOYO_MAX_PATH_OPERATION 214 TOMOYO_MAX_PATH_OPERATION
143}; 215};
144 216
145#define TOMOYO_RW_MASK ((1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE)) 217/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
218enum tomoyo_memory_stat_type {
219 TOMOYO_MEMORY_POLICY,
220 TOMOYO_MEMORY_AUDIT,
221 TOMOYO_MEMORY_QUERY,
222 TOMOYO_MAX_MEMORY_STAT
223};
146 224
147enum tomoyo_mkdev_acl_index { 225enum tomoyo_mkdev_acl_index {
148 TOMOYO_TYPE_MKBLOCK, 226 TOMOYO_TYPE_MKBLOCK,
@@ -150,6 +228,7 @@ enum tomoyo_mkdev_acl_index {
150 TOMOYO_MAX_MKDEV_OPERATION 228 TOMOYO_MAX_MKDEV_OPERATION
151}; 229};
152 230
231/* Index numbers for access controls with two pathnames. */
153enum tomoyo_path2_acl_index { 232enum tomoyo_path2_acl_index {
154 TOMOYO_TYPE_LINK, 233 TOMOYO_TYPE_LINK,
155 TOMOYO_TYPE_RENAME, 234 TOMOYO_TYPE_RENAME,
@@ -157,6 +236,7 @@ enum tomoyo_path2_acl_index {
157 TOMOYO_MAX_PATH2_OPERATION 236 TOMOYO_MAX_PATH2_OPERATION
158}; 237};
159 238
239/* Index numbers for access controls with one pathname and one number. */
160enum tomoyo_path_number_acl_index { 240enum tomoyo_path_number_acl_index {
161 TOMOYO_TYPE_CREATE, 241 TOMOYO_TYPE_CREATE,
162 TOMOYO_TYPE_MKDIR, 242 TOMOYO_TYPE_MKDIR,
@@ -169,31 +249,45 @@ enum tomoyo_path_number_acl_index {
169 TOMOYO_MAX_PATH_NUMBER_OPERATION 249 TOMOYO_MAX_PATH_NUMBER_OPERATION
170}; 250};
171 251
252/* Index numbers for /sys/kernel/security/tomoyo/ interfaces. */
172enum tomoyo_securityfs_interface_index { 253enum tomoyo_securityfs_interface_index {
173 TOMOYO_DOMAINPOLICY, 254 TOMOYO_DOMAINPOLICY,
174 TOMOYO_EXCEPTIONPOLICY, 255 TOMOYO_EXCEPTIONPOLICY,
175 TOMOYO_DOMAIN_STATUS,
176 TOMOYO_PROCESS_STATUS, 256 TOMOYO_PROCESS_STATUS,
177 TOMOYO_MEMINFO, 257 TOMOYO_STAT,
178 TOMOYO_SELFDOMAIN, 258 TOMOYO_SELFDOMAIN,
259 TOMOYO_AUDIT,
179 TOMOYO_VERSION, 260 TOMOYO_VERSION,
180 TOMOYO_PROFILE, 261 TOMOYO_PROFILE,
181 TOMOYO_QUERY, 262 TOMOYO_QUERY,
182 TOMOYO_MANAGER 263 TOMOYO_MANAGER
183}; 264};
184 265
266/* Index numbers for special mount operations. */
267enum tomoyo_special_mount {
268 TOMOYO_MOUNT_BIND, /* mount --bind /source /dest */
269 TOMOYO_MOUNT_MOVE, /* mount --move /old /new */
270 TOMOYO_MOUNT_REMOUNT, /* mount -o remount /dir */
271 TOMOYO_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
272 TOMOYO_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
273 TOMOYO_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
274 TOMOYO_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
275 TOMOYO_MAX_SPECIAL_MOUNT
276};
277
278/* Index numbers for functionality. */
185enum tomoyo_mac_index { 279enum tomoyo_mac_index {
186 TOMOYO_MAC_FILE_EXECUTE, 280 TOMOYO_MAC_FILE_EXECUTE,
187 TOMOYO_MAC_FILE_OPEN, 281 TOMOYO_MAC_FILE_OPEN,
188 TOMOYO_MAC_FILE_CREATE, 282 TOMOYO_MAC_FILE_CREATE,
189 TOMOYO_MAC_FILE_UNLINK, 283 TOMOYO_MAC_FILE_UNLINK,
284 TOMOYO_MAC_FILE_GETATTR,
190 TOMOYO_MAC_FILE_MKDIR, 285 TOMOYO_MAC_FILE_MKDIR,
191 TOMOYO_MAC_FILE_RMDIR, 286 TOMOYO_MAC_FILE_RMDIR,
192 TOMOYO_MAC_FILE_MKFIFO, 287 TOMOYO_MAC_FILE_MKFIFO,
193 TOMOYO_MAC_FILE_MKSOCK, 288 TOMOYO_MAC_FILE_MKSOCK,
194 TOMOYO_MAC_FILE_TRUNCATE, 289 TOMOYO_MAC_FILE_TRUNCATE,
195 TOMOYO_MAC_FILE_SYMLINK, 290 TOMOYO_MAC_FILE_SYMLINK,
196 TOMOYO_MAC_FILE_REWRITE,
197 TOMOYO_MAC_FILE_MKBLOCK, 291 TOMOYO_MAC_FILE_MKBLOCK,
198 TOMOYO_MAC_FILE_MKCHAR, 292 TOMOYO_MAC_FILE_MKCHAR,
199 TOMOYO_MAC_FILE_LINK, 293 TOMOYO_MAC_FILE_LINK,
@@ -209,38 +303,66 @@ enum tomoyo_mac_index {
209 TOMOYO_MAX_MAC_INDEX 303 TOMOYO_MAX_MAC_INDEX
210}; 304};
211 305
306/* Index numbers for category of functionality. */
212enum tomoyo_mac_category_index { 307enum tomoyo_mac_category_index {
213 TOMOYO_MAC_CATEGORY_FILE, 308 TOMOYO_MAC_CATEGORY_FILE,
214 TOMOYO_MAX_MAC_CATEGORY_INDEX 309 TOMOYO_MAX_MAC_CATEGORY_INDEX
215}; 310};
216 311
217#define TOMOYO_RETRY_REQUEST 1 /* Retry this request. */
218
219/********** Structure definitions. **********/
220
221/* 312/*
222 * tomoyo_acl_head is a structure which is used for holding elements not in 313 * Retry this request. Returned by tomoyo_supervisor() if policy violation has
223 * domain policy. 314 * occurred in enforcing mode and the userspace daemon decided to retry.
224 * It has following fields.
225 * 315 *
226 * (1) "list" which is linked to tomoyo_policy_list[] . 316 * We must choose a positive value in order to distinguish "granted" (which is
227 * (2) "is_deleted" is a bool which is true if marked as deleted, false 317 * 0) and "rejected" (which is a negative value) and "retry".
228 * otherwise.
229 */ 318 */
319#define TOMOYO_RETRY_REQUEST 1
320
321/* Index numbers for /sys/kernel/security/tomoyo/stat interface. */
322enum tomoyo_policy_stat_type {
323 /* Do not change this order. */
324 TOMOYO_STAT_POLICY_UPDATES,
325 TOMOYO_STAT_POLICY_LEARNING, /* == TOMOYO_CONFIG_LEARNING */
326 TOMOYO_STAT_POLICY_PERMISSIVE, /* == TOMOYO_CONFIG_PERMISSIVE */
327 TOMOYO_STAT_POLICY_ENFORCING, /* == TOMOYO_CONFIG_ENFORCING */
328 TOMOYO_MAX_POLICY_STAT
329};
330
331/* Index numbers for profile's PREFERENCE values. */
332enum tomoyo_pref_index {
333 TOMOYO_PREF_MAX_AUDIT_LOG,
334 TOMOYO_PREF_MAX_LEARNING_ENTRY,
335 TOMOYO_MAX_PREF
336};
337
338/********** Structure definitions. **********/
339
340/* Common header for holding ACL entries. */
230struct tomoyo_acl_head { 341struct tomoyo_acl_head {
231 struct list_head list; 342 struct list_head list;
232 bool is_deleted; 343 bool is_deleted;
233} __packed; 344} __packed;
234 345
235/* 346/* Common header for shared entries. */
236 * tomoyo_request_info is a structure which is used for holding 347struct tomoyo_shared_acl_head {
237 * 348 struct list_head list;
238 * (1) Domain information of current process. 349 atomic_t users;
239 * (2) How many retries are made for this request. 350} __packed;
240 * (3) Profile number used for this request. 351
241 * (4) Access control mode of the profile. 352struct tomoyo_policy_namespace;
242 */ 353
354/* Structure for request info. */
243struct tomoyo_request_info { 355struct tomoyo_request_info {
356 /*
357 * For holding parameters specific to operations which deal files.
358 * NULL if not dealing files.
359 */
360 struct tomoyo_obj_info *obj;
361 /*
362 * For holding parameters specific to execve() request.
363 * NULL if not dealing do_execve().
364 */
365 struct tomoyo_execve *ee;
244 struct tomoyo_domain_info *domain; 366 struct tomoyo_domain_info *domain;
245 /* For holding parameters. */ 367 /* For holding parameters. */
246 union { 368 union {
@@ -248,11 +370,13 @@ struct tomoyo_request_info {
248 const struct tomoyo_path_info *filename; 370 const struct tomoyo_path_info *filename;
249 /* For using wildcards at tomoyo_find_next_domain(). */ 371 /* For using wildcards at tomoyo_find_next_domain(). */
250 const struct tomoyo_path_info *matched_path; 372 const struct tomoyo_path_info *matched_path;
373 /* One of values in "enum tomoyo_path_acl_index". */
251 u8 operation; 374 u8 operation;
252 } path; 375 } path;
253 struct { 376 struct {
254 const struct tomoyo_path_info *filename1; 377 const struct tomoyo_path_info *filename1;
255 const struct tomoyo_path_info *filename2; 378 const struct tomoyo_path_info *filename2;
379 /* One of values in "enum tomoyo_path2_acl_index". */
256 u8 operation; 380 u8 operation;
257 } path2; 381 } path2;
258 struct { 382 struct {
@@ -260,11 +384,16 @@ struct tomoyo_request_info {
260 unsigned int mode; 384 unsigned int mode;
261 unsigned int major; 385 unsigned int major;
262 unsigned int minor; 386 unsigned int minor;
387 /* One of values in "enum tomoyo_mkdev_acl_index". */
263 u8 operation; 388 u8 operation;
264 } mkdev; 389 } mkdev;
265 struct { 390 struct {
266 const struct tomoyo_path_info *filename; 391 const struct tomoyo_path_info *filename;
267 unsigned long number; 392 unsigned long number;
393 /*
394 * One of values in
395 * "enum tomoyo_path_number_acl_index".
396 */
268 u8 operation; 397 u8 operation;
269 } path_number; 398 } path_number;
270 struct { 399 struct {
@@ -283,26 +412,7 @@ struct tomoyo_request_info {
283 u8 type; 412 u8 type;
284}; 413};
285 414
286/* 415/* Structure for holding a token. */
287 * tomoyo_path_info is a structure which is used for holding a string data
288 * used by TOMOYO.
289 * This structure has several fields for supporting pattern matching.
290 *
291 * (1) "name" is the '\0' terminated string data.
292 * (2) "hash" is full_name_hash(name, strlen(name)).
293 * This allows tomoyo_pathcmp() to compare by hash before actually compare
294 * using strcmp().
295 * (3) "const_len" is the length of the initial segment of "name" which
296 * consists entirely of non wildcard characters. In other words, the length
297 * which we can compare two strings using strncmp().
298 * (4) "is_dir" is a bool which is true if "name" ends with "/",
299 * false otherwise.
300 * TOMOYO distinguishes directory and non-directory. A directory ends with
301 * "/" and non-directory does not end with "/".
302 * (5) "is_patterned" is a bool which is true if "name" contains wildcard
303 * characters, false otherwise. This allows TOMOYO to use "hash" and
304 * strcmp() for string comparison if "is_patterned" is false.
305 */
306struct tomoyo_path_info { 416struct tomoyo_path_info {
307 const char *name; 417 const char *name;
308 u32 hash; /* = full_name_hash(name, strlen(name)) */ 418 u32 hash; /* = full_name_hash(name, strlen(name)) */
@@ -311,36 +421,32 @@ struct tomoyo_path_info {
311 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 421 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
312}; 422};
313 423
314/* 424/* Structure for holding string data. */
315 * tomoyo_name is a structure which is used for linking
316 * "struct tomoyo_path_info" into tomoyo_name_list .
317 */
318struct tomoyo_name { 425struct tomoyo_name {
319 struct list_head list; 426 struct tomoyo_shared_acl_head head;
320 atomic_t users;
321 struct tomoyo_path_info entry; 427 struct tomoyo_path_info entry;
322}; 428};
323 429
430/* Structure for holding a word. */
324struct tomoyo_name_union { 431struct tomoyo_name_union {
432 /* Either @filename or @group is NULL. */
325 const struct tomoyo_path_info *filename; 433 const struct tomoyo_path_info *filename;
326 struct tomoyo_group *group; 434 struct tomoyo_group *group;
327 u8 is_group;
328}; 435};
329 436
437/* Structure for holding a number. */
330struct tomoyo_number_union { 438struct tomoyo_number_union {
331 unsigned long values[2]; 439 unsigned long values[2];
332 struct tomoyo_group *group; 440 struct tomoyo_group *group; /* Maybe NULL. */
333 u8 min_type; 441 /* One of values in "enum tomoyo_value_type". */
334 u8 max_type; 442 u8 value_type[2];
335 u8 is_group;
336}; 443};
337 444
338/* Structure for "path_group"/"number_group" directive. */ 445/* Structure for "path_group"/"number_group" directive. */
339struct tomoyo_group { 446struct tomoyo_group {
340 struct list_head list; 447 struct tomoyo_shared_acl_head head;
341 const struct tomoyo_path_info *group_name; 448 const struct tomoyo_path_info *group_name;
342 struct list_head member_list; 449 struct list_head member_list;
343 atomic_t users;
344}; 450};
345 451
346/* Structure for "path_group" directive. */ 452/* Structure for "path_group" directive. */
@@ -355,130 +461,158 @@ struct tomoyo_number_group {
355 struct tomoyo_number_union number; 461 struct tomoyo_number_union number;
356}; 462};
357 463
358/* 464/* Subset of "struct stat". Used by conditional ACL and audit logs. */
359 * tomoyo_acl_info is a structure which is used for holding 465struct tomoyo_mini_stat {
360 * 466 uid_t uid;
361 * (1) "list" which is linked to the ->acl_info_list of 467 gid_t gid;
362 * "struct tomoyo_domain_info" 468 ino_t ino;
363 * (2) "is_deleted" is a bool which is true if this domain is marked as 469 mode_t mode;
364 * "deleted", false otherwise. 470 dev_t dev;
365 * (3) "type" which tells type of the entry. 471 dev_t rdev;
366 * 472};
367 * Packing "struct tomoyo_acl_info" allows 473
368 * "struct tomoyo_path_acl" to embed "u16" and "struct tomoyo_path2_acl" 474/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
369 * "struct tomoyo_path_number_acl" "struct tomoyo_mkdev_acl" to embed 475struct tomoyo_page_dump {
370 * "u8" without enlarging their structure size. 476 struct page *page; /* Previously dumped page. */
371 */ 477 char *data; /* Contents of "page". Size is PAGE_SIZE. */
478};
479
480/* Structure for attribute checks in addition to pathname checks. */
481struct tomoyo_obj_info {
482 /*
483 * True if tomoyo_get_attributes() was already called, false otherwise.
484 */
485 bool validate_done;
486 /* True if @stat[] is valid. */
487 bool stat_valid[TOMOYO_MAX_PATH_STAT];
488 /* First pathname. Initialized with { NULL, NULL } if no path. */
489 struct path path1;
490 /* Second pathname. Initialized with { NULL, NULL } if no path. */
491 struct path path2;
492 /*
493 * Information on @path1, @path1's parent directory, @path2, @path2's
494 * parent directory.
495 */
496 struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT];
497 /*
498 * Content of symbolic link to be created. NULL for operations other
499 * than symlink().
500 */
501 struct tomoyo_path_info *symlink_target;
502};
503
504/* Structure for argv[]. */
505struct tomoyo_argv {
506 unsigned long index;
507 const struct tomoyo_path_info *value;
508 bool is_not;
509};
510
511/* Structure for envp[]. */
512struct tomoyo_envp {
513 const struct tomoyo_path_info *name;
514 const struct tomoyo_path_info *value;
515 bool is_not;
516};
517
518/* Structure for execve() operation. */
519struct tomoyo_execve {
520 struct tomoyo_request_info r;
521 struct tomoyo_obj_info obj;
522 struct linux_binprm *bprm;
523 /* For dumping argv[] and envp[]. */
524 struct tomoyo_page_dump dump;
525 /* For temporary use. */
526 char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
527};
528
529/* Structure for entries which follows "struct tomoyo_condition". */
530struct tomoyo_condition_element {
531 /*
532 * Left hand operand. A "struct tomoyo_argv" for TOMOYO_ARGV_ENTRY, a
533 * "struct tomoyo_envp" for TOMOYO_ENVP_ENTRY is attached to the tail
534 * of the array of this struct.
535 */
536 u8 left;
537 /*
538 * Right hand operand. A "struct tomoyo_number_union" for
539 * TOMOYO_NUMBER_UNION, a "struct tomoyo_name_union" for
540 * TOMOYO_NAME_UNION is attached to the tail of the array of this
541 * struct.
542 */
543 u8 right;
544 /* Equation operator. True if equals or overlaps, false otherwise. */
545 bool equals;
546};
547
548/* Structure for optional arguments. */
549struct tomoyo_condition {
550 struct tomoyo_shared_acl_head head;
551 u32 size; /* Memory size allocated for this entry. */
552 u16 condc; /* Number of conditions in this struct. */
553 u16 numbers_count; /* Number of "struct tomoyo_number_union values". */
554 u16 names_count; /* Number of "struct tomoyo_name_union names". */
555 u16 argc; /* Number of "struct tomoyo_argv". */
556 u16 envc; /* Number of "struct tomoyo_envp". */
557 /*
558 * struct tomoyo_condition_element condition[condc];
559 * struct tomoyo_number_union values[numbers_count];
560 * struct tomoyo_name_union names[names_count];
561 * struct tomoyo_argv argv[argc];
562 * struct tomoyo_envp envp[envc];
563 */
564};
565
566/* Common header for individual entries. */
372struct tomoyo_acl_info { 567struct tomoyo_acl_info {
373 struct list_head list; 568 struct list_head list;
569 struct tomoyo_condition *cond; /* Maybe NULL. */
374 bool is_deleted; 570 bool is_deleted;
375 u8 type; /* = one of values in "enum tomoyo_acl_entry_type_index". */ 571 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */
376} __packed; 572} __packed;
377 573
378/* 574/* Structure for domain information. */
379 * tomoyo_domain_info is a structure which is used for holding permissions
380 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
381 * It has following fields.
382 *
383 * (1) "list" which is linked to tomoyo_domain_list .
384 * (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
385 * (3) "domainname" which holds the name of the domain.
386 * (4) "profile" which remembers profile number assigned to this domain.
387 * (5) "is_deleted" is a bool which is true if this domain is marked as
388 * "deleted", false otherwise.
389 * (6) "quota_warned" is a bool which is used for suppressing warning message
390 * when learning mode learned too much entries.
391 * (7) "ignore_global_allow_read" is a bool which is true if this domain
392 * should ignore "allow_read" directive in exception policy.
393 * (8) "transition_failed" is a bool which is set to true when this domain was
394 * unable to create a new domain at tomoyo_find_next_domain() because the
395 * name of the domain to be created was too long or it could not allocate
396 * memory. If set to true, more than one process continued execve()
397 * without domain transition.
398 * (9) "users" is an atomic_t that holds how many "struct cred"->security
399 * are referring this "struct tomoyo_domain_info". If is_deleted == true
400 * and users == 0, this struct will be kfree()d upon next garbage
401 * collection.
402 *
403 * A domain's lifecycle is an analogy of files on / directory.
404 * Multiple domains with the same domainname cannot be created (as with
405 * creating files with the same filename fails with -EEXIST).
406 * If a process reached a domain, that process can reside in that domain after
407 * that domain is marked as "deleted" (as with a process can access an already
408 * open()ed file after that file was unlink()ed).
409 */
410struct tomoyo_domain_info { 575struct tomoyo_domain_info {
411 struct list_head list; 576 struct list_head list;
412 struct list_head acl_info_list; 577 struct list_head acl_info_list;
413 /* Name of this domain. Never NULL. */ 578 /* Name of this domain. Never NULL. */
414 const struct tomoyo_path_info *domainname; 579 const struct tomoyo_path_info *domainname;
580 /* Namespace for this domain. Never NULL. */
581 struct tomoyo_policy_namespace *ns;
415 u8 profile; /* Profile number to use. */ 582 u8 profile; /* Profile number to use. */
583 u8 group; /* Group number to use. */
416 bool is_deleted; /* Delete flag. */ 584 bool is_deleted; /* Delete flag. */
417 bool quota_warned; /* Quota warnning flag. */ 585 bool flags[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
418 bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
419 bool transition_failed; /* Domain transition failed flag. */
420 atomic_t users; /* Number of referring credentials. */ 586 atomic_t users; /* Number of referring credentials. */
421}; 587};
422 588
423/* 589/*
424 * tomoyo_path_acl is a structure which is used for holding an 590 * Structure for "file execute", "file read", "file write", "file append",
425 * entry with one pathname operation (e.g. open(), mkdir()). 591 * "file unlink", "file getattr", "file rmdir", "file truncate",
426 * It has following fields. 592 * "file symlink", "file chroot" and "file unmount" directive.
427 *
428 * (1) "head" which is a "struct tomoyo_acl_info".
429 * (2) "perm" which is a bitmask of permitted operations.
430 * (3) "name" is the pathname.
431 *
432 * Directives held by this structure are "allow_read/write", "allow_execute",
433 * "allow_read", "allow_write", "allow_unlink", "allow_rmdir",
434 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_chroot" and
435 * "allow_unmount".
436 */ 593 */
437struct tomoyo_path_acl { 594struct tomoyo_path_acl {
438 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */ 595 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
439 u16 perm; 596 u16 perm; /* Bitmask of values in "enum tomoyo_path_acl_index". */
440 struct tomoyo_name_union name; 597 struct tomoyo_name_union name;
441}; 598};
442 599
443/* 600/*
444 * tomoyo_path_number_acl is a structure which is used for holding an 601 * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
445 * entry with one pathname and one number operation. 602 * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
446 * It has following fields.
447 *
448 * (1) "head" which is a "struct tomoyo_acl_info".
449 * (2) "perm" which is a bitmask of permitted operations.
450 * (3) "name" is the pathname.
451 * (4) "number" is the numeric value.
452 *
453 * Directives held by this structure are "allow_create", "allow_mkdir",
454 * "allow_ioctl", "allow_mkfifo", "allow_mksock", "allow_chmod", "allow_chown"
455 * and "allow_chgrp".
456 *
457 */ 603 */
458struct tomoyo_path_number_acl { 604struct tomoyo_path_number_acl {
459 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_NUMBER_ACL */ 605 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_NUMBER_ACL */
606 /* Bitmask of values in "enum tomoyo_path_number_acl_index". */
460 u8 perm; 607 u8 perm;
461 struct tomoyo_name_union name; 608 struct tomoyo_name_union name;
462 struct tomoyo_number_union number; 609 struct tomoyo_number_union number;
463}; 610};
464 611
465/* 612/* Structure for "file mkblock" and "file mkchar" directive. */
466 * tomoyo_mkdev_acl is a structure which is used for holding an
467 * entry with one pathname and three numbers operation.
468 * It has following fields.
469 *
470 * (1) "head" which is a "struct tomoyo_acl_info".
471 * (2) "perm" which is a bitmask of permitted operations.
472 * (3) "mode" is the create mode.
473 * (4) "major" is the major number of device node.
474 * (5) "minor" is the minor number of device node.
475 *
476 * Directives held by this structure are "allow_mkchar", "allow_mkblock".
477 *
478 */
479struct tomoyo_mkdev_acl { 613struct tomoyo_mkdev_acl {
480 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MKDEV_ACL */ 614 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MKDEV_ACL */
481 u8 perm; 615 u8 perm; /* Bitmask of values in "enum tomoyo_mkdev_acl_index". */
482 struct tomoyo_name_union name; 616 struct tomoyo_name_union name;
483 struct tomoyo_number_union mode; 617 struct tomoyo_number_union mode;
484 struct tomoyo_number_union major; 618 struct tomoyo_number_union major;
@@ -486,38 +620,16 @@ struct tomoyo_mkdev_acl {
486}; 620};
487 621
488/* 622/*
489 * tomoyo_path2_acl is a structure which is used for holding an 623 * Structure for "file rename", "file link" and "file pivot_root" directive.
490 * entry with two pathnames operation (i.e. link(), rename() and pivot_root()).
491 * It has following fields.
492 *
493 * (1) "head" which is a "struct tomoyo_acl_info".
494 * (2) "perm" which is a bitmask of permitted operations.
495 * (3) "name1" is the source/old pathname.
496 * (4) "name2" is the destination/new pathname.
497 *
498 * Directives held by this structure are "allow_rename", "allow_link" and
499 * "allow_pivot_root".
500 */ 624 */
501struct tomoyo_path2_acl { 625struct tomoyo_path2_acl {
502 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */ 626 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
503 u8 perm; 627 u8 perm; /* Bitmask of values in "enum tomoyo_path2_acl_index". */
504 struct tomoyo_name_union name1; 628 struct tomoyo_name_union name1;
505 struct tomoyo_name_union name2; 629 struct tomoyo_name_union name2;
506}; 630};
507 631
508/* 632/* Structure for "file mount" directive. */
509 * tomoyo_mount_acl is a structure which is used for holding an
510 * entry for mount operation.
511 * It has following fields.
512 *
513 * (1) "head" which is a "struct tomoyo_acl_info".
514 * (2) "dev_name" is the device name.
515 * (3) "dir_name" is the mount point.
516 * (4) "fs_type" is the filesystem type.
517 * (5) "flags" is the mount flags.
518 *
519 * Directive held by this structure is "allow_mount".
520 */
521struct tomoyo_mount_acl { 633struct tomoyo_mount_acl {
522 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MOUNT_ACL */ 634 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_MOUNT_ACL */
523 struct tomoyo_name_union dev_name; 635 struct tomoyo_name_union dev_name;
@@ -526,7 +638,15 @@ struct tomoyo_mount_acl {
526 struct tomoyo_number_union flags; 638 struct tomoyo_number_union flags;
527}; 639};
528 640
529#define TOMOYO_MAX_IO_READ_QUEUE 32 641/* Structure for holding a line from /sys/kernel/security/tomoyo/ interface. */
642struct tomoyo_acl_param {
643 char *data;
644 struct list_head *list;
645 struct tomoyo_policy_namespace *ns;
646 bool is_delete;
647};
648
649#define TOMOYO_MAX_IO_READ_QUEUE 64
530 650
531/* 651/*
532 * Structure for reading/writing policy via /sys/kernel/security/tomoyo 652 * Structure for reading/writing policy via /sys/kernel/security/tomoyo
@@ -538,95 +658,55 @@ struct tomoyo_io_buffer {
538 int (*poll) (struct file *file, poll_table *wait); 658 int (*poll) (struct file *file, poll_table *wait);
539 /* Exclusive lock for this structure. */ 659 /* Exclusive lock for this structure. */
540 struct mutex io_sem; 660 struct mutex io_sem;
541 /* Index returned by tomoyo_read_lock(). */
542 int reader_idx;
543 char __user *read_user_buf; 661 char __user *read_user_buf;
544 int read_user_buf_avail; 662 size_t read_user_buf_avail;
545 struct { 663 struct {
664 struct list_head *ns;
546 struct list_head *domain; 665 struct list_head *domain;
547 struct list_head *group; 666 struct list_head *group;
548 struct list_head *acl; 667 struct list_head *acl;
549 int avail; 668 size_t avail;
550 int step; 669 unsigned int step;
551 int query_index; 670 unsigned int query_index;
552 u16 index; 671 u16 index;
672 u16 cond_index;
673 u8 acl_group_index;
674 u8 cond_step;
553 u8 bit; 675 u8 bit;
554 u8 w_pos; 676 u8 w_pos;
555 bool eof; 677 bool eof;
556 bool print_this_domain_only; 678 bool print_this_domain_only;
557 bool print_execute_only; 679 bool print_transition_related_only;
680 bool print_cond_part;
558 const char *w[TOMOYO_MAX_IO_READ_QUEUE]; 681 const char *w[TOMOYO_MAX_IO_READ_QUEUE];
559 } r; 682 } r;
560 /* The position currently writing to. */ 683 struct {
561 struct tomoyo_domain_info *write_var1; 684 struct tomoyo_policy_namespace *ns;
685 /* The position currently writing to. */
686 struct tomoyo_domain_info *domain;
687 /* Bytes available for writing. */
688 size_t avail;
689 bool is_delete;
690 } w;
562 /* Buffer for reading. */ 691 /* Buffer for reading. */
563 char *read_buf; 692 char *read_buf;
564 /* Size of read buffer. */ 693 /* Size of read buffer. */
565 int readbuf_size; 694 size_t readbuf_size;
566 /* Buffer for writing. */ 695 /* Buffer for writing. */
567 char *write_buf; 696 char *write_buf;
568 /* Bytes available for writing. */
569 int write_avail;
570 /* Size of write buffer. */ 697 /* Size of write buffer. */
571 int writebuf_size; 698 size_t writebuf_size;
572 /* Type of this interface. */ 699 /* Type of this interface. */
573 u8 type; 700 enum tomoyo_securityfs_interface_index type;
574}; 701 /* Users counter protected by tomoyo_io_buffer_list_lock. */
575 702 u8 users;
576/* 703 /* List for telling GC not to kfree() elements. */
577 * tomoyo_readable_file is a structure which is used for holding 704 struct list_head list;
578 * "allow_read" entries.
579 * It has following fields.
580 *
581 * (1) "head" is "struct tomoyo_acl_head".
582 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
583 */
584struct tomoyo_readable_file {
585 struct tomoyo_acl_head head;
586 const struct tomoyo_path_info *filename;
587};
588
589/*
590 * tomoyo_no_pattern is a structure which is used for holding
591 * "file_pattern" entries.
592 * It has following fields.
593 *
594 * (1) "head" is "struct tomoyo_acl_head".
595 * (2) "pattern" is a pathname pattern which is used for converting pathnames
596 * to pathname patterns during learning mode.
597 */
598struct tomoyo_no_pattern {
599 struct tomoyo_acl_head head;
600 const struct tomoyo_path_info *pattern;
601};
602
603/*
604 * tomoyo_no_rewrite is a structure which is used for holding
605 * "deny_rewrite" entries.
606 * It has following fields.
607 *
608 * (1) "head" is "struct tomoyo_acl_head".
609 * (2) "pattern" is a pathname which is by default not permitted to modify
610 * already existing content.
611 */
612struct tomoyo_no_rewrite {
613 struct tomoyo_acl_head head;
614 const struct tomoyo_path_info *pattern;
615}; 705};
616 706
617/* 707/*
618 * tomoyo_transition_control is a structure which is used for holding 708 * Structure for "initialize_domain"/"no_initialize_domain"/"keep_domain"/
619 * "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain" 709 * "no_keep_domain" keyword.
620 * entries.
621 * It has following fields.
622 *
623 * (1) "head" is "struct tomoyo_acl_head".
624 * (2) "type" is type of this entry.
625 * (3) "is_last_name" is a bool which is true if "domainname" is "the last
626 * component of a domainname", false otherwise.
627 * (4) "domainname" which is "a domainname" or "the last component of a
628 * domainname".
629 * (5) "program" which is a program's pathname.
630 */ 710 */
631struct tomoyo_transition_control { 711struct tomoyo_transition_control {
632 struct tomoyo_acl_head head; 712 struct tomoyo_acl_head head;
@@ -637,32 +717,14 @@ struct tomoyo_transition_control {
637 const struct tomoyo_path_info *program; /* Maybe NULL */ 717 const struct tomoyo_path_info *program; /* Maybe NULL */
638}; 718};
639 719
640/* 720/* Structure for "aggregator" keyword. */
641 * tomoyo_aggregator is a structure which is used for holding
642 * "aggregator" entries.
643 * It has following fields.
644 *
645 * (1) "head" is "struct tomoyo_acl_head".
646 * (2) "original_name" which is originally requested name.
647 * (3) "aggregated_name" which is name to rewrite.
648 */
649struct tomoyo_aggregator { 721struct tomoyo_aggregator {
650 struct tomoyo_acl_head head; 722 struct tomoyo_acl_head head;
651 const struct tomoyo_path_info *original_name; 723 const struct tomoyo_path_info *original_name;
652 const struct tomoyo_path_info *aggregated_name; 724 const struct tomoyo_path_info *aggregated_name;
653}; 725};
654 726
655/* 727/* Structure for policy manager. */
656 * tomoyo_manager is a structure which is used for holding list of
657 * domainnames or programs which are permitted to modify configuration via
658 * /sys/kernel/security/tomoyo/ interface.
659 * It has following fields.
660 *
661 * (1) "head" is "struct tomoyo_acl_head".
662 * (2) "is_domain" is a bool which is true if "manager" is a domainname, false
663 * otherwise.
664 * (3) "manager" is a domainname or a program's pathname.
665 */
666struct tomoyo_manager { 728struct tomoyo_manager {
667 struct tomoyo_acl_head head; 729 struct tomoyo_acl_head head;
668 bool is_domain; /* True if manager is a domainname. */ 730 bool is_domain; /* True if manager is a domainname. */
@@ -677,6 +739,7 @@ struct tomoyo_preference {
677 bool permissive_verbose; 739 bool permissive_verbose;
678}; 740};
679 741
742/* Structure for /sys/kernel/security/tomnoyo/profile interface. */
680struct tomoyo_profile { 743struct tomoyo_profile {
681 const struct tomoyo_path_info *comment; 744 const struct tomoyo_path_info *comment;
682 struct tomoyo_preference *learning; 745 struct tomoyo_preference *learning;
@@ -685,323 +748,409 @@ struct tomoyo_profile {
685 struct tomoyo_preference preference; 748 struct tomoyo_preference preference;
686 u8 default_config; 749 u8 default_config;
687 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 750 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
751 unsigned int pref[TOMOYO_MAX_PREF];
752};
753
754/* Structure for representing YYYY/MM/DD hh/mm/ss. */
755struct tomoyo_time {
756 u16 year;
757 u8 month;
758 u8 day;
759 u8 hour;
760 u8 min;
761 u8 sec;
762};
763
764/* Structure for policy namespace. */
765struct tomoyo_policy_namespace {
766 /* Profile table. Memory is allocated as needed. */
767 struct tomoyo_profile *profile_ptr[TOMOYO_MAX_PROFILES];
768 /* List of "struct tomoyo_group". */
769 struct list_head group_list[TOMOYO_MAX_GROUP];
770 /* List of policy. */
771 struct list_head policy_list[TOMOYO_MAX_POLICY];
772 /* The global ACL referred by "use_group" keyword. */
773 struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS];
774 /* List for connecting to tomoyo_namespace_list list. */
775 struct list_head namespace_list;
776 /* Profile version. Currently only 20100903 is defined. */
777 unsigned int profile_version;
778 /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
779 const char *name;
688}; 780};
689 781
690/********** Function prototypes. **********/ 782/********** Function prototypes. **********/
691 783
692/* Check whether the given string starts with the given keyword. */
693bool tomoyo_str_starts(char **src, const char *find);
694/* Get tomoyo_realpath() of current process. */
695const char *tomoyo_get_exe(void);
696/* Format string. */
697void tomoyo_normalize_line(unsigned char *buffer);
698/* Print warning or error message on console. */
699void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
700 __attribute__ ((format(printf, 2, 3)));
701/* Check all profiles currently assigned to domains are defined. */
702void tomoyo_check_profile(void);
703/* Open operation for /sys/kernel/security/tomoyo/ interface. */
704int tomoyo_open_control(const u8 type, struct file *file);
705/* Close /sys/kernel/security/tomoyo/ interface. */
706int tomoyo_close_control(struct file *file);
707/* Poll operation for /sys/kernel/security/tomoyo/ interface. */
708int tomoyo_poll_control(struct file *file, poll_table *wait);
709/* Read operation for /sys/kernel/security/tomoyo/ interface. */
710int tomoyo_read_control(struct file *file, char __user *buffer,
711 const int buffer_len);
712/* Write operation for /sys/kernel/security/tomoyo/ interface. */
713int tomoyo_write_control(struct file *file, const char __user *buffer,
714 const int buffer_len);
715/* Check whether the domain has too many ACL entries to hold. */
716bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
717/* Print out of memory warning message. */
718void tomoyo_warn_oom(const char *function);
719/* Check whether the given name matches the given name_union. */
720const struct tomoyo_path_info *
721tomoyo_compare_name_union(const struct tomoyo_path_info *name,
722 const struct tomoyo_name_union *ptr);
723/* Check whether the given number matches the given number_union. */
724bool tomoyo_compare_number_union(const unsigned long value, 784bool tomoyo_compare_number_union(const unsigned long value,
725 const struct tomoyo_number_union *ptr); 785 const struct tomoyo_number_union *ptr);
726int tomoyo_get_mode(const u8 profile, const u8 index); 786bool tomoyo_condition(struct tomoyo_request_info *r,
727void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 787 const struct tomoyo_condition *cond);
728 __attribute__ ((format(printf, 2, 3)));
729/* Check whether the domainname is correct. */
730bool tomoyo_correct_domain(const unsigned char *domainname); 788bool tomoyo_correct_domain(const unsigned char *domainname);
731/* Check whether the token is correct. */
732bool tomoyo_correct_path(const char *filename); 789bool tomoyo_correct_path(const char *filename);
733bool tomoyo_correct_word(const char *string); 790bool tomoyo_correct_word(const char *string);
734/* Check whether the token can be a domainname. */
735bool tomoyo_domain_def(const unsigned char *buffer); 791bool tomoyo_domain_def(const unsigned char *buffer);
736bool tomoyo_parse_name_union(const char *filename, 792bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
737 struct tomoyo_name_union *ptr); 793bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
738/* Check whether the given filename matches the given path_group. */ 794 struct tomoyo_page_dump *dump);
739const struct tomoyo_path_info * 795bool tomoyo_memory_ok(void *ptr);
740tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
741 const struct tomoyo_group *group);
742/* Check whether the given value matches the given number_group. */
743bool tomoyo_number_matches_group(const unsigned long min, 796bool tomoyo_number_matches_group(const unsigned long min,
744 const unsigned long max, 797 const unsigned long max,
745 const struct tomoyo_group *group); 798 const struct tomoyo_group *group);
746/* Check whether the given filename matches the given pattern. */ 799bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
800 struct tomoyo_name_union *ptr);
801bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
802 struct tomoyo_number_union *ptr);
747bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 803bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
748 const struct tomoyo_path_info *pattern); 804 const struct tomoyo_path_info *pattern);
749 805bool tomoyo_permstr(const char *string, const char *keyword);
750bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); 806bool tomoyo_str_starts(char **src, const char *find);
751/* Tokenize a line. */
752bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
753/* Write domain policy violation warning message to console? */
754bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
755/* Fill "struct tomoyo_request_info". */
756int tomoyo_init_request_info(struct tomoyo_request_info *r,
757 struct tomoyo_domain_info *domain,
758 const u8 index);
759/* Check permission for mount operation. */
760int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
761 unsigned long flags, void *data_page);
762/* Create "aggregator" entry in exception policy. */
763int tomoyo_write_aggregator(char *data, const bool is_delete);
764int tomoyo_write_transition_control(char *data, const bool is_delete,
765 const u8 type);
766/*
767 * Create "allow_read/write", "allow_execute", "allow_read", "allow_write",
768 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
769 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
770 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and
771 * "allow_link" entry in domain policy.
772 */
773int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain,
774 const bool is_delete);
775/* Create "allow_read" entry in exception policy. */
776int tomoyo_write_globally_readable(char *data, const bool is_delete);
777/* Create "allow_mount" entry in domain policy. */
778int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
779 const bool is_delete);
780/* Create "deny_rewrite" entry in exception policy. */
781int tomoyo_write_no_rewrite(char *data, const bool is_delete);
782/* Create "file_pattern" entry in exception policy. */
783int tomoyo_write_pattern(char *data, const bool is_delete);
784/* Create "path_group"/"number_group" entry in exception policy. */
785int tomoyo_write_group(char *data, const bool is_delete, const u8 type);
786int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
787 __attribute__ ((format(printf, 2, 3)));
788/* Find a domain by the given name. */
789struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
790/* Find or create a domain by the given name. */
791struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
792 const u8 profile);
793struct tomoyo_profile *tomoyo_profile(const u8 profile);
794/*
795 * Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
796 */
797struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 type);
798
799/* Check mode for specified functionality. */
800unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
801 const u8 index);
802/* Fill in "struct tomoyo_path_info" members. */
803void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
804/* Run policy loader when /sbin/init starts. */
805void tomoyo_load_policy(const char *filename);
806
807void tomoyo_put_number_union(struct tomoyo_number_union *ptr);
808
809/* Convert binary string to ascii string. */
810char *tomoyo_encode(const char *str); 807char *tomoyo_encode(const char *str);
811 808char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
812/* 809 va_list args);
813 * Returns realpath(3) of the given pathname except that 810char *tomoyo_read_token(struct tomoyo_acl_param *param);
814 * ignores chroot'ed root and does not follow the final symlink.
815 */
816char *tomoyo_realpath_nofollow(const char *pathname);
817/*
818 * Returns realpath(3) of the given pathname except that
819 * ignores chroot'ed root and the pathname is already solved.
820 */
821char *tomoyo_realpath_from_path(struct path *path); 811char *tomoyo_realpath_from_path(struct path *path);
822/* Get patterned pathname. */ 812char *tomoyo_realpath_nofollow(const char *pathname);
823const char *tomoyo_pattern(const struct tomoyo_path_info *filename); 813const char *tomoyo_get_exe(void);
824 814const char *tomoyo_yesno(const unsigned int value);
825/* Check memory quota. */ 815const struct tomoyo_path_info *tomoyo_compare_name_union
826bool tomoyo_memory_ok(void *ptr); 816(const struct tomoyo_path_info *name, const struct tomoyo_name_union *ptr);
827void *tomoyo_commit_ok(void *data, const unsigned int size);
828
829/*
830 * Keep the given name on the RAM.
831 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
832 */
833const struct tomoyo_path_info *tomoyo_get_name(const char *name); 817const struct tomoyo_path_info *tomoyo_get_name(const char *name);
834 818const struct tomoyo_path_info *tomoyo_path_matches_group
835/* Check for memory usage. */ 819(const struct tomoyo_path_info *pathname, const struct tomoyo_group *group);
836void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
837
838/* Set memory quota. */
839int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
840
841/* Initialize mm related code. */
842void __init tomoyo_mm_init(void);
843int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
844 const struct tomoyo_path_info *filename);
845int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 820int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
846 struct path *path, const int flag); 821 struct path *path, const int flag);
847int tomoyo_path_number_perm(const u8 operation, struct path *path, 822int tomoyo_close_control(struct tomoyo_io_buffer *head);
848 unsigned long number); 823int tomoyo_find_next_domain(struct linux_binprm *bprm);
824int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
825 const u8 index);
826int tomoyo_init_request_info(struct tomoyo_request_info *r,
827 struct tomoyo_domain_info *domain,
828 const u8 index);
849int tomoyo_mkdev_perm(const u8 operation, struct path *path, 829int tomoyo_mkdev_perm(const u8 operation, struct path *path,
850 const unsigned int mode, unsigned int dev); 830 const unsigned int mode, unsigned int dev);
851int tomoyo_path_perm(const u8 operation, struct path *path); 831int tomoyo_mount_permission(char *dev_name, struct path *path,
832 const char *type, unsigned long flags,
833 void *data_page);
834int tomoyo_open_control(const u8 type, struct file *file);
852int tomoyo_path2_perm(const u8 operation, struct path *path1, 835int tomoyo_path2_perm(const u8 operation, struct path *path1,
853 struct path *path2); 836 struct path *path2);
854int tomoyo_find_next_domain(struct linux_binprm *bprm); 837int tomoyo_path_number_perm(const u8 operation, struct path *path,
855 838 unsigned long number);
856void tomoyo_print_ulong(char *buffer, const int buffer_len, 839int tomoyo_path_perm(const u8 operation, struct path *path,
857 const unsigned long value, const u8 type); 840 const char *target);
858 841int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
859/* Drop refcount on tomoyo_name_union. */ 842 const struct tomoyo_path_info *filename);
860void tomoyo_put_name_union(struct tomoyo_name_union *ptr); 843int tomoyo_poll_control(struct file *file, poll_table *wait);
861 844int tomoyo_poll_log(struct file *file, poll_table *wait);
862/* Run garbage collector. */ 845int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
863void tomoyo_run_gc(void); 846 __printf(2, 3);
864
865void tomoyo_memory_free(void *ptr);
866
867int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 847int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
868 bool is_delete, struct tomoyo_domain_info *domain, 848 struct tomoyo_acl_param *param,
869 bool (*check_duplicate) (const struct tomoyo_acl_info 849 bool (*check_duplicate)
870 *, 850 (const struct tomoyo_acl_info *,
871 const struct tomoyo_acl_info 851 const struct tomoyo_acl_info *),
872 *), 852 bool (*merge_duplicate)
873 bool (*merge_duplicate) (struct tomoyo_acl_info *, 853 (struct tomoyo_acl_info *, struct tomoyo_acl_info *,
874 struct tomoyo_acl_info *, 854 const bool));
875 const bool));
876int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 855int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
877 bool is_delete, struct list_head *list, 856 struct tomoyo_acl_param *param,
878 bool (*check_duplicate) (const struct tomoyo_acl_head 857 bool (*check_duplicate)
879 *, 858 (const struct tomoyo_acl_head *,
880 const struct tomoyo_acl_head 859 const struct tomoyo_acl_head *));
881 *)); 860int tomoyo_write_aggregator(struct tomoyo_acl_param *param);
861int tomoyo_write_file(struct tomoyo_acl_param *param);
862int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type);
863int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
864 const u8 type);
865ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
866 const int buffer_len);
867ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
868 const char __user *buffer, const int buffer_len);
869struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param);
870struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
871 const bool transit);
872struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
873struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
874 const u8 idx);
875struct tomoyo_policy_namespace *tomoyo_assign_namespace
876(const char *domainname);
877struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
878 const u8 profile);
879unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
880 const u8 index);
881u8 tomoyo_parse_ulong(unsigned long *result, char **str);
882void *tomoyo_commit_ok(void *data, const unsigned int size);
883void __init tomoyo_load_builtin_policy(void);
884void __init tomoyo_mm_init(void);
882void tomoyo_check_acl(struct tomoyo_request_info *r, 885void tomoyo_check_acl(struct tomoyo_request_info *r,
883 bool (*check_entry) (struct tomoyo_request_info *, 886 bool (*check_entry) (struct tomoyo_request_info *,
884 const struct tomoyo_acl_info *)); 887 const struct tomoyo_acl_info *));
888void tomoyo_check_profile(void);
889void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
890void tomoyo_del_condition(struct list_head *element);
891void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
892void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
893void 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);
897void tomoyo_memory_free(void *ptr);
898void tomoyo_normalize_line(unsigned char *buffer);
899void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
900void tomoyo_print_ulong(char *buffer, const int buffer_len,
901 const unsigned long value, const u8 type);
902void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
903void tomoyo_put_number_union(struct tomoyo_number_union *ptr);
904void tomoyo_read_log(struct tomoyo_io_buffer *head);
905void tomoyo_update_stat(const u8 index);
906void tomoyo_warn_oom(const char *function);
907void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
908 __printf(2, 3);
909void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
910 va_list args);
885 911
886/********** External variable definitions. **********/ 912/********** External variable definitions. **********/
887 913
888/* Lock for GC. */ 914extern bool tomoyo_policy_loaded;
889extern struct srcu_struct tomoyo_ss; 915extern const char * const tomoyo_condition_keyword
890 916[TOMOYO_MAX_CONDITION_KEYWORD];
891/* The list for "struct tomoyo_domain_info". */ 917extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS];
918extern const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
919 + TOMOYO_MAX_MAC_CATEGORY_INDEX];
920extern const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE];
921extern const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
922extern const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX];
923extern const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION];
924extern const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION];
925extern const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION];
926extern struct list_head tomoyo_condition_list;
892extern struct list_head tomoyo_domain_list; 927extern struct list_head tomoyo_domain_list;
893
894extern struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
895extern struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
896extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 928extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
897 929extern struct list_head tomoyo_namespace_list;
898/* Lock for protecting policy. */
899extern struct mutex tomoyo_policy_lock; 930extern struct mutex tomoyo_policy_lock;
900 931extern struct srcu_struct tomoyo_ss;
901/* Has /sbin/init started? */
902extern bool tomoyo_policy_loaded;
903
904/* The kernel's domain. */
905extern struct tomoyo_domain_info tomoyo_kernel_domain; 932extern struct tomoyo_domain_info tomoyo_kernel_domain;
906 933extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
907extern const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 934extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
908extern const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION]; 935extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
909extern const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION];
910extern const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION];
911
912extern unsigned int tomoyo_quota_for_query;
913extern unsigned int tomoyo_query_memory_size;
914 936
915/********** Inlined functions. **********/ 937/********** Inlined functions. **********/
916 938
939/**
940 * tomoyo_read_lock - Take lock for protecting policy.
941 *
942 * Returns index number for tomoyo_read_unlock().
943 */
917static inline int tomoyo_read_lock(void) 944static inline int tomoyo_read_lock(void)
918{ 945{
919 return srcu_read_lock(&tomoyo_ss); 946 return srcu_read_lock(&tomoyo_ss);
920} 947}
921 948
949/**
950 * tomoyo_read_unlock - Release lock for protecting policy.
951 *
952 * @idx: Index number returned by tomoyo_read_lock().
953 *
954 * Returns nothing.
955 */
922static inline void tomoyo_read_unlock(int idx) 956static inline void tomoyo_read_unlock(int idx)
923{ 957{
924 srcu_read_unlock(&tomoyo_ss, idx); 958 srcu_read_unlock(&tomoyo_ss, idx);
925} 959}
926 960
927/* strcmp() for "struct tomoyo_path_info" structure. */ 961/**
928static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, 962 * tomoyo_sys_getppid - Copy of getppid().
929 const struct tomoyo_path_info *b) 963 *
964 * Returns parent process's PID.
965 *
966 * Alpha does not have getppid() defined. To be able to build this module on
967 * Alpha, I have to copy getppid() from kernel/timer.c.
968 */
969static inline pid_t tomoyo_sys_getppid(void)
930{ 970{
931 return a->hash != b->hash || strcmp(a->name, b->name); 971 pid_t pid;
972 rcu_read_lock();
973 pid = task_tgid_vnr(current->real_parent);
974 rcu_read_unlock();
975 return pid;
932} 976}
933 977
934/** 978/**
935 * tomoyo_valid - Check whether the character is a valid char. 979 * tomoyo_sys_getpid - Copy of getpid().
936 * 980 *
937 * @c: The character to check. 981 * Returns current thread's PID.
938 * 982 *
939 * Returns true if @c is a valid character, false otherwise. 983 * Alpha does not have getpid() defined. To be able to build this module on
984 * Alpha, I have to copy getpid() from kernel/timer.c.
940 */ 985 */
941static inline bool tomoyo_valid(const unsigned char c) 986static inline pid_t tomoyo_sys_getpid(void)
942{ 987{
943 return c > ' ' && c < 127; 988 return task_tgid_vnr(current);
944} 989}
945 990
946/** 991/**
947 * tomoyo_invalid - Check whether the character is an invalid char. 992 * tomoyo_pathcmp - strcmp() for "struct tomoyo_path_info" structure.
948 * 993 *
949 * @c: The character to check. 994 * @a: Pointer to "struct tomoyo_path_info".
995 * @b: Pointer to "struct tomoyo_path_info".
950 * 996 *
951 * Returns true if @c is an invalid character, false otherwise. 997 * Returns true if @a == @b, false otherwise.
952 */ 998 */
953static inline bool tomoyo_invalid(const unsigned char c) 999static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
1000 const struct tomoyo_path_info *b)
954{ 1001{
955 return c && (c <= ' ' || c >= 127); 1002 return a->hash != b->hash || strcmp(a->name, b->name);
956} 1003}
957 1004
1005/**
1006 * tomoyo_put_name - Drop reference on "struct tomoyo_name".
1007 *
1008 * @name: Pointer to "struct tomoyo_path_info". Maybe NULL.
1009 *
1010 * Returns nothing.
1011 */
958static inline void tomoyo_put_name(const struct tomoyo_path_info *name) 1012static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
959{ 1013{
960 if (name) { 1014 if (name) {
961 struct tomoyo_name *ptr = 1015 struct tomoyo_name *ptr =
962 container_of(name, typeof(*ptr), entry); 1016 container_of(name, typeof(*ptr), entry);
963 atomic_dec(&ptr->users); 1017 atomic_dec(&ptr->head.users);
964 } 1018 }
965} 1019}
966 1020
1021/**
1022 * tomoyo_put_condition - Drop reference on "struct tomoyo_condition".
1023 *
1024 * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
1025 *
1026 * Returns nothing.
1027 */
1028static inline void tomoyo_put_condition(struct tomoyo_condition *cond)
1029{
1030 if (cond)
1031 atomic_dec(&cond->head.users);
1032}
1033
1034/**
1035 * tomoyo_put_group - Drop reference on "struct tomoyo_group".
1036 *
1037 * @group: Pointer to "struct tomoyo_group". Maybe NULL.
1038 *
1039 * Returns nothing.
1040 */
967static inline void tomoyo_put_group(struct tomoyo_group *group) 1041static inline void tomoyo_put_group(struct tomoyo_group *group)
968{ 1042{
969 if (group) 1043 if (group)
970 atomic_dec(&group->users); 1044 atomic_dec(&group->head.users);
971} 1045}
972 1046
1047/**
1048 * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
1049 *
1050 * Returns pointer to "struct tomoyo_domain_info" for current thread.
1051 */
973static inline struct tomoyo_domain_info *tomoyo_domain(void) 1052static inline struct tomoyo_domain_info *tomoyo_domain(void)
974{ 1053{
975 return current_cred()->security; 1054 return current_cred()->security;
976} 1055}
977 1056
1057/**
1058 * tomoyo_real_domain - Get "struct tomoyo_domain_info" for specified thread.
1059 *
1060 * @task: Pointer to "struct task_struct".
1061 *
1062 * Returns pointer to "struct tomoyo_security" for specified thread.
1063 */
978static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct 1064static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
979 *task) 1065 *task)
980{ 1066{
981 return task_cred_xxx(task, security); 1067 return task_cred_xxx(task, security);
982} 1068}
983 1069
984static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *p1, 1070/**
985 const struct tomoyo_acl_info *p2) 1071 * tomoyo_same_name_union - Check for duplicated "struct tomoyo_name_union" entry.
1072 *
1073 * @a: Pointer to "struct tomoyo_name_union".
1074 * @b: Pointer to "struct tomoyo_name_union".
1075 *
1076 * Returns true if @a == @b, false otherwise.
1077 */
1078static inline bool tomoyo_same_name_union
1079(const struct tomoyo_name_union *a, const struct tomoyo_name_union *b)
986{ 1080{
987 return p1->type == p2->type; 1081 return a->filename == b->filename && a->group == b->group;
988} 1082}
989 1083
990static inline bool tomoyo_same_name_union 1084/**
991(const struct tomoyo_name_union *p1, const struct tomoyo_name_union *p2) 1085 * tomoyo_same_number_union - Check for duplicated "struct tomoyo_number_union" entry.
1086 *
1087 * @a: Pointer to "struct tomoyo_number_union".
1088 * @b: Pointer to "struct tomoyo_number_union".
1089 *
1090 * Returns true if @a == @b, false otherwise.
1091 */
1092static inline bool tomoyo_same_number_union
1093(const struct tomoyo_number_union *a, const struct tomoyo_number_union *b)
992{ 1094{
993 return p1->filename == p2->filename && p1->group == p2->group && 1095 return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
994 p1->is_group == p2->is_group; 1096 a->group == b->group && a->value_type[0] == b->value_type[0] &&
1097 a->value_type[1] == b->value_type[1];
995} 1098}
996 1099
997static inline bool tomoyo_same_number_union 1100/**
998(const struct tomoyo_number_union *p1, const struct tomoyo_number_union *p2) 1101 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
1102 *
1103 * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
1104 */
1105static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
1106{
1107 return tomoyo_domain()->ns;
1108}
1109
1110#if defined(CONFIG_SLOB)
1111
1112/**
1113 * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
1114 *
1115 * @size: Size to be rounded up.
1116 *
1117 * Returns @size.
1118 *
1119 * Since SLOB does not round up, this function simply returns @size.
1120 */
1121static inline int tomoyo_round2(size_t size)
1122{
1123 return size;
1124}
1125
1126#else
1127
1128/**
1129 * tomoyo_round2 - Round up to power of 2 for calculating memory usage.
1130 *
1131 * @size: Size to be rounded up.
1132 *
1133 * Returns rounded size.
1134 *
1135 * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
1136 * (e.g.) 128 bytes.
1137 */
1138static inline int tomoyo_round2(size_t size)
999{ 1139{
1000 return p1->values[0] == p2->values[0] && p1->values[1] == p2->values[1] 1140#if PAGE_SIZE == 4096
1001 && p1->group == p2->group && p1->min_type == p2->min_type && 1141 size_t bsize = 32;
1002 p1->max_type == p2->max_type && p1->is_group == p2->is_group; 1142#else
1143 size_t bsize = 64;
1144#endif
1145 if (!size)
1146 return 0;
1147 while (size > bsize)
1148 bsize <<= 1;
1149 return bsize;
1003} 1150}
1004 1151
1152#endif
1153
1005/** 1154/**
1006 * list_for_each_cookie - iterate over a list with cookie. 1155 * list_for_each_cookie - iterate over a list with cookie.
1007 * @pos: the &struct list_head to use as a loop cursor. 1156 * @pos: the &struct list_head to use as a loop cursor.
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
new file mode 100644
index 000000000000..8a05f71eaf67
--- /dev/null
+++ b/security/tomoyo/condition.c
@@ -0,0 +1,1035 @@
1/*
2 * security/tomoyo/condition.c
3 *
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
6
7#include "common.h"
8#include <linux/slab.h>
9
10/* List of "struct tomoyo_condition". */
11LIST_HEAD(tomoyo_condition_list);
12
13/**
14 * tomoyo_argv - Check argv[] in "struct linux_binbrm".
15 *
16 * @index: Index number of @arg_ptr.
17 * @arg_ptr: Contents of argv[@index].
18 * @argc: Length of @argv.
19 * @argv: Pointer to "struct tomoyo_argv".
20 * @checked: Set to true if @argv[@index] was found.
21 *
22 * Returns true on success, false otherwise.
23 */
24static bool tomoyo_argv(const unsigned int index, const char *arg_ptr,
25 const int argc, const struct tomoyo_argv *argv,
26 u8 *checked)
27{
28 int i;
29 struct tomoyo_path_info arg;
30 arg.name = arg_ptr;
31 for (i = 0; i < argc; argv++, checked++, i++) {
32 bool result;
33 if (index != argv->index)
34 continue;
35 *checked = 1;
36 tomoyo_fill_path_info(&arg);
37 result = tomoyo_path_matches_pattern(&arg, argv->value);
38 if (argv->is_not)
39 result = !result;
40 if (!result)
41 return false;
42 }
43 return true;
44}
45
46/**
47 * tomoyo_envp - Check envp[] in "struct linux_binbrm".
48 *
49 * @env_name: The name of environment variable.
50 * @env_value: The value of environment variable.
51 * @envc: Length of @envp.
52 * @envp: Pointer to "struct tomoyo_envp".
53 * @checked: Set to true if @envp[@env_name] was found.
54 *
55 * Returns true on success, false otherwise.
56 */
57static bool tomoyo_envp(const char *env_name, const char *env_value,
58 const int envc, const struct tomoyo_envp *envp,
59 u8 *checked)
60{
61 int i;
62 struct tomoyo_path_info name;
63 struct tomoyo_path_info value;
64 name.name = env_name;
65 tomoyo_fill_path_info(&name);
66 value.name = env_value;
67 tomoyo_fill_path_info(&value);
68 for (i = 0; i < envc; envp++, checked++, i++) {
69 bool result;
70 if (!tomoyo_path_matches_pattern(&name, envp->name))
71 continue;
72 *checked = 1;
73 if (envp->value) {
74 result = tomoyo_path_matches_pattern(&value,
75 envp->value);
76 if (envp->is_not)
77 result = !result;
78 } else {
79 result = true;
80 if (!envp->is_not)
81 result = !result;
82 }
83 if (!result)
84 return false;
85 }
86 return true;
87}
88
89/**
90 * tomoyo_scan_bprm - Scan "struct linux_binprm".
91 *
92 * @ee: Pointer to "struct tomoyo_execve".
93 * @argc: Length of @argc.
94 * @argv: Pointer to "struct tomoyo_argv".
95 * @envc: Length of @envp.
96 * @envp: Poiner to "struct tomoyo_envp".
97 *
98 * Returns true on success, false otherwise.
99 */
100static bool tomoyo_scan_bprm(struct tomoyo_execve *ee,
101 const u16 argc, const struct tomoyo_argv *argv,
102 const u16 envc, const struct tomoyo_envp *envp)
103{
104 struct linux_binprm *bprm = ee->bprm;
105 struct tomoyo_page_dump *dump = &ee->dump;
106 char *arg_ptr = ee->tmp;
107 int arg_len = 0;
108 unsigned long pos = bprm->p;
109 int offset = pos % PAGE_SIZE;
110 int argv_count = bprm->argc;
111 int envp_count = bprm->envc;
112 bool result = true;
113 u8 local_checked[32];
114 u8 *checked;
115 if (argc + envc <= sizeof(local_checked)) {
116 checked = local_checked;
117 memset(local_checked, 0, sizeof(local_checked));
118 } else {
119 checked = kzalloc(argc + envc, GFP_NOFS);
120 if (!checked)
121 return false;
122 }
123 while (argv_count || envp_count) {
124 if (!tomoyo_dump_page(bprm, pos, dump)) {
125 result = false;
126 goto out;
127 }
128 pos += PAGE_SIZE - offset;
129 while (offset < PAGE_SIZE) {
130 /* Read. */
131 const char *kaddr = dump->data;
132 const unsigned char c = kaddr[offset++];
133 if (c && arg_len < TOMOYO_EXEC_TMPSIZE - 10) {
134 if (c == '\\') {
135 arg_ptr[arg_len++] = '\\';
136 arg_ptr[arg_len++] = '\\';
137 } else if (c > ' ' && c < 127) {
138 arg_ptr[arg_len++] = c;
139 } else {
140 arg_ptr[arg_len++] = '\\';
141 arg_ptr[arg_len++] = (c >> 6) + '0';
142 arg_ptr[arg_len++] =
143 ((c >> 3) & 7) + '0';
144 arg_ptr[arg_len++] = (c & 7) + '0';
145 }
146 } else {
147 arg_ptr[arg_len] = '\0';
148 }
149 if (c)
150 continue;
151 /* Check. */
152 if (argv_count) {
153 if (!tomoyo_argv(bprm->argc - argv_count,
154 arg_ptr, argc, argv,
155 checked)) {
156 result = false;
157 break;
158 }
159 argv_count--;
160 } else if (envp_count) {
161 char *cp = strchr(arg_ptr, '=');
162 if (cp) {
163 *cp = '\0';
164 if (!tomoyo_envp(arg_ptr, cp + 1,
165 envc, envp,
166 checked + argc)) {
167 result = false;
168 break;
169 }
170 }
171 envp_count--;
172 } else {
173 break;
174 }
175 arg_len = 0;
176 }
177 offset = 0;
178 if (!result)
179 break;
180 }
181out:
182 if (result) {
183 int i;
184 /* Check not-yet-checked entries. */
185 for (i = 0; i < argc; i++) {
186 if (checked[i])
187 continue;
188 /*
189 * Return true only if all unchecked indexes in
190 * bprm->argv[] are not matched.
191 */
192 if (argv[i].is_not)
193 continue;
194 result = false;
195 break;
196 }
197 for (i = 0; i < envc; envp++, i++) {
198 if (checked[argc + i])
199 continue;
200 /*
201 * Return true only if all unchecked environ variables
202 * in bprm->envp[] are either undefined or not matched.
203 */
204 if ((!envp->value && !envp->is_not) ||
205 (envp->value && envp->is_not))
206 continue;
207 result = false;
208 break;
209 }
210 }
211 if (checked != local_checked)
212 kfree(checked);
213 return result;
214}
215
216/**
217 * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition".
218 *
219 * @file: Pointer to "struct file".
220 * @ptr: Pointer to "struct tomoyo_name_union".
221 * @match: True if "exec.realpath=", false if "exec.realpath!=".
222 *
223 * Returns true on success, false otherwise.
224 */
225static bool tomoyo_scan_exec_realpath(struct file *file,
226 const struct tomoyo_name_union *ptr,
227 const bool match)
228{
229 bool result;
230 struct tomoyo_path_info exe;
231 if (!file)
232 return false;
233 exe.name = tomoyo_realpath_from_path(&file->f_path);
234 if (!exe.name)
235 return false;
236 tomoyo_fill_path_info(&exe);
237 result = tomoyo_compare_name_union(&exe, ptr);
238 kfree(exe.name);
239 return result == match;
240}
241
242/**
243 * tomoyo_get_dqword - tomoyo_get_name() for a quoted string.
244 *
245 * @start: String to save.
246 *
247 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
248 */
249static const struct tomoyo_path_info *tomoyo_get_dqword(char *start)
250{
251 char *cp = start + strlen(start) - 1;
252 if (cp == start || *start++ != '"' || *cp != '"')
253 return NULL;
254 *cp = '\0';
255 if (*start && !tomoyo_correct_word(start))
256 return NULL;
257 return tomoyo_get_name(start);
258}
259
260/**
261 * tomoyo_parse_name_union_quoted - Parse a quoted word.
262 *
263 * @param: Pointer to "struct tomoyo_acl_param".
264 * @ptr: Pointer to "struct tomoyo_name_union".
265 *
266 * Returns true on success, false otherwise.
267 */
268static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param,
269 struct tomoyo_name_union *ptr)
270{
271 char *filename = param->data;
272 if (*filename == '@')
273 return tomoyo_parse_name_union(param, ptr);
274 ptr->filename = tomoyo_get_dqword(filename);
275 return ptr->filename != NULL;
276}
277
278/**
279 * tomoyo_parse_argv - Parse an argv[] condition part.
280 *
281 * @left: Lefthand value.
282 * @right: Righthand value.
283 * @argv: Pointer to "struct tomoyo_argv".
284 *
285 * Returns true on success, false otherwise.
286 */
287static bool tomoyo_parse_argv(char *left, char *right,
288 struct tomoyo_argv *argv)
289{
290 if (tomoyo_parse_ulong(&argv->index, &left) !=
291 TOMOYO_VALUE_TYPE_DECIMAL || *left++ != ']' || *left)
292 return false;
293 argv->value = tomoyo_get_dqword(right);
294 return argv->value != NULL;
295}
296
297/**
298 * tomoyo_parse_envp - Parse an envp[] condition part.
299 *
300 * @left: Lefthand value.
301 * @right: Righthand value.
302 * @envp: Pointer to "struct tomoyo_envp".
303 *
304 * Returns true on success, false otherwise.
305 */
306static bool tomoyo_parse_envp(char *left, char *right,
307 struct tomoyo_envp *envp)
308{
309 const struct tomoyo_path_info *name;
310 const struct tomoyo_path_info *value;
311 char *cp = left + strlen(left) - 1;
312 if (*cp-- != ']' || *cp != '"')
313 goto out;
314 *cp = '\0';
315 if (!tomoyo_correct_word(left))
316 goto out;
317 name = tomoyo_get_name(left);
318 if (!name)
319 goto out;
320 if (!strcmp(right, "NULL")) {
321 value = NULL;
322 } else {
323 value = tomoyo_get_dqword(right);
324 if (!value) {
325 tomoyo_put_name(name);
326 goto out;
327 }
328 }
329 envp->name = name;
330 envp->value = value;
331 return true;
332out:
333 return false;
334}
335
336/**
337 * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry.
338 *
339 * @a: Pointer to "struct tomoyo_condition".
340 * @b: Pointer to "struct tomoyo_condition".
341 *
342 * Returns true if @a == @b, false otherwise.
343 */
344static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
345 const struct tomoyo_condition *b)
346{
347 return a->size == b->size && a->condc == b->condc &&
348 a->numbers_count == b->numbers_count &&
349 a->names_count == b->names_count &&
350 a->argc == b->argc && a->envc == b->envc &&
351 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
352}
353
354/**
355 * tomoyo_condition_type - Get condition type.
356 *
357 * @word: Keyword string.
358 *
359 * Returns one of values in "enum tomoyo_conditions_index" on success,
360 * TOMOYO_MAX_CONDITION_KEYWORD otherwise.
361 */
362static u8 tomoyo_condition_type(const char *word)
363{
364 u8 i;
365 for (i = 0; i < TOMOYO_MAX_CONDITION_KEYWORD; i++) {
366 if (!strcmp(word, tomoyo_condition_keyword[i]))
367 break;
368 }
369 return i;
370}
371
372/* Define this to enable debug mode. */
373/* #define DEBUG_CONDITION */
374
375#ifdef DEBUG_CONDITION
376#define dprintk printk
377#else
378#define dprintk(...) do { } while (0)
379#endif
380
381/**
382 * tomoyo_commit_condition - Commit "struct tomoyo_condition".
383 *
384 * @entry: Pointer to "struct tomoyo_condition".
385 *
386 * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
387 *
388 * This function merges duplicated entries. This function returns NULL if
389 * @entry is not duplicated but memory quota for policy has exceeded.
390 */
391static struct tomoyo_condition *tomoyo_commit_condition
392(struct tomoyo_condition *entry)
393{
394 struct tomoyo_condition *ptr;
395 bool found = false;
396 if (mutex_lock_interruptible(&tomoyo_policy_lock)) {
397 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
398 ptr = NULL;
399 found = true;
400 goto out;
401 }
402 list_for_each_entry_rcu(ptr, &tomoyo_condition_list, head.list) {
403 if (!tomoyo_same_condition(ptr, entry))
404 continue;
405 /* Same entry found. Share this entry. */
406 atomic_inc(&ptr->head.users);
407 found = true;
408 break;
409 }
410 if (!found) {
411 if (tomoyo_memory_ok(entry)) {
412 atomic_set(&entry->head.users, 1);
413 list_add_rcu(&entry->head.list,
414 &tomoyo_condition_list);
415 } else {
416 found = true;
417 ptr = NULL;
418 }
419 }
420 mutex_unlock(&tomoyo_policy_lock);
421out:
422 if (found) {
423 tomoyo_del_condition(&entry->head.list);
424 kfree(entry);
425 entry = ptr;
426 }
427 return entry;
428}
429
430/**
431 * tomoyo_get_condition - Parse condition part.
432 *
433 * @param: Pointer to "struct tomoyo_acl_param".
434 *
435 * Returns pointer to "struct tomoyo_condition" on success, NULL otherwise.
436 */
437struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
438{
439 struct tomoyo_condition *entry = NULL;
440 struct tomoyo_condition_element *condp = NULL;
441 struct tomoyo_number_union *numbers_p = NULL;
442 struct tomoyo_name_union *names_p = NULL;
443 struct tomoyo_argv *argv = NULL;
444 struct tomoyo_envp *envp = NULL;
445 struct tomoyo_condition e = { };
446 char * const start_of_string = param->data;
447 char * const end_of_string = start_of_string + strlen(start_of_string);
448 char *pos;
449rerun:
450 pos = start_of_string;
451 while (1) {
452 u8 left = -1;
453 u8 right = -1;
454 char *left_word = pos;
455 char *cp;
456 char *right_word;
457 bool is_not;
458 if (!*left_word)
459 break;
460 /*
461 * Since left-hand condition does not allow use of "path_group"
462 * or "number_group" and environment variable's names do not
463 * accept '=', it is guaranteed that the original line consists
464 * of one or more repetition of $left$operator$right blocks
465 * where "$left is free from '=' and ' '" and "$operator is
466 * either '=' or '!='" and "$right is free from ' '".
467 * Therefore, we can reconstruct the original line at the end
468 * of dry run even if we overwrite $operator with '\0'.
469 */
470 cp = strchr(pos, ' ');
471 if (cp) {
472 *cp = '\0'; /* Will restore later. */
473 pos = cp + 1;
474 } else {
475 pos = "";
476 }
477 right_word = strchr(left_word, '=');
478 if (!right_word || right_word == left_word)
479 goto out;
480 is_not = *(right_word - 1) == '!';
481 if (is_not)
482 *(right_word++ - 1) = '\0'; /* Will restore later. */
483 else if (*(right_word + 1) != '=')
484 *right_word++ = '\0'; /* Will restore later. */
485 else
486 goto out;
487 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
488 is_not ? "!" : "", right_word);
489 if (!strncmp(left_word, "exec.argv[", 10)) {
490 if (!argv) {
491 e.argc++;
492 e.condc++;
493 } else {
494 e.argc--;
495 e.condc--;
496 left = TOMOYO_ARGV_ENTRY;
497 argv->is_not = is_not;
498 if (!tomoyo_parse_argv(left_word + 10,
499 right_word, argv++))
500 goto out;
501 }
502 goto store_value;
503 }
504 if (!strncmp(left_word, "exec.envp[\"", 11)) {
505 if (!envp) {
506 e.envc++;
507 e.condc++;
508 } else {
509 e.envc--;
510 e.condc--;
511 left = TOMOYO_ENVP_ENTRY;
512 envp->is_not = is_not;
513 if (!tomoyo_parse_envp(left_word + 11,
514 right_word, envp++))
515 goto out;
516 }
517 goto store_value;
518 }
519 left = tomoyo_condition_type(left_word);
520 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
521 left);
522 if (left == TOMOYO_MAX_CONDITION_KEYWORD) {
523 if (!numbers_p) {
524 e.numbers_count++;
525 } else {
526 e.numbers_count--;
527 left = TOMOYO_NUMBER_UNION;
528 param->data = left_word;
529 if (*left_word == '@' ||
530 !tomoyo_parse_number_union(param,
531 numbers_p++))
532 goto out;
533 }
534 }
535 if (!condp)
536 e.condc++;
537 else
538 e.condc--;
539 if (left == TOMOYO_EXEC_REALPATH ||
540 left == TOMOYO_SYMLINK_TARGET) {
541 if (!names_p) {
542 e.names_count++;
543 } else {
544 e.names_count--;
545 right = TOMOYO_NAME_UNION;
546 param->data = right_word;
547 if (!tomoyo_parse_name_union_quoted(param,
548 names_p++))
549 goto out;
550 }
551 goto store_value;
552 }
553 right = tomoyo_condition_type(right_word);
554 if (right == TOMOYO_MAX_CONDITION_KEYWORD) {
555 if (!numbers_p) {
556 e.numbers_count++;
557 } else {
558 e.numbers_count--;
559 right = TOMOYO_NUMBER_UNION;
560 param->data = right_word;
561 if (!tomoyo_parse_number_union(param,
562 numbers_p++))
563 goto out;
564 }
565 }
566store_value:
567 if (!condp) {
568 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
569 "match=%u\n", __LINE__, left, right, !is_not);
570 continue;
571 }
572 condp->left = left;
573 condp->right = right;
574 condp->equals = !is_not;
575 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
576 __LINE__, condp->left, condp->right,
577 condp->equals);
578 condp++;
579 }
580 dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
581 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
582 e.envc);
583 if (entry) {
584 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
585 e.condc);
586 return tomoyo_commit_condition(entry);
587 }
588 e.size = sizeof(*entry)
589 + e.condc * sizeof(struct tomoyo_condition_element)
590 + e.numbers_count * sizeof(struct tomoyo_number_union)
591 + e.names_count * sizeof(struct tomoyo_name_union)
592 + e.argc * sizeof(struct tomoyo_argv)
593 + e.envc * sizeof(struct tomoyo_envp);
594 entry = kzalloc(e.size, GFP_NOFS);
595 if (!entry)
596 return NULL;
597 *entry = e;
598 condp = (struct tomoyo_condition_element *) (entry + 1);
599 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
600 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
601 argv = (struct tomoyo_argv *) (names_p + e.names_count);
602 envp = (struct tomoyo_envp *) (argv + e.argc);
603 {
604 bool flag = false;
605 for (pos = start_of_string; pos < end_of_string; pos++) {
606 if (*pos)
607 continue;
608 if (flag) /* Restore " ". */
609 *pos = ' ';
610 else if (*(pos + 1) == '=') /* Restore "!=". */
611 *pos = '!';
612 else /* Restore "=". */
613 *pos = '=';
614 flag = !flag;
615 }
616 }
617 goto rerun;
618out:
619 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
620 if (entry) {
621 tomoyo_del_condition(&entry->head.list);
622 kfree(entry);
623 }
624 return NULL;
625}
626
627/**
628 * tomoyo_get_attributes - Revalidate "struct inode".
629 *
630 * @obj: Pointer to "struct tomoyo_obj_info".
631 *
632 * Returns nothing.
633 */
634void tomoyo_get_attributes(struct tomoyo_obj_info *obj)
635{
636 u8 i;
637 struct dentry *dentry = NULL;
638
639 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
640 struct inode *inode;
641 switch (i) {
642 case TOMOYO_PATH1:
643 dentry = obj->path1.dentry;
644 if (!dentry)
645 continue;
646 break;
647 case TOMOYO_PATH2:
648 dentry = obj->path2.dentry;
649 if (!dentry)
650 continue;
651 break;
652 default:
653 if (!dentry)
654 continue;
655 dentry = dget_parent(dentry);
656 break;
657 }
658 inode = dentry->d_inode;
659 if (inode) {
660 struct tomoyo_mini_stat *stat = &obj->stat[i];
661 stat->uid = inode->i_uid;
662 stat->gid = inode->i_gid;
663 stat->ino = inode->i_ino;
664 stat->mode = inode->i_mode;
665 stat->dev = inode->i_sb->s_dev;
666 stat->rdev = inode->i_rdev;
667 obj->stat_valid[i] = true;
668 }
669 if (i & 1) /* i == TOMOYO_PATH1_PARENT ||
670 i == TOMOYO_PATH2_PARENT */
671 dput(dentry);
672 }
673}
674
675/**
676 * tomoyo_condition - Check condition part.
677 *
678 * @r: Pointer to "struct tomoyo_request_info".
679 * @cond: Pointer to "struct tomoyo_condition". Maybe NULL.
680 *
681 * Returns true on success, false otherwise.
682 *
683 * Caller holds tomoyo_read_lock().
684 */
685bool tomoyo_condition(struct tomoyo_request_info *r,
686 const struct tomoyo_condition *cond)
687{
688 u32 i;
689 unsigned long min_v[2] = { 0, 0 };
690 unsigned long max_v[2] = { 0, 0 };
691 const struct tomoyo_condition_element *condp;
692 const struct tomoyo_number_union *numbers_p;
693 const struct tomoyo_name_union *names_p;
694 const struct tomoyo_argv *argv;
695 const struct tomoyo_envp *envp;
696 struct tomoyo_obj_info *obj;
697 u16 condc;
698 u16 argc;
699 u16 envc;
700 struct linux_binprm *bprm = NULL;
701 if (!cond)
702 return true;
703 condc = cond->condc;
704 argc = cond->argc;
705 envc = cond->envc;
706 obj = r->obj;
707 if (r->ee)
708 bprm = r->ee->bprm;
709 if (!bprm && (argc || envc))
710 return false;
711 condp = (struct tomoyo_condition_element *) (cond + 1);
712 numbers_p = (const struct tomoyo_number_union *) (condp + condc);
713 names_p = (const struct tomoyo_name_union *)
714 (numbers_p + cond->numbers_count);
715 argv = (const struct tomoyo_argv *) (names_p + cond->names_count);
716 envp = (const struct tomoyo_envp *) (argv + argc);
717 for (i = 0; i < condc; i++) {
718 const bool match = condp->equals;
719 const u8 left = condp->left;
720 const u8 right = condp->right;
721 bool is_bitop[2] = { false, false };
722 u8 j;
723 condp++;
724 /* Check argv[] and envp[] later. */
725 if (left == TOMOYO_ARGV_ENTRY || left == TOMOYO_ENVP_ENTRY)
726 continue;
727 /* Check string expressions. */
728 if (right == TOMOYO_NAME_UNION) {
729 const struct tomoyo_name_union *ptr = names_p++;
730 switch (left) {
731 struct tomoyo_path_info *symlink;
732 struct tomoyo_execve *ee;
733 struct file *file;
734 case TOMOYO_SYMLINK_TARGET:
735 symlink = obj ? obj->symlink_target : NULL;
736 if (!symlink ||
737 !tomoyo_compare_name_union(symlink, ptr)
738 == match)
739 goto out;
740 break;
741 case TOMOYO_EXEC_REALPATH:
742 ee = r->ee;
743 file = ee ? ee->bprm->file : NULL;
744 if (!tomoyo_scan_exec_realpath(file, ptr,
745 match))
746 goto out;
747 break;
748 }
749 continue;
750 }
751 /* Check numeric or bit-op expressions. */
752 for (j = 0; j < 2; j++) {
753 const u8 index = j ? right : left;
754 unsigned long value = 0;
755 switch (index) {
756 case TOMOYO_TASK_UID:
757 value = current_uid();
758 break;
759 case TOMOYO_TASK_EUID:
760 value = current_euid();
761 break;
762 case TOMOYO_TASK_SUID:
763 value = current_suid();
764 break;
765 case TOMOYO_TASK_FSUID:
766 value = current_fsuid();
767 break;
768 case TOMOYO_TASK_GID:
769 value = current_gid();
770 break;
771 case TOMOYO_TASK_EGID:
772 value = current_egid();
773 break;
774 case TOMOYO_TASK_SGID:
775 value = current_sgid();
776 break;
777 case TOMOYO_TASK_FSGID:
778 value = current_fsgid();
779 break;
780 case TOMOYO_TASK_PID:
781 value = tomoyo_sys_getpid();
782 break;
783 case TOMOYO_TASK_PPID:
784 value = tomoyo_sys_getppid();
785 break;
786 case TOMOYO_TYPE_IS_SOCKET:
787 value = S_IFSOCK;
788 break;
789 case TOMOYO_TYPE_IS_SYMLINK:
790 value = S_IFLNK;
791 break;
792 case TOMOYO_TYPE_IS_FILE:
793 value = S_IFREG;
794 break;
795 case TOMOYO_TYPE_IS_BLOCK_DEV:
796 value = S_IFBLK;
797 break;
798 case TOMOYO_TYPE_IS_DIRECTORY:
799 value = S_IFDIR;
800 break;
801 case TOMOYO_TYPE_IS_CHAR_DEV:
802 value = S_IFCHR;
803 break;
804 case TOMOYO_TYPE_IS_FIFO:
805 value = S_IFIFO;
806 break;
807 case TOMOYO_MODE_SETUID:
808 value = S_ISUID;
809 break;
810 case TOMOYO_MODE_SETGID:
811 value = S_ISGID;
812 break;
813 case TOMOYO_MODE_STICKY:
814 value = S_ISVTX;
815 break;
816 case TOMOYO_MODE_OWNER_READ:
817 value = S_IRUSR;
818 break;
819 case TOMOYO_MODE_OWNER_WRITE:
820 value = S_IWUSR;
821 break;
822 case TOMOYO_MODE_OWNER_EXECUTE:
823 value = S_IXUSR;
824 break;
825 case TOMOYO_MODE_GROUP_READ:
826 value = S_IRGRP;
827 break;
828 case TOMOYO_MODE_GROUP_WRITE:
829 value = S_IWGRP;
830 break;
831 case TOMOYO_MODE_GROUP_EXECUTE:
832 value = S_IXGRP;
833 break;
834 case TOMOYO_MODE_OTHERS_READ:
835 value = S_IROTH;
836 break;
837 case TOMOYO_MODE_OTHERS_WRITE:
838 value = S_IWOTH;
839 break;
840 case TOMOYO_MODE_OTHERS_EXECUTE:
841 value = S_IXOTH;
842 break;
843 case TOMOYO_EXEC_ARGC:
844 if (!bprm)
845 goto out;
846 value = bprm->argc;
847 break;
848 case TOMOYO_EXEC_ENVC:
849 if (!bprm)
850 goto out;
851 value = bprm->envc;
852 break;
853 case TOMOYO_NUMBER_UNION:
854 /* Fetch values later. */
855 break;
856 default:
857 if (!obj)
858 goto out;
859 if (!obj->validate_done) {
860 tomoyo_get_attributes(obj);
861 obj->validate_done = true;
862 }
863 {
864 u8 stat_index;
865 struct tomoyo_mini_stat *stat;
866 switch (index) {
867 case TOMOYO_PATH1_UID:
868 case TOMOYO_PATH1_GID:
869 case TOMOYO_PATH1_INO:
870 case TOMOYO_PATH1_MAJOR:
871 case TOMOYO_PATH1_MINOR:
872 case TOMOYO_PATH1_TYPE:
873 case TOMOYO_PATH1_DEV_MAJOR:
874 case TOMOYO_PATH1_DEV_MINOR:
875 case TOMOYO_PATH1_PERM:
876 stat_index = TOMOYO_PATH1;
877 break;
878 case TOMOYO_PATH2_UID:
879 case TOMOYO_PATH2_GID:
880 case TOMOYO_PATH2_INO:
881 case TOMOYO_PATH2_MAJOR:
882 case TOMOYO_PATH2_MINOR:
883 case TOMOYO_PATH2_TYPE:
884 case TOMOYO_PATH2_DEV_MAJOR:
885 case TOMOYO_PATH2_DEV_MINOR:
886 case TOMOYO_PATH2_PERM:
887 stat_index = TOMOYO_PATH2;
888 break;
889 case TOMOYO_PATH1_PARENT_UID:
890 case TOMOYO_PATH1_PARENT_GID:
891 case TOMOYO_PATH1_PARENT_INO:
892 case TOMOYO_PATH1_PARENT_PERM:
893 stat_index =
894 TOMOYO_PATH1_PARENT;
895 break;
896 case TOMOYO_PATH2_PARENT_UID:
897 case TOMOYO_PATH2_PARENT_GID:
898 case TOMOYO_PATH2_PARENT_INO:
899 case TOMOYO_PATH2_PARENT_PERM:
900 stat_index =
901 TOMOYO_PATH2_PARENT;
902 break;
903 default:
904 goto out;
905 }
906 if (!obj->stat_valid[stat_index])
907 goto out;
908 stat = &obj->stat[stat_index];
909 switch (index) {
910 case TOMOYO_PATH1_UID:
911 case TOMOYO_PATH2_UID:
912 case TOMOYO_PATH1_PARENT_UID:
913 case TOMOYO_PATH2_PARENT_UID:
914 value = stat->uid;
915 break;
916 case TOMOYO_PATH1_GID:
917 case TOMOYO_PATH2_GID:
918 case TOMOYO_PATH1_PARENT_GID:
919 case TOMOYO_PATH2_PARENT_GID:
920 value = stat->gid;
921 break;
922 case TOMOYO_PATH1_INO:
923 case TOMOYO_PATH2_INO:
924 case TOMOYO_PATH1_PARENT_INO:
925 case TOMOYO_PATH2_PARENT_INO:
926 value = stat->ino;
927 break;
928 case TOMOYO_PATH1_MAJOR:
929 case TOMOYO_PATH2_MAJOR:
930 value = MAJOR(stat->dev);
931 break;
932 case TOMOYO_PATH1_MINOR:
933 case TOMOYO_PATH2_MINOR:
934 value = MINOR(stat->dev);
935 break;
936 case TOMOYO_PATH1_TYPE:
937 case TOMOYO_PATH2_TYPE:
938 value = stat->mode & S_IFMT;
939 break;
940 case TOMOYO_PATH1_DEV_MAJOR:
941 case TOMOYO_PATH2_DEV_MAJOR:
942 value = MAJOR(stat->rdev);
943 break;
944 case TOMOYO_PATH1_DEV_MINOR:
945 case TOMOYO_PATH2_DEV_MINOR:
946 value = MINOR(stat->rdev);
947 break;
948 case TOMOYO_PATH1_PERM:
949 case TOMOYO_PATH2_PERM:
950 case TOMOYO_PATH1_PARENT_PERM:
951 case TOMOYO_PATH2_PARENT_PERM:
952 value = stat->mode & S_IALLUGO;
953 break;
954 }
955 }
956 break;
957 }
958 max_v[j] = value;
959 min_v[j] = value;
960 switch (index) {
961 case TOMOYO_MODE_SETUID:
962 case TOMOYO_MODE_SETGID:
963 case TOMOYO_MODE_STICKY:
964 case TOMOYO_MODE_OWNER_READ:
965 case TOMOYO_MODE_OWNER_WRITE:
966 case TOMOYO_MODE_OWNER_EXECUTE:
967 case TOMOYO_MODE_GROUP_READ:
968 case TOMOYO_MODE_GROUP_WRITE:
969 case TOMOYO_MODE_GROUP_EXECUTE:
970 case TOMOYO_MODE_OTHERS_READ:
971 case TOMOYO_MODE_OTHERS_WRITE:
972 case TOMOYO_MODE_OTHERS_EXECUTE:
973 is_bitop[j] = true;
974 }
975 }
976 if (left == TOMOYO_NUMBER_UNION) {
977 /* Fetch values now. */
978 const struct tomoyo_number_union *ptr = numbers_p++;
979 min_v[0] = ptr->values[0];
980 max_v[0] = ptr->values[1];
981 }
982 if (right == TOMOYO_NUMBER_UNION) {
983 /* Fetch values now. */
984 const struct tomoyo_number_union *ptr = numbers_p++;
985 if (ptr->group) {
986 if (tomoyo_number_matches_group(min_v[0],
987 max_v[0],
988 ptr->group)
989 == match)
990 continue;
991 } else {
992 if ((min_v[0] <= ptr->values[1] &&
993 max_v[0] >= ptr->values[0]) == match)
994 continue;
995 }
996 goto out;
997 }
998 /*
999 * Bit operation is valid only when counterpart value
1000 * represents permission.
1001 */
1002 if (is_bitop[0] && is_bitop[1]) {
1003 goto out;
1004 } else if (is_bitop[0]) {
1005 switch (right) {
1006 case TOMOYO_PATH1_PERM:
1007 case TOMOYO_PATH1_PARENT_PERM:
1008 case TOMOYO_PATH2_PERM:
1009 case TOMOYO_PATH2_PARENT_PERM:
1010 if (!(max_v[0] & max_v[1]) == !match)
1011 continue;
1012 }
1013 goto out;
1014 } else if (is_bitop[1]) {
1015 switch (left) {
1016 case TOMOYO_PATH1_PERM:
1017 case TOMOYO_PATH1_PARENT_PERM:
1018 case TOMOYO_PATH2_PERM:
1019 case TOMOYO_PATH2_PARENT_PERM:
1020 if (!(max_v[0] & max_v[1]) == !match)
1021 continue;
1022 }
1023 goto out;
1024 }
1025 /* Normal value range comparison. */
1026 if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match)
1027 continue;
1028out:
1029 return false;
1030 }
1031 /* Check argv[] and envp[] now. */
1032 if (r->ee && (argc || envc))
1033 return tomoyo_scan_bprm(r->ee, argc, argv, envc, envp);
1034 return true;
1035}
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 35388408e475..cd0f92d88bb4 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/domain.c 2 * security/tomoyo/domain.c
3 * 3 *
4 * Domain transition functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
@@ -20,8 +18,7 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
20 * 18 *
21 * @new_entry: Pointer to "struct tomoyo_acl_info". 19 * @new_entry: Pointer to "struct tomoyo_acl_info".
22 * @size: Size of @new_entry in bytes. 20 * @size: Size of @new_entry in bytes.
23 * @is_delete: True if it is a delete request. 21 * @param: Pointer to "struct tomoyo_acl_param".
24 * @list: Pointer to "struct list_head".
25 * @check_duplicate: Callback function to find duplicated entry. 22 * @check_duplicate: Callback function to find duplicated entry.
26 * 23 *
27 * Returns 0 on success, negative value otherwise. 24 * Returns 0 on success, negative value otherwise.
@@ -29,25 +26,26 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
29 * Caller holds tomoyo_read_lock(). 26 * Caller holds tomoyo_read_lock().
30 */ 27 */
31int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 28int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
32 bool is_delete, struct list_head *list, 29 struct tomoyo_acl_param *param,
33 bool (*check_duplicate) (const struct tomoyo_acl_head 30 bool (*check_duplicate) (const struct tomoyo_acl_head
34 *, 31 *,
35 const struct tomoyo_acl_head 32 const struct tomoyo_acl_head
36 *)) 33 *))
37{ 34{
38 int error = is_delete ? -ENOENT : -ENOMEM; 35 int error = param->is_delete ? -ENOENT : -ENOMEM;
39 struct tomoyo_acl_head *entry; 36 struct tomoyo_acl_head *entry;
37 struct list_head *list = param->list;
40 38
41 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 39 if (mutex_lock_interruptible(&tomoyo_policy_lock))
42 return -ENOMEM; 40 return -ENOMEM;
43 list_for_each_entry_rcu(entry, list, list) { 41 list_for_each_entry_rcu(entry, list, list) {
44 if (!check_duplicate(entry, new_entry)) 42 if (!check_duplicate(entry, new_entry))
45 continue; 43 continue;
46 entry->is_deleted = is_delete; 44 entry->is_deleted = param->is_delete;
47 error = 0; 45 error = 0;
48 break; 46 break;
49 } 47 }
50 if (error && !is_delete) { 48 if (error && !param->is_delete) {
51 entry = tomoyo_commit_ok(new_entry, size); 49 entry = tomoyo_commit_ok(new_entry, size);
52 if (entry) { 50 if (entry) {
53 list_add_tail_rcu(&entry->list, list); 51 list_add_tail_rcu(&entry->list, list);
@@ -59,12 +57,25 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
59} 57}
60 58
61/** 59/**
60 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
61 *
62 * @a: Pointer to "struct tomoyo_acl_info".
63 * @b: Pointer to "struct tomoyo_acl_info".
64 *
65 * Returns true if @a == @b, false otherwise.
66 */
67static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
68 const struct tomoyo_acl_info *b)
69{
70 return a->type == b->type && a->cond == b->cond;
71}
72
73/**
62 * tomoyo_update_domain - Update an entry for domain policy. 74 * tomoyo_update_domain - Update an entry for domain policy.
63 * 75 *
64 * @new_entry: Pointer to "struct tomoyo_acl_info". 76 * @new_entry: Pointer to "struct tomoyo_acl_info".
65 * @size: Size of @new_entry in bytes. 77 * @size: Size of @new_entry in bytes.
66 * @is_delete: True if it is a delete request. 78 * @param: Pointer to "struct tomoyo_acl_param".
67 * @domain: Pointer to "struct tomoyo_domain_info".
68 * @check_duplicate: Callback function to find duplicated entry. 79 * @check_duplicate: Callback function to find duplicated entry.
69 * @merge_duplicate: Callback function to merge duplicated entry. 80 * @merge_duplicate: Callback function to merge duplicated entry.
70 * 81 *
@@ -73,7 +84,7 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
73 * Caller holds tomoyo_read_lock(). 84 * Caller holds tomoyo_read_lock().
74 */ 85 */
75int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 86int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
76 bool is_delete, struct tomoyo_domain_info *domain, 87 struct tomoyo_acl_param *param,
77 bool (*check_duplicate) (const struct tomoyo_acl_info 88 bool (*check_duplicate) (const struct tomoyo_acl_info
78 *, 89 *,
79 const struct tomoyo_acl_info 90 const struct tomoyo_acl_info
@@ -82,13 +93,21 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
82 struct tomoyo_acl_info *, 93 struct tomoyo_acl_info *,
83 const bool)) 94 const bool))
84{ 95{
96 const bool is_delete = param->is_delete;
85 int error = is_delete ? -ENOENT : -ENOMEM; 97 int error = is_delete ? -ENOENT : -ENOMEM;
86 struct tomoyo_acl_info *entry; 98 struct tomoyo_acl_info *entry;
99 struct list_head * const list = param->list;
87 100
101 if (param->data[0]) {
102 new_entry->cond = tomoyo_get_condition(param);
103 if (!new_entry->cond)
104 return -EINVAL;
105 }
88 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 106 if (mutex_lock_interruptible(&tomoyo_policy_lock))
89 return error; 107 goto out;
90 list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { 108 list_for_each_entry_rcu(entry, list, list) {
91 if (!check_duplicate(entry, new_entry)) 109 if (!tomoyo_same_acl_head(entry, new_entry) ||
110 !check_duplicate(entry, new_entry))
92 continue; 111 continue;
93 if (merge_duplicate) 112 if (merge_duplicate)
94 entry->is_deleted = merge_duplicate(entry, new_entry, 113 entry->is_deleted = merge_duplicate(entry, new_entry,
@@ -101,28 +120,50 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
101 if (error && !is_delete) { 120 if (error && !is_delete) {
102 entry = tomoyo_commit_ok(new_entry, size); 121 entry = tomoyo_commit_ok(new_entry, size);
103 if (entry) { 122 if (entry) {
104 list_add_tail_rcu(&entry->list, &domain->acl_info_list); 123 list_add_tail_rcu(&entry->list, list);
105 error = 0; 124 error = 0;
106 } 125 }
107 } 126 }
108 mutex_unlock(&tomoyo_policy_lock); 127 mutex_unlock(&tomoyo_policy_lock);
128out:
129 tomoyo_put_condition(new_entry->cond);
109 return error; 130 return error;
110} 131}
111 132
133/**
134 * tomoyo_check_acl - Do permission check.
135 *
136 * @r: Pointer to "struct tomoyo_request_info".
137 * @check_entry: Callback function to check type specific parameters.
138 *
139 * Returns 0 on success, negative value otherwise.
140 *
141 * Caller holds tomoyo_read_lock().
142 */
112void tomoyo_check_acl(struct tomoyo_request_info *r, 143void tomoyo_check_acl(struct tomoyo_request_info *r,
113 bool (*check_entry) (struct tomoyo_request_info *, 144 bool (*check_entry) (struct tomoyo_request_info *,
114 const struct tomoyo_acl_info *)) 145 const struct tomoyo_acl_info *))
115{ 146{
116 const struct tomoyo_domain_info *domain = r->domain; 147 const struct tomoyo_domain_info *domain = r->domain;
117 struct tomoyo_acl_info *ptr; 148 struct tomoyo_acl_info *ptr;
149 bool retried = false;
150 const struct list_head *list = &domain->acl_info_list;
118 151
119 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 152retry:
153 list_for_each_entry_rcu(ptr, list, list) {
120 if (ptr->is_deleted || ptr->type != r->param_type) 154 if (ptr->is_deleted || ptr->type != r->param_type)
121 continue; 155 continue;
122 if (check_entry(r, ptr)) { 156 if (!check_entry(r, ptr))
123 r->granted = true; 157 continue;
124 return; 158 if (!tomoyo_condition(r, ptr->cond))
125 } 159 continue;
160 r->granted = true;
161 return;
162 }
163 if (!retried) {
164 retried = true;
165 list = &domain->ns->acl_group[domain->group];
166 goto retry;
126 } 167 }
127 r->granted = false; 168 r->granted = false;
128} 169}
@@ -130,24 +171,29 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
130/* The list for "struct tomoyo_domain_info". */ 171/* The list for "struct tomoyo_domain_info". */
131LIST_HEAD(tomoyo_domain_list); 172LIST_HEAD(tomoyo_domain_list);
132 173
133struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
134struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
135
136/** 174/**
137 * tomoyo_last_word - Get last component of a domainname. 175 * tomoyo_last_word - Get last component of a domainname.
138 * 176 *
139 * @domainname: Domainname to check. 177 * @name: Domainname to check.
140 * 178 *
141 * Returns the last word of @domainname. 179 * Returns the last word of @domainname.
142 */ 180 */
143static const char *tomoyo_last_word(const char *name) 181static const char *tomoyo_last_word(const char *name)
144{ 182{
145 const char *cp = strrchr(name, ' '); 183 const char *cp = strrchr(name, ' ');
146 if (cp) 184 if (cp)
147 return cp + 1; 185 return cp + 1;
148 return name; 186 return name;
149} 187}
150 188
189/**
190 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry.
191 *
192 * @a: Pointer to "struct tomoyo_acl_head".
193 * @b: Pointer to "struct tomoyo_acl_head".
194 *
195 * Returns true if @a == @b, false otherwise.
196 */
151static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a, 197static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
152 const struct tomoyo_acl_head *b) 198 const struct tomoyo_acl_head *b)
153{ 199{
@@ -163,30 +209,36 @@ static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
163} 209}
164 210
165/** 211/**
166 * tomoyo_update_transition_control_entry - Update "struct tomoyo_transition_control" list. 212 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
167 * 213 *
168 * @domainname: The name of domain. Maybe NULL. 214 * @param: Pointer to "struct tomoyo_acl_param".
169 * @program: The name of program. Maybe NULL. 215 * @type: Type of this entry.
170 * @type: Type of transition.
171 * @is_delete: True if it is a delete request.
172 * 216 *
173 * Returns 0 on success, negative value otherwise. 217 * Returns 0 on success, negative value otherwise.
174 */ 218 */
175static int tomoyo_update_transition_control_entry(const char *domainname, 219int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
176 const char *program, 220 const u8 type)
177 const u8 type,
178 const bool is_delete)
179{ 221{
180 struct tomoyo_transition_control e = { .type = type }; 222 struct tomoyo_transition_control e = { .type = type };
181 int error = is_delete ? -ENOENT : -ENOMEM; 223 int error = param->is_delete ? -ENOENT : -ENOMEM;
182 if (program) { 224 char *program = param->data;
225 char *domainname = strstr(program, " from ");
226 if (domainname) {
227 *domainname = '\0';
228 domainname += 6;
229 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
230 type == TOMOYO_TRANSITION_CONTROL_KEEP) {
231 domainname = program;
232 program = NULL;
233 }
234 if (program && strcmp(program, "any")) {
183 if (!tomoyo_correct_path(program)) 235 if (!tomoyo_correct_path(program))
184 return -EINVAL; 236 return -EINVAL;
185 e.program = tomoyo_get_name(program); 237 e.program = tomoyo_get_name(program);
186 if (!e.program) 238 if (!e.program)
187 goto out; 239 goto out;
188 } 240 }
189 if (domainname) { 241 if (domainname && strcmp(domainname, "any")) {
190 if (!tomoyo_correct_domain(domainname)) { 242 if (!tomoyo_correct_domain(domainname)) {
191 if (!tomoyo_correct_path(domainname)) 243 if (!tomoyo_correct_path(domainname))
192 goto out; 244 goto out;
@@ -196,126 +248,136 @@ static int tomoyo_update_transition_control_entry(const char *domainname,
196 if (!e.domainname) 248 if (!e.domainname)
197 goto out; 249 goto out;
198 } 250 }
199 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 251 param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
200 &tomoyo_policy_list 252 error = tomoyo_update_policy(&e.head, sizeof(e), param,
201 [TOMOYO_ID_TRANSITION_CONTROL],
202 tomoyo_same_transition_control); 253 tomoyo_same_transition_control);
203 out: 254out:
204 tomoyo_put_name(e.domainname); 255 tomoyo_put_name(e.domainname);
205 tomoyo_put_name(e.program); 256 tomoyo_put_name(e.program);
206 return error; 257 return error;
207} 258}
208 259
209/** 260/**
210 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list. 261 * tomoyo_scan_transition - Try to find specific domain transition type.
211 * 262 *
212 * @data: String to parse. 263 * @list: Pointer to "struct list_head".
213 * @is_delete: True if it is a delete request. 264 * @domainname: The name of current domain.
214 * @type: Type of this entry. 265 * @program: The name of requested program.
266 * @last_name: The last component of @domainname.
267 * @type: One of values in "enum tomoyo_transition_type".
215 * 268 *
216 * Returns 0 on success, negative value otherwise. 269 * Returns true if found one, false otherwise.
270 *
271 * Caller holds tomoyo_read_lock().
217 */ 272 */
218int tomoyo_write_transition_control(char *data, const bool is_delete, 273static inline bool tomoyo_scan_transition
219 const u8 type) 274(const struct list_head *list, const struct tomoyo_path_info *domainname,
275 const struct tomoyo_path_info *program, const char *last_name,
276 const enum tomoyo_transition_type type)
220{ 277{
221 char *domainname = strstr(data, " from "); 278 const struct tomoyo_transition_control *ptr;
222 if (domainname) { 279 list_for_each_entry_rcu(ptr, list, head.list) {
223 *domainname = '\0'; 280 if (ptr->head.is_deleted || ptr->type != type)
224 domainname += 6; 281 continue;
225 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP || 282 if (ptr->domainname) {
226 type == TOMOYO_TRANSITION_CONTROL_KEEP) { 283 if (!ptr->is_last_name) {
227 domainname = data; 284 if (ptr->domainname != domainname)
228 data = NULL; 285 continue;
286 } else {
287 /*
288 * Use direct strcmp() since this is
289 * unlikely used.
290 */
291 if (strcmp(ptr->domainname->name, last_name))
292 continue;
293 }
294 }
295 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
296 continue;
297 return true;
229 } 298 }
230 return tomoyo_update_transition_control_entry(domainname, data, type, 299 return false;
231 is_delete);
232} 300}
233 301
234/** 302/**
235 * tomoyo_transition_type - Get domain transition type. 303 * tomoyo_transition_type - Get domain transition type.
236 * 304 *
237 * @domainname: The name of domain. 305 * @ns: Pointer to "struct tomoyo_policy_namespace".
238 * @program: The name of program. 306 * @domainname: The name of current domain.
307 * @program: The name of requested program.
239 * 308 *
240 * Returns TOMOYO_TRANSITION_CONTROL_INITIALIZE if executing @program 309 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes
241 * reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing 310 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if
242 * @program suppresses domain transition, others otherwise. 311 * executing @program reinitializes domain transition within that namespace,
312 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
313 * others otherwise.
243 * 314 *
244 * Caller holds tomoyo_read_lock(). 315 * Caller holds tomoyo_read_lock().
245 */ 316 */
246static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname, 317static enum tomoyo_transition_type tomoyo_transition_type
247 const struct tomoyo_path_info *program) 318(const struct tomoyo_policy_namespace *ns,
319 const struct tomoyo_path_info *domainname,
320 const struct tomoyo_path_info *program)
248{ 321{
249 const struct tomoyo_transition_control *ptr;
250 const char *last_name = tomoyo_last_word(domainname->name); 322 const char *last_name = tomoyo_last_word(domainname->name);
251 u8 type; 323 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
252 for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) { 324 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
253 next: 325 const struct list_head * const list =
254 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 326 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
255 [TOMOYO_ID_TRANSITION_CONTROL], 327 if (!tomoyo_scan_transition(list, domainname, program,
256 head.list) { 328 last_name, type)) {
257 if (ptr->head.is_deleted || ptr->type != type) 329 type++;
258 continue; 330 continue;
259 if (ptr->domainname) {
260 if (!ptr->is_last_name) {
261 if (ptr->domainname != domainname)
262 continue;
263 } else {
264 /*
265 * Use direct strcmp() since this is
266 * unlikely used.
267 */
268 if (strcmp(ptr->domainname->name,
269 last_name))
270 continue;
271 }
272 }
273 if (ptr->program &&
274 tomoyo_pathcmp(ptr->program, program))
275 continue;
276 if (type == TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) {
277 /*
278 * Do not check for initialize_domain if
279 * no_initialize_domain matched.
280 */
281 type = TOMOYO_TRANSITION_CONTROL_NO_KEEP;
282 goto next;
283 }
284 goto done;
285 } 331 }
332 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
333 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
334 break;
335 /*
336 * Do not check for reset_domain if no_reset_domain matched.
337 * Do not check for initialize_domain if no_initialize_domain
338 * matched.
339 */
340 type++;
341 type++;
286 } 342 }
287 done:
288 return type; 343 return type;
289} 344}
290 345
346/**
347 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry.
348 *
349 * @a: Pointer to "struct tomoyo_acl_head".
350 * @b: Pointer to "struct tomoyo_acl_head".
351 *
352 * Returns true if @a == @b, false otherwise.
353 */
291static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a, 354static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
292 const struct tomoyo_acl_head *b) 355 const struct tomoyo_acl_head *b)
293{ 356{
294 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), head); 357 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
295 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), head); 358 head);
359 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
360 head);
296 return p1->original_name == p2->original_name && 361 return p1->original_name == p2->original_name &&
297 p1->aggregated_name == p2->aggregated_name; 362 p1->aggregated_name == p2->aggregated_name;
298} 363}
299 364
300/** 365/**
301 * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator" list. 366 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
302 * 367 *
303 * @original_name: The original program's name. 368 * @param: Pointer to "struct tomoyo_acl_param".
304 * @aggregated_name: The program name to use.
305 * @is_delete: True if it is a delete request.
306 * 369 *
307 * Returns 0 on success, negative value otherwise. 370 * Returns 0 on success, negative value otherwise.
308 * 371 *
309 * Caller holds tomoyo_read_lock(). 372 * Caller holds tomoyo_read_lock().
310 */ 373 */
311static int tomoyo_update_aggregator_entry(const char *original_name, 374int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
312 const char *aggregated_name,
313 const bool is_delete)
314{ 375{
315 struct tomoyo_aggregator e = { }; 376 struct tomoyo_aggregator e = { };
316 int error = is_delete ? -ENOENT : -ENOMEM; 377 int error = param->is_delete ? -ENOENT : -ENOMEM;
317 378 const char *original_name = tomoyo_read_token(param);
318 if (!tomoyo_correct_path(original_name) || 379 const char *aggregated_name = tomoyo_read_token(param);
380 if (!tomoyo_correct_word(original_name) ||
319 !tomoyo_correct_path(aggregated_name)) 381 !tomoyo_correct_path(aggregated_name))
320 return -EINVAL; 382 return -EINVAL;
321 e.original_name = tomoyo_get_name(original_name); 383 e.original_name = tomoyo_get_name(original_name);
@@ -323,83 +385,181 @@ static int tomoyo_update_aggregator_entry(const char *original_name,
323 if (!e.original_name || !e.aggregated_name || 385 if (!e.original_name || !e.aggregated_name ||
324 e.aggregated_name->is_patterned) /* No patterns allowed. */ 386 e.aggregated_name->is_patterned) /* No patterns allowed. */
325 goto out; 387 goto out;
326 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 388 param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
327 &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR], 389 error = tomoyo_update_policy(&e.head, sizeof(e), param,
328 tomoyo_same_aggregator); 390 tomoyo_same_aggregator);
329 out: 391out:
330 tomoyo_put_name(e.original_name); 392 tomoyo_put_name(e.original_name);
331 tomoyo_put_name(e.aggregated_name); 393 tomoyo_put_name(e.aggregated_name);
332 return error; 394 return error;
333} 395}
334 396
335/** 397/**
336 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list. 398 * tomoyo_find_namespace - Find specified namespace.
337 * 399 *
338 * @data: String to parse. 400 * @name: Name of namespace to find.
339 * @is_delete: True if it is a delete request. 401 * @len: Length of @name.
340 * 402 *
341 * Returns 0 on success, negative value otherwise. 403 * Returns pointer to "struct tomoyo_policy_namespace" if found,
404 * NULL otherwise.
342 * 405 *
343 * Caller holds tomoyo_read_lock(). 406 * Caller holds tomoyo_read_lock().
344 */ 407 */
345int tomoyo_write_aggregator(char *data, const bool is_delete) 408static struct tomoyo_policy_namespace *tomoyo_find_namespace
409(const char *name, const unsigned int len)
346{ 410{
347 char *cp = strchr(data, ' '); 411 struct tomoyo_policy_namespace *ns;
412 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
413 if (strncmp(name, ns->name, len) ||
414 (name[len] && name[len] != ' '))
415 continue;
416 return ns;
417 }
418 return NULL;
419}
348 420
349 if (!cp) 421/**
350 return -EINVAL; 422 * tomoyo_assign_namespace - Create a new namespace.
351 *cp++ = '\0'; 423 *
352 return tomoyo_update_aggregator_entry(data, cp, is_delete); 424 * @domainname: Name of namespace to create.
425 *
426 * Returns pointer to "struct tomoyo_policy_namespace" on success,
427 * NULL otherwise.
428 *
429 * Caller holds tomoyo_read_lock().
430 */
431struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
432{
433 struct tomoyo_policy_namespace *ptr;
434 struct tomoyo_policy_namespace *entry;
435 const char *cp = domainname;
436 unsigned int len = 0;
437 while (*cp && *cp++ != ' ')
438 len++;
439 ptr = tomoyo_find_namespace(domainname, len);
440 if (ptr)
441 return ptr;
442 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
443 return NULL;
444 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
445 if (!entry)
446 return NULL;
447 if (mutex_lock_interruptible(&tomoyo_policy_lock))
448 goto out;
449 ptr = tomoyo_find_namespace(domainname, len);
450 if (!ptr && tomoyo_memory_ok(entry)) {
451 char *name = (char *) (entry + 1);
452 ptr = entry;
453 memmove(name, domainname, len);
454 name[len] = '\0';
455 entry->name = name;
456 tomoyo_init_policy_namespace(entry);
457 entry = NULL;
458 }
459 mutex_unlock(&tomoyo_policy_lock);
460out:
461 kfree(entry);
462 return ptr;
353} 463}
354 464
355/** 465/**
356 * tomoyo_assign_domain - Create a domain. 466 * tomoyo_namespace_jump - Check for namespace jump.
467 *
468 * @domainname: Name of domain.
469 *
470 * Returns true if namespace differs, false otherwise.
471 */
472static bool tomoyo_namespace_jump(const char *domainname)
473{
474 const char *namespace = tomoyo_current_namespace()->name;
475 const int len = strlen(namespace);
476 return strncmp(domainname, namespace, len) ||
477 (domainname[len] && domainname[len] != ' ');
478}
479
480/**
481 * tomoyo_assign_domain - Create a domain or a namespace.
357 * 482 *
358 * @domainname: The name of domain. 483 * @domainname: The name of domain.
359 * @profile: Profile number to assign if the domain was newly created. 484 * @transit: True if transit to domain found or created.
360 * 485 *
361 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 486 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
362 * 487 *
363 * Caller holds tomoyo_read_lock(). 488 * Caller holds tomoyo_read_lock().
364 */ 489 */
365struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 490struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
366 const u8 profile) 491 const bool transit)
367{ 492{
368 struct tomoyo_domain_info *entry; 493 struct tomoyo_domain_info e = { };
369 struct tomoyo_domain_info *domain = NULL; 494 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
370 const struct tomoyo_path_info *saved_domainname; 495 bool created = false;
371 bool found = false; 496 if (entry) {
372 497 if (transit) {
373 if (!tomoyo_correct_domain(domainname)) 498 /*
499 * Since namespace is created at runtime, profiles may
500 * not be created by the moment the process transits to
501 * that domain. Do not perform domain transition if
502 * profile for that domain is not yet created.
503 */
504 if (!entry->ns->profile_ptr[entry->profile])
505 return NULL;
506 }
507 return entry;
508 }
509 /* Requested domain does not exist. */
510 /* Don't create requested domain if domainname is invalid. */
511 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
512 !tomoyo_correct_domain(domainname))
513 return NULL;
514 /*
515 * Since definition of profiles and acl_groups may differ across
516 * namespaces, do not inherit "use_profile" and "use_group" settings
517 * by automatically creating requested domain upon domain transition.
518 */
519 if (transit && tomoyo_namespace_jump(domainname))
520 return NULL;
521 e.ns = tomoyo_assign_namespace(domainname);
522 if (!e.ns)
374 return NULL; 523 return NULL;
375 saved_domainname = tomoyo_get_name(domainname); 524 /*
376 if (!saved_domainname) 525 * "use_profile" and "use_group" settings for automatically created
526 * domains are inherited from current domain. These are 0 for manually
527 * created domains.
528 */
529 if (transit) {
530 const struct tomoyo_domain_info *domain = tomoyo_domain();
531 e.profile = domain->profile;
532 e.group = domain->group;
533 }
534 e.domainname = tomoyo_get_name(domainname);
535 if (!e.domainname)
377 return NULL; 536 return NULL;
378 entry = kzalloc(sizeof(*entry), GFP_NOFS);
379 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 537 if (mutex_lock_interruptible(&tomoyo_policy_lock))
380 goto out; 538 goto out;
381 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 539 entry = tomoyo_find_domain(domainname);
382 if (domain->is_deleted || 540 if (!entry) {
383 tomoyo_pathcmp(saved_domainname, domain->domainname)) 541 entry = tomoyo_commit_ok(&e, sizeof(e));
384 continue; 542 if (entry) {
385 found = true; 543 INIT_LIST_HEAD(&entry->acl_info_list);
386 break; 544 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
387 } 545 created = true;
388 if (!found && tomoyo_memory_ok(entry)) { 546 }
389 INIT_LIST_HEAD(&entry->acl_info_list);
390 entry->domainname = saved_domainname;
391 saved_domainname = NULL;
392 entry->profile = profile;
393 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
394 domain = entry;
395 entry = NULL;
396 found = true;
397 } 547 }
398 mutex_unlock(&tomoyo_policy_lock); 548 mutex_unlock(&tomoyo_policy_lock);
399 out: 549out:
400 tomoyo_put_name(saved_domainname); 550 tomoyo_put_name(e.domainname);
401 kfree(entry); 551 if (entry && transit) {
402 return found ? domain : NULL; 552 if (created) {
553 struct tomoyo_request_info r;
554 tomoyo_init_request_info(&r, entry,
555 TOMOYO_MAC_FILE_EXECUTE);
556 r.granted = false;
557 tomoyo_write_log(&r, "use_profile %u\n",
558 entry->profile);
559 tomoyo_write_log(&r, "use_group %u\n", entry->group);
560 }
561 }
562 return entry;
403} 563}
404 564
405/** 565/**
@@ -413,22 +573,27 @@ struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
413 */ 573 */
414int tomoyo_find_next_domain(struct linux_binprm *bprm) 574int tomoyo_find_next_domain(struct linux_binprm *bprm)
415{ 575{
416 struct tomoyo_request_info r;
417 char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
418 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 576 struct tomoyo_domain_info *old_domain = tomoyo_domain();
419 struct tomoyo_domain_info *domain = NULL; 577 struct tomoyo_domain_info *domain = NULL;
420 const char *original_name = bprm->filename; 578 const char *original_name = bprm->filename;
421 u8 mode;
422 bool is_enforce;
423 int retval = -ENOMEM; 579 int retval = -ENOMEM;
424 bool need_kfree = false; 580 bool need_kfree = false;
581 bool reject_on_transition_failure = false;
425 struct tomoyo_path_info rn = { }; /* real name */ 582 struct tomoyo_path_info rn = { }; /* real name */
426 583 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
427 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); 584 if (!ee)
428 is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 585 return -ENOMEM;
429 if (!tmp) 586 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
430 goto out; 587 if (!ee->tmp) {
431 588 kfree(ee);
589 return -ENOMEM;
590 }
591 /* ee->dump->data is allocated by tomoyo_dump_page(). */
592 tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE);
593 ee->r.ee = ee;
594 ee->bprm = bprm;
595 ee->r.obj = &ee->obj;
596 ee->obj.path1 = bprm->file->f_path;
432 retry: 597 retry:
433 if (need_kfree) { 598 if (need_kfree) {
434 kfree(rn.name); 599 kfree(rn.name);
@@ -445,8 +610,10 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
445 /* Check 'aggregator' directive. */ 610 /* Check 'aggregator' directive. */
446 { 611 {
447 struct tomoyo_aggregator *ptr; 612 struct tomoyo_aggregator *ptr;
448 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 613 struct list_head *list =
449 [TOMOYO_ID_AGGREGATOR], head.list) { 614 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
615 /* Check 'aggregator' directive. */
616 list_for_each_entry_rcu(ptr, list, head.list) {
450 if (ptr->head.is_deleted || 617 if (ptr->head.is_deleted ||
451 !tomoyo_path_matches_pattern(&rn, 618 !tomoyo_path_matches_pattern(&rn,
452 ptr->original_name)) 619 ptr->original_name))
@@ -460,7 +627,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
460 } 627 }
461 628
462 /* Check execute permission. */ 629 /* Check execute permission. */
463 retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn); 630 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn);
464 if (retval == TOMOYO_RETRY_REQUEST) 631 if (retval == TOMOYO_RETRY_REQUEST)
465 goto retry; 632 goto retry;
466 if (retval < 0) 633 if (retval < 0)
@@ -471,20 +638,30 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
471 * wildcard) rather than the pathname passed to execve() 638 * wildcard) rather than the pathname passed to execve()
472 * (which never contains wildcard). 639 * (which never contains wildcard).
473 */ 640 */
474 if (r.param.path.matched_path) { 641 if (ee->r.param.path.matched_path) {
475 if (need_kfree) 642 if (need_kfree)
476 kfree(rn.name); 643 kfree(rn.name);
477 need_kfree = false; 644 need_kfree = false;
478 /* This is OK because it is read only. */ 645 /* This is OK because it is read only. */
479 rn = *r.param.path.matched_path; 646 rn = *ee->r.param.path.matched_path;
480 } 647 }
481 648
482 /* Calculate domain to transit to. */ 649 /* Calculate domain to transit to. */
483 switch (tomoyo_transition_type(old_domain->domainname, &rn)) { 650 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
651 &rn)) {
652 case TOMOYO_TRANSITION_CONTROL_RESET:
653 /* Transit to the root of specified namespace. */
654 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name);
655 /*
656 * Make do_execve() fail if domain transition across namespaces
657 * has failed.
658 */
659 reject_on_transition_failure = true;
660 break;
484 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 661 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
485 /* Transit to the child of tomoyo_kernel_domain domain. */ 662 /* Transit to the child of current namespace's root. */
486 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " " 663 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
487 "%s", rn.name); 664 old_domain->ns->name, rn.name);
488 break; 665 break;
489 case TOMOYO_TRANSITION_CONTROL_KEEP: 666 case TOMOYO_TRANSITION_CONTROL_KEEP:
490 /* Keep current domain. */ 667 /* Keep current domain. */
@@ -502,33 +679,32 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
502 domain = old_domain; 679 domain = old_domain;
503 } else { 680 } else {
504 /* Normal domain transition. */ 681 /* Normal domain transition. */
505 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 682 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
506 old_domain->domainname->name, rn.name); 683 old_domain->domainname->name, rn.name);
507 } 684 }
508 break; 685 break;
509 } 686 }
510 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10) 687 if (!domain)
511 goto done; 688 domain = tomoyo_assign_domain(ee->tmp, true);
512 domain = tomoyo_find_domain(tmp);
513 if (domain) 689 if (domain)
514 goto done; 690 retval = 0;
515 if (is_enforce) { 691 else if (reject_on_transition_failure) {
516 int error = tomoyo_supervisor(&r, "# wants to create domain\n" 692 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n",
517 "%s\n", tmp); 693 ee->tmp);
518 if (error == TOMOYO_RETRY_REQUEST) 694 retval = -ENOMEM;
519 goto retry; 695 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
520 if (error < 0) 696 retval = -ENOMEM;
521 goto done; 697 else {
698 retval = 0;
699 if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) {
700 old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true;
701 ee->r.granted = false;
702 tomoyo_write_log(&ee->r, "%s", tomoyo_dif
703 [TOMOYO_DIF_TRANSITION_FAILED]);
704 printk(KERN_WARNING
705 "ERROR: Domain '%s' not defined.\n", ee->tmp);
706 }
522 } 707 }
523 domain = tomoyo_assign_domain(tmp, old_domain->profile);
524 done:
525 if (domain)
526 goto out;
527 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp);
528 if (is_enforce)
529 retval = -EPERM;
530 else
531 old_domain->transition_failed = true;
532 out: 708 out:
533 if (!domain) 709 if (!domain)
534 domain = old_domain; 710 domain = old_domain;
@@ -537,6 +713,54 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
537 bprm->cred->security = domain; 713 bprm->cred->security = domain;
538 if (need_kfree) 714 if (need_kfree)
539 kfree(rn.name); 715 kfree(rn.name);
540 kfree(tmp); 716 kfree(ee->tmp);
717 kfree(ee->dump.data);
718 kfree(ee);
541 return retval; 719 return retval;
542} 720}
721
722/**
723 * tomoyo_dump_page - Dump a page to buffer.
724 *
725 * @bprm: Pointer to "struct linux_binprm".
726 * @pos: Location to dump.
727 * @dump: Poiner to "struct tomoyo_page_dump".
728 *
729 * Returns true on success, false otherwise.
730 */
731bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
732 struct tomoyo_page_dump *dump)
733{
734 struct page *page;
735 /* dump->data is released by tomoyo_finish_execve(). */
736 if (!dump->data) {
737 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
738 if (!dump->data)
739 return false;
740 }
741 /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
742#ifdef CONFIG_MMU
743 if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
744 return false;
745#else
746 page = bprm->page[pos / PAGE_SIZE];
747#endif
748 if (page != dump->page) {
749 const unsigned int offset = pos % PAGE_SIZE;
750 /*
751 * Maybe kmap()/kunmap() should be used here.
752 * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
753 * So do I.
754 */
755 char *kaddr = kmap_atomic(page, KM_USER0);
756 dump->page = page;
757 memcpy(dump->data + offset, kaddr + offset,
758 PAGE_SIZE - offset);
759 kunmap_atomic(kaddr, KM_USER0);
760 }
761 /* Same with put_arg_page(page) in fs/exec.c */
762#ifdef CONFIG_MMU
763 put_page(page);
764#endif
765 return true;
766}
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index d64e8ecb6fb3..743c35f5084a 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -1,80 +1,51 @@
1/* 1/*
2 * security/tomoyo/file.c 2 * security/tomoyo/file.c
3 * 3 *
4 * Pathname restriction functions. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
10#include <linux/slab.h> 8#include <linux/slab.h>
11 9
12/* Keyword array for operations with one pathname. */ 10/*
13const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 11 * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
14 [TOMOYO_TYPE_READ_WRITE] = "read/write", 12 */
15 [TOMOYO_TYPE_EXECUTE] = "execute",
16 [TOMOYO_TYPE_READ] = "read",
17 [TOMOYO_TYPE_WRITE] = "write",
18 [TOMOYO_TYPE_UNLINK] = "unlink",
19 [TOMOYO_TYPE_RMDIR] = "rmdir",
20 [TOMOYO_TYPE_TRUNCATE] = "truncate",
21 [TOMOYO_TYPE_SYMLINK] = "symlink",
22 [TOMOYO_TYPE_REWRITE] = "rewrite",
23 [TOMOYO_TYPE_CHROOT] = "chroot",
24 [TOMOYO_TYPE_UMOUNT] = "unmount",
25};
26
27/* Keyword array for operations with one pathname and three numbers. */
28const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION] = {
29 [TOMOYO_TYPE_MKBLOCK] = "mkblock",
30 [TOMOYO_TYPE_MKCHAR] = "mkchar",
31};
32
33/* Keyword array for operations with two pathnames. */
34const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
35 [TOMOYO_TYPE_LINK] = "link",
36 [TOMOYO_TYPE_RENAME] = "rename",
37 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
38};
39
40/* Keyword array for operations with one pathname and one number. */
41const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
42 [TOMOYO_TYPE_CREATE] = "create",
43 [TOMOYO_TYPE_MKDIR] = "mkdir",
44 [TOMOYO_TYPE_MKFIFO] = "mkfifo",
45 [TOMOYO_TYPE_MKSOCK] = "mksock",
46 [TOMOYO_TYPE_IOCTL] = "ioctl",
47 [TOMOYO_TYPE_CHMOD] = "chmod",
48 [TOMOYO_TYPE_CHOWN] = "chown",
49 [TOMOYO_TYPE_CHGRP] = "chgrp",
50};
51
52static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 13static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
53 [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN,
54 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 14 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
55 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 15 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
56 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, 16 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
17 [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
57 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, 18 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
19 [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
58 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, 20 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
59 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, 21 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
60 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, 22 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
61 [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE,
62 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, 23 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 24 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
64}; 25};
65 26
66static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { 27/*
28 * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
29 */
30const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
67 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, 31 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
68 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, 32 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
69}; 33};
70 34
71static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { 35/*
36 * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
37 */
38const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
72 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, 39 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
73 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, 40 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
74 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, 41 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
75}; 42};
76 43
77static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 44/*
45 * Mapping table from "enum tomoyo_path_number_acl_index" to
46 * "enum tomoyo_mac_index".
47 */
48const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
78 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, 49 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
79 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, 50 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
80 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO, 51 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
@@ -85,41 +56,76 @@ static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
85 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, 56 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
86}; 57};
87 58
59/**
60 * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
61 *
62 * @ptr: Pointer to "struct tomoyo_name_union".
63 *
64 * Returns nothing.
65 */
88void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 66void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
89{ 67{
90 if (!ptr) 68 tomoyo_put_group(ptr->group);
91 return; 69 tomoyo_put_name(ptr->filename);
92 if (ptr->is_group)
93 tomoyo_put_group(ptr->group);
94 else
95 tomoyo_put_name(ptr->filename);
96} 70}
97 71
72/**
73 * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
74 *
75 * @name: Pointer to "struct tomoyo_path_info".
76 * @ptr: Pointer to "struct tomoyo_name_union".
77 *
78 * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
79 */
98const struct tomoyo_path_info * 80const struct tomoyo_path_info *
99tomoyo_compare_name_union(const struct tomoyo_path_info *name, 81tomoyo_compare_name_union(const struct tomoyo_path_info *name,
100 const struct tomoyo_name_union *ptr) 82 const struct tomoyo_name_union *ptr)
101{ 83{
102 if (ptr->is_group) 84 if (ptr->group)
103 return tomoyo_path_matches_group(name, ptr->group); 85 return tomoyo_path_matches_group(name, ptr->group);
104 if (tomoyo_path_matches_pattern(name, ptr->filename)) 86 if (tomoyo_path_matches_pattern(name, ptr->filename))
105 return ptr->filename; 87 return ptr->filename;
106 return NULL; 88 return NULL;
107} 89}
108 90
91/**
92 * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
93 *
94 * @ptr: Pointer to "struct tomoyo_number_union".
95 *
96 * Returns nothing.
97 */
109void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 98void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
110{ 99{
111 if (ptr && ptr->is_group) 100 tomoyo_put_group(ptr->group);
112 tomoyo_put_group(ptr->group);
113} 101}
114 102
103/**
104 * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
105 *
106 * @value: Number to check.
107 * @ptr: Pointer to "struct tomoyo_number_union".
108 *
109 * Returns true if @value matches @ptr, false otherwise.
110 */
115bool tomoyo_compare_number_union(const unsigned long value, 111bool tomoyo_compare_number_union(const unsigned long value,
116 const struct tomoyo_number_union *ptr) 112 const struct tomoyo_number_union *ptr)
117{ 113{
118 if (ptr->is_group) 114 if (ptr->group)
119 return tomoyo_number_matches_group(value, value, ptr->group); 115 return tomoyo_number_matches_group(value, value, ptr->group);
120 return value >= ptr->values[0] && value <= ptr->values[1]; 116 return value >= ptr->values[0] && value <= ptr->values[1];
121} 117}
122 118
119/**
120 * tomoyo_add_slash - Add trailing '/' if needed.
121 *
122 * @buf: Pointer to "struct tomoyo_path_info".
123 *
124 * Returns nothing.
125 *
126 * @buf must be generated by tomoyo_encode() because this function does not
127 * allocate memory for adding '/'.
128 */
123static void tomoyo_add_slash(struct tomoyo_path_info *buf) 129static void tomoyo_add_slash(struct tomoyo_path_info *buf)
124{ 130{
125 if (buf->is_dir) 131 if (buf->is_dir)
@@ -132,24 +138,6 @@ static void tomoyo_add_slash(struct tomoyo_path_info *buf)
132} 138}
133 139
134/** 140/**
135 * tomoyo_strendswith - Check whether the token ends with the given token.
136 *
137 * @name: The token to check.
138 * @tail: The token to find.
139 *
140 * Returns true if @name ends with @tail, false otherwise.
141 */
142static bool tomoyo_strendswith(const char *name, const char *tail)
143{
144 int len;
145
146 if (!name || !tail)
147 return false;
148 len = strlen(name) - strlen(tail);
149 return len >= 0 && !strcmp(name + len, tail);
150}
151
152/**
153 * tomoyo_get_realpath - Get realpath. 141 * tomoyo_get_realpath - Get realpath.
154 * 142 *
155 * @buf: Pointer to "struct tomoyo_path_info". 143 * @buf: Pointer to "struct tomoyo_path_info".
@@ -164,7 +152,7 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
164 tomoyo_fill_path_info(buf); 152 tomoyo_fill_path_info(buf);
165 return true; 153 return true;
166 } 154 }
167 return false; 155 return false;
168} 156}
169 157
170/** 158/**
@@ -176,13 +164,9 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
176 */ 164 */
177static int tomoyo_audit_path_log(struct tomoyo_request_info *r) 165static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
178{ 166{
179 const char *operation = tomoyo_path_keyword[r->param.path.operation]; 167 return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
180 const struct tomoyo_path_info *filename = r->param.path.filename; 168 [r->param.path.operation],
181 if (r->granted) 169 r->param.path.filename->name);
182 return 0;
183 tomoyo_warn_log(r, "%s %s", operation, filename->name);
184 return tomoyo_supervisor(r, "allow_%s %s\n", operation,
185 tomoyo_pattern(filename));
186} 170}
187 171
188/** 172/**
@@ -194,16 +178,10 @@ static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
194 */ 178 */
195static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) 179static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
196{ 180{
197 const char *operation = tomoyo_path2_keyword[r->param.path2.operation]; 181 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
198 const struct tomoyo_path_info *filename1 = r->param.path2.filename1; 182 [tomoyo_pp2mac[r->param.path2.operation]],
199 const struct tomoyo_path_info *filename2 = r->param.path2.filename2; 183 r->param.path2.filename1->name,
200 if (r->granted) 184 r->param.path2.filename2->name);
201 return 0;
202 tomoyo_warn_log(r, "%s %s %s", operation, filename1->name,
203 filename2->name);
204 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
205 tomoyo_pattern(filename1),
206 tomoyo_pattern(filename2));
207} 185}
208 186
209/** 187/**
@@ -215,24 +193,18 @@ static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
215 */ 193 */
216static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) 194static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
217{ 195{
218 const char *operation = tomoyo_mkdev_keyword[r->param.mkdev.operation]; 196 return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
219 const struct tomoyo_path_info *filename = r->param.mkdev.filename; 197 tomoyo_mac_keywords
220 const unsigned int major = r->param.mkdev.major; 198 [tomoyo_pnnn2mac[r->param.mkdev.operation]],
221 const unsigned int minor = r->param.mkdev.minor; 199 r->param.mkdev.filename->name,
222 const unsigned int mode = r->param.mkdev.mode; 200 r->param.mkdev.mode, r->param.mkdev.major,
223 if (r->granted) 201 r->param.mkdev.minor);
224 return 0;
225 tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode,
226 major, minor);
227 return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation,
228 tomoyo_pattern(filename), mode, major, minor);
229} 202}
230 203
231/** 204/**
232 * tomoyo_audit_path_number_log - Audit path/number request log. 205 * tomoyo_audit_path_number_log - Audit path/number request log.
233 * 206 *
234 * @r: Pointer to "struct tomoyo_request_info". 207 * @r: Pointer to "struct tomoyo_request_info".
235 * @error: Error code.
236 * 208 *
237 * Returns 0 on success, negative value otherwise. 209 * Returns 0 on success, negative value otherwise.
238 */ 210 */
@@ -240,11 +212,7 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
240{ 212{
241 const u8 type = r->param.path_number.operation; 213 const u8 type = r->param.path_number.operation;
242 u8 radix; 214 u8 radix;
243 const struct tomoyo_path_info *filename = r->param.path_number.filename;
244 const char *operation = tomoyo_path_number_keyword[type];
245 char buffer[64]; 215 char buffer[64];
246 if (r->granted)
247 return 0;
248 switch (type) { 216 switch (type) {
249 case TOMOYO_TYPE_CREATE: 217 case TOMOYO_TYPE_CREATE:
250 case TOMOYO_TYPE_MKDIR: 218 case TOMOYO_TYPE_MKDIR:
@@ -262,251 +230,23 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
262 } 230 }
263 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number, 231 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
264 radix); 232 radix);
265 tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); 233 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
266 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 234 [tomoyo_pn2mac[type]],
267 tomoyo_pattern(filename), buffer); 235 r->param.path_number.filename->name, buffer);
268}
269
270static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a,
271 const struct tomoyo_acl_head *b)
272{
273 return container_of(a, struct tomoyo_readable_file,
274 head)->filename ==
275 container_of(b, struct tomoyo_readable_file,
276 head)->filename;
277}
278
279/**
280 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_readable_file" list.
281 *
282 * @filename: Filename unconditionally permitted to open() for reading.
283 * @is_delete: True if it is a delete request.
284 *
285 * Returns 0 on success, negative value otherwise.
286 *
287 * Caller holds tomoyo_read_lock().
288 */
289static int tomoyo_update_globally_readable_entry(const char *filename,
290 const bool is_delete)
291{
292 struct tomoyo_readable_file e = { };
293 int error;
294
295 if (!tomoyo_correct_word(filename))
296 return -EINVAL;
297 e.filename = tomoyo_get_name(filename);
298 if (!e.filename)
299 return -ENOMEM;
300 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
301 &tomoyo_policy_list
302 [TOMOYO_ID_GLOBALLY_READABLE],
303 tomoyo_same_globally_readable);
304 tomoyo_put_name(e.filename);
305 return error;
306}
307
308/**
309 * tomoyo_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
310 *
311 * @filename: The filename to check.
312 *
313 * Returns true if any domain can open @filename for reading, false otherwise.
314 *
315 * Caller holds tomoyo_read_lock().
316 */
317static bool tomoyo_globally_readable_file(const struct tomoyo_path_info *
318 filename)
319{
320 struct tomoyo_readable_file *ptr;
321 bool found = false;
322
323 list_for_each_entry_rcu(ptr, &tomoyo_policy_list
324 [TOMOYO_ID_GLOBALLY_READABLE], head.list) {
325 if (!ptr->head.is_deleted &&
326 tomoyo_path_matches_pattern(filename, ptr->filename)) {
327 found = true;
328 break;
329 }
330 }
331 return found;
332}
333
334/**
335 * tomoyo_write_globally_readable - Write "struct tomoyo_readable_file" list.
336 *
337 * @data: String to parse.
338 * @is_delete: True if it is a delete request.
339 *
340 * Returns 0 on success, negative value otherwise.
341 *
342 * Caller holds tomoyo_read_lock().
343 */
344int tomoyo_write_globally_readable(char *data, const bool is_delete)
345{
346 return tomoyo_update_globally_readable_entry(data, is_delete);
347}
348
349static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a,
350 const struct tomoyo_acl_head *b)
351{
352 return container_of(a, struct tomoyo_no_pattern, head)->pattern ==
353 container_of(b, struct tomoyo_no_pattern, head)->pattern;
354}
355
356/**
357 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_no_pattern" list.
358 *
359 * @pattern: Pathname pattern.
360 * @is_delete: True if it is a delete request.
361 *
362 * Returns 0 on success, negative value otherwise.
363 *
364 * Caller holds tomoyo_read_lock().
365 */
366static int tomoyo_update_file_pattern_entry(const char *pattern,
367 const bool is_delete)
368{
369 struct tomoyo_no_pattern e = { };
370 int error;
371
372 if (!tomoyo_correct_word(pattern))
373 return -EINVAL;
374 e.pattern = tomoyo_get_name(pattern);
375 if (!e.pattern)
376 return -ENOMEM;
377 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
378 &tomoyo_policy_list[TOMOYO_ID_PATTERN],
379 tomoyo_same_pattern);
380 tomoyo_put_name(e.pattern);
381 return error;
382}
383
384/**
385 * tomoyo_pattern - Get patterned pathname.
386 *
387 * @filename: The filename to find patterned pathname.
388 *
389 * Returns pointer to pathname pattern if matched, @filename otherwise.
390 *
391 * Caller holds tomoyo_read_lock().
392 */
393const char *tomoyo_pattern(const struct tomoyo_path_info *filename)
394{
395 struct tomoyo_no_pattern *ptr;
396 const struct tomoyo_path_info *pattern = NULL;
397
398 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN],
399 head.list) {
400 if (ptr->head.is_deleted)
401 continue;
402 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
403 continue;
404 pattern = ptr->pattern;
405 if (tomoyo_strendswith(pattern->name, "/\\*")) {
406 /* Do nothing. Try to find the better match. */
407 } else {
408 /* This would be the better match. Use this. */
409 break;
410 }
411 }
412 if (pattern)
413 filename = pattern;
414 return filename->name;
415}
416
417/**
418 * tomoyo_write_pattern - Write "struct tomoyo_no_pattern" list.
419 *
420 * @data: String to parse.
421 * @is_delete: True if it is a delete request.
422 *
423 * Returns 0 on success, negative value otherwise.
424 *
425 * Caller holds tomoyo_read_lock().
426 */
427int tomoyo_write_pattern(char *data, const bool is_delete)
428{
429 return tomoyo_update_file_pattern_entry(data, is_delete);
430}
431
432static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a,
433 const struct tomoyo_acl_head *b)
434{
435 return container_of(a, struct tomoyo_no_rewrite, head)->pattern
436 == container_of(b, struct tomoyo_no_rewrite, head)
437 ->pattern;
438}
439
440/**
441 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite" list.
442 *
443 * @pattern: Pathname pattern that are not rewritable by default.
444 * @is_delete: True if it is a delete request.
445 *
446 * Returns 0 on success, negative value otherwise.
447 *
448 * Caller holds tomoyo_read_lock().
449 */
450static int tomoyo_update_no_rewrite_entry(const char *pattern,
451 const bool is_delete)
452{
453 struct tomoyo_no_rewrite e = { };
454 int error;
455
456 if (!tomoyo_correct_word(pattern))
457 return -EINVAL;
458 e.pattern = tomoyo_get_name(pattern);
459 if (!e.pattern)
460 return -ENOMEM;
461 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
462 &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
463 tomoyo_same_no_rewrite);
464 tomoyo_put_name(e.pattern);
465 return error;
466} 236}
467 237
468/** 238/**
469 * tomoyo_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. 239 * tomoyo_check_path_acl - Check permission for path operation.
470 * 240 *
471 * @filename: Filename to check. 241 * @r: Pointer to "struct tomoyo_request_info".
242 * @ptr: Pointer to "struct tomoyo_acl_info".
472 * 243 *
473 * Returns true if @filename is specified by "deny_rewrite" directive, 244 * Returns true if granted, false otherwise.
474 * false otherwise.
475 * 245 *
476 * Caller holds tomoyo_read_lock(). 246 * To be able to use wildcard for domain transition, this function sets
247 * matching entry on success. Since the caller holds tomoyo_read_lock(),
248 * it is safe to set matching entry.
477 */ 249 */
478static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename)
479{
480 struct tomoyo_no_rewrite *ptr;
481 bool found = false;
482
483 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
484 head.list) {
485 if (ptr->head.is_deleted)
486 continue;
487 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
488 continue;
489 found = true;
490 break;
491 }
492 return found;
493}
494
495/**
496 * tomoyo_write_no_rewrite - Write "struct tomoyo_no_rewrite" list.
497 *
498 * @data: String to parse.
499 * @is_delete: True if it is a delete request.
500 *
501 * Returns 0 on success, negative value otherwise.
502 *
503 * Caller holds tomoyo_read_lock().
504 */
505int tomoyo_write_no_rewrite(char *data, const bool is_delete)
506{
507 return tomoyo_update_no_rewrite_entry(data, is_delete);
508}
509
510static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 250static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
511 const struct tomoyo_acl_info *ptr) 251 const struct tomoyo_acl_info *ptr)
512{ 252{
@@ -521,6 +261,14 @@ static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
521 return false; 261 return false;
522} 262}
523 263
264/**
265 * tomoyo_check_path_number_acl - Check permission for path number operation.
266 *
267 * @r: Pointer to "struct tomoyo_request_info".
268 * @ptr: Pointer to "struct tomoyo_acl_info".
269 *
270 * Returns true if granted, false otherwise.
271 */
524static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, 272static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
525 const struct tomoyo_acl_info *ptr) 273 const struct tomoyo_acl_info *ptr)
526{ 274{
@@ -533,6 +281,14 @@ static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
533 &acl->name); 281 &acl->name);
534} 282}
535 283
284/**
285 * tomoyo_check_path2_acl - Check permission for path path operation.
286 *
287 * @r: Pointer to "struct tomoyo_request_info".
288 * @ptr: Pointer to "struct tomoyo_acl_info".
289 *
290 * Returns true if granted, false otherwise.
291 */
536static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, 292static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
537 const struct tomoyo_acl_info *ptr) 293 const struct tomoyo_acl_info *ptr)
538{ 294{
@@ -544,8 +300,16 @@ static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
544 &acl->name2); 300 &acl->name2);
545} 301}
546 302
303/**
304 * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
305 *
306 * @r: Pointer to "struct tomoyo_request_info".
307 * @ptr: Pointer to "struct tomoyo_acl_info".
308 *
309 * Returns true if granted, false otherwise.
310 */
547static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, 311static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
548 const struct tomoyo_acl_info *ptr) 312 const struct tomoyo_acl_info *ptr)
549{ 313{
550 const struct tomoyo_mkdev_acl *acl = 314 const struct tomoyo_mkdev_acl *acl =
551 container_of(ptr, typeof(*acl), head); 315 container_of(ptr, typeof(*acl), head);
@@ -560,15 +324,31 @@ static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
560 &acl->name); 324 &acl->name);
561} 325}
562 326
327/**
328 * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
329 *
330 * @a: Pointer to "struct tomoyo_acl_info".
331 * @b: Pointer to "struct tomoyo_acl_info".
332 *
333 * Returns true if @a == @b except permission bits, false otherwise.
334 */
563static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 335static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
564 const struct tomoyo_acl_info *b) 336 const struct tomoyo_acl_info *b)
565{ 337{
566 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head); 338 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
567 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head); 339 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
568 return tomoyo_same_acl_head(&p1->head, &p2->head) && 340 return tomoyo_same_name_union(&p1->name, &p2->name);
569 tomoyo_same_name_union(&p1->name, &p2->name);
570} 341}
571 342
343/**
344 * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
345 *
346 * @a: Pointer to "struct tomoyo_acl_info".
347 * @b: Pointer to "struct tomoyo_acl_info".
348 * @is_delete: True for @a &= ~@b, false for @a |= @b.
349 *
350 * Returns true if @a is empty, false otherwise.
351 */
572static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, 352static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
573 struct tomoyo_acl_info *b, 353 struct tomoyo_acl_info *b,
574 const bool is_delete) 354 const bool is_delete)
@@ -577,19 +357,10 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
577 ->perm; 357 ->perm;
578 u16 perm = *a_perm; 358 u16 perm = *a_perm;
579 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; 359 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
580 if (is_delete) { 360 if (is_delete)
581 perm &= ~b_perm; 361 perm &= ~b_perm;
582 if ((perm & TOMOYO_RW_MASK) != TOMOYO_RW_MASK) 362 else
583 perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
584 else if (!(perm & (1 << TOMOYO_TYPE_READ_WRITE)))
585 perm &= ~TOMOYO_RW_MASK;
586 } else {
587 perm |= b_perm; 363 perm |= b_perm;
588 if ((perm & TOMOYO_RW_MASK) == TOMOYO_RW_MASK)
589 perm |= (1 << TOMOYO_TYPE_READ_WRITE);
590 else if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
591 perm |= TOMOYO_RW_MASK;
592 }
593 *a_perm = perm; 364 *a_perm = perm;
594 return !perm; 365 return !perm;
595} 366}
@@ -597,52 +368,62 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
597/** 368/**
598 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 369 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
599 * 370 *
600 * @type: Type of operation. 371 * @perm: Permission.
601 * @filename: Filename. 372 * @param: Pointer to "struct tomoyo_acl_param".
602 * @domain: Pointer to "struct tomoyo_domain_info".
603 * @is_delete: True if it is a delete request.
604 * 373 *
605 * Returns 0 on success, negative value otherwise. 374 * Returns 0 on success, negative value otherwise.
606 * 375 *
607 * Caller holds tomoyo_read_lock(). 376 * Caller holds tomoyo_read_lock().
608 */ 377 */
609static int tomoyo_update_path_acl(const u8 type, const char *filename, 378static int tomoyo_update_path_acl(const u16 perm,
610 struct tomoyo_domain_info * const domain, 379 struct tomoyo_acl_param *param)
611 const bool is_delete)
612{ 380{
613 struct tomoyo_path_acl e = { 381 struct tomoyo_path_acl e = {
614 .head.type = TOMOYO_TYPE_PATH_ACL, 382 .head.type = TOMOYO_TYPE_PATH_ACL,
615 .perm = 1 << type 383 .perm = perm
616 }; 384 };
617 int error; 385 int error;
618 if (e.perm == (1 << TOMOYO_TYPE_READ_WRITE)) 386 if (!tomoyo_parse_name_union(param, &e.name))
619 e.perm |= TOMOYO_RW_MASK; 387 error = -EINVAL;
620 if (!tomoyo_parse_name_union(filename, &e.name)) 388 else
621 return -EINVAL; 389 error = tomoyo_update_domain(&e.head, sizeof(e), param,
622 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 390 tomoyo_same_path_acl,
623 tomoyo_same_path_acl, 391 tomoyo_merge_path_acl);
624 tomoyo_merge_path_acl);
625 tomoyo_put_name_union(&e.name); 392 tomoyo_put_name_union(&e.name);
626 return error; 393 return error;
627} 394}
628 395
396/**
397 * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
398 *
399 * @a: Pointer to "struct tomoyo_acl_info".
400 * @b: Pointer to "struct tomoyo_acl_info".
401 *
402 * Returns true if @a == @b except permission bits, false otherwise.
403 */
629static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, 404static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
630 const struct tomoyo_acl_info *b) 405 const struct tomoyo_acl_info *b)
631{ 406{
632 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), 407 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
633 head); 408 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
634 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), 409 return tomoyo_same_name_union(&p1->name, &p2->name) &&
635 head); 410 tomoyo_same_number_union(&p1->mode, &p2->mode) &&
636 return tomoyo_same_acl_head(&p1->head, &p2->head) 411 tomoyo_same_number_union(&p1->major, &p2->major) &&
637 && tomoyo_same_name_union(&p1->name, &p2->name) 412 tomoyo_same_number_union(&p1->minor, &p2->minor);
638 && tomoyo_same_number_union(&p1->mode, &p2->mode)
639 && tomoyo_same_number_union(&p1->major, &p2->major)
640 && tomoyo_same_number_union(&p1->minor, &p2->minor);
641} 413}
642 414
415/**
416 * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
417 *
418 * @a: Pointer to "struct tomoyo_acl_info".
419 * @b: Pointer to "struct tomoyo_acl_info".
420 * @is_delete: True for @a &= ~@b, false for @a |= @b.
421 *
422 * Returns true if @a is empty, false otherwise.
423 */
643static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, 424static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
644 struct tomoyo_acl_info *b, 425 struct tomoyo_acl_info *b,
645 const bool is_delete) 426 const bool is_delete)
646{ 427{
647 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, 428 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
648 head)->perm; 429 head)->perm;
@@ -660,37 +441,30 @@ static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
660/** 441/**
661 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list. 442 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
662 * 443 *
663 * @type: Type of operation. 444 * @perm: Permission.
664 * @filename: Filename. 445 * @param: Pointer to "struct tomoyo_acl_param".
665 * @mode: Create mode.
666 * @major: Device major number.
667 * @minor: Device minor number.
668 * @domain: Pointer to "struct tomoyo_domain_info".
669 * @is_delete: True if it is a delete request.
670 * 446 *
671 * Returns 0 on success, negative value otherwise. 447 * Returns 0 on success, negative value otherwise.
672 * 448 *
673 * Caller holds tomoyo_read_lock(). 449 * Caller holds tomoyo_read_lock().
674 */ 450 */
675static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, 451static int tomoyo_update_mkdev_acl(const u8 perm,
676 char *mode, char *major, char *minor, 452 struct tomoyo_acl_param *param)
677 struct tomoyo_domain_info * const
678 domain, const bool is_delete)
679{ 453{
680 struct tomoyo_mkdev_acl e = { 454 struct tomoyo_mkdev_acl e = {
681 .head.type = TOMOYO_TYPE_MKDEV_ACL, 455 .head.type = TOMOYO_TYPE_MKDEV_ACL,
682 .perm = 1 << type 456 .perm = perm
683 }; 457 };
684 int error = is_delete ? -ENOENT : -ENOMEM; 458 int error;
685 if (!tomoyo_parse_name_union(filename, &e.name) || 459 if (!tomoyo_parse_name_union(param, &e.name) ||
686 !tomoyo_parse_number_union(mode, &e.mode) || 460 !tomoyo_parse_number_union(param, &e.mode) ||
687 !tomoyo_parse_number_union(major, &e.major) || 461 !tomoyo_parse_number_union(param, &e.major) ||
688 !tomoyo_parse_number_union(minor, &e.minor)) 462 !tomoyo_parse_number_union(param, &e.minor))
689 goto out; 463 error = -EINVAL;
690 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 464 else
691 tomoyo_same_mkdev_acl, 465 error = tomoyo_update_domain(&e.head, sizeof(e), param,
692 tomoyo_merge_mkdev_acl); 466 tomoyo_same_mkdev_acl,
693 out: 467 tomoyo_merge_mkdev_acl);
694 tomoyo_put_name_union(&e.name); 468 tomoyo_put_name_union(&e.name);
695 tomoyo_put_number_union(&e.mode); 469 tomoyo_put_number_union(&e.mode);
696 tomoyo_put_number_union(&e.major); 470 tomoyo_put_number_union(&e.major);
@@ -698,16 +472,32 @@ static int tomoyo_update_mkdev_acl(const u8 type, const char *filename,
698 return error; 472 return error;
699} 473}
700 474
475/**
476 * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
477 *
478 * @a: Pointer to "struct tomoyo_acl_info".
479 * @b: Pointer to "struct tomoyo_acl_info".
480 *
481 * Returns true if @a == @b except permission bits, false otherwise.
482 */
701static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, 483static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
702 const struct tomoyo_acl_info *b) 484 const struct tomoyo_acl_info *b)
703{ 485{
704 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head); 486 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
705 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head); 487 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
706 return tomoyo_same_acl_head(&p1->head, &p2->head) 488 return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
707 && tomoyo_same_name_union(&p1->name1, &p2->name1) 489 tomoyo_same_name_union(&p1->name2, &p2->name2);
708 && tomoyo_same_name_union(&p1->name2, &p2->name2);
709} 490}
710 491
492/**
493 * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
494 *
495 * @a: Pointer to "struct tomoyo_acl_info".
496 * @b: Pointer to "struct tomoyo_acl_info".
497 * @is_delete: True for @a &= ~@b, false for @a |= @b.
498 *
499 * Returns true if @a is empty, false otherwise.
500 */
711static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, 501static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
712 struct tomoyo_acl_info *b, 502 struct tomoyo_acl_info *b,
713 const bool is_delete) 503 const bool is_delete)
@@ -727,33 +517,28 @@ static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
727/** 517/**
728 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 518 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
729 * 519 *
730 * @type: Type of operation. 520 * @perm: Permission.
731 * @filename1: First filename. 521 * @param: Pointer to "struct tomoyo_acl_param".
732 * @filename2: Second filename.
733 * @domain: Pointer to "struct tomoyo_domain_info".
734 * @is_delete: True if it is a delete request.
735 * 522 *
736 * Returns 0 on success, negative value otherwise. 523 * Returns 0 on success, negative value otherwise.
737 * 524 *
738 * Caller holds tomoyo_read_lock(). 525 * Caller holds tomoyo_read_lock().
739 */ 526 */
740static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 527static int tomoyo_update_path2_acl(const u8 perm,
741 const char *filename2, 528 struct tomoyo_acl_param *param)
742 struct tomoyo_domain_info * const domain,
743 const bool is_delete)
744{ 529{
745 struct tomoyo_path2_acl e = { 530 struct tomoyo_path2_acl e = {
746 .head.type = TOMOYO_TYPE_PATH2_ACL, 531 .head.type = TOMOYO_TYPE_PATH2_ACL,
747 .perm = 1 << type 532 .perm = perm
748 }; 533 };
749 int error = is_delete ? -ENOENT : -ENOMEM; 534 int error;
750 if (!tomoyo_parse_name_union(filename1, &e.name1) || 535 if (!tomoyo_parse_name_union(param, &e.name1) ||
751 !tomoyo_parse_name_union(filename2, &e.name2)) 536 !tomoyo_parse_name_union(param, &e.name2))
752 goto out; 537 error = -EINVAL;
753 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 538 else
754 tomoyo_same_path2_acl, 539 error = tomoyo_update_domain(&e.head, sizeof(e), param,
755 tomoyo_merge_path2_acl); 540 tomoyo_same_path2_acl,
756 out: 541 tomoyo_merge_path2_acl);
757 tomoyo_put_name_union(&e.name1); 542 tomoyo_put_name_union(&e.name1);
758 tomoyo_put_name_union(&e.name2); 543 tomoyo_put_name_union(&e.name2);
759 return error; 544 return error;
@@ -775,9 +560,8 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
775{ 560{
776 int error; 561 int error;
777 562
778 next:
779 r->type = tomoyo_p2mac[operation]; 563 r->type = tomoyo_p2mac[operation];
780 r->mode = tomoyo_get_mode(r->profile, r->type); 564 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
781 if (r->mode == TOMOYO_CONFIG_DISABLED) 565 if (r->mode == TOMOYO_CONFIG_DISABLED)
782 return 0; 566 return 0;
783 r->param_type = TOMOYO_TYPE_PATH_ACL; 567 r->param_type = TOMOYO_TYPE_PATH_ACL;
@@ -785,10 +569,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
785 r->param.path.operation = operation; 569 r->param.path.operation = operation;
786 do { 570 do {
787 tomoyo_check_acl(r, tomoyo_check_path_acl); 571 tomoyo_check_acl(r, tomoyo_check_path_acl);
788 if (!r->granted && operation == TOMOYO_TYPE_READ &&
789 !r->domain->ignore_global_allow_read &&
790 tomoyo_globally_readable_file(filename))
791 r->granted = true;
792 error = tomoyo_audit_path_log(r); 572 error = tomoyo_audit_path_log(r);
793 /* 573 /*
794 * Do not retry for execute request, for alias may have 574 * Do not retry for execute request, for alias may have
@@ -796,19 +576,17 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
796 */ 576 */
797 } while (error == TOMOYO_RETRY_REQUEST && 577 } while (error == TOMOYO_RETRY_REQUEST &&
798 operation != TOMOYO_TYPE_EXECUTE); 578 operation != TOMOYO_TYPE_EXECUTE);
799 /*
800 * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
801 * we need to check "allow_rewrite" permission if the filename is
802 * specified by "deny_rewrite" keyword.
803 */
804 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
805 tomoyo_no_rewrite_file(filename)) {
806 operation = TOMOYO_TYPE_REWRITE;
807 goto next;
808 }
809 return error; 579 return error;
810} 580}
811 581
582/**
583 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
584 *
585 * @a: Pointer to "struct tomoyo_acl_info".
586 * @b: Pointer to "struct tomoyo_acl_info".
587 *
588 * Returns true if @a == @b except permission bits, false otherwise.
589 */
812static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 590static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
813 const struct tomoyo_acl_info *b) 591 const struct tomoyo_acl_info *b)
814{ 592{
@@ -816,11 +594,19 @@ static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
816 head); 594 head);
817 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2), 595 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
818 head); 596 head);
819 return tomoyo_same_acl_head(&p1->head, &p2->head) 597 return tomoyo_same_name_union(&p1->name, &p2->name) &&
820 && tomoyo_same_name_union(&p1->name, &p2->name) 598 tomoyo_same_number_union(&p1->number, &p2->number);
821 && tomoyo_same_number_union(&p1->number, &p2->number);
822} 599}
823 600
601/**
602 * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
603 *
604 * @a: Pointer to "struct tomoyo_acl_info".
605 * @b: Pointer to "struct tomoyo_acl_info".
606 * @is_delete: True for @a &= ~@b, false for @a |= @b.
607 *
608 * Returns true if @a is empty, false otherwise.
609 */
824static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, 610static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
825 struct tomoyo_acl_info *b, 611 struct tomoyo_acl_info *b,
826 const bool is_delete) 612 const bool is_delete)
@@ -841,33 +627,26 @@ static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
841/** 627/**
842 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. 628 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
843 * 629 *
844 * @type: Type of operation. 630 * @perm: Permission.
845 * @filename: Filename. 631 * @param: Pointer to "struct tomoyo_acl_param".
846 * @number: Number.
847 * @domain: Pointer to "struct tomoyo_domain_info".
848 * @is_delete: True if it is a delete request.
849 * 632 *
850 * Returns 0 on success, negative value otherwise. 633 * Returns 0 on success, negative value otherwise.
851 */ 634 */
852static int tomoyo_update_path_number_acl(const u8 type, const char *filename, 635static int tomoyo_update_path_number_acl(const u8 perm,
853 char *number, 636 struct tomoyo_acl_param *param)
854 struct tomoyo_domain_info * const
855 domain,
856 const bool is_delete)
857{ 637{
858 struct tomoyo_path_number_acl e = { 638 struct tomoyo_path_number_acl e = {
859 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 639 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
860 .perm = 1 << type 640 .perm = perm
861 }; 641 };
862 int error = is_delete ? -ENOENT : -ENOMEM; 642 int error;
863 if (!tomoyo_parse_name_union(filename, &e.name)) 643 if (!tomoyo_parse_name_union(param, &e.name) ||
864 return -EINVAL; 644 !tomoyo_parse_number_union(param, &e.number))
865 if (!tomoyo_parse_number_union(number, &e.number)) 645 error = -EINVAL;
866 goto out; 646 else
867 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 647 error = tomoyo_update_domain(&e.head, sizeof(e), param,
868 tomoyo_same_path_number_acl, 648 tomoyo_same_path_number_acl,
869 tomoyo_merge_path_number_acl); 649 tomoyo_merge_path_number_acl);
870 out:
871 tomoyo_put_name_union(&e.name); 650 tomoyo_put_name_union(&e.name);
872 tomoyo_put_number_union(&e.number); 651 tomoyo_put_number_union(&e.number);
873 return error; 652 return error;
@@ -886,16 +665,20 @@ int tomoyo_path_number_perm(const u8 type, struct path *path,
886 unsigned long number) 665 unsigned long number)
887{ 666{
888 struct tomoyo_request_info r; 667 struct tomoyo_request_info r;
668 struct tomoyo_obj_info obj = {
669 .path1 = *path,
670 };
889 int error = -ENOMEM; 671 int error = -ENOMEM;
890 struct tomoyo_path_info buf; 672 struct tomoyo_path_info buf;
891 int idx; 673 int idx;
892 674
893 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) 675 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
894 == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry) 676 == TOMOYO_CONFIG_DISABLED || !path->dentry)
895 return 0; 677 return 0;
896 idx = tomoyo_read_lock(); 678 idx = tomoyo_read_lock();
897 if (!tomoyo_get_realpath(&buf, path)) 679 if (!tomoyo_get_realpath(&buf, path))
898 goto out; 680 goto out;
681 r.obj = &obj;
899 if (type == TOMOYO_TYPE_MKDIR) 682 if (type == TOMOYO_TYPE_MKDIR)
900 tomoyo_add_slash(&buf); 683 tomoyo_add_slash(&buf);
901 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; 684 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
@@ -930,45 +713,30 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
930 int error = 0; 713 int error = 0;
931 struct tomoyo_path_info buf; 714 struct tomoyo_path_info buf;
932 struct tomoyo_request_info r; 715 struct tomoyo_request_info r;
716 struct tomoyo_obj_info obj = {
717 .path1 = *path,
718 };
933 int idx; 719 int idx;
934 720
935 if (!path->mnt ||
936 (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
937 return 0;
938 buf.name = NULL; 721 buf.name = NULL;
939 r.mode = TOMOYO_CONFIG_DISABLED; 722 r.mode = TOMOYO_CONFIG_DISABLED;
940 idx = tomoyo_read_lock(); 723 idx = tomoyo_read_lock();
941 /* 724 if (acc_mode &&
942 * If the filename is specified by "deny_rewrite" keyword, 725 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
943 * we need to check "allow_rewrite" permission when the filename is not
944 * opened for append mode or the filename is truncated at open time.
945 */
946 if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND)
947 && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE)
948 != TOMOYO_CONFIG_DISABLED) { 726 != TOMOYO_CONFIG_DISABLED) {
949 if (!tomoyo_get_realpath(&buf, path)) { 727 if (!tomoyo_get_realpath(&buf, path)) {
950 error = -ENOMEM; 728 error = -ENOMEM;
951 goto out; 729 goto out;
952 } 730 }
953 if (tomoyo_no_rewrite_file(&buf)) 731 r.obj = &obj;
954 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, 732 if (acc_mode & MAY_READ)
733 error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
734 &buf);
735 if (!error && (acc_mode & MAY_WRITE))
736 error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
737 TOMOYO_TYPE_APPEND :
738 TOMOYO_TYPE_WRITE,
955 &buf); 739 &buf);
956 }
957 if (!error && acc_mode &&
958 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
959 != TOMOYO_CONFIG_DISABLED) {
960 u8 operation;
961 if (!buf.name && !tomoyo_get_realpath(&buf, path)) {
962 error = -ENOMEM;
963 goto out;
964 }
965 if (acc_mode == (MAY_READ | MAY_WRITE))
966 operation = TOMOYO_TYPE_READ_WRITE;
967 else if (acc_mode == MAY_READ)
968 operation = TOMOYO_TYPE_READ;
969 else
970 operation = TOMOYO_TYPE_WRITE;
971 error = tomoyo_path_permission(&r, operation, &buf);
972 } 740 }
973 out: 741 out:
974 kfree(buf.name); 742 kfree(buf.name);
@@ -979,46 +747,57 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
979} 747}
980 748
981/** 749/**
982 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount". 750 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
983 * 751 *
984 * @operation: Type of operation. 752 * @operation: Type of operation.
985 * @path: Pointer to "struct path". 753 * @path: Pointer to "struct path".
754 * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
755 * NULL otherwise.
986 * 756 *
987 * Returns 0 on success, negative value otherwise. 757 * Returns 0 on success, negative value otherwise.
988 */ 758 */
989int tomoyo_path_perm(const u8 operation, struct path *path) 759int tomoyo_path_perm(const u8 operation, struct path *path, const char *target)
990{ 760{
991 int error = -ENOMEM;
992 struct tomoyo_path_info buf;
993 struct tomoyo_request_info r; 761 struct tomoyo_request_info r;
762 struct tomoyo_obj_info obj = {
763 .path1 = *path,
764 };
765 int error;
766 struct tomoyo_path_info buf;
767 bool is_enforce;
768 struct tomoyo_path_info symlink_target;
994 int idx; 769 int idx;
995 770
996 if (!path->mnt)
997 return 0;
998 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) 771 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
999 == TOMOYO_CONFIG_DISABLED) 772 == TOMOYO_CONFIG_DISABLED)
1000 return 0; 773 return 0;
774 is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
775 error = -ENOMEM;
1001 buf.name = NULL; 776 buf.name = NULL;
1002 idx = tomoyo_read_lock(); 777 idx = tomoyo_read_lock();
1003 if (!tomoyo_get_realpath(&buf, path)) 778 if (!tomoyo_get_realpath(&buf, path))
1004 goto out; 779 goto out;
780 r.obj = &obj;
1005 switch (operation) { 781 switch (operation) {
1006 case TOMOYO_TYPE_REWRITE:
1007 if (!tomoyo_no_rewrite_file(&buf)) {
1008 error = 0;
1009 goto out;
1010 }
1011 break;
1012 case TOMOYO_TYPE_RMDIR: 782 case TOMOYO_TYPE_RMDIR:
1013 case TOMOYO_TYPE_CHROOT: 783 case TOMOYO_TYPE_CHROOT:
1014 tomoyo_add_slash(&buf); 784 tomoyo_add_slash(&buf);
1015 break; 785 break;
786 case TOMOYO_TYPE_SYMLINK:
787 symlink_target.name = tomoyo_encode(target);
788 if (!symlink_target.name)
789 goto out;
790 tomoyo_fill_path_info(&symlink_target);
791 obj.symlink_target = &symlink_target;
792 break;
1016 } 793 }
1017 error = tomoyo_path_permission(&r, operation, &buf); 794 error = tomoyo_path_permission(&r, operation, &buf);
795 if (operation == TOMOYO_TYPE_SYMLINK)
796 kfree(symlink_target.name);
1018 out: 797 out:
1019 kfree(buf.name); 798 kfree(buf.name);
1020 tomoyo_read_unlock(idx); 799 tomoyo_read_unlock(idx);
1021 if (r.mode != TOMOYO_CONFIG_ENFORCING) 800 if (!is_enforce)
1022 error = 0; 801 error = 0;
1023 return error; 802 return error;
1024} 803}
@@ -1034,20 +813,23 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1034 * Returns 0 on success, negative value otherwise. 813 * Returns 0 on success, negative value otherwise.
1035 */ 814 */
1036int tomoyo_mkdev_perm(const u8 operation, struct path *path, 815int tomoyo_mkdev_perm(const u8 operation, struct path *path,
1037 const unsigned int mode, unsigned int dev) 816 const unsigned int mode, unsigned int dev)
1038{ 817{
1039 struct tomoyo_request_info r; 818 struct tomoyo_request_info r;
819 struct tomoyo_obj_info obj = {
820 .path1 = *path,
821 };
1040 int error = -ENOMEM; 822 int error = -ENOMEM;
1041 struct tomoyo_path_info buf; 823 struct tomoyo_path_info buf;
1042 int idx; 824 int idx;
1043 825
1044 if (!path->mnt || 826 if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1045 tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1046 == TOMOYO_CONFIG_DISABLED) 827 == TOMOYO_CONFIG_DISABLED)
1047 return 0; 828 return 0;
1048 idx = tomoyo_read_lock(); 829 idx = tomoyo_read_lock();
1049 error = -ENOMEM; 830 error = -ENOMEM;
1050 if (tomoyo_get_realpath(&buf, path)) { 831 if (tomoyo_get_realpath(&buf, path)) {
832 r.obj = &obj;
1051 dev = new_decode_dev(dev); 833 dev = new_decode_dev(dev);
1052 r.param_type = TOMOYO_TYPE_MKDEV_ACL; 834 r.param_type = TOMOYO_TYPE_MKDEV_ACL;
1053 r.param.mkdev.filename = &buf; 835 r.param.mkdev.filename = &buf;
@@ -1081,10 +863,13 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1081 struct tomoyo_path_info buf1; 863 struct tomoyo_path_info buf1;
1082 struct tomoyo_path_info buf2; 864 struct tomoyo_path_info buf2;
1083 struct tomoyo_request_info r; 865 struct tomoyo_request_info r;
866 struct tomoyo_obj_info obj = {
867 .path1 = *path1,
868 .path2 = *path2,
869 };
1084 int idx; 870 int idx;
1085 871
1086 if (!path1->mnt || !path2->mnt || 872 if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1087 tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1088 == TOMOYO_CONFIG_DISABLED) 873 == TOMOYO_CONFIG_DISABLED)
1089 return 0; 874 return 0;
1090 buf1.name = NULL; 875 buf1.name = NULL;
@@ -1096,16 +881,17 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1096 switch (operation) { 881 switch (operation) {
1097 struct dentry *dentry; 882 struct dentry *dentry;
1098 case TOMOYO_TYPE_RENAME: 883 case TOMOYO_TYPE_RENAME:
1099 case TOMOYO_TYPE_LINK: 884 case TOMOYO_TYPE_LINK:
1100 dentry = path1->dentry; 885 dentry = path1->dentry;
1101 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) 886 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
1102 break; 887 break;
1103 /* fall through */ 888 /* fall through */
1104 case TOMOYO_TYPE_PIVOT_ROOT: 889 case TOMOYO_TYPE_PIVOT_ROOT:
1105 tomoyo_add_slash(&buf1); 890 tomoyo_add_slash(&buf1);
1106 tomoyo_add_slash(&buf2); 891 tomoyo_add_slash(&buf2);
1107 break; 892 break;
1108 } 893 }
894 r.obj = &obj;
1109 r.param_type = TOMOYO_TYPE_PATH2_ACL; 895 r.param_type = TOMOYO_TYPE_PATH2_ACL;
1110 r.param.path2.operation = operation; 896 r.param.path2.operation = operation;
1111 r.param.path2.filename1 = &buf1; 897 r.param.path2.filename1 = &buf1;
@@ -1124,53 +910,91 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1124} 910}
1125 911
1126/** 912/**
913 * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
914 *
915 * @a: Pointer to "struct tomoyo_acl_info".
916 * @b: Pointer to "struct tomoyo_acl_info".
917 *
918 * Returns true if @a == @b, false otherwise.
919 */
920static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
921 const struct tomoyo_acl_info *b)
922{
923 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
924 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
925 return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
926 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
927 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
928 tomoyo_same_number_union(&p1->flags, &p2->flags);
929}
930
931/**
932 * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
933 *
934 * @param: Pointer to "struct tomoyo_acl_param".
935 *
936 * Returns 0 on success, negative value otherwise.
937 *
938 * Caller holds tomoyo_read_lock().
939 */
940static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
941{
942 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
943 int error;
944 if (!tomoyo_parse_name_union(param, &e.dev_name) ||
945 !tomoyo_parse_name_union(param, &e.dir_name) ||
946 !tomoyo_parse_name_union(param, &e.fs_type) ||
947 !tomoyo_parse_number_union(param, &e.flags))
948 error = -EINVAL;
949 else
950 error = tomoyo_update_domain(&e.head, sizeof(e), param,
951 tomoyo_same_mount_acl, NULL);
952 tomoyo_put_name_union(&e.dev_name);
953 tomoyo_put_name_union(&e.dir_name);
954 tomoyo_put_name_union(&e.fs_type);
955 tomoyo_put_number_union(&e.flags);
956 return error;
957}
958
959/**
1127 * tomoyo_write_file - Update file related list. 960 * tomoyo_write_file - Update file related list.
1128 * 961 *
1129 * @data: String to parse. 962 * @param: Pointer to "struct tomoyo_acl_param".
1130 * @domain: Pointer to "struct tomoyo_domain_info".
1131 * @is_delete: True if it is a delete request.
1132 * 963 *
1133 * Returns 0 on success, negative value otherwise. 964 * Returns 0 on success, negative value otherwise.
1134 * 965 *
1135 * Caller holds tomoyo_read_lock(). 966 * Caller holds tomoyo_read_lock().
1136 */ 967 */
1137int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain, 968int tomoyo_write_file(struct tomoyo_acl_param *param)
1138 const bool is_delete)
1139{ 969{
1140 char *w[5]; 970 u16 perm = 0;
1141 u8 type; 971 u8 type;
1142 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) 972 const char *operation = tomoyo_read_token(param);
1143 return -EINVAL; 973 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
1144 if (strncmp(w[0], "allow_", 6)) 974 if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
1145 goto out; 975 perm |= 1 << type;
1146 w[0] += 6; 976 if (perm)
1147 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { 977 return tomoyo_update_path_acl(perm, param);
1148 if (strcmp(w[0], tomoyo_path_keyword[type])) 978 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
1149 continue; 979 if (tomoyo_permstr(operation,
1150 return tomoyo_update_path_acl(type, w[1], domain, is_delete); 980 tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
1151 } 981 perm |= 1 << type;
1152 if (!w[2][0]) 982 if (perm)
1153 goto out; 983 return tomoyo_update_path2_acl(perm, param);
1154 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { 984 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
1155 if (strcmp(w[0], tomoyo_path2_keyword[type])) 985 if (tomoyo_permstr(operation,
1156 continue; 986 tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
1157 return tomoyo_update_path2_acl(type, w[1], w[2], domain, 987 perm |= 1 << type;
1158 is_delete); 988 if (perm)
1159 } 989 return tomoyo_update_path_number_acl(perm, param);
1160 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) { 990 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
1161 if (strcmp(w[0], tomoyo_path_number_keyword[type])) 991 if (tomoyo_permstr(operation,
1162 continue; 992 tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
1163 return tomoyo_update_path_number_acl(type, w[1], w[2], domain, 993 perm |= 1 << type;
1164 is_delete); 994 if (perm)
1165 } 995 return tomoyo_update_mkdev_acl(perm, param);
1166 if (!w[3][0] || !w[4][0]) 996 if (tomoyo_permstr(operation,
1167 goto out; 997 tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
1168 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++) { 998 return tomoyo_update_mount_acl(param);
1169 if (strcmp(w[0], tomoyo_mkdev_keyword[type]))
1170 continue;
1171 return tomoyo_update_mkdev_acl(type, w[1], w[2], w[3],
1172 w[4], domain, is_delete);
1173 }
1174 out:
1175 return -EINVAL; 999 return -EINVAL;
1176} 1000}
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index a877e4c3b101..ae135fbbbe95 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -1,58 +1,205 @@
1/* 1/*
2 * security/tomoyo/gc.c 2 * security/tomoyo/gc.c
3 * 3 *
4 * Implementation of the Domain-Based Mandatory Access Control. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 *
8 */ 5 */
9 6
10#include "common.h" 7#include "common.h"
11#include <linux/kthread.h> 8#include <linux/kthread.h>
12#include <linux/slab.h> 9#include <linux/slab.h>
13 10
11/* The list for "struct tomoyo_io_buffer". */
12static LIST_HEAD(tomoyo_io_buffer_list);
13/* Lock for protecting tomoyo_io_buffer_list. */
14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
15
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/**
42 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
43 *
44 * @element: Pointer to "struct list_head".
45 *
46 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
47 * false otherwise.
48 */
49static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
50{
51 struct tomoyo_io_buffer *head;
52 bool in_use = false;
53
54 spin_lock(&tomoyo_io_buffer_list_lock);
55 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
56 head->users++;
57 spin_unlock(&tomoyo_io_buffer_list_lock);
58 if (mutex_lock_interruptible(&head->io_sem)) {
59 in_use = true;
60 goto out;
61 }
62 if (head->r.domain == element || head->r.group == element ||
63 head->r.acl == element || &head->w.domain->list == element)
64 in_use = true;
65 mutex_unlock(&head->io_sem);
66out:
67 spin_lock(&tomoyo_io_buffer_list_lock);
68 head->users--;
69 if (in_use)
70 break;
71 }
72 spin_unlock(&tomoyo_io_buffer_list_lock);
73 return in_use;
74}
75
76/**
77 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
78 *
79 * @string: String to check.
80 * @size: Memory allocated for @string .
81 *
82 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
83 * false otherwise.
84 */
85static bool tomoyo_name_used_by_io_buffer(const char *string,
86 const size_t size)
87{
88 struct tomoyo_io_buffer *head;
89 bool in_use = false;
90
91 spin_lock(&tomoyo_io_buffer_list_lock);
92 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
93 int i;
94 head->users++;
95 spin_unlock(&tomoyo_io_buffer_list_lock);
96 if (mutex_lock_interruptible(&head->io_sem)) {
97 in_use = true;
98 goto out;
99 }
100 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
101 const char *w = head->r.w[i];
102 if (w < string || w > string + size)
103 continue;
104 in_use = true;
105 break;
106 }
107 mutex_unlock(&head->io_sem);
108out:
109 spin_lock(&tomoyo_io_buffer_list_lock);
110 head->users--;
111 if (in_use)
112 break;
113 }
114 spin_unlock(&tomoyo_io_buffer_list_lock);
115 return in_use;
116}
117
118/* Structure for garbage collection. */
14struct tomoyo_gc { 119struct tomoyo_gc {
15 struct list_head list; 120 struct list_head list;
16 int type; 121 enum tomoyo_policy_id type;
122 size_t size;
17 struct list_head *element; 123 struct list_head *element;
18}; 124};
19static LIST_HEAD(tomoyo_gc_queue); 125/* List of entries to be deleted. */
20static DEFINE_MUTEX(tomoyo_gc_mutex); 126static LIST_HEAD(tomoyo_gc_list);
127/* Length of tomoyo_gc_list. */
128static int tomoyo_gc_list_len;
21 129
22/* Caller holds tomoyo_policy_lock mutex. */ 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 */
23static bool tomoyo_add_to_gc(const int type, struct list_head *element) 148static bool tomoyo_add_to_gc(const int type, struct list_head *element)
24{ 149{
25 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 150 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
26 if (!entry) 151 if (!entry)
27 return false; 152 return false;
28 entry->type = type; 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];
29 entry->element = element; 169 entry->element = element;
30 list_add(&entry->list, &tomoyo_gc_queue); 170 list_add(&entry->list, &tomoyo_gc_list);
31 list_del_rcu(element); 171 list_del_rcu(element);
32 return true; 172 return tomoyo_gc_list_len++ < 128;
33} 173}
34 174
35static void tomoyo_del_allow_read(struct list_head *element) 175/**
36{ 176 * tomoyo_element_linked_by_gc - Validate next element of an entry.
37 struct tomoyo_readable_file *ptr = 177 *
38 container_of(element, typeof(*ptr), head.list); 178 * @element: Pointer to an element.
39 tomoyo_put_name(ptr->filename); 179 * @size: Size of @element in byte.
40} 180 *
41 181 * Returns true if @element is linked by other elements in the garbage
42static void tomoyo_del_file_pattern(struct list_head *element) 182 * collector's queue, false otherwise.
43{ 183 */
44 struct tomoyo_no_pattern *ptr = 184static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
45 container_of(element, typeof(*ptr), head.list);
46 tomoyo_put_name(ptr->pattern);
47}
48
49static void tomoyo_del_no_rewrite(struct list_head *element)
50{ 185{
51 struct tomoyo_no_rewrite *ptr = 186 struct tomoyo_gc *p;
52 container_of(element, typeof(*ptr), head.list); 187 list_for_each_entry(p, &tomoyo_gc_list, list) {
53 tomoyo_put_name(ptr->pattern); 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;
54} 194}
55 195
196/**
197 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
198 *
199 * @element: Pointer to "struct list_head".
200 *
201 * Returns nothing.
202 */
56static void tomoyo_del_transition_control(struct list_head *element) 203static void tomoyo_del_transition_control(struct list_head *element)
57{ 204{
58 struct tomoyo_transition_control *ptr = 205 struct tomoyo_transition_control *ptr =
@@ -61,6 +208,13 @@ static void tomoyo_del_transition_control(struct list_head *element)
61 tomoyo_put_name(ptr->program); 208 tomoyo_put_name(ptr->program);
62} 209}
63 210
211/**
212 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
213 *
214 * @element: Pointer to "struct list_head".
215 *
216 * Returns nothing.
217 */
64static void tomoyo_del_aggregator(struct list_head *element) 218static void tomoyo_del_aggregator(struct list_head *element)
65{ 219{
66 struct tomoyo_aggregator *ptr = 220 struct tomoyo_aggregator *ptr =
@@ -69,6 +223,13 @@ static void tomoyo_del_aggregator(struct list_head *element)
69 tomoyo_put_name(ptr->aggregated_name); 223 tomoyo_put_name(ptr->aggregated_name);
70} 224}
71 225
226/**
227 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
228 *
229 * @element: Pointer to "struct list_head".
230 *
231 * Returns nothing.
232 */
72static void tomoyo_del_manager(struct list_head *element) 233static void tomoyo_del_manager(struct list_head *element)
73{ 234{
74 struct tomoyo_manager *ptr = 235 struct tomoyo_manager *ptr =
@@ -76,10 +237,18 @@ static void tomoyo_del_manager(struct list_head *element)
76 tomoyo_put_name(ptr->manager); 237 tomoyo_put_name(ptr->manager);
77} 238}
78 239
240/**
241 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
242 *
243 * @element: Pointer to "struct list_head".
244 *
245 * Returns nothing.
246 */
79static void tomoyo_del_acl(struct list_head *element) 247static void tomoyo_del_acl(struct list_head *element)
80{ 248{
81 struct tomoyo_acl_info *acl = 249 struct tomoyo_acl_info *acl =
82 container_of(element, typeof(*acl), list); 250 container_of(element, typeof(*acl), list);
251 tomoyo_put_condition(acl->cond);
83 switch (acl->type) { 252 switch (acl->type) {
84 case TOMOYO_TYPE_PATH_ACL: 253 case TOMOYO_TYPE_PATH_ACL:
85 { 254 {
@@ -127,6 +296,13 @@ static void tomoyo_del_acl(struct list_head *element)
127 } 296 }
128} 297}
129 298
299/**
300 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
301 *
302 * @element: Pointer to "struct list_head".
303 *
304 * Returns true if deleted, false otherwise.
305 */
130static bool tomoyo_del_domain(struct list_head *element) 306static bool tomoyo_del_domain(struct list_head *element)
131{ 307{
132 struct tomoyo_domain_info *domain = 308 struct tomoyo_domain_info *domain =
@@ -165,13 +341,65 @@ static bool tomoyo_del_domain(struct list_head *element)
165 return true; 341 return true;
166} 342}
167 343
344/**
345 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
346 *
347 * @element: Pointer to "struct list_head".
348 *
349 * Returns nothing.
350 */
351void tomoyo_del_condition(struct list_head *element)
352{
353 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
354 head.list);
355 const u16 condc = cond->condc;
356 const u16 numbers_count = cond->numbers_count;
357 const u16 names_count = cond->names_count;
358 const u16 argc = cond->argc;
359 const u16 envc = cond->envc;
360 unsigned int i;
361 const struct tomoyo_condition_element *condp
362 = (const struct tomoyo_condition_element *) (cond + 1);
363 struct tomoyo_number_union *numbers_p
364 = (struct tomoyo_number_union *) (condp + condc);
365 struct tomoyo_name_union *names_p
366 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
367 const struct tomoyo_argv *argv
368 = (const struct tomoyo_argv *) (names_p + names_count);
369 const struct tomoyo_envp *envp
370 = (const struct tomoyo_envp *) (argv + argc);
371 for (i = 0; i < numbers_count; i++)
372 tomoyo_put_number_union(numbers_p++);
373 for (i = 0; i < names_count; i++)
374 tomoyo_put_name_union(names_p++);
375 for (i = 0; i < argc; argv++, i++)
376 tomoyo_put_name(argv->value);
377 for (i = 0; i < envc; envp++, i++) {
378 tomoyo_put_name(envp->name);
379 tomoyo_put_name(envp->value);
380 }
381}
168 382
383/**
384 * tomoyo_del_name - Delete members in "struct tomoyo_name".
385 *
386 * @element: Pointer to "struct list_head".
387 *
388 * Returns nothing.
389 */
169static void tomoyo_del_name(struct list_head *element) 390static void tomoyo_del_name(struct list_head *element)
170{ 391{
171 const struct tomoyo_name *ptr = 392 const struct tomoyo_name *ptr =
172 container_of(element, typeof(*ptr), list); 393 container_of(element, typeof(*ptr), head.list);
173} 394}
174 395
396/**
397 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
398 *
399 * @element: Pointer to "struct list_head".
400 *
401 * Returns nothing.
402 */
175static void tomoyo_del_path_group(struct list_head *element) 403static void tomoyo_del_path_group(struct list_head *element)
176{ 404{
177 struct tomoyo_path_group *member = 405 struct tomoyo_path_group *member =
@@ -179,20 +407,43 @@ static void tomoyo_del_path_group(struct list_head *element)
179 tomoyo_put_name(member->member_name); 407 tomoyo_put_name(member->member_name);
180} 408}
181 409
410/**
411 * tomoyo_del_group - Delete "struct tomoyo_group".
412 *
413 * @element: Pointer to "struct list_head".
414 *
415 * Returns nothing.
416 */
182static void tomoyo_del_group(struct list_head *element) 417static void tomoyo_del_group(struct list_head *element)
183{ 418{
184 struct tomoyo_group *group = 419 struct tomoyo_group *group =
185 container_of(element, typeof(*group), list); 420 container_of(element, typeof(*group), head.list);
186 tomoyo_put_name(group->group_name); 421 tomoyo_put_name(group->group_name);
187} 422}
188 423
424/**
425 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
426 *
427 * @element: Pointer to "struct list_head".
428 *
429 * Returns nothing.
430 */
189static void tomoyo_del_number_group(struct list_head *element) 431static void tomoyo_del_number_group(struct list_head *element)
190{ 432{
191 struct tomoyo_number_group *member = 433 struct tomoyo_number_group *member =
192 container_of(element, typeof(*member), head.list); 434 container_of(element, typeof(*member), head.list);
193} 435}
194 436
195static bool tomoyo_collect_member(struct list_head *member_list, int id) 437/**
438 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
439 *
440 * @id: One of values in "enum tomoyo_policy_id".
441 * @member_list: Pointer to "struct list_head".
442 *
443 * Returns true if some elements are deleted, false otherwise.
444 */
445static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
446 struct list_head *member_list)
196{ 447{
197 struct tomoyo_acl_head *member; 448 struct tomoyo_acl_head *member;
198 list_for_each_entry(member, member_list, list) { 449 list_for_each_entry(member, member_list, list) {
@@ -201,13 +452,20 @@ static bool tomoyo_collect_member(struct list_head *member_list, int id)
201 if (!tomoyo_add_to_gc(id, &member->list)) 452 if (!tomoyo_add_to_gc(id, &member->list))
202 return false; 453 return false;
203 } 454 }
204 return true; 455 return true;
205} 456}
206 457
207static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain) 458/**
459 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
460 *
461 * @list: Pointer to "struct list_head".
462 *
463 * Returns true if some elements are deleted, false otherwise.
464 */
465static bool tomoyo_collect_acl(struct list_head *list)
208{ 466{
209 struct tomoyo_acl_info *acl; 467 struct tomoyo_acl_info *acl;
210 list_for_each_entry(acl, &domain->acl_info_list, list) { 468 list_for_each_entry(acl, list, list) {
211 if (!acl->is_deleted) 469 if (!acl->is_deleted)
212 continue; 470 continue;
213 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 471 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
@@ -216,19 +474,24 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
216 return true; 474 return true;
217} 475}
218 476
477/**
478 * tomoyo_collect_entry - Scan lists for deleted elements.
479 *
480 * Returns nothing.
481 */
219static void tomoyo_collect_entry(void) 482static void tomoyo_collect_entry(void)
220{ 483{
221 int i; 484 int i;
485 enum tomoyo_policy_id id;
486 struct tomoyo_policy_namespace *ns;
487 int idx;
222 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 488 if (mutex_lock_interruptible(&tomoyo_policy_lock))
223 return; 489 return;
224 for (i = 0; i < TOMOYO_MAX_POLICY; i++) { 490 idx = tomoyo_read_lock();
225 if (!tomoyo_collect_member(&tomoyo_policy_list[i], i))
226 goto unlock;
227 }
228 { 491 {
229 struct tomoyo_domain_info *domain; 492 struct tomoyo_domain_info *domain;
230 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 493 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
231 if (!tomoyo_collect_acl(domain)) 494 if (!tomoyo_collect_acl(&domain->acl_info_list))
232 goto unlock; 495 goto unlock;
233 if (!domain->is_deleted || atomic_read(&domain->users)) 496 if (!domain->is_deleted || atomic_read(&domain->users))
234 continue; 497 continue;
@@ -241,48 +504,93 @@ static void tomoyo_collect_entry(void)
241 goto unlock; 504 goto unlock;
242 } 505 }
243 } 506 }
244 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 507 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
245 struct tomoyo_name *ptr; 508 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
246 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { 509 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
247 if (atomic_read(&ptr->users))
248 continue;
249 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
250 goto unlock; 510 goto unlock;
511 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
512 if (!tomoyo_collect_acl(&ns->acl_group[i]))
513 goto unlock;
514 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
515 struct list_head *list = &ns->group_list[i];
516 struct tomoyo_group *group;
517 switch (i) {
518 case 0:
519 id = TOMOYO_ID_PATH_GROUP;
520 break;
521 default:
522 id = TOMOYO_ID_NUMBER_GROUP;
523 break;
524 }
525 list_for_each_entry(group, list, head.list) {
526 if (!tomoyo_collect_member
527 (id, &group->member_list))
528 goto unlock;
529 if (!list_empty(&group->member_list) ||
530 atomic_read(&group->head.users))
531 continue;
532 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
533 &group->head.list))
534 goto unlock;
535 }
251 } 536 }
252 } 537 }
253 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 538 id = TOMOYO_ID_CONDITION;
254 struct list_head *list = &tomoyo_group_list[i]; 539 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
255 int id; 540 struct list_head *list = !i ?
256 struct tomoyo_group *group; 541 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
257 switch (i) { 542 struct tomoyo_shared_acl_head *ptr;
258 case 0: 543 list_for_each_entry(ptr, list, list) {
259 id = TOMOYO_ID_PATH_GROUP; 544 if (atomic_read(&ptr->users))
260 break;
261 default:
262 id = TOMOYO_ID_NUMBER_GROUP;
263 break;
264 }
265 list_for_each_entry(group, list, list) {
266 if (!tomoyo_collect_member(&group->member_list, id))
267 goto unlock;
268 if (!list_empty(&group->member_list) ||
269 atomic_read(&group->users))
270 continue; 545 continue;
271 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list)) 546 if (!tomoyo_add_to_gc(id, &ptr->list))
272 goto unlock; 547 goto unlock;
273 } 548 }
549 id = TOMOYO_ID_NAME;
274 } 550 }
275 unlock: 551unlock:
552 tomoyo_read_unlock(idx);
276 mutex_unlock(&tomoyo_policy_lock); 553 mutex_unlock(&tomoyo_policy_lock);
277} 554}
278 555
279static void tomoyo_kfree_entry(void) 556/**
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)
280{ 562{
281 struct tomoyo_gc *p; 563 struct tomoyo_gc *p;
282 struct tomoyo_gc *tmp; 564 struct tomoyo_gc *tmp;
565 bool result = false;
283 566
284 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) { 567 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
285 struct list_head *element = p->element; 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;
286 switch (p->type) { 594 switch (p->type) {
287 case TOMOYO_ID_TRANSITION_CONTROL: 595 case TOMOYO_ID_TRANSITION_CONTROL:
288 tomoyo_del_transition_control(element); 596 tomoyo_del_transition_control(element);
@@ -290,19 +598,21 @@ static void tomoyo_kfree_entry(void)
290 case TOMOYO_ID_AGGREGATOR: 598 case TOMOYO_ID_AGGREGATOR:
291 tomoyo_del_aggregator(element); 599 tomoyo_del_aggregator(element);
292 break; 600 break;
293 case TOMOYO_ID_GLOBALLY_READABLE:
294 tomoyo_del_allow_read(element);
295 break;
296 case TOMOYO_ID_PATTERN:
297 tomoyo_del_file_pattern(element);
298 break;
299 case TOMOYO_ID_NO_REWRITE:
300 tomoyo_del_no_rewrite(element);
301 break;
302 case TOMOYO_ID_MANAGER: 601 case TOMOYO_ID_MANAGER:
303 tomoyo_del_manager(element); 602 tomoyo_del_manager(element);
304 break; 603 break;
604 case TOMOYO_ID_CONDITION:
605 tomoyo_del_condition(element);
606 break;
305 case TOMOYO_ID_NAME: 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;
306 tomoyo_del_name(element); 616 tomoyo_del_name(element);
307 break; 617 break;
308 case TOMOYO_ID_ACL: 618 case TOMOYO_ID_ACL:
@@ -321,34 +631,95 @@ static void tomoyo_kfree_entry(void)
321 case TOMOYO_ID_NUMBER_GROUP: 631 case TOMOYO_ID_NUMBER_GROUP:
322 tomoyo_del_number_group(element); 632 tomoyo_del_number_group(element);
323 break; 633 break;
634 case TOMOYO_MAX_POLICY:
635 break;
324 } 636 }
325 tomoyo_memory_free(element); 637 tomoyo_memory_free(element);
326 list_del(&p->list); 638 list_del(&p->list);
327 kfree(p); 639 kfree(p);
640 tomoyo_gc_list_len--;
641 result = true;
328 } 642 }
643 return result;
329} 644}
330 645
646/**
647 * tomoyo_gc_thread - Garbage collector thread function.
648 *
649 * @unused: Unused.
650 *
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.
656 */
331static int tomoyo_gc_thread(void *unused) 657static int tomoyo_gc_thread(void *unused)
332{ 658{
659 /* Garbage collector thread is exclusive. */
660 static DEFINE_MUTEX(tomoyo_gc_mutex);
661 if (!mutex_trylock(&tomoyo_gc_mutex))
662 goto out;
333 daemonize("GC for TOMOYO"); 663 daemonize("GC for TOMOYO");
334 if (mutex_trylock(&tomoyo_gc_mutex)) { 664 do {
335 int i; 665 tomoyo_collect_entry();
336 for (i = 0; i < 10; i++) { 666 if (list_empty(&tomoyo_gc_list))
337 tomoyo_collect_entry(); 667 break;
338 if (list_empty(&tomoyo_gc_queue)) 668 synchronize_srcu(&tomoyo_ss);
339 break; 669 } while (tomoyo_kfree_entry());
340 synchronize_srcu(&tomoyo_ss); 670 {
341 tomoyo_kfree_entry(); 671 struct tomoyo_io_buffer *head;
672 struct tomoyo_io_buffer *tmp;
673
674 spin_lock(&tomoyo_io_buffer_list_lock);
675 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
676 list) {
677 if (head->users)
678 continue;
679 list_del(&head->list);
680 kfree(head->read_buf);
681 kfree(head->write_buf);
682 kfree(head);
342 } 683 }
343 mutex_unlock(&tomoyo_gc_mutex); 684 spin_unlock(&tomoyo_io_buffer_list_lock);
344 } 685 }
345 do_exit(0); 686 mutex_unlock(&tomoyo_gc_mutex);
687out:
688 /* This acts as do_exit(0). */
689 return 0;
346} 690}
347 691
348void tomoyo_run_gc(void) 692/**
693 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
694 *
695 * @head: Pointer to "struct tomoyo_io_buffer".
696 * @is_register: True if register, false if unregister.
697 *
698 * Returns nothing.
699 */
700void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
349{ 701{
350 struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL, 702 bool is_write = false;
351 "GC for TOMOYO"); 703
352 if (!IS_ERR(task)) 704 spin_lock(&tomoyo_io_buffer_list_lock);
353 wake_up_process(task); 705 if (is_register) {
706 head->users = 1;
707 list_add(&head->list, &tomoyo_io_buffer_list);
708 } else {
709 is_write = head->write_buf != NULL;
710 if (!--head->users) {
711 list_del(&head->list);
712 kfree(head->read_buf);
713 kfree(head->write_buf);
714 kfree(head);
715 }
716 }
717 spin_unlock(&tomoyo_io_buffer_list_lock);
718 if (is_write) {
719 struct task_struct *task = kthread_create(tomoyo_gc_thread,
720 NULL,
721 "GC for TOMOYO");
722 if (!IS_ERR(task))
723 wake_up_process(task);
724 }
354} 725}
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index e94352ce723f..5fb0e1298400 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -1,21 +1,37 @@
1/* 1/*
2 * security/tomoyo/group.c 2 * security/tomoyo/group.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include "common.h" 8#include "common.h"
9 9
10/**
11 * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry.
12 *
13 * @a: Pointer to "struct tomoyo_acl_head".
14 * @b: Pointer to "struct tomoyo_acl_head".
15 *
16 * Returns true if @a == @b, false otherwise.
17 */
10static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, 18static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a,
11 const struct tomoyo_acl_head *b) 19 const struct tomoyo_acl_head *b)
12{ 20{
13 return container_of(a, struct tomoyo_path_group, head)->member_name == 21 return container_of(a, struct tomoyo_path_group, head)->member_name ==
14 container_of(b, struct tomoyo_path_group, head)->member_name; 22 container_of(b, struct tomoyo_path_group, head)->member_name;
15} 23}
16 24
25/**
26 * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry.
27 *
28 * @a: Pointer to "struct tomoyo_acl_head".
29 * @b: Pointer to "struct tomoyo_acl_head".
30 *
31 * Returns true if @a == @b, false otherwise.
32 */
17static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, 33static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
18 const struct tomoyo_acl_head *b) 34 const struct tomoyo_acl_head *b)
19{ 35{
20 return !memcmp(&container_of(a, struct tomoyo_number_group, head) 36 return !memcmp(&container_of(a, struct tomoyo_number_group, head)
21 ->number, 37 ->number,
@@ -28,48 +44,41 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
28/** 44/**
29 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
30 * 46 *
31 * @data: String to parse. 47 * @param: Pointer to "struct tomoyo_acl_param".
32 * @is_delete: True if it is a delete request. 48 * @type: Type of this group.
33 * @type: Type of this group.
34 * 49 *
35 * Returns 0 on success, negative value otherwise. 50 * Returns 0 on success, negative value otherwise.
36 */ 51 */
37int tomoyo_write_group(char *data, const bool is_delete, const u8 type) 52int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
38{ 53{
39 struct tomoyo_group *group; 54 struct tomoyo_group *group = tomoyo_get_group(param, type);
40 struct list_head *member;
41 char *w[2];
42 int error = -EINVAL; 55 int error = -EINVAL;
43 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
44 return -EINVAL;
45 group = tomoyo_get_group(w[0], type);
46 if (!group) 56 if (!group)
47 return -ENOMEM; 57 return -ENOMEM;
48 member = &group->member_list; 58 param->list = &group->member_list;
49 if (type == TOMOYO_PATH_GROUP) { 59 if (type == TOMOYO_PATH_GROUP) {
50 struct tomoyo_path_group e = { }; 60 struct tomoyo_path_group e = { };
51 e.member_name = tomoyo_get_name(w[1]); 61 e.member_name = tomoyo_get_name(tomoyo_read_token(param));
52 if (!e.member_name) { 62 if (!e.member_name) {
53 error = -ENOMEM; 63 error = -ENOMEM;
54 goto out; 64 goto out;
55 } 65 }
56 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 66 error = tomoyo_update_policy(&e.head, sizeof(e), param,
57 member, tomoyo_same_path_group); 67 tomoyo_same_path_group);
58 tomoyo_put_name(e.member_name); 68 tomoyo_put_name(e.member_name);
59 } else if (type == TOMOYO_NUMBER_GROUP) { 69 } else if (type == TOMOYO_NUMBER_GROUP) {
60 struct tomoyo_number_group e = { }; 70 struct tomoyo_number_group e = { };
61 if (w[1][0] == '@' 71 if (param->data[0] == '@' ||
62 || !tomoyo_parse_number_union(w[1], &e.number) 72 !tomoyo_parse_number_union(param, &e.number))
63 || e.number.values[0] > e.number.values[1])
64 goto out; 73 goto out;
65 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 74 error = tomoyo_update_policy(&e.head, sizeof(e), param,
66 member, tomoyo_same_number_group); 75 tomoyo_same_number_group);
67 /* 76 /*
68 * tomoyo_put_number_union() is not needed because 77 * tomoyo_put_number_union() is not needed because
69 * w[1][0] != '@'. 78 * param->data[0] != '@'.
70 */ 79 */
71 } 80 }
72 out: 81out:
73 tomoyo_put_group(group); 82 tomoyo_put_group(group);
74 return error; 83 return error;
75} 84}
@@ -77,8 +86,8 @@ int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
77/** 86/**
78 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 87 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
79 * 88 *
80 * @pathname: The name of pathname. 89 * @pathname: The name of pathname.
81 * @group: Pointer to "struct tomoyo_path_group". 90 * @group: Pointer to "struct tomoyo_path_group".
82 * 91 *
83 * Returns matched member's pathname if @pathname matches pathnames in @group, 92 * Returns matched member's pathname if @pathname matches pathnames in @group,
84 * NULL otherwise. 93 * NULL otherwise.
diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c
index 3312e5624f24..67975405140f 100644
--- a/security/tomoyo/load_policy.c
+++ b/security/tomoyo/load_policy.c
@@ -1,15 +1,32 @@
1/* 1/*
2 * security/tomoyo/load_policy.c 2 * security/tomoyo/load_policy.c
3 * 3 *
4 * Policy loader launcher for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include "common.h" 7#include "common.h"
10 8
11/* path to policy loader */ 9#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
12static const char *tomoyo_loader = "/sbin/tomoyo-init"; 10
11/*
12 * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER)
13 */
14static const char *tomoyo_loader;
15
16/**
17 * tomoyo_loader_setup - Set policy loader.
18 *
19 * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ).
20 *
21 * Returns 0.
22 */
23static int __init tomoyo_loader_setup(char *str)
24{
25 tomoyo_loader = str;
26 return 0;
27}
28
29__setup("TOMOYO_loader=", tomoyo_loader_setup);
13 30
14/** 31/**
15 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 32 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
@@ -18,24 +35,38 @@ static const char *tomoyo_loader = "/sbin/tomoyo-init";
18 */ 35 */
19static bool tomoyo_policy_loader_exists(void) 36static bool tomoyo_policy_loader_exists(void)
20{ 37{
21 /*
22 * Don't activate MAC if the policy loader doesn't exist.
23 * If the initrd includes /sbin/init but real-root-dev has not
24 * mounted on / yet, activating MAC will block the system since
25 * policies are not loaded yet.
26 * Thus, let do_execve() call this function every time.
27 */
28 struct path path; 38 struct path path;
29 39 if (!tomoyo_loader)
40 tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
30 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) { 41 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
31 printk(KERN_INFO "Not activating Mandatory Access Control now " 42 printk(KERN_INFO "Not activating Mandatory Access Control "
32 "since %s doesn't exist.\n", tomoyo_loader); 43 "as %s does not exist.\n", tomoyo_loader);
33 return false; 44 return false;
34 } 45 }
35 path_put(&path); 46 path_put(&path);
36 return true; 47 return true;
37} 48}
38 49
50/*
51 * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER)
52 */
53static const char *tomoyo_trigger;
54
55/**
56 * tomoyo_trigger_setup - Set trigger for activation.
57 *
58 * @str: Program to use as an activation trigger (e.g. /sbin/init ).
59 *
60 * Returns 0.
61 */
62static int __init tomoyo_trigger_setup(char *str)
63{
64 tomoyo_trigger = str;
65 return 0;
66}
67
68__setup("TOMOYO_trigger=", tomoyo_trigger_setup);
69
39/** 70/**
40 * tomoyo_load_policy - Run external policy loader to load policy. 71 * tomoyo_load_policy - Run external policy loader to load policy.
41 * 72 *
@@ -51,24 +82,19 @@ static bool tomoyo_policy_loader_exists(void)
51 */ 82 */
52void tomoyo_load_policy(const char *filename) 83void tomoyo_load_policy(const char *filename)
53{ 84{
85 static bool done;
54 char *argv[2]; 86 char *argv[2];
55 char *envp[3]; 87 char *envp[3];
56 88
57 if (tomoyo_policy_loaded) 89 if (tomoyo_policy_loaded || done)
58 return; 90 return;
59 /* 91 if (!tomoyo_trigger)
60 * Check filename is /sbin/init or /sbin/tomoyo-start. 92 tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER;
61 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't 93 if (strcmp(filename, tomoyo_trigger))
62 * be passed.
63 * You can create /sbin/tomoyo-start by
64 * "ln -s /bin/true /sbin/tomoyo-start".
65 */
66 if (strcmp(filename, "/sbin/init") &&
67 strcmp(filename, "/sbin/tomoyo-start"))
68 return; 94 return;
69 if (!tomoyo_policy_loader_exists()) 95 if (!tomoyo_policy_loader_exists())
70 return; 96 return;
71 97 done = true;
72 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 98 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
73 tomoyo_loader); 99 tomoyo_loader);
74 argv[0] = (char *) tomoyo_loader; 100 argv[0] = (char *) tomoyo_loader;
@@ -79,3 +105,5 @@ void tomoyo_load_policy(const char *filename)
79 call_usermodehelper(argv[0], argv, envp, 1); 105 call_usermodehelper(argv[0], argv, envp, 1);
80 tomoyo_check_profile(); 106 tomoyo_check_profile();
81} 107}
108
109#endif
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 42a7b1ba8cbf..7a56051146c2 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/memory.c 2 * security/tomoyo/memory.c
3 * 3 *
4 * Memory management functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/hash.h> 7#include <linux/hash.h>
@@ -29,10 +27,12 @@ void tomoyo_warn_oom(const char *function)
29 panic("MAC Initialization failed.\n"); 27 panic("MAC Initialization failed.\n");
30} 28}
31 29
32/* Memory allocated for policy. */ 30/* Lock for protecting tomoyo_memory_used. */
33static atomic_t tomoyo_policy_memory_size; 31static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
34/* Quota for holding policy. */ 32/* Memoy currently used by policy/audit log/query. */
35static unsigned int tomoyo_quota_for_policy; 33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */
35unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
36 36
37/** 37/**
38 * tomoyo_memory_ok - Check memory quota. 38 * tomoyo_memory_ok - Check memory quota.
@@ -45,15 +45,20 @@ static unsigned int tomoyo_quota_for_policy;
45 */ 45 */
46bool tomoyo_memory_ok(void *ptr) 46bool tomoyo_memory_ok(void *ptr)
47{ 47{
48 size_t s = ptr ? ksize(ptr) : 0; 48 if (ptr) {
49 atomic_add(s, &tomoyo_policy_memory_size); 49 const size_t s = ksize(ptr);
50 if (ptr && (!tomoyo_quota_for_policy || 50 bool result;
51 atomic_read(&tomoyo_policy_memory_size) 51 spin_lock(&tomoyo_policy_memory_lock);
52 <= tomoyo_quota_for_policy)) { 52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
53 memset(ptr, 0, s); 53 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
54 return true; 54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
55 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;
55 } 61 }
56 atomic_sub(s, &tomoyo_policy_memory_size);
57 tomoyo_warn_oom(__func__); 62 tomoyo_warn_oom(__func__);
58 return false; 63 return false;
59} 64}
@@ -86,22 +91,28 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
86 */ 91 */
87void tomoyo_memory_free(void *ptr) 92void tomoyo_memory_free(void *ptr)
88{ 93{
89 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); 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);
90 kfree(ptr); 98 kfree(ptr);
91} 99}
92 100
93/** 101/**
94 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group". 102 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
95 * 103 *
96 * @group_name: The name of address group. 104 * @param: Pointer to "struct tomoyo_acl_param".
97 * @idx: Index number. 105 * @idx: Index number.
98 * 106 *
99 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise. 107 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
100 */ 108 */
101struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx) 109struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
110 const u8 idx)
102{ 111{
103 struct tomoyo_group e = { }; 112 struct tomoyo_group e = { };
104 struct tomoyo_group *group = NULL; 113 struct tomoyo_group *group = NULL;
114 struct list_head *list;
115 const char *group_name = tomoyo_read_token(param);
105 bool found = false; 116 bool found = false;
106 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP) 117 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP)
107 return NULL; 118 return NULL;
@@ -110,10 +121,11 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
110 return NULL; 121 return NULL;
111 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 122 if (mutex_lock_interruptible(&tomoyo_policy_lock))
112 goto out; 123 goto out;
113 list_for_each_entry(group, &tomoyo_group_list[idx], list) { 124 list = &param->ns->group_list[idx];
125 list_for_each_entry(group, list, head.list) {
114 if (e.group_name != group->group_name) 126 if (e.group_name != group->group_name)
115 continue; 127 continue;
116 atomic_inc(&group->users); 128 atomic_inc(&group->head.users);
117 found = true; 129 found = true;
118 break; 130 break;
119 } 131 }
@@ -121,15 +133,14 @@ struct tomoyo_group *tomoyo_get_group(const char *group_name, const u8 idx)
121 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e)); 133 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
122 if (entry) { 134 if (entry) {
123 INIT_LIST_HEAD(&entry->member_list); 135 INIT_LIST_HEAD(&entry->member_list);
124 atomic_set(&entry->users, 1); 136 atomic_set(&entry->head.users, 1);
125 list_add_tail_rcu(&entry->list, 137 list_add_tail_rcu(&entry->head.list, list);
126 &tomoyo_group_list[idx]);
127 group = entry; 138 group = entry;
128 found = true; 139 found = true;
129 } 140 }
130 } 141 }
131 mutex_unlock(&tomoyo_policy_lock); 142 mutex_unlock(&tomoyo_policy_lock);
132 out: 143out:
133 tomoyo_put_name(e.group_name); 144 tomoyo_put_name(e.group_name);
134 return found ? group : NULL; 145 return found ? group : NULL;
135} 146}
@@ -154,7 +165,6 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
154 struct tomoyo_name *ptr; 165 struct tomoyo_name *ptr;
155 unsigned int hash; 166 unsigned int hash;
156 int len; 167 int len;
157 int allocated_len;
158 struct list_head *head; 168 struct list_head *head;
159 169
160 if (!name) 170 if (!name)
@@ -164,120 +174,43 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
164 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 174 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
165 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 175 if (mutex_lock_interruptible(&tomoyo_policy_lock))
166 return NULL; 176 return NULL;
167 list_for_each_entry(ptr, head, list) { 177 list_for_each_entry(ptr, head, head.list) {
168 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 178 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
169 continue; 179 continue;
170 atomic_inc(&ptr->users); 180 atomic_inc(&ptr->head.users);
171 goto out; 181 goto out;
172 } 182 }
173 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 183 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
174 allocated_len = ptr ? ksize(ptr) : 0; 184 if (tomoyo_memory_ok(ptr)) {
175 if (!ptr || (tomoyo_quota_for_policy && 185 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
176 atomic_read(&tomoyo_policy_memory_size) + allocated_len 186 memmove((char *) ptr->entry.name, name, len);
177 > tomoyo_quota_for_policy)) { 187 atomic_set(&ptr->head.users, 1);
188 tomoyo_fill_path_info(&ptr->entry);
189 list_add_tail(&ptr->head.list, head);
190 } else {
178 kfree(ptr); 191 kfree(ptr);
179 ptr = NULL; 192 ptr = NULL;
180 tomoyo_warn_oom(__func__);
181 goto out;
182 } 193 }
183 atomic_add(allocated_len, &tomoyo_policy_memory_size); 194out:
184 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
185 memmove((char *) ptr->entry.name, name, len);
186 atomic_set(&ptr->users, 1);
187 tomoyo_fill_path_info(&ptr->entry);
188 list_add_tail(&ptr->list, head);
189 out:
190 mutex_unlock(&tomoyo_policy_lock); 195 mutex_unlock(&tomoyo_policy_lock);
191 return ptr ? &ptr->entry : NULL; 196 return ptr ? &ptr->entry : NULL;
192} 197}
193 198
199/* Initial namespace.*/
200struct tomoyo_policy_namespace tomoyo_kernel_namespace;
201
194/** 202/**
195 * tomoyo_mm_init - Initialize mm related code. 203 * tomoyo_mm_init - Initialize mm related code.
196 */ 204 */
197void __init tomoyo_mm_init(void) 205void __init tomoyo_mm_init(void)
198{ 206{
199 int idx; 207 int idx;
200
201 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
202 INIT_LIST_HEAD(&tomoyo_policy_list[idx]);
203 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
204 INIT_LIST_HEAD(&tomoyo_group_list[idx]);
205 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++) 208 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
206 INIT_LIST_HEAD(&tomoyo_name_list[idx]); 209 INIT_LIST_HEAD(&tomoyo_name_list[idx]);
210 tomoyo_kernel_namespace.name = "<kernel>";
211 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
212 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
207 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 213 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
208 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME); 214 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
209 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 215 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
210 idx = tomoyo_read_lock();
211 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
212 panic("Can't register tomoyo_kernel_domain");
213 {
214 /* Load built-in policy. */
215 tomoyo_write_transition_control("/sbin/hotplug", false,
216 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
217 tomoyo_write_transition_control("/sbin/modprobe", false,
218 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
219 }
220 tomoyo_read_unlock(idx);
221}
222
223
224/* Memory allocated for query lists. */
225unsigned int tomoyo_query_memory_size;
226/* Quota for holding query lists. */
227unsigned int tomoyo_quota_for_query;
228
229/**
230 * tomoyo_read_memory_counter - Check for memory usage in bytes.
231 *
232 * @head: Pointer to "struct tomoyo_io_buffer".
233 *
234 * Returns memory usage.
235 */
236void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
237{
238 if (!head->r.eof) {
239 const unsigned int policy
240 = atomic_read(&tomoyo_policy_memory_size);
241 const unsigned int query = tomoyo_query_memory_size;
242 char buffer[64];
243
244 memset(buffer, 0, sizeof(buffer));
245 if (tomoyo_quota_for_policy)
246 snprintf(buffer, sizeof(buffer) - 1,
247 " (Quota: %10u)",
248 tomoyo_quota_for_policy);
249 else
250 buffer[0] = '\0';
251 tomoyo_io_printf(head, "Policy: %10u%s\n", policy,
252 buffer);
253 if (tomoyo_quota_for_query)
254 snprintf(buffer, sizeof(buffer) - 1,
255 " (Quota: %10u)",
256 tomoyo_quota_for_query);
257 else
258 buffer[0] = '\0';
259 tomoyo_io_printf(head, "Query lists: %10u%s\n", query,
260 buffer);
261 tomoyo_io_printf(head, "Total: %10u\n", policy + query);
262 head->r.eof = true;
263 }
264}
265
266/**
267 * tomoyo_write_memory_quota - Set memory quota.
268 *
269 * @head: Pointer to "struct tomoyo_io_buffer".
270 *
271 * Returns 0.
272 */
273int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
274{
275 char *data = head->write_buf;
276 unsigned int size;
277
278 if (sscanf(data, "Policy: %u", &size) == 1)
279 tomoyo_quota_for_policy = size;
280 else if (sscanf(data, "Query lists: %u", &size) == 1)
281 tomoyo_quota_for_query = size;
282 return 0;
283} 216}
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 9fc2e15841c9..bee09d062057 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -1,28 +1,22 @@
1/* 1/*
2 * security/tomoyo/mount.c 2 * security/tomoyo/mount.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include "common.h" 8#include "common.h"
9 9
10/* Keywords for mount restrictions. */ 10/* String table for special mount operations. */
11 11static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = {
12/* Allow to call 'mount --bind /source_dir /dest_dir' */ 12 [TOMOYO_MOUNT_BIND] = "--bind",
13#define TOMOYO_MOUNT_BIND_KEYWORD "--bind" 13 [TOMOYO_MOUNT_MOVE] = "--move",
14/* Allow to call 'mount --move /old_dir /new_dir ' */ 14 [TOMOYO_MOUNT_REMOUNT] = "--remount",
15#define TOMOYO_MOUNT_MOVE_KEYWORD "--move" 15 [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
16/* Allow to call 'mount -o remount /dir ' */ 16 [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private",
17#define TOMOYO_MOUNT_REMOUNT_KEYWORD "--remount" 17 [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave",
18/* Allow to call 'mount --make-unbindable /dir' */ 18 [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared",
19#define TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD "--make-unbindable" 19};
20/* Allow to call 'mount --make-private /dir' */
21#define TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD "--make-private"
22/* Allow to call 'mount --make-slave /dir' */
23#define TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD "--make-slave"
24/* Allow to call 'mount --make-shared /dir' */
25#define TOMOYO_MOUNT_MAKE_SHARED_KEYWORD "--make-shared"
26 20
27/** 21/**
28 * tomoyo_audit_mount_log - Audit mount log. 22 * tomoyo_audit_mount_log - Audit mount log.
@@ -33,50 +27,42 @@
33 */ 27 */
34static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) 28static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
35{ 29{
36 const char *dev = r->param.mount.dev->name; 30 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n",
37 const char *dir = r->param.mount.dir->name; 31 r->param.mount.dev->name,
38 const char *type = r->param.mount.type->name; 32 r->param.mount.dir->name,
39 const unsigned long flags = r->param.mount.flags; 33 r->param.mount.type->name,
40 if (r->granted) 34 r->param.mount.flags);
41 return 0;
42 if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD))
43 tomoyo_warn_log(r, "mount -o remount %s 0x%lX", dir, flags);
44 else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD)
45 || !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD))
46 tomoyo_warn_log(r, "mount %s %s %s 0x%lX", type, dev, dir,
47 flags);
48 else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) ||
49 !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) ||
50 !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) ||
51 !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD))
52 tomoyo_warn_log(r, "mount %s %s 0x%lX", type, dir, flags);
53 else
54 tomoyo_warn_log(r, "mount -t %s %s %s 0x%lX", type, dev, dir,
55 flags);
56 return tomoyo_supervisor(r,
57 TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
58 tomoyo_pattern(r->param.mount.dev),
59 tomoyo_pattern(r->param.mount.dir), type,
60 flags);
61} 35}
62 36
37/**
38 * tomoyo_check_mount_acl - Check permission for path path path number operation.
39 *
40 * @r: Pointer to "struct tomoyo_request_info".
41 * @ptr: Pointer to "struct tomoyo_acl_info".
42 *
43 * Returns true if granted, false otherwise.
44 */
63static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, 45static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
64 const struct tomoyo_acl_info *ptr) 46 const struct tomoyo_acl_info *ptr)
65{ 47{
66 const struct tomoyo_mount_acl *acl = 48 const struct tomoyo_mount_acl *acl =
67 container_of(ptr, typeof(*acl), head); 49 container_of(ptr, typeof(*acl), head);
68 return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) && 50 return tomoyo_compare_number_union(r->param.mount.flags,
69 tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) && 51 &acl->flags) &&
70 tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) && 52 tomoyo_compare_name_union(r->param.mount.type,
53 &acl->fs_type) &&
54 tomoyo_compare_name_union(r->param.mount.dir,
55 &acl->dir_name) &&
71 (!r->param.mount.need_dev || 56 (!r->param.mount.need_dev ||
72 tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name)); 57 tomoyo_compare_name_union(r->param.mount.dev,
58 &acl->dev_name));
73} 59}
74 60
75/** 61/**
76 * tomoyo_mount_acl - Check permission for mount() operation. 62 * tomoyo_mount_acl - Check permission for mount() operation.
77 * 63 *
78 * @r: Pointer to "struct tomoyo_request_info". 64 * @r: Pointer to "struct tomoyo_request_info".
79 * @dev_name: Name of device file. 65 * @dev_name: Name of device file. Maybe NULL.
80 * @dir: Pointer to "struct path". 66 * @dir: Pointer to "struct path".
81 * @type: Name of filesystem type. 67 * @type: Name of filesystem type.
82 * @flags: Mount options. 68 * @flags: Mount options.
@@ -86,8 +72,10 @@ static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
86 * Caller holds tomoyo_read_lock(). 72 * Caller holds tomoyo_read_lock().
87 */ 73 */
88static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, 74static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
89 struct path *dir, char *type, unsigned long flags) 75 struct path *dir, const char *type,
76 unsigned long flags)
90{ 77{
78 struct tomoyo_obj_info obj = { };
91 struct path path; 79 struct path path;
92 struct file_system_type *fstype = NULL; 80 struct file_system_type *fstype = NULL;
93 const char *requested_type = NULL; 81 const char *requested_type = NULL;
@@ -98,6 +86,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
98 struct tomoyo_path_info rdir; 86 struct tomoyo_path_info rdir;
99 int need_dev = 0; 87 int need_dev = 0;
100 int error = -ENOMEM; 88 int error = -ENOMEM;
89 r->obj = &obj;
101 90
102 /* Get fstype. */ 91 /* Get fstype. */
103 requested_type = tomoyo_encode(type); 92 requested_type = tomoyo_encode(type);
@@ -107,6 +96,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
107 tomoyo_fill_path_info(&rtype); 96 tomoyo_fill_path_info(&rtype);
108 97
109 /* Get mount point. */ 98 /* Get mount point. */
99 obj.path2 = *dir;
110 requested_dir_name = tomoyo_realpath_from_path(dir); 100 requested_dir_name = tomoyo_realpath_from_path(dir);
111 if (!requested_dir_name) { 101 if (!requested_dir_name) {
112 error = -ENOMEM; 102 error = -ENOMEM;
@@ -116,15 +106,15 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
116 tomoyo_fill_path_info(&rdir); 106 tomoyo_fill_path_info(&rdir);
117 107
118 /* Compare fs name. */ 108 /* Compare fs name. */
119 if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD)) { 109 if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) {
120 /* dev_name is ignored. */ 110 /* dev_name is ignored. */
121 } else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) || 111 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] ||
122 !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) || 112 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] ||
123 !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) || 113 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] ||
124 !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD)) { 114 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) {
125 /* dev_name is ignored. */ 115 /* dev_name is ignored. */
126 } else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD) || 116 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] ||
127 !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD)) { 117 type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
128 need_dev = -1; /* dev_name is a directory */ 118 need_dev = -1; /* dev_name is a directory */
129 } else { 119 } else {
130 fstype = get_fs_type(type); 120 fstype = get_fs_type(type);
@@ -142,8 +132,8 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
142 error = -ENOENT; 132 error = -ENOENT;
143 goto out; 133 goto out;
144 } 134 }
135 obj.path1 = path;
145 requested_dev_name = tomoyo_realpath_from_path(&path); 136 requested_dev_name = tomoyo_realpath_from_path(&path);
146 path_put(&path);
147 if (!requested_dev_name) { 137 if (!requested_dev_name) {
148 error = -ENOENT; 138 error = -ENOENT;
149 goto out; 139 goto out;
@@ -176,22 +166,26 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
176 if (fstype) 166 if (fstype)
177 put_filesystem(fstype); 167 put_filesystem(fstype);
178 kfree(requested_type); 168 kfree(requested_type);
169 /* Drop refcount obtained by kern_path(). */
170 if (obj.path1.dentry)
171 path_put(&obj.path1);
179 return error; 172 return error;
180} 173}
181 174
182/** 175/**
183 * tomoyo_mount_permission - Check permission for mount() operation. 176 * tomoyo_mount_permission - Check permission for mount() operation.
184 * 177 *
185 * @dev_name: Name of device file. 178 * @dev_name: Name of device file. Maybe NULL.
186 * @path: Pointer to "struct path". 179 * @path: Pointer to "struct path".
187 * @type: Name of filesystem type. May be NULL. 180 * @type: Name of filesystem type. Maybe NULL.
188 * @flags: Mount options. 181 * @flags: Mount options.
189 * @data_page: Optional data. May be NULL. 182 * @data_page: Optional data. Maybe NULL.
190 * 183 *
191 * Returns 0 on success, negative value otherwise. 184 * Returns 0 on success, negative value otherwise.
192 */ 185 */
193int tomoyo_mount_permission(char *dev_name, struct path *path, char *type, 186int tomoyo_mount_permission(char *dev_name, struct path *path,
194 unsigned long flags, void *data_page) 187 const char *type, unsigned long flags,
188 void *data_page)
195{ 189{
196 struct tomoyo_request_info r; 190 struct tomoyo_request_info r;
197 int error; 191 int error;
@@ -203,31 +197,31 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
203 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 197 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
204 flags &= ~MS_MGC_MSK; 198 flags &= ~MS_MGC_MSK;
205 if (flags & MS_REMOUNT) { 199 if (flags & MS_REMOUNT) {
206 type = TOMOYO_MOUNT_REMOUNT_KEYWORD; 200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
207 flags &= ~MS_REMOUNT; 201 flags &= ~MS_REMOUNT;
208 } 202 }
209 if (flags & MS_MOVE) { 203 if (flags & MS_MOVE) {
210 type = TOMOYO_MOUNT_MOVE_KEYWORD; 204 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
211 flags &= ~MS_MOVE; 205 flags &= ~MS_MOVE;
212 } 206 }
213 if (flags & MS_BIND) { 207 if (flags & MS_BIND) {
214 type = TOMOYO_MOUNT_BIND_KEYWORD; 208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
215 flags &= ~MS_BIND; 209 flags &= ~MS_BIND;
216 } 210 }
217 if (flags & MS_UNBINDABLE) { 211 if (flags & MS_UNBINDABLE) {
218 type = TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD; 212 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
219 flags &= ~MS_UNBINDABLE; 213 flags &= ~MS_UNBINDABLE;
220 } 214 }
221 if (flags & MS_PRIVATE) { 215 if (flags & MS_PRIVATE) {
222 type = TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD; 216 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
223 flags &= ~MS_PRIVATE; 217 flags &= ~MS_PRIVATE;
224 } 218 }
225 if (flags & MS_SLAVE) { 219 if (flags & MS_SLAVE) {
226 type = TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD; 220 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
227 flags &= ~MS_SLAVE; 221 flags &= ~MS_SLAVE;
228 } 222 }
229 if (flags & MS_SHARED) { 223 if (flags & MS_SHARED) {
230 type = TOMOYO_MOUNT_MAKE_SHARED_KEYWORD; 224 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
231 flags &= ~MS_SHARED; 225 flags &= ~MS_SHARED;
232 } 226 }
233 if (!type) 227 if (!type)
@@ -237,49 +231,3 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
237 tomoyo_read_unlock(idx); 231 tomoyo_read_unlock(idx);
238 return error; 232 return error;
239} 233}
240
241static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
242 const struct tomoyo_acl_info *b)
243{
244 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
245 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
246 return tomoyo_same_acl_head(&p1->head, &p2->head) &&
247 tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
248 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
249 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
250 tomoyo_same_number_union(&p1->flags, &p2->flags);
251}
252
253/**
254 * tomoyo_write_mount - Write "struct tomoyo_mount_acl" list.
255 *
256 * @data: String to parse.
257 * @domain: Pointer to "struct tomoyo_domain_info".
258 * @is_delete: True if it is a delete request.
259 *
260 * Returns 0 on success, negative value otherwise.
261 *
262 * Caller holds tomoyo_read_lock().
263 */
264int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
265 const bool is_delete)
266{
267 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
268 int error = is_delete ? -ENOENT : -ENOMEM;
269 char *w[4];
270 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[3][0])
271 return -EINVAL;
272 if (!tomoyo_parse_name_union(w[0], &e.dev_name) ||
273 !tomoyo_parse_name_union(w[1], &e.dir_name) ||
274 !tomoyo_parse_name_union(w[2], &e.fs_type) ||
275 !tomoyo_parse_number_union(w[3], &e.flags))
276 goto out;
277 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain,
278 tomoyo_same_mount_acl, NULL);
279 out:
280 tomoyo_put_name_union(&e.dev_name);
281 tomoyo_put_name_union(&e.dir_name);
282 tomoyo_put_name_union(&e.fs_type);
283 tomoyo_put_number_union(&e.flags);
284 return error;
285}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 8d95e91c9fc4..6c601bd300f3 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/realpath.c 2 * security/tomoyo/realpath.c
3 * 3 *
4 * Pathname calculation functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/types.h> 7#include <linux/types.h>
@@ -70,6 +68,161 @@ char *tomoyo_encode(const char *str)
70} 68}
71 69
72/** 70/**
71 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
72 *
73 * @path: Pointer to "struct path".
74 * @buffer: Pointer to buffer to return value in.
75 * @buflen: Sizeof @buffer.
76 *
77 * Returns the buffer on success, an error code otherwise.
78 *
79 * If dentry is a directory, trailing '/' is appended.
80 */
81static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
82 const int buflen)
83{
84 char *pos = ERR_PTR(-ENOMEM);
85 if (buflen >= 256) {
86 struct path ns_root = { };
87 /* go to whatever namespace root we are under */
88 pos = __d_path(path, &ns_root, buffer, buflen - 1);
89 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
90 struct inode *inode = path->dentry->d_inode;
91 if (inode && S_ISDIR(inode->i_mode)) {
92 buffer[buflen - 2] = '/';
93 buffer[buflen - 1] = '\0';
94 }
95 }
96 }
97 return pos;
98}
99
100/**
101 * tomoyo_get_dentry_path - Get the path of a dentry.
102 *
103 * @dentry: Pointer to "struct dentry".
104 * @buffer: Pointer to buffer to return value in.
105 * @buflen: Sizeof @buffer.
106 *
107 * Returns the buffer on success, an error code otherwise.
108 *
109 * If dentry is a directory, trailing '/' is appended.
110 */
111static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer,
112 const int buflen)
113{
114 char *pos = ERR_PTR(-ENOMEM);
115 if (buflen >= 256) {
116 pos = dentry_path_raw(dentry, buffer, buflen - 1);
117 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
118 struct inode *inode = dentry->d_inode;
119 if (inode && S_ISDIR(inode->i_mode)) {
120 buffer[buflen - 2] = '/';
121 buffer[buflen - 1] = '\0';
122 }
123 }
124 }
125 return pos;
126}
127
128/**
129 * tomoyo_get_local_path - Get the path of a dentry.
130 *
131 * @dentry: Pointer to "struct dentry".
132 * @buffer: Pointer to buffer to return value in.
133 * @buflen: Sizeof @buffer.
134 *
135 * Returns the buffer on success, an error code otherwise.
136 */
137static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
138 const int buflen)
139{
140 struct super_block *sb = dentry->d_sb;
141 char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen);
142 if (IS_ERR(pos))
143 return pos;
144 /* Convert from $PID to self if $PID is current thread. */
145 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
146 char *ep;
147 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
148 if (*ep == '/' && pid && pid ==
149 task_tgid_nr_ns(current, sb->s_fs_info)) {
150 pos = ep - 5;
151 if (pos < buffer)
152 goto out;
153 memmove(pos, "/self", 5);
154 }
155 goto prepend_filesystem_name;
156 }
157 /* Use filesystem name for unnamed devices. */
158 if (!MAJOR(sb->s_dev))
159 goto prepend_filesystem_name;
160 {
161 struct inode *inode = sb->s_root->d_inode;
162 /*
163 * Use filesystem name if filesystem does not support rename()
164 * operation.
165 */
166 if (inode->i_op && !inode->i_op->rename)
167 goto prepend_filesystem_name;
168 }
169 /* Prepend device name. */
170 {
171 char name[64];
172 int name_len;
173 const dev_t dev = sb->s_dev;
174 name[sizeof(name) - 1] = '\0';
175 snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev),
176 MINOR(dev));
177 name_len = strlen(name);
178 pos -= name_len;
179 if (pos < buffer)
180 goto out;
181 memmove(pos, name, name_len);
182 return pos;
183 }
184 /* Prepend filesystem name. */
185prepend_filesystem_name:
186 {
187 const char *name = sb->s_type->name;
188 const int name_len = strlen(name);
189 pos -= name_len + 1;
190 if (pos < buffer)
191 goto out;
192 memmove(pos, name, name_len);
193 pos[name_len] = ':';
194 }
195 return pos;
196out:
197 return ERR_PTR(-ENOMEM);
198}
199
200/**
201 * tomoyo_get_socket_name - Get the name of a socket.
202 *
203 * @path: Pointer to "struct path".
204 * @buffer: Pointer to buffer to return value in.
205 * @buflen: Sizeof @buffer.
206 *
207 * Returns the buffer.
208 */
209static char *tomoyo_get_socket_name(struct path *path, char * const buffer,
210 const int buflen)
211{
212 struct inode *inode = path->dentry->d_inode;
213 struct socket *sock = inode ? SOCKET_I(inode) : NULL;
214 struct sock *sk = sock ? sock->sk : NULL;
215 if (sk) {
216 snprintf(buffer, buflen, "socket:[family=%u:type=%u:"
217 "protocol=%u]", sk->sk_family, sk->sk_type,
218 sk->sk_protocol);
219 } else {
220 snprintf(buffer, buflen, "socket:[unknown]");
221 }
222 return buffer;
223}
224
225/**
73 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. 226 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
74 * 227 *
75 * @path: Pointer to "struct path". 228 * @path: Pointer to "struct path".
@@ -90,55 +243,42 @@ char *tomoyo_realpath_from_path(struct path *path)
90 char *name = NULL; 243 char *name = NULL;
91 unsigned int buf_len = PAGE_SIZE / 2; 244 unsigned int buf_len = PAGE_SIZE / 2;
92 struct dentry *dentry = path->dentry; 245 struct dentry *dentry = path->dentry;
93 bool is_dir; 246 struct super_block *sb;
94 if (!dentry) 247 if (!dentry)
95 return NULL; 248 return NULL;
96 is_dir = dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode); 249 sb = dentry->d_sb;
97 while (1) { 250 while (1) {
98 struct path ns_root = { .mnt = NULL, .dentry = NULL };
99 char *pos; 251 char *pos;
252 struct inode *inode;
100 buf_len <<= 1; 253 buf_len <<= 1;
101 kfree(buf); 254 kfree(buf);
102 buf = kmalloc(buf_len, GFP_NOFS); 255 buf = kmalloc(buf_len, GFP_NOFS);
103 if (!buf) 256 if (!buf)
104 break; 257 break;
258 /* To make sure that pos is '\0' terminated. */
259 buf[buf_len - 1] = '\0';
105 /* Get better name for socket. */ 260 /* Get better name for socket. */
106 if (dentry->d_sb->s_magic == SOCKFS_MAGIC) { 261 if (sb->s_magic == SOCKFS_MAGIC) {
107 struct inode *inode = dentry->d_inode; 262 pos = tomoyo_get_socket_name(path, buf, buf_len - 1);
108 struct socket *sock = inode ? SOCKET_I(inode) : NULL; 263 goto encode;
109 struct sock *sk = sock ? sock->sk : NULL;
110 if (sk) {
111 snprintf(buf, buf_len - 1, "socket:[family=%u:"
112 "type=%u:protocol=%u]", sk->sk_family,
113 sk->sk_type, sk->sk_protocol);
114 } else {
115 snprintf(buf, buf_len - 1, "socket:[unknown]");
116 }
117 name = tomoyo_encode(buf);
118 break;
119 } 264 }
120 /* For "socket:[\$]" and "pipe:[\$]". */ 265 /* For "pipe:[\$]". */
121 if (dentry->d_op && dentry->d_op->d_dname) { 266 if (dentry->d_op && dentry->d_op->d_dname) {
122 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); 267 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
123 if (IS_ERR(pos)) 268 goto encode;
124 continue;
125 name = tomoyo_encode(pos);
126 break;
127 }
128 /* If we don't have a vfsmount, we can't calculate. */
129 if (!path->mnt)
130 break;
131 /* go to whatever namespace root we are under */
132 pos = __d_path(path, &ns_root, buf, buf_len);
133 /* Prepend "/proc" prefix if using internal proc vfs mount. */
134 if (!IS_ERR(pos) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
135 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
136 pos -= 5;
137 if (pos >= buf)
138 memcpy(pos, "/proc", 5);
139 else
140 pos = ERR_PTR(-ENOMEM);
141 } 269 }
270 inode = sb->s_root->d_inode;
271 /*
272 * Get local name for filesystems without rename() operation
273 * or dentry without vfsmount.
274 */
275 if (!path->mnt || (inode->i_op && !inode->i_op->rename))
276 pos = tomoyo_get_local_path(path->dentry, buf,
277 buf_len - 1);
278 /* Get absolute name for the rest. */
279 else
280 pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
281encode:
142 if (IS_ERR(pos)) 282 if (IS_ERR(pos))
143 continue; 283 continue;
144 name = tomoyo_encode(pos); 284 name = tomoyo_encode(pos);
@@ -147,16 +287,6 @@ char *tomoyo_realpath_from_path(struct path *path)
147 kfree(buf); 287 kfree(buf);
148 if (!name) 288 if (!name)
149 tomoyo_warn_oom(__func__); 289 tomoyo_warn_oom(__func__);
150 else if (is_dir && *name) {
151 /* Append trailing '/' if dentry is a directory. */
152 char *pos = name + strlen(name) - 1;
153 if (*pos != '/')
154 /*
155 * This is OK because tomoyo_encode() reserves space
156 * for appending "/".
157 */
158 *++pos = '/';
159 }
160 return name; 290 return name;
161} 291}
162 292
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index e43d5554b506..a49c3bfd4dd5 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/common.c 2 * security/tomoyo/securityfs_if.c
3 * 3 *
4 * Securityfs interface for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/security.h> 7#include <linux/security.h>
@@ -34,11 +32,11 @@ static int tomoyo_open(struct inode *inode, struct file *file)
34 */ 32 */
35static int tomoyo_release(struct inode *inode, struct file *file) 33static int tomoyo_release(struct inode *inode, struct file *file)
36{ 34{
37 return tomoyo_close_control(file); 35 return tomoyo_close_control(file->private_data);
38} 36}
39 37
40/** 38/**
41 * tomoyo_poll - poll() for /proc/ccs/ interface. 39 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
42 * 40 *
43 * @file: Pointer to "struct file". 41 * @file: Pointer to "struct file".
44 * @wait: Pointer to "poll_table". 42 * @wait: Pointer to "poll_table".
@@ -63,7 +61,7 @@ static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
63static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 61static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
64 loff_t *ppos) 62 loff_t *ppos)
65{ 63{
66 return tomoyo_read_control(file, buf, count); 64 return tomoyo_read_control(file->private_data, buf, count);
67} 65}
68 66
69/** 67/**
@@ -79,7 +77,7 @@ static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
79static ssize_t tomoyo_write(struct file *file, const char __user *buf, 77static ssize_t tomoyo_write(struct file *file, const char __user *buf,
80 size_t count, loff_t *ppos) 78 size_t count, loff_t *ppos)
81{ 79{
82 return tomoyo_write_control(file, buf, count); 80 return tomoyo_write_control(file->private_data, buf, count);
83} 81}
84 82
85/* 83/*
@@ -135,14 +133,14 @@ static int __init tomoyo_initerface_init(void)
135 TOMOYO_DOMAINPOLICY); 133 TOMOYO_DOMAINPOLICY);
136 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 134 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
137 TOMOYO_EXCEPTIONPOLICY); 135 TOMOYO_EXCEPTIONPOLICY);
136 tomoyo_create_entry("audit", 0400, tomoyo_dir,
137 TOMOYO_AUDIT);
138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
139 TOMOYO_SELFDOMAIN); 139 TOMOYO_SELFDOMAIN);
140 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir,
141 TOMOYO_DOMAIN_STATUS);
142 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 140 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
143 TOMOYO_PROCESS_STATUS); 141 TOMOYO_PROCESS_STATUS);
144 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 142 tomoyo_create_entry("stat", 0644, tomoyo_dir,
145 TOMOYO_MEMINFO); 143 TOMOYO_STAT);
146 tomoyo_create_entry("profile", 0600, tomoyo_dir, 144 tomoyo_create_entry("profile", 0600, tomoyo_dir,
147 TOMOYO_PROFILE); 145 TOMOYO_PROFILE);
148 tomoyo_create_entry("manager", 0600, tomoyo_dir, 146 tomoyo_create_entry("manager", 0600, tomoyo_dir,
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 95d3f9572237..f776400a8f31 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -1,20 +1,35 @@
1/* 1/*
2 * security/tomoyo/tomoyo.c 2 * security/tomoyo/tomoyo.c
3 * 3 *
4 * LSM hooks for TOMOYO Linux. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/security.h> 7#include <linux/security.h>
10#include "common.h" 8#include "common.h"
11 9
10/**
11 * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
12 *
13 * @new: Pointer to "struct cred".
14 * @gfp: Memory allocation flags.
15 *
16 * Returns 0.
17 */
12static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 18static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
13{ 19{
14 new->security = NULL; 20 new->security = NULL;
15 return 0; 21 return 0;
16} 22}
17 23
24/**
25 * tomoyo_cred_prepare - Target for security_prepare_creds().
26 *
27 * @new: Pointer to "struct cred".
28 * @old: Pointer to "struct cred".
29 * @gfp: Memory allocation flags.
30 *
31 * Returns 0.
32 */
18static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 33static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
19 gfp_t gfp) 34 gfp_t gfp)
20{ 35{
@@ -25,11 +40,22 @@ static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
25 return 0; 40 return 0;
26} 41}
27 42
43/**
44 * tomoyo_cred_transfer - Target for security_transfer_creds().
45 *
46 * @new: Pointer to "struct cred".
47 * @old: Pointer to "struct cred".
48 */
28static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 49static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
29{ 50{
30 tomoyo_cred_prepare(new, old, 0); 51 tomoyo_cred_prepare(new, old, 0);
31} 52}
32 53
54/**
55 * tomoyo_cred_free - Target for security_cred_free().
56 *
57 * @cred: Pointer to "struct cred".
58 */
33static void tomoyo_cred_free(struct cred *cred) 59static void tomoyo_cred_free(struct cred *cred)
34{ 60{
35 struct tomoyo_domain_info *domain = cred->security; 61 struct tomoyo_domain_info *domain = cred->security;
@@ -37,6 +63,13 @@ static void tomoyo_cred_free(struct cred *cred)
37 atomic_dec(&domain->users); 63 atomic_dec(&domain->users);
38} 64}
39 65
66/**
67 * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
68 *
69 * @bprm: Pointer to "struct linux_binprm".
70 *
71 * Returns 0 on success, negative value otherwise.
72 */
40static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 73static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
41{ 74{
42 int rc; 75 int rc;
@@ -51,12 +84,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
51 */ 84 */
52 if (bprm->cred_prepared) 85 if (bprm->cred_prepared)
53 return 0; 86 return 0;
87#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
54 /* 88 /*
55 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested 89 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
56 * for the first time. 90 * for the first time.
57 */ 91 */
58 if (!tomoyo_policy_loaded) 92 if (!tomoyo_policy_loaded)
59 tomoyo_load_policy(bprm->filename); 93 tomoyo_load_policy(bprm->filename);
94#endif
60 /* 95 /*
61 * Release reference to "struct tomoyo_domain_info" stored inside 96 * Release reference to "struct tomoyo_domain_info" stored inside
62 * "bprm->cred->security". New reference to "struct tomoyo_domain_info" 97 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
@@ -73,6 +108,13 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
73 return 0; 108 return 0;
74} 109}
75 110
111/**
112 * tomoyo_bprm_check_security - Target for security_bprm_check().
113 *
114 * @bprm: Pointer to "struct linux_binprm".
115 *
116 * Returns 0 on success, negative value otherwise.
117 */
76static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 118static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
77{ 119{
78 struct tomoyo_domain_info *domain = bprm->cred->security; 120 struct tomoyo_domain_info *domain = bprm->cred->security;
@@ -90,20 +132,59 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
90 /* 132 /*
91 * Read permission is checked against interpreters using next domain. 133 * Read permission is checked against interpreters using next domain.
92 */ 134 */
93 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY); 135 return tomoyo_check_open_permission(domain, &bprm->file->f_path,
136 O_RDONLY);
137}
138
139/**
140 * tomoyo_inode_getattr - Target for security_inode_getattr().
141 *
142 * @mnt: Pointer to "struct vfsmount".
143 * @dentry: Pointer to "struct dentry".
144 *
145 * Returns 0 on success, negative value otherwise.
146 */
147static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
148{
149 struct path path = { mnt, dentry };
150 return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
94} 151}
95 152
153/**
154 * tomoyo_path_truncate - Target for security_path_truncate().
155 *
156 * @path: Pointer to "struct path".
157 *
158 * Returns 0 on success, negative value otherwise.
159 */
96static int tomoyo_path_truncate(struct path *path) 160static int tomoyo_path_truncate(struct path *path)
97{ 161{
98 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path); 162 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
99} 163}
100 164
165/**
166 * tomoyo_path_unlink - Target for security_path_unlink().
167 *
168 * @parent: Pointer to "struct path".
169 * @dentry: Pointer to "struct dentry".
170 *
171 * Returns 0 on success, negative value otherwise.
172 */
101static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 173static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
102{ 174{
103 struct path path = { parent->mnt, dentry }; 175 struct path path = { parent->mnt, dentry };
104 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path); 176 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
105} 177}
106 178
179/**
180 * tomoyo_path_mkdir - Target for security_path_mkdir().
181 *
182 * @parent: Pointer to "struct path".
183 * @dentry: Pointer to "struct dentry".
184 * @mode: DAC permission mode.
185 *
186 * Returns 0 on success, negative value otherwise.
187 */
107static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 188static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
108 int mode) 189 int mode)
109{ 190{
@@ -112,19 +193,46 @@ static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
112 mode & S_IALLUGO); 193 mode & S_IALLUGO);
113} 194}
114 195
196/**
197 * tomoyo_path_rmdir - Target for security_path_rmdir().
198 *
199 * @parent: Pointer to "struct path".
200 * @dentry: Pointer to "struct dentry".
201 *
202 * Returns 0 on success, negative value otherwise.
203 */
115static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 204static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
116{ 205{
117 struct path path = { parent->mnt, dentry }; 206 struct path path = { parent->mnt, dentry };
118 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path); 207 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
119} 208}
120 209
210/**
211 * tomoyo_path_symlink - Target for security_path_symlink().
212 *
213 * @parent: Pointer to "struct path".
214 * @dentry: Pointer to "struct dentry".
215 * @old_name: Symlink's content.
216 *
217 * Returns 0 on success, negative value otherwise.
218 */
121static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 219static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
122 const char *old_name) 220 const char *old_name)
123{ 221{
124 struct path path = { parent->mnt, dentry }; 222 struct path path = { parent->mnt, dentry };
125 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path); 223 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
126} 224}
127 225
226/**
227 * tomoyo_path_mknod - Target for security_path_mknod().
228 *
229 * @parent: Pointer to "struct path".
230 * @dentry: Pointer to "struct dentry".
231 * @mode: DAC permission mode.
232 * @dev: Device attributes.
233 *
234 * Returns 0 on success, negative value otherwise.
235 */
128static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 236static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
129 int mode, unsigned int dev) 237 int mode, unsigned int dev)
130{ 238{
@@ -155,6 +263,15 @@ static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
155 return tomoyo_path_number_perm(type, &path, perm); 263 return tomoyo_path_number_perm(type, &path, perm);
156} 264}
157 265
266/**
267 * tomoyo_path_link - Target for security_path_link().
268 *
269 * @old_dentry: Pointer to "struct dentry".
270 * @new_dir: Pointer to "struct path".
271 * @new_dentry: Pointer to "struct dentry".
272 *
273 * Returns 0 on success, negative value otherwise.
274 */
158static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 275static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
159 struct dentry *new_dentry) 276 struct dentry *new_dentry)
160{ 277{
@@ -163,6 +280,16 @@ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
163 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2); 280 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
164} 281}
165 282
283/**
284 * tomoyo_path_rename - Target for security_path_rename().
285 *
286 * @old_parent: Pointer to "struct path".
287 * @old_dentry: Pointer to "struct dentry".
288 * @new_parent: Pointer to "struct path".
289 * @new_dentry: Pointer to "struct dentry".
290 *
291 * Returns 0 on success, negative value otherwise.
292 */
166static int tomoyo_path_rename(struct path *old_parent, 293static int tomoyo_path_rename(struct path *old_parent,
167 struct dentry *old_dentry, 294 struct dentry *old_dentry,
168 struct path *new_parent, 295 struct path *new_parent,
@@ -173,14 +300,32 @@ static int tomoyo_path_rename(struct path *old_parent,
173 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); 300 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
174} 301}
175 302
303/**
304 * tomoyo_file_fcntl - Target for security_file_fcntl().
305 *
306 * @file: Pointer to "struct file".
307 * @cmd: Command for fcntl().
308 * @arg: Argument for @cmd.
309 *
310 * Returns 0 on success, negative value otherwise.
311 */
176static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 312static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
177 unsigned long arg) 313 unsigned long arg)
178{ 314{
179 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 315 if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
180 return tomoyo_path_perm(TOMOYO_TYPE_REWRITE, &file->f_path); 316 return 0;
181 return 0; 317 return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
318 O_WRONLY | (arg & O_APPEND));
182} 319}
183 320
321/**
322 * tomoyo_dentry_open - Target for security_dentry_open().
323 *
324 * @f: Pointer to "struct file".
325 * @cred: Pointer to "struct cred".
326 *
327 * Returns 0 on success, negative value otherwise.
328 */
184static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 329static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
185{ 330{
186 int flags = f->f_flags; 331 int flags = f->f_flags;
@@ -190,12 +335,30 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
190 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 335 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
191} 336}
192 337
338/**
339 * tomoyo_file_ioctl - Target for security_file_ioctl().
340 *
341 * @file: Pointer to "struct file".
342 * @cmd: Command for ioctl().
343 * @arg: Argument for @cmd.
344 *
345 * Returns 0 on success, negative value otherwise.
346 */
193static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 347static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
194 unsigned long arg) 348 unsigned long arg)
195{ 349{
196 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd); 350 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
197} 351}
198 352
353/**
354 * tomoyo_path_chmod - Target for security_path_chmod().
355 *
356 * @dentry: Pointer to "struct dentry".
357 * @mnt: Pointer to "struct vfsmount".
358 * @mode: DAC permission mode.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
199static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 362static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
200 mode_t mode) 363 mode_t mode)
201{ 364{
@@ -204,6 +367,15 @@ static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
204 mode & S_IALLUGO); 367 mode & S_IALLUGO);
205} 368}
206 369
370/**
371 * tomoyo_path_chown - Target for security_path_chown().
372 *
373 * @path: Pointer to "struct path".
374 * @uid: Owner ID.
375 * @gid: Group ID.
376 *
377 * Returns 0 on success, negative value otherwise.
378 */
207static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 379static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
208{ 380{
209 int error = 0; 381 int error = 0;
@@ -214,23 +386,57 @@ static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
214 return error; 386 return error;
215} 387}
216 388
389/**
390 * tomoyo_path_chroot - Target for security_path_chroot().
391 *
392 * @path: Pointer to "struct path".
393 *
394 * Returns 0 on success, negative value otherwise.
395 */
217static int tomoyo_path_chroot(struct path *path) 396static int tomoyo_path_chroot(struct path *path)
218{ 397{
219 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path); 398 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
220} 399}
221 400
401/**
402 * tomoyo_sb_mount - Target for security_sb_mount().
403 *
404 * @dev_name: Name of device file. Maybe NULL.
405 * @path: Pointer to "struct path".
406 * @type: Name of filesystem type. Maybe NULL.
407 * @flags: Mount options.
408 * @data: Optional data. Maybe NULL.
409 *
410 * Returns 0 on success, negative value otherwise.
411 */
222static int tomoyo_sb_mount(char *dev_name, struct path *path, 412static int tomoyo_sb_mount(char *dev_name, struct path *path,
223 char *type, unsigned long flags, void *data) 413 char *type, unsigned long flags, void *data)
224{ 414{
225 return tomoyo_mount_permission(dev_name, path, type, flags, data); 415 return tomoyo_mount_permission(dev_name, path, type, flags, data);
226} 416}
227 417
418/**
419 * tomoyo_sb_umount - Target for security_sb_umount().
420 *
421 * @mnt: Pointer to "struct vfsmount".
422 * @flags: Unmount options.
423 *
424 * Returns 0 on success, negative value otherwise.
425 */
228static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 426static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
229{ 427{
230 struct path path = { mnt, mnt->mnt_root }; 428 struct path path = { mnt, mnt->mnt_root };
231 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path); 429 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
232} 430}
233 431
432/**
433 * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
434 *
435 * @old_path: Pointer to "struct path".
436 * @new_path: Pointer to "struct path".
437 *
438 * Returns 0 on success, negative value otherwise.
439 */
234static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 440static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
235{ 441{
236 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);
@@ -258,6 +464,7 @@ static struct security_operations tomoyo_security_ops = {
258 .path_mknod = tomoyo_path_mknod, 464 .path_mknod = tomoyo_path_mknod,
259 .path_link = tomoyo_path_link, 465 .path_link = tomoyo_path_link,
260 .path_rename = tomoyo_path_rename, 466 .path_rename = tomoyo_path_rename,
467 .inode_getattr = tomoyo_inode_getattr,
261 .file_ioctl = tomoyo_file_ioctl, 468 .file_ioctl = tomoyo_file_ioctl,
262 .path_chmod = tomoyo_path_chmod, 469 .path_chmod = tomoyo_path_chmod,
263 .path_chown = tomoyo_path_chown, 470 .path_chown = tomoyo_path_chown,
@@ -270,6 +477,11 @@ static struct security_operations tomoyo_security_ops = {
270/* Lock for GC. */ 477/* Lock for GC. */
271struct srcu_struct tomoyo_ss; 478struct srcu_struct tomoyo_ss;
272 479
480/**
481 * tomoyo_init - Register TOMOYO Linux as a LSM module.
482 *
483 * Returns 0.
484 */
273static int __init tomoyo_init(void) 485static int __init tomoyo_init(void)
274{ 486{
275 struct cred *cred = (struct cred *) current_cred(); 487 struct cred *cred = (struct cred *) current_cred();
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 6d5393204d95..c36bd1107fc8 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * security/tomoyo/util.c 2 * security/tomoyo/util.c
3 * 3 *
4 * Utility functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9#include <linux/slab.h> 7#include <linux/slab.h>
@@ -15,18 +13,130 @@ DEFINE_MUTEX(tomoyo_policy_lock);
15/* Has /sbin/init started? */ 13/* Has /sbin/init started? */
16bool tomoyo_policy_loaded; 14bool tomoyo_policy_loaded;
17 15
16/*
17 * Mapping table from "enum tomoyo_mac_index" to
18 * "enum tomoyo_mac_category_index".
19 */
20const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
21 /* CONFIG::file group */
22 [TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE,
23 [TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE,
24 [TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE,
25 [TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE,
26 [TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE,
27 [TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE,
28 [TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE,
29 [TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE,
30 [TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE,
31 [TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE,
32 [TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE,
33 [TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE,
34 [TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE,
35 [TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE,
36 [TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE,
37 [TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE,
38 [TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE,
39 [TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE,
40 [TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE,
41 [TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE,
42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
45};
46
47/**
48 * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
49 *
50 * @time: Seconds since 1970/01/01 00:00:00.
51 * @stamp: Pointer to "struct tomoyo_time".
52 *
53 * Returns nothing.
54 *
55 * This function does not handle Y2038 problem.
56 */
57void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
58{
59 static const u16 tomoyo_eom[2][12] = {
60 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
61 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
62 };
63 u16 y;
64 u8 m;
65 bool r;
66 stamp->sec = time % 60;
67 time /= 60;
68 stamp->min = time % 60;
69 time /= 60;
70 stamp->hour = time % 24;
71 time /= 24;
72 for (y = 1970; ; y++) {
73 const unsigned short days = (y & 3) ? 365 : 366;
74 if (time < days)
75 break;
76 time -= days;
77 }
78 r = (y & 3) == 0;
79 for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
80 ;
81 if (m)
82 time -= tomoyo_eom[r][m - 1];
83 stamp->year = y;
84 stamp->month = ++m;
85 stamp->day = ++time;
86}
87
88/**
89 * tomoyo_permstr - Find permission keywords.
90 *
91 * @string: String representation for permissions in foo/bar/buz format.
92 * @keyword: Keyword to find from @string/
93 *
94 * Returns ture if @keyword was found in @string, false otherwise.
95 *
96 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
97 */
98bool tomoyo_permstr(const char *string, const char *keyword)
99{
100 const char *cp = strstr(string, keyword);
101 if (cp)
102 return cp == string || *(cp - 1) == '/';
103 return false;
104}
105
106/**
107 * tomoyo_read_token - Read a word from a line.
108 *
109 * @param: Pointer to "struct tomoyo_acl_param".
110 *
111 * Returns a word on success, "" otherwise.
112 *
113 * To allow the caller to skip NULL check, this function returns "" rather than
114 * NULL if there is no more words to read.
115 */
116char *tomoyo_read_token(struct tomoyo_acl_param *param)
117{
118 char *pos = param->data;
119 char *del = strchr(pos, ' ');
120 if (del)
121 *del++ = '\0';
122 else
123 del = pos + strlen(pos);
124 param->data = del;
125 return pos;
126}
127
18/** 128/**
19 * tomoyo_parse_ulong - Parse an "unsigned long" value. 129 * tomoyo_parse_ulong - Parse an "unsigned long" value.
20 * 130 *
21 * @result: Pointer to "unsigned long". 131 * @result: Pointer to "unsigned long".
22 * @str: Pointer to string to parse. 132 * @str: Pointer to string to parse.
23 * 133 *
24 * Returns value type on success, 0 otherwise. 134 * Returns one of values in "enum tomoyo_value_type".
25 * 135 *
26 * The @src is updated to point the first character after the value 136 * The @src is updated to point the first character after the value
27 * on success. 137 * on success.
28 */ 138 */
29static u8 tomoyo_parse_ulong(unsigned long *result, char **str) 139u8 tomoyo_parse_ulong(unsigned long *result, char **str)
30{ 140{
31 const char *cp = *str; 141 const char *cp = *str;
32 char *ep; 142 char *ep;
@@ -43,7 +153,7 @@ static u8 tomoyo_parse_ulong(unsigned long *result, char **str)
43 } 153 }
44 *result = simple_strtoul(cp, &ep, base); 154 *result = simple_strtoul(cp, &ep, base);
45 if (cp == ep) 155 if (cp == ep)
46 return 0; 156 return TOMOYO_VALUE_TYPE_INVALID;
47 *str = ep; 157 *str = ep;
48 switch (base) { 158 switch (base) {
49 case 16: 159 case 16:
@@ -81,63 +191,65 @@ void tomoyo_print_ulong(char *buffer, const int buffer_len,
81/** 191/**
82 * tomoyo_parse_name_union - Parse a tomoyo_name_union. 192 * tomoyo_parse_name_union - Parse a tomoyo_name_union.
83 * 193 *
84 * @filename: Name or name group. 194 * @param: Pointer to "struct tomoyo_acl_param".
85 * @ptr: Pointer to "struct tomoyo_name_union". 195 * @ptr: Pointer to "struct tomoyo_name_union".
86 * 196 *
87 * Returns true on success, false otherwise. 197 * Returns true on success, false otherwise.
88 */ 198 */
89bool tomoyo_parse_name_union(const char *filename, 199bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
90 struct tomoyo_name_union *ptr) 200 struct tomoyo_name_union *ptr)
91{ 201{
92 if (!tomoyo_correct_word(filename)) 202 char *filename;
93 return false; 203 if (param->data[0] == '@') {
94 if (filename[0] == '@') { 204 param->data++;
95 ptr->group = tomoyo_get_group(filename + 1, TOMOYO_PATH_GROUP); 205 ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP);
96 ptr->is_group = true;
97 return ptr->group != NULL; 206 return ptr->group != NULL;
98 } 207 }
208 filename = tomoyo_read_token(param);
209 if (!tomoyo_correct_word(filename))
210 return false;
99 ptr->filename = tomoyo_get_name(filename); 211 ptr->filename = tomoyo_get_name(filename);
100 ptr->is_group = false;
101 return ptr->filename != NULL; 212 return ptr->filename != NULL;
102} 213}
103 214
104/** 215/**
105 * tomoyo_parse_number_union - Parse a tomoyo_number_union. 216 * tomoyo_parse_number_union - Parse a tomoyo_number_union.
106 * 217 *
107 * @data: Number or number range or number group. 218 * @param: Pointer to "struct tomoyo_acl_param".
108 * @ptr: Pointer to "struct tomoyo_number_union". 219 * @ptr: Pointer to "struct tomoyo_number_union".
109 * 220 *
110 * Returns true on success, false otherwise. 221 * Returns true on success, false otherwise.
111 */ 222 */
112bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num) 223bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
224 struct tomoyo_number_union *ptr)
113{ 225{
226 char *data;
114 u8 type; 227 u8 type;
115 unsigned long v; 228 unsigned long v;
116 memset(num, 0, sizeof(*num)); 229 memset(ptr, 0, sizeof(*ptr));
117 if (data[0] == '@') { 230 if (param->data[0] == '@') {
118 if (!tomoyo_correct_word(data)) 231 param->data++;
119 return false; 232 ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP);
120 num->group = tomoyo_get_group(data + 1, TOMOYO_NUMBER_GROUP); 233 return ptr->group != NULL;
121 num->is_group = true;
122 return num->group != NULL;
123 } 234 }
235 data = tomoyo_read_token(param);
124 type = tomoyo_parse_ulong(&v, &data); 236 type = tomoyo_parse_ulong(&v, &data);
125 if (!type) 237 if (type == TOMOYO_VALUE_TYPE_INVALID)
126 return false; 238 return false;
127 num->values[0] = v; 239 ptr->values[0] = v;
128 num->min_type = type; 240 ptr->value_type[0] = type;
129 if (!*data) { 241 if (!*data) {
130 num->values[1] = v; 242 ptr->values[1] = v;
131 num->max_type = type; 243 ptr->value_type[1] = type;
132 return true; 244 return true;
133 } 245 }
134 if (*data++ != '-') 246 if (*data++ != '-')
135 return false; 247 return false;
136 type = tomoyo_parse_ulong(&v, &data); 248 type = tomoyo_parse_ulong(&v, &data);
137 if (!type || *data) 249 if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
138 return false; 250 return false;
139 num->values[1] = v; 251 ptr->values[1] = v;
140 num->max_type = type; 252 ptr->value_type[1] = type;
141 return true; 253 return true;
142} 254}
143 255
@@ -185,6 +297,30 @@ static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
185} 297}
186 298
187/** 299/**
300 * tomoyo_valid - Check whether the character is a valid char.
301 *
302 * @c: The character to check.
303 *
304 * Returns true if @c is a valid character, false otherwise.
305 */
306static inline bool tomoyo_valid(const unsigned char c)
307{
308 return c > ' ' && c < 127;
309}
310
311/**
312 * tomoyo_invalid - Check whether the character is an invalid char.
313 *
314 * @c: The character to check.
315 *
316 * Returns true if @c is an invalid character, false otherwise.
317 */
318static inline bool tomoyo_invalid(const unsigned char c)
319{
320 return c && (c <= ' ' || c >= 127);
321}
322
323/**
188 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 324 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
189 * 325 *
190 * @src: Pointer to pointer to the string. 326 * @src: Pointer to pointer to the string.
@@ -238,36 +374,9 @@ void tomoyo_normalize_line(unsigned char *buffer)
238} 374}
239 375
240/** 376/**
241 * tomoyo_tokenize - Tokenize string.
242 *
243 * @buffer: The line to tokenize.
244 * @w: Pointer to "char *".
245 * @size: Sizeof @w .
246 *
247 * Returns true on success, false otherwise.
248 */
249bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
250{
251 int count = size / sizeof(char *);
252 int i;
253 for (i = 0; i < count; i++)
254 w[i] = "";
255 for (i = 0; i < count; i++) {
256 char *cp = strchr(buffer, ' ');
257 if (cp)
258 *cp = '\0';
259 w[i] = buffer;
260 if (!cp)
261 break;
262 buffer = cp + 1;
263 }
264 return i < count || !*buffer;
265}
266
267/**
268 * tomoyo_correct_word2 - Validate a string. 377 * tomoyo_correct_word2 - Validate a string.
269 * 378 *
270 * @string: The string to check. May be non-'\0'-terminated. 379 * @string: The string to check. Maybe non-'\0'-terminated.
271 * @len: Length of @string. 380 * @len: Length of @string.
272 * 381 *
273 * Check whether the given string follows the naming rules. 382 * Check whether the given string follows the naming rules.
@@ -377,26 +486,21 @@ bool tomoyo_correct_path(const char *filename)
377 */ 486 */
378bool tomoyo_correct_domain(const unsigned char *domainname) 487bool tomoyo_correct_domain(const unsigned char *domainname)
379{ 488{
380 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 489 if (!domainname || !tomoyo_domain_def(domainname))
381 TOMOYO_ROOT_NAME_LEN)) 490 return false;
382 goto out; 491 domainname = strchr(domainname, ' ');
383 domainname += TOMOYO_ROOT_NAME_LEN; 492 if (!domainname++)
384 if (!*domainname)
385 return true; 493 return true;
386 if (*domainname++ != ' ')
387 goto out;
388 while (1) { 494 while (1) {
389 const unsigned char *cp = strchr(domainname, ' '); 495 const unsigned char *cp = strchr(domainname, ' ');
390 if (!cp) 496 if (!cp)
391 break; 497 break;
392 if (*domainname != '/' || 498 if (*domainname != '/' ||
393 !tomoyo_correct_word2(domainname, cp - domainname)) 499 !tomoyo_correct_word2(domainname, cp - domainname))
394 goto out; 500 return false;
395 domainname = cp + 1; 501 domainname = cp + 1;
396 } 502 }
397 return tomoyo_correct_path(domainname); 503 return tomoyo_correct_path(domainname);
398 out:
399 return false;
400} 504}
401 505
402/** 506/**
@@ -408,7 +512,19 @@ bool tomoyo_correct_domain(const unsigned char *domainname)
408 */ 512 */
409bool tomoyo_domain_def(const unsigned char *buffer) 513bool tomoyo_domain_def(const unsigned char *buffer)
410{ 514{
411 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN); 515 const unsigned char *cp;
516 int len;
517 if (*buffer != '<')
518 return false;
519 cp = strchr(buffer, ' ');
520 if (!cp)
521 len = strlen(buffer);
522 else
523 len = cp - buffer;
524 if (buffer[len - 1] != '>' ||
525 !tomoyo_correct_word2(buffer + 1, len - 2))
526 return false;
527 return true;
412} 528}
413 529
414/** 530/**
@@ -794,22 +910,24 @@ const char *tomoyo_get_exe(void)
794/** 910/**
795 * tomoyo_get_mode - Get MAC mode. 911 * tomoyo_get_mode - Get MAC mode.
796 * 912 *
913 * @ns: Pointer to "struct tomoyo_policy_namespace".
797 * @profile: Profile number. 914 * @profile: Profile number.
798 * @index: Index number of functionality. 915 * @index: Index number of functionality.
799 * 916 *
800 * Returns mode. 917 * Returns mode.
801 */ 918 */
802int tomoyo_get_mode(const u8 profile, const u8 index) 919int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
920 const u8 index)
803{ 921{
804 u8 mode; 922 u8 mode;
805 const u8 category = TOMOYO_MAC_CATEGORY_FILE; 923 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
806 if (!tomoyo_policy_loaded) 924 if (!tomoyo_policy_loaded)
807 return TOMOYO_CONFIG_DISABLED; 925 return TOMOYO_CONFIG_DISABLED;
808 mode = tomoyo_profile(profile)->config[index]; 926 mode = tomoyo_profile(ns, profile)->config[index];
809 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 927 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
810 mode = tomoyo_profile(profile)->config[category]; 928 mode = tomoyo_profile(ns, profile)->config[category];
811 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 929 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
812 mode = tomoyo_profile(profile)->default_config; 930 mode = tomoyo_profile(ns, profile)->default_config;
813 return mode & 3; 931 return mode & 3;
814} 932}
815 933
@@ -833,65 +951,11 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
833 profile = domain->profile; 951 profile = domain->profile;
834 r->profile = profile; 952 r->profile = profile;
835 r->type = index; 953 r->type = index;
836 r->mode = tomoyo_get_mode(profile, index); 954 r->mode = tomoyo_get_mode(domain->ns, profile, index);
837 return r->mode; 955 return r->mode;
838} 956}
839 957
840/** 958/**
841 * tomoyo_last_word - Get last component of a line.
842 *
843 * @line: A line.
844 *
845 * Returns the last word of a line.
846 */
847const char *tomoyo_last_word(const char *name)
848{
849 const char *cp = strrchr(name, ' ');
850 if (cp)
851 return cp + 1;
852 return name;
853}
854
855/**
856 * tomoyo_warn_log - Print warning or error message on console.
857 *
858 * @r: Pointer to "struct tomoyo_request_info".
859 * @fmt: The printf()'s format string, followed by parameters.
860 */
861void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
862{
863 va_list args;
864 char *buffer;
865 const struct tomoyo_domain_info * const domain = r->domain;
866 const struct tomoyo_profile *profile = tomoyo_profile(domain->profile);
867 switch (r->mode) {
868 case TOMOYO_CONFIG_ENFORCING:
869 if (!profile->enforcing->enforcing_verbose)
870 return;
871 break;
872 case TOMOYO_CONFIG_PERMISSIVE:
873 if (!profile->permissive->permissive_verbose)
874 return;
875 break;
876 case TOMOYO_CONFIG_LEARNING:
877 if (!profile->learning->learning_verbose)
878 return;
879 break;
880 }
881 buffer = kmalloc(4096, GFP_NOFS);
882 if (!buffer)
883 return;
884 va_start(args, fmt);
885 vsnprintf(buffer, 4095, fmt, args);
886 va_end(args);
887 buffer[4095] = '\0';
888 printk(KERN_WARNING "%s: Access %s denied for %s\n",
889 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING", buffer,
890 tomoyo_last_word(domain->domainname->name));
891 kfree(buffer);
892}
893
894/**
895 * tomoyo_domain_quota_is_ok - Check for domain's quota. 959 * tomoyo_domain_quota_is_ok - Check for domain's quota.
896 * 960 *
897 * @r: Pointer to "struct tomoyo_request_info". 961 * @r: Pointer to "struct tomoyo_request_info".
@@ -911,52 +975,43 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
911 if (!domain) 975 if (!domain)
912 return true; 976 return true;
913 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 977 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
978 u16 perm;
979 u8 i;
914 if (ptr->is_deleted) 980 if (ptr->is_deleted)
915 continue; 981 continue;
916 switch (ptr->type) { 982 switch (ptr->type) {
917 u16 perm;
918 u8 i;
919 case TOMOYO_TYPE_PATH_ACL: 983 case TOMOYO_TYPE_PATH_ACL:
920 perm = container_of(ptr, struct tomoyo_path_acl, head) 984 perm = container_of(ptr, struct tomoyo_path_acl, head)
921 ->perm; 985 ->perm;
922 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
923 if (perm & (1 << i))
924 count++;
925 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
926 count -= 2;
927 break; 986 break;
928 case TOMOYO_TYPE_PATH2_ACL: 987 case TOMOYO_TYPE_PATH2_ACL:
929 perm = container_of(ptr, struct tomoyo_path2_acl, head) 988 perm = container_of(ptr, struct tomoyo_path2_acl, head)
930 ->perm; 989 ->perm;
931 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
932 if (perm & (1 << i))
933 count++;
934 break; 990 break;
935 case TOMOYO_TYPE_PATH_NUMBER_ACL: 991 case TOMOYO_TYPE_PATH_NUMBER_ACL:
936 perm = container_of(ptr, struct tomoyo_path_number_acl, 992 perm = container_of(ptr, struct tomoyo_path_number_acl,
937 head)->perm; 993 head)->perm;
938 for (i = 0; i < TOMOYO_MAX_PATH_NUMBER_OPERATION; i++)
939 if (perm & (1 << i))
940 count++;
941 break; 994 break;
942 case TOMOYO_TYPE_MKDEV_ACL: 995 case TOMOYO_TYPE_MKDEV_ACL:
943 perm = container_of(ptr, struct tomoyo_mkdev_acl, 996 perm = container_of(ptr, struct tomoyo_mkdev_acl,
944 head)->perm; 997 head)->perm;
945 for (i = 0; i < TOMOYO_MAX_MKDEV_OPERATION; i++)
946 if (perm & (1 << i))
947 count++;
948 break; 998 break;
949 default: 999 default:
950 count++; 1000 perm = 1;
951 } 1001 }
1002 for (i = 0; i < 16; i++)
1003 if (perm & (1 << i))
1004 count++;
952 } 1005 }
953 if (count < tomoyo_profile(domain->profile)->learning-> 1006 if (count < tomoyo_profile(domain->ns, domain->profile)->
954 learning_max_entry) 1007 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
955 return true; 1008 return true;
956 if (!domain->quota_warned) { 1009 if (!domain->flags[TOMOYO_DIF_QUOTA_WARNED]) {
957 domain->quota_warned = true; 1010 domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true;
958 printk(KERN_WARNING "TOMOYO-WARNING: " 1011 /* r->granted = false; */
959 "Domain '%s' has so many ACLs to hold. " 1012 tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
1013 printk(KERN_WARNING "WARNING: "
1014 "Domain '%s' has too many ACLs to hold. "
960 "Stopped learning mode.\n", domain->domainname->name); 1015 "Stopped learning mode.\n", domain->domainname->name);
961 } 1016 }
962 return false; 1017 return false;