aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c431
-rw-r--r--security/tomoyo/common.h68
-rw-r--r--security/tomoyo/domain.c9
-rw-r--r--security/tomoyo/file.c131
-rw-r--r--security/tomoyo/mount.c3
-rw-r--r--security/tomoyo/util.c92
6 files changed, 486 insertions, 248 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index bdf1ed7ca45b..811adb5e9fea 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -9,53 +9,74 @@
9#include <linux/uaccess.h> 9#include <linux/uaccess.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/security.h> 11#include <linux/security.h>
12#include <linux/hardirq.h>
13#include "common.h" 12#include "common.h"
14 13
14static struct tomoyo_profile tomoyo_default_profile = {
15 .learning = &tomoyo_default_profile.preference,
16 .permissive = &tomoyo_default_profile.preference,
17 .enforcing = &tomoyo_default_profile.preference,
18 .preference.enforcing_verbose = true,
19 .preference.learning_max_entry = 2048,
20 .preference.learning_verbose = false,
21 .preference.permissive_verbose = true
22};
23
24/* Profile version. Currently only 20090903 is defined. */
25static unsigned int tomoyo_profile_version;
26
27/* Profile table. Memory is allocated as needed. */
28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
29
15/* String table for functionality that takes 4 modes. */ 30/* String table for functionality that takes 4 modes. */
16static const char *tomoyo_mode_4[4] = { 31static const char *tomoyo_mode_4[4] = {
17 "disabled", "learning", "permissive", "enforcing" 32 "disabled", "learning", "permissive", "enforcing"
18}; 33};
19/* String table for functionality that takes 2 modes. */
20static const char *tomoyo_mode_2[4] = {
21 "disabled", "enabled", "enabled", "enabled"
22};
23 34
24/* 35/* String table for /sys/kernel/security/tomoyo/profile */
25 * tomoyo_control_array is a static data which contains 36static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
26 * 37 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
27 * (1) functionality name used by /sys/kernel/security/tomoyo/profile . 38 [TOMOYO_MAC_FILE_EXECUTE] = "file::execute",
28 * (2) initial values for "struct tomoyo_profile". 39 [TOMOYO_MAC_FILE_OPEN] = "file::open",
29 * (3) max values for "struct tomoyo_profile". 40 [TOMOYO_MAC_FILE_CREATE] = "file::create",
30 */ 41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink",
31static struct { 42 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir",
32 const char *keyword; 43 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir",
33 unsigned int current_value; 44 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo",
34 const unsigned int max_value; 45 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock",
35} tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = { 46 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate",
36 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 }, 47 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink",
37 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX }, 48 [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite",
38 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock",
50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar",
51 [TOMOYO_MAC_FILE_LINK] = "file::link",
52 [TOMOYO_MAC_FILE_RENAME] = "file::rename",
53 [TOMOYO_MAC_FILE_CHMOD] = "file::chmod",
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",
39}; 62};
40 63
41/*
42 * tomoyo_profile is a structure which is used for holding the mode of access
43 * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
44 * An administrator can define up to 256 profiles.
45 * The ->profile of "struct tomoyo_domain_info" is used for remembering
46 * the profile's number (0 - 255) assigned to that domain.
47 */
48static struct tomoyo_profile {
49 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
50 const struct tomoyo_path_info *comment;
51} *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
52
53/* Permit policy management by non-root user? */ 64/* Permit policy management by non-root user? */
54static bool tomoyo_manage_by_non_root; 65static bool tomoyo_manage_by_non_root;
55 66
56/* Utility functions. */ 67/* Utility functions. */
57 68
58/** 69/**
70 * tomoyo_yesno - Return "yes" or "no".
71 *
72 * @value: Bool value.
73 */
74static const char *tomoyo_yesno(const unsigned int value)
75{
76 return value ? "yes" : "no";
77}
78
79/**
59 * tomoyo_print_name_union - Print a tomoyo_name_union. 80 * tomoyo_print_name_union - Print a tomoyo_name_union.
60 * 81 *
61 * @head: Pointer to "struct tomoyo_io_buffer". 82 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -154,80 +175,62 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
154} 175}
155 176
156/** 177/**
157 * tomoyo_check_flags - Check mode for specified functionality.
158 *
159 * @domain: Pointer to "struct tomoyo_domain_info".
160 * @index: The functionality to check mode.
161 *
162 * TOMOYO checks only process context.
163 * This code disables TOMOYO's enforcement in case the function is called from
164 * interrupt context.
165 */
166unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
167 const u8 index)
168{
169 const u8 profile = domain->profile;
170
171 if (WARN_ON(in_interrupt()))
172 return 0;
173 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX
174#if TOMOYO_MAX_PROFILES != 256
175 && profile < TOMOYO_MAX_PROFILES
176#endif
177 && tomoyo_profile_ptr[profile] ?
178 tomoyo_profile_ptr[profile]->value[index] : 0;
179}
180
181/**
182 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode.
183 *
184 * @domain: Pointer to "struct tomoyo_domain_info".
185 *
186 * Returns true if domain policy violation warning should be printed to
187 * console.
188 */
189bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
190{
191 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0;
192}
193
194/**
195 * tomoyo_find_or_assign_new_profile - Create a new profile. 178 * tomoyo_find_or_assign_new_profile - Create a new profile.
196 * 179 *
197 * @profile: Profile number to create. 180 * @profile: Profile number to create.
198 * 181 *
199 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 182 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
200 */ 183 */
201static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned 184static struct tomoyo_profile *tomoyo_find_or_assign_new_profile
202 int profile) 185(const unsigned int profile)
203{ 186{
204 struct tomoyo_profile *ptr = NULL; 187 struct tomoyo_profile *ptr;
205 int i; 188 struct tomoyo_profile *entry;
206
207 if (profile >= TOMOYO_MAX_PROFILES) 189 if (profile >= TOMOYO_MAX_PROFILES)
208 return NULL; 190 return NULL;
209 if (mutex_lock_interruptible(&tomoyo_policy_lock))
210 return NULL;
211 ptr = tomoyo_profile_ptr[profile]; 191 ptr = tomoyo_profile_ptr[profile];
212 if (ptr) 192 if (ptr)
213 goto ok; 193 return ptr;
214 ptr = kmalloc(sizeof(*ptr), GFP_NOFS); 194 entry = kzalloc(sizeof(*entry), GFP_NOFS);
215 if (!tomoyo_memory_ok(ptr)) { 195 if (mutex_lock_interruptible(&tomoyo_policy_lock))
216 kfree(ptr); 196 goto out;
217 ptr = NULL; 197 ptr = tomoyo_profile_ptr[profile];
218 goto ok; 198 if (!ptr && tomoyo_memory_ok(entry)) {
199 ptr = entry;
200 ptr->learning = &tomoyo_default_profile.preference;
201 ptr->permissive = &tomoyo_default_profile.preference;
202 ptr->enforcing = &tomoyo_default_profile.preference;
203 ptr->default_config = TOMOYO_CONFIG_DISABLED;
204 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
205 sizeof(ptr->config));
206 mb(); /* Avoid out-of-order execution. */
207 tomoyo_profile_ptr[profile] = ptr;
208 entry = NULL;
219 } 209 }
220 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
221 ptr->value[i] = tomoyo_control_array[i].current_value;
222 mb(); /* Avoid out-of-order execution. */
223 tomoyo_profile_ptr[profile] = ptr;
224 ok:
225 mutex_unlock(&tomoyo_policy_lock); 210 mutex_unlock(&tomoyo_policy_lock);
211 out:
212 kfree(entry);
226 return ptr; 213 return ptr;
227} 214}
228 215
229/** 216/**
230 * tomoyo_write_profile - Write to profile table. 217 * tomoyo_profile - Find a profile.
218 *
219 * @profile: Profile number to find.
220 *
221 * Returns pointer to "struct tomoyo_profile".
222 */
223struct tomoyo_profile *tomoyo_profile(const u8 profile)
224{
225 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile];
226 if (!tomoyo_policy_loaded)
227 return &tomoyo_default_profile;
228 BUG_ON(!ptr);
229 return ptr;
230}
231
232/**
233 * tomoyo_write_profile - Write profile table.
231 * 234 *
232 * @head: Pointer to "struct tomoyo_io_buffer". 235 * @head: Pointer to "struct tomoyo_io_buffer".
233 * 236 *
@@ -237,64 +240,116 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
237{ 240{
238 char *data = head->write_buf; 241 char *data = head->write_buf;
239 unsigned int i; 242 unsigned int i;
240 unsigned int value; 243 int value;
244 int mode;
245 u8 config;
246 bool use_default = false;
241 char *cp; 247 char *cp;
242 struct tomoyo_profile *profile; 248 struct tomoyo_profile *profile;
243 unsigned long num; 249 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1)
244 250 return 0;
245 cp = strchr(data, '-'); 251 i = simple_strtoul(data, &cp, 10);
246 if (cp) 252 if (data == cp) {
247 *cp = '\0'; 253 profile = &tomoyo_default_profile;
248 if (strict_strtoul(data, 10, &num)) 254 } else {
249 return -EINVAL; 255 if (*cp != '-')
250 if (cp) 256 return -EINVAL;
251 data = cp + 1; 257 data = cp + 1;
252 profile = tomoyo_find_or_assign_new_profile(num); 258 profile = tomoyo_find_or_assign_new_profile(i);
253 if (!profile) 259 if (!profile)
254 return -EINVAL; 260 return -EINVAL;
261 }
255 cp = strchr(data, '='); 262 cp = strchr(data, '=');
256 if (!cp) 263 if (!cp)
257 return -EINVAL; 264 return -EINVAL;
258 *cp = '\0'; 265 *cp++ = '\0';
266 if (profile != &tomoyo_default_profile)
267 use_default = strstr(cp, "use_default") != NULL;
268 if (strstr(cp, "verbose=yes"))
269 value = 1;
270 else if (strstr(cp, "verbose=no"))
271 value = 0;
272 else
273 value = -1;
274 if (!strcmp(data, "PREFERENCE::enforcing")) {
275 if (use_default) {
276 profile->enforcing = &tomoyo_default_profile.preference;
277 return 0;
278 }
279 profile->enforcing = &profile->preference;
280 if (value >= 0)
281 profile->preference.enforcing_verbose = value;
282 return 0;
283 }
284 if (!strcmp(data, "PREFERENCE::permissive")) {
285 if (use_default) {
286 profile->permissive = &tomoyo_default_profile.preference;
287 return 0;
288 }
289 profile->permissive = &profile->preference;
290 if (value >= 0)
291 profile->preference.permissive_verbose = value;
292 return 0;
293 }
294 if (!strcmp(data, "PREFERENCE::learning")) {
295 char *cp2;
296 if (use_default) {
297 profile->learning = &tomoyo_default_profile.preference;
298 return 0;
299 }
300 profile->learning = &profile->preference;
301 if (value >= 0)
302 profile->preference.learning_verbose = value;
303 cp2 = strstr(cp, "max_entry=");
304 if (cp2)
305 sscanf(cp2 + 10, "%u",
306 &profile->preference.learning_max_entry);
307 return 0;
308 }
309 if (profile == &tomoyo_default_profile)
310 return -EINVAL;
259 if (!strcmp(data, "COMMENT")) { 311 if (!strcmp(data, "COMMENT")) {
260 const struct tomoyo_path_info *old_comment = profile->comment; 312 const struct tomoyo_path_info *old_comment = profile->comment;
261 profile->comment = tomoyo_get_name(cp + 1); 313 profile->comment = tomoyo_get_name(cp);
262 tomoyo_put_name(old_comment); 314 tomoyo_put_name(old_comment);
263 return 0; 315 return 0;
264 } 316 }
265 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 317 if (!strcmp(data, "CONFIG")) {
266 if (strcmp(data, tomoyo_control_array[i].keyword)) 318 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
267 continue; 319 config = profile->default_config;
268 if (sscanf(cp + 1, "%u", &value) != 1) { 320 } else if (tomoyo_str_starts(&data, "CONFIG::")) {
269 int j; 321 config = 0;
270 const char **modes; 322 for (i = 0; i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
271 switch (i) { 323 if (strcmp(data, tomoyo_mac_keywords[i]))
272 case TOMOYO_VERBOSE: 324 continue;
273 modes = tomoyo_mode_2; 325 config = profile->config[i];
274 break; 326 break;
275 default:
276 modes = tomoyo_mode_4;
277 break;
278 }
279 for (j = 0; j < 4; j++) {
280 if (strcmp(cp + 1, modes[j]))
281 continue;
282 value = j;
283 break;
284 }
285 if (j == 4)
286 return -EINVAL;
287 } else if (value > tomoyo_control_array[i].max_value) {
288 value = tomoyo_control_array[i].max_value;
289 } 327 }
290 profile->value[i] = value; 328 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
291 return 0; 329 return -EINVAL;
330 } else {
331 return -EINVAL;
292 } 332 }
293 return -EINVAL; 333 if (use_default) {
334 config = TOMOYO_CONFIG_USE_DEFAULT;
335 } else {
336 for (mode = 3; mode >= 0; mode--)
337 if (strstr(cp, tomoyo_mode_4[mode]))
338 /*
339 * Update lower 3 bits in order to distinguish
340 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
341 */
342 config = (config & ~7) | mode;
343 }
344 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
345 profile->config[i] = config;
346 else if (config != TOMOYO_CONFIG_USE_DEFAULT)
347 profile->default_config = config;
348 return 0;
294} 349}
295 350
296/** 351/**
297 * tomoyo_read_profile - Read from profile table. 352 * tomoyo_read_profile - Read profile table.
298 * 353 *
299 * @head: Pointer to "struct tomoyo_io_buffer". 354 * @head: Pointer to "struct tomoyo_io_buffer".
300 * 355 *
@@ -302,53 +357,82 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
302 */ 357 */
303static int tomoyo_read_profile(struct tomoyo_io_buffer *head) 358static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
304{ 359{
305 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; 360 int index;
306 int step;
307
308 if (head->read_eof) 361 if (head->read_eof)
309 return 0; 362 return 0;
310 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; 363 if (head->read_bit)
311 step++) { 364 goto body;
312 const u8 index = step / total; 365 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
313 u8 type = step % total; 366 tomoyo_io_printf(head, "PREFERENCE::learning={ verbose=%s "
367 "max_entry=%u }\n",
368 tomoyo_yesno(tomoyo_default_profile.preference.
369 learning_verbose),
370 tomoyo_default_profile.preference.learning_max_entry);
371 tomoyo_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n",
372 tomoyo_yesno(tomoyo_default_profile.preference.
373 permissive_verbose));
374 tomoyo_io_printf(head, "PREFERENCE::enforcing={ verbose=%s }\n",
375 tomoyo_yesno(tomoyo_default_profile.preference.
376 enforcing_verbose));
377 head->read_bit = 1;
378 body:
379 for (index = head->read_step; index < TOMOYO_MAX_PROFILES; index++) {
380 bool done;
381 u8 config;
382 int i;
383 int pos;
314 const struct tomoyo_profile *profile 384 const struct tomoyo_profile *profile
315 = tomoyo_profile_ptr[index]; 385 = tomoyo_profile_ptr[index];
316 head->read_step = step; 386 const struct tomoyo_path_info *comment;
387 head->read_step = index;
317 if (!profile) 388 if (!profile)
318 continue; 389 continue;
319 if (!type) { /* Print profile' comment tag. */ 390 pos = head->read_avail;
320 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", 391 comment = profile->comment;
321 index, profile->comment ? 392 done = tomoyo_io_printf(head, "%u-COMMENT=%s\n", index,
322 profile->comment->name : "")) 393 comment ? comment->name : "");
323 break; 394 if (!done)
324 continue; 395 goto out;
325 } 396 config = profile->default_config;
326 type--; 397 if (!tomoyo_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,
327 if (type < TOMOYO_MAX_CONTROL_INDEX) { 398 tomoyo_mode_4[config & 3]))
328 const unsigned int value = profile->value[type]; 399 goto out;
329 const char **modes = NULL; 400 for (i = 0; i < TOMOYO_MAX_MAC_INDEX +
330 const char *keyword 401 TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
331 = tomoyo_control_array[type].keyword; 402 config = profile->config[i];
332 switch (tomoyo_control_array[type].max_value) { 403 if (config == TOMOYO_CONFIG_USE_DEFAULT)
333 case 3: 404 continue;
334 modes = tomoyo_mode_4; 405 if (!tomoyo_io_printf(head,
335 break; 406 "%u-CONFIG::%s={ mode=%s }\n",
336 case 1: 407 index, tomoyo_mac_keywords[i],
337 modes = tomoyo_mode_2; 408 tomoyo_mode_4[config & 3]))
338 break; 409 goto out;
339 }
340 if (modes) {
341 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index,
342 keyword, modes[value]))
343 break;
344 } else {
345 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index,
346 keyword, value))
347 break;
348 }
349 } 410 }
411 if (profile->learning != &tomoyo_default_profile.preference &&
412 !tomoyo_io_printf(head, "%u-PREFERENCE::learning={ "
413 "verbose=%s max_entry=%u }\n", index,
414 tomoyo_yesno(profile->preference.
415 learning_verbose),
416 profile->preference.learning_max_entry))
417 goto out;
418 if (profile->permissive != &tomoyo_default_profile.preference
419 && !tomoyo_io_printf(head, "%u-PREFERENCE::permissive={ "
420 "verbose=%s }\n", index,
421 tomoyo_yesno(profile->preference.
422 permissive_verbose)))
423 goto out;
424 if (profile->enforcing != &tomoyo_default_profile.preference &&
425 !tomoyo_io_printf(head, "%u-PREFERENCE::enforcing={ "
426 "verbose=%s }\n", index,
427 tomoyo_yesno(profile->preference.
428 enforcing_verbose)))
429 goto out;
430 continue;
431 out:
432 head->read_avail = pos;
433 break;
350 } 434 }
351 if (step == TOMOYO_MAX_PROFILES * total) 435 if (index == TOMOYO_MAX_PROFILES)
352 head->read_eof = true; 436 head->read_eof = true;
353 return 0; 437 return 0;
354} 438}
@@ -1595,7 +1679,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1595static int tomoyo_read_version(struct tomoyo_io_buffer *head) 1679static int tomoyo_read_version(struct tomoyo_io_buffer *head)
1596{ 1680{
1597 if (!head->read_eof) { 1681 if (!head->read_eof) {
1598 tomoyo_io_printf(head, "2.2.0"); 1682 tomoyo_io_printf(head, "2.3.0-pre");
1599 head->read_eof = true; 1683 head->read_eof = true;
1600 } 1684 }
1601 return 0; 1685 return 0;
@@ -1915,6 +1999,9 @@ void tomoyo_check_profile(void)
1915 profile, domain->domainname->name); 1999 profile, domain->domainname->name);
1916 } 2000 }
1917 tomoyo_read_unlock(idx); 2001 tomoyo_read_unlock(idx);
1918 printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n"); 2002 if (tomoyo_profile_version != 20090903)
2003 panic("Profile version %u is not supported.\n",
2004 tomoyo_profile_version);
2005 printk(KERN_INFO "TOMOYO: 2.3.0-pre 2010/06/03\n");
1919 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2006 printk(KERN_INFO "Mandatory Access Control activated.\n");
1920} 2007}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 54db39aa339b..c777c594a00b 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -42,7 +42,8 @@ enum tomoyo_mode_index {
42 TOMOYO_CONFIG_DISABLED, 42 TOMOYO_CONFIG_DISABLED,
43 TOMOYO_CONFIG_LEARNING, 43 TOMOYO_CONFIG_LEARNING,
44 TOMOYO_CONFIG_PERMISSIVE, 44 TOMOYO_CONFIG_PERMISSIVE,
45 TOMOYO_CONFIG_ENFORCING 45 TOMOYO_CONFIG_ENFORCING,
46 TOMOYO_CONFIG_USE_DEFAULT = 255
46}; 47};
47 48
48/* Keywords for ACLs. */ 49/* Keywords for ACLs. */
@@ -75,14 +76,6 @@ enum tomoyo_mode_index {
75#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3 76#define TOMOYO_VALUE_TYPE_HEXADECIMAL 3
76 77
77/* Index numbers for Access Controls. */ 78/* Index numbers for Access Controls. */
78enum tomoyo_mac_index {
79 TOMOYO_MAC_FOR_FILE, /* domain_policy.conf */
80 TOMOYO_MAX_ACCEPT_ENTRY,
81 TOMOYO_VERBOSE,
82 TOMOYO_MAX_CONTROL_INDEX
83};
84
85/* Index numbers for Access Controls. */
86enum tomoyo_acl_entry_type_index { 79enum tomoyo_acl_entry_type_index {
87 TOMOYO_TYPE_PATH_ACL, 80 TOMOYO_TYPE_PATH_ACL,
88 TOMOYO_TYPE_PATH2_ACL, 81 TOMOYO_TYPE_PATH2_ACL,
@@ -157,6 +150,38 @@ enum tomoyo_securityfs_interface_index {
157 TOMOYO_MANAGER 150 TOMOYO_MANAGER
158}; 151};
159 152
153enum tomoyo_mac_index {
154 TOMOYO_MAC_FILE_EXECUTE,
155 TOMOYO_MAC_FILE_OPEN,
156 TOMOYO_MAC_FILE_CREATE,
157 TOMOYO_MAC_FILE_UNLINK,
158 TOMOYO_MAC_FILE_MKDIR,
159 TOMOYO_MAC_FILE_RMDIR,
160 TOMOYO_MAC_FILE_MKFIFO,
161 TOMOYO_MAC_FILE_MKSOCK,
162 TOMOYO_MAC_FILE_TRUNCATE,
163 TOMOYO_MAC_FILE_SYMLINK,
164 TOMOYO_MAC_FILE_REWRITE,
165 TOMOYO_MAC_FILE_MKBLOCK,
166 TOMOYO_MAC_FILE_MKCHAR,
167 TOMOYO_MAC_FILE_LINK,
168 TOMOYO_MAC_FILE_RENAME,
169 TOMOYO_MAC_FILE_CHMOD,
170 TOMOYO_MAC_FILE_CHOWN,
171 TOMOYO_MAC_FILE_CHGRP,
172 TOMOYO_MAC_FILE_IOCTL,
173 TOMOYO_MAC_FILE_CHROOT,
174 TOMOYO_MAC_FILE_MOUNT,
175 TOMOYO_MAC_FILE_UMOUNT,
176 TOMOYO_MAC_FILE_PIVOT_ROOT,
177 TOMOYO_MAX_MAC_INDEX
178};
179
180enum tomoyo_mac_category_index {
181 TOMOYO_MAC_CATEGORY_FILE,
182 TOMOYO_MAX_MAC_CATEGORY_INDEX
183};
184
160#define TOMOYO_RETRY_REQUEST 1 /* Retry this request. */ 185#define TOMOYO_RETRY_REQUEST 1 /* Retry this request. */
161 186
162/********** Structure definitions. **********/ 187/********** Structure definitions. **********/
@@ -174,6 +199,7 @@ struct tomoyo_request_info {
174 u8 retry; 199 u8 retry;
175 u8 profile; 200 u8 profile;
176 u8 mode; /* One of tomoyo_mode_index . */ 201 u8 mode; /* One of tomoyo_mode_index . */
202 u8 type;
177}; 203};
178 204
179/* 205/*
@@ -649,6 +675,23 @@ struct tomoyo_policy_manager_entry {
649 bool is_deleted; /* True if this entry is deleted. */ 675 bool is_deleted; /* True if this entry is deleted. */
650}; 676};
651 677
678struct tomoyo_preference {
679 unsigned int learning_max_entry;
680 bool enforcing_verbose;
681 bool learning_verbose;
682 bool permissive_verbose;
683};
684
685struct tomoyo_profile {
686 const struct tomoyo_path_info *comment;
687 struct tomoyo_preference *learning;
688 struct tomoyo_preference *permissive;
689 struct tomoyo_preference *enforcing;
690 struct tomoyo_preference preference;
691 u8 default_config;
692 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
693};
694
652/********** Function prototypes. **********/ 695/********** Function prototypes. **********/
653 696
654extern asmlinkage long sys_getpid(void); 697extern asmlinkage long sys_getpid(void);
@@ -685,6 +728,7 @@ bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
685/* Check whether the given number matches the given number_union. */ 728/* Check whether the given number matches the given number_union. */
686bool tomoyo_compare_number_union(const unsigned long value, 729bool tomoyo_compare_number_union(const unsigned long value,
687 const struct tomoyo_number_union *ptr); 730 const struct tomoyo_number_union *ptr);
731int tomoyo_get_mode(const u8 profile, const u8 index);
688/* Transactional sprintf() for policy dump. */ 732/* Transactional sprintf() for policy dump. */
689bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 733bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
690 __attribute__ ((format(printf, 2, 3))); 734 __attribute__ ((format(printf, 2, 3)));
@@ -747,7 +791,8 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
747const char *tomoyo_path2keyword(const u8 operation); 791const char *tomoyo_path2keyword(const u8 operation);
748/* Fill "struct tomoyo_request_info". */ 792/* Fill "struct tomoyo_request_info". */
749int tomoyo_init_request_info(struct tomoyo_request_info *r, 793int tomoyo_init_request_info(struct tomoyo_request_info *r,
750 struct tomoyo_domain_info *domain); 794 struct tomoyo_domain_info *domain,
795 const u8 index);
751/* Check permission for mount operation. */ 796/* Check permission for mount operation. */
752int tomoyo_mount_permission(char *dev_name, struct path *path, char *type, 797int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
753 unsigned long flags, void *data_page); 798 unsigned long flags, void *data_page);
@@ -794,6 +839,7 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
794struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 839struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
795 domainname, 840 domainname,
796 const u8 profile); 841 const u8 profile);
842struct tomoyo_profile *tomoyo_profile(const u8 profile);
797/* Allocate memory for "struct tomoyo_path_group". */ 843/* Allocate memory for "struct tomoyo_path_group". */
798struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name); 844struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name);
799struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name); 845struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name);
@@ -844,7 +890,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
844 890
845/* Initialize mm related code. */ 891/* Initialize mm related code. */
846void __init tomoyo_mm_init(void); 892void __init tomoyo_mm_init(void);
847int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 893int tomoyo_check_exec_perm(struct tomoyo_request_info *r,
848 const struct tomoyo_path_info *filename); 894 const struct tomoyo_path_info *filename);
849int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 895int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
850 struct path *path, const int flag); 896 struct path *path, const int flag);
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index a07ca6dc1a08..09ec37c12a9c 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -812,8 +812,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
812 struct tomoyo_domain_info *domain = NULL; 812 struct tomoyo_domain_info *domain = NULL;
813 const char *old_domain_name = old_domain->domainname->name; 813 const char *old_domain_name = old_domain->domainname->name;
814 const char *original_name = bprm->filename; 814 const char *original_name = bprm->filename;
815 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 815 u8 mode;
816 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); 816 bool is_enforce;
817 int retval = -ENOMEM; 817 int retval = -ENOMEM;
818 bool need_kfree = false; 818 bool need_kfree = false;
819 struct tomoyo_path_info rn = { }; /* real name */ 819 struct tomoyo_path_info rn = { }; /* real name */
@@ -822,7 +822,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
822 822
823 ln.name = tomoyo_get_last_name(old_domain); 823 ln.name = tomoyo_get_last_name(old_domain);
824 tomoyo_fill_path_info(&ln); 824 tomoyo_fill_path_info(&ln);
825 tomoyo_init_request_info(&r, NULL); 825 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
826 is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
826 if (!tmp) 827 if (!tmp)
827 goto out; 828 goto out;
828 829
@@ -880,7 +881,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
880 } 881 }
881 882
882 /* Check execute permission. */ 883 /* Check execute permission. */
883 retval = tomoyo_check_exec_perm(old_domain, &rn); 884 retval = tomoyo_check_exec_perm(&r, &rn);
884 if (retval == TOMOYO_RETRY_REQUEST) 885 if (retval == TOMOYO_RETRY_REQUEST)
885 goto retry; 886 goto retry;
886 if (retval < 0) 887 if (retval < 0)
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 83fa17a1113a..8e51348d022e 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -51,6 +51,42 @@ static const char *tomoyo_path_number_keyword
51 [TOMOYO_TYPE_CHGRP] = "chgrp", 51 [TOMOYO_TYPE_CHGRP] = "chgrp",
52}; 52};
53 53
54static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
55 [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN,
56 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
57 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
58 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
59 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
60 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
61 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
62 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
63 [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE,
64 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
65 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
66};
67
68static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_PATH_NUMBER3_OPERATION] = {
69 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
70 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
71};
72
73static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
74 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
75 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
76 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
77};
78
79static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
80 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
81 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
82 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
83 [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
84 [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL,
85 [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD,
86 [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN,
87 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
88};
89
54void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 90void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
55{ 91{
56 if (!ptr) 92 if (!ptr)
@@ -1057,6 +1093,10 @@ static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
1057 int error; 1093 int error;
1058 1094
1059 next: 1095 next:
1096 r->type = tomoyo_p2mac[operation];
1097 r->mode = tomoyo_get_mode(r->profile, r->type);
1098 if (r->mode == TOMOYO_CONFIG_DISABLED)
1099 return 0;
1060 do { 1100 do {
1061 error = tomoyo_path_acl(r, filename, 1 << operation); 1101 error = tomoyo_path_acl(r, filename, 1 << operation);
1062 if (!error) 1102 if (!error)
@@ -1249,8 +1289,8 @@ int tomoyo_path_number_perm(const u8 type, struct path *path,
1249 struct tomoyo_path_info buf; 1289 struct tomoyo_path_info buf;
1250 int idx; 1290 int idx;
1251 1291
1252 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1292 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
1253 !path->mnt || !path->dentry) 1293 == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry)
1254 return 0; 1294 return 0;
1255 idx = tomoyo_read_lock(); 1295 idx = tomoyo_read_lock();
1256 if (!tomoyo_get_realpath(&buf, path)) 1296 if (!tomoyo_get_realpath(&buf, path))
@@ -1269,21 +1309,19 @@ int tomoyo_path_number_perm(const u8 type, struct path *path,
1269/** 1309/**
1270 * tomoyo_check_exec_perm - Check permission for "execute". 1310 * tomoyo_check_exec_perm - Check permission for "execute".
1271 * 1311 *
1272 * @domain: Pointer to "struct tomoyo_domain_info". 1312 * @r: Pointer to "struct tomoyo_request_info".
1273 * @filename: Check permission for "execute". 1313 * @filename: Check permission for "execute".
1274 * 1314 *
1275 * Returns 0 on success, negativevalue otherwise. 1315 * Returns 0 on success, negativevalue otherwise.
1276 * 1316 *
1277 * Caller holds tomoyo_read_lock(). 1317 * Caller holds tomoyo_read_lock().
1278 */ 1318 */
1279int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1319int tomoyo_check_exec_perm(struct tomoyo_request_info *r,
1280 const struct tomoyo_path_info *filename) 1320 const struct tomoyo_path_info *filename)
1281{ 1321{
1282 struct tomoyo_request_info r; 1322 if (r->mode == TOMOYO_CONFIG_DISABLED)
1283
1284 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED)
1285 return 0; 1323 return 0;
1286 return tomoyo_file_perm(&r, filename, 1); 1324 return tomoyo_file_perm(r, filename, 1);
1287} 1325}
1288 1326
1289/** 1327/**
@@ -1304,17 +1342,11 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1304 struct tomoyo_request_info r; 1342 struct tomoyo_request_info r;
1305 int idx; 1343 int idx;
1306 1344
1307 if (tomoyo_init_request_info(&r, domain) == TOMOYO_CONFIG_DISABLED || 1345 if (!path->mnt ||
1308 !path->mnt) 1346 (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
1309 return 0;
1310 if (acc_mode == 0)
1311 return 0;
1312 if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))
1313 /*
1314 * I don't check directories here because mkdir() and rmdir()
1315 * don't call me.
1316 */
1317 return 0; 1347 return 0;
1348 buf.name = NULL;
1349 r.mode = TOMOYO_CONFIG_DISABLED;
1318 idx = tomoyo_read_lock(); 1350 idx = tomoyo_read_lock();
1319 if (!tomoyo_get_realpath(&buf, path)) 1351 if (!tomoyo_get_realpath(&buf, path))
1320 goto out; 1352 goto out;
@@ -1324,15 +1356,26 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1324 * we need to check "allow_rewrite" permission when the filename is not 1356 * we need to check "allow_rewrite" permission when the filename is not
1325 * opened for append mode or the filename is truncated at open time. 1357 * opened for append mode or the filename is truncated at open time.
1326 */ 1358 */
1327 if ((acc_mode & MAY_WRITE) && 1359 if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND)
1328 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1360 && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE)
1329 (tomoyo_is_no_rewrite_file(&buf))) { 1361 != TOMOYO_CONFIG_DISABLED) {
1330 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, &buf); 1362 if (!tomoyo_get_realpath(&buf, path)) {
1363 error = -ENOMEM;
1364 goto out;
1365 }
1366 if (tomoyo_is_no_rewrite_file(&buf))
1367 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE,
1368 &buf);
1331 } 1369 }
1332 if (!error) 1370 if (!error && acc_mode &&
1371 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
1372 != TOMOYO_CONFIG_DISABLED) {
1373 if (!buf.name && !tomoyo_get_realpath(&buf, path)) {
1374 error = -ENOMEM;
1375 goto out;
1376 }
1333 error = tomoyo_file_perm(&r, &buf, acc_mode); 1377 error = tomoyo_file_perm(&r, &buf, acc_mode);
1334 if (!error && (flag & O_TRUNC)) 1378 }
1335 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, &buf);
1336 out: 1379 out:
1337 kfree(buf.name); 1380 kfree(buf.name);
1338 tomoyo_read_unlock(idx); 1381 tomoyo_read_unlock(idx);
@@ -1356,9 +1399,12 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1356 struct tomoyo_request_info r; 1399 struct tomoyo_request_info r;
1357 int idx; 1400 int idx;
1358 1401
1359 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1402 if (!path->mnt)
1360 !path->mnt) 1403 return 0;
1404 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
1405 == TOMOYO_CONFIG_DISABLED)
1361 return 0; 1406 return 0;
1407 buf.name = NULL;
1362 idx = tomoyo_read_lock(); 1408 idx = tomoyo_read_lock();
1363 if (!tomoyo_get_realpath(&buf, path)) 1409 if (!tomoyo_get_realpath(&buf, path))
1364 goto out; 1410 goto out;
@@ -1371,6 +1417,7 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1371 break; 1417 break;
1372 case TOMOYO_TYPE_RMDIR: 1418 case TOMOYO_TYPE_RMDIR:
1373 case TOMOYO_TYPE_CHROOT: 1419 case TOMOYO_TYPE_CHROOT:
1420 case TOMOYO_TYPE_UMOUNT:
1374 tomoyo_add_slash(&buf); 1421 tomoyo_add_slash(&buf);
1375 break; 1422 break;
1376 } 1423 }
@@ -1442,8 +1489,9 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path,
1442 struct tomoyo_path_info buf; 1489 struct tomoyo_path_info buf;
1443 int idx; 1490 int idx;
1444 1491
1445 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1492 if (!path->mnt ||
1446 !path->mnt) 1493 tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1494 == TOMOYO_CONFIG_DISABLED)
1447 return 0; 1495 return 0;
1448 idx = tomoyo_read_lock(); 1496 idx = tomoyo_read_lock();
1449 error = -ENOMEM; 1497 error = -ENOMEM;
@@ -1477,8 +1525,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1477 struct tomoyo_request_info r; 1525 struct tomoyo_request_info r;
1478 int idx; 1526 int idx;
1479 1527
1480 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1528 if (!path1->mnt || !path2->mnt ||
1481 !path1->mnt || !path2->mnt) 1529 tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1530 == TOMOYO_CONFIG_DISABLED)
1482 return 0; 1531 return 0;
1483 buf1.name = NULL; 1532 buf1.name = NULL;
1484 buf2.name = NULL; 1533 buf2.name = NULL;
@@ -1486,13 +1535,19 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1486 if (!tomoyo_get_realpath(&buf1, path1) || 1535 if (!tomoyo_get_realpath(&buf1, path1) ||
1487 !tomoyo_get_realpath(&buf2, path2)) 1536 !tomoyo_get_realpath(&buf2, path2))
1488 goto out; 1537 goto out;
1489 { 1538 switch (operation) {
1490 struct dentry *dentry = path1->dentry; 1539 struct dentry *dentry;
1491 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { 1540 case TOMOYO_TYPE_RENAME:
1492 tomoyo_add_slash(&buf1); 1541 case TOMOYO_TYPE_LINK:
1493 tomoyo_add_slash(&buf2); 1542 dentry = path1->dentry;
1494 } 1543 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
1495 } 1544 break;
1545 /* fall through */
1546 case TOMOYO_TYPE_PIVOT_ROOT:
1547 tomoyo_add_slash(&buf1);
1548 tomoyo_add_slash(&buf2);
1549 break;
1550 }
1496 do { 1551 do {
1497 error = tomoyo_path2_acl(&r, operation, &buf1, &buf2); 1552 error = tomoyo_path2_acl(&r, operation, &buf1, &buf2);
1498 if (!error) 1553 if (!error)
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 7c1c7fdd3681..77ee8bf41948 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -248,7 +248,8 @@ int tomoyo_mount_permission(char *dev_name, struct path *path, char *type,
248 int error; 248 int error;
249 int idx; 249 int idx;
250 250
251 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED) 251 if (tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_MOUNT)
252 == TOMOYO_CONFIG_DISABLED)
252 return 0; 253 return 0;
253 if (!type) 254 if (!type)
254 type = "<NULL>"; 255 type = "<NULL>";
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 592b76a2bce8..307793ed6075 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -792,25 +792,67 @@ const char *tomoyo_get_exe(void)
792} 792}
793 793
794/** 794/**
795 * tomoyo_get_mode - Get MAC mode.
796 *
797 * @profile: Profile number.
798 * @index: Index number of functionality.
799 *
800 * Returns mode.
801 */
802int tomoyo_get_mode(const u8 profile, const u8 index)
803{
804 u8 mode;
805 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
806 if (!tomoyo_policy_loaded)
807 return TOMOYO_CONFIG_DISABLED;
808 mode = tomoyo_profile(profile)->config[index];
809 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
810 mode = tomoyo_profile(profile)->config[category];
811 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
812 mode = tomoyo_profile(profile)->default_config;
813 return mode & 3;
814}
815
816/**
795 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members. 817 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
796 * 818 *
797 * @r: Pointer to "struct tomoyo_request_info" to initialize. 819 * @r: Pointer to "struct tomoyo_request_info" to initialize.
798 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain(). 820 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
821 * @index: Index number of functionality.
799 * 822 *
800 * Returns mode. 823 * Returns mode.
801 */ 824 */
802int tomoyo_init_request_info(struct tomoyo_request_info *r, 825int tomoyo_init_request_info(struct tomoyo_request_info *r,
803 struct tomoyo_domain_info *domain) 826 struct tomoyo_domain_info *domain, const u8 index)
804{ 827{
828 u8 profile;
805 memset(r, 0, sizeof(*r)); 829 memset(r, 0, sizeof(*r));
806 if (!domain) 830 if (!domain)
807 domain = tomoyo_domain(); 831 domain = tomoyo_domain();
808 r->domain = domain; 832 r->domain = domain;
809 r->mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 833 profile = domain->profile;
834 r->profile = profile;
835 r->type = index;
836 r->mode = tomoyo_get_mode(profile, index);
810 return r->mode; 837 return r->mode;
811} 838}
812 839
813/** 840/**
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 */
847static const 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/**
814 * tomoyo_warn_log - Print warning or error message on console. 856 * tomoyo_warn_log - Print warning or error message on console.
815 * 857 *
816 * @r: Pointer to "struct tomoyo_request_info". 858 * @r: Pointer to "struct tomoyo_request_info".
@@ -818,29 +860,34 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
818 */ 860 */
819void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...) 861void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
820{ 862{
821 int len = PAGE_SIZE;
822 va_list args; 863 va_list args;
823 char *buffer; 864 char *buffer;
824 if (!tomoyo_verbose_mode(r->domain)) 865 const struct tomoyo_domain_info * const domain = r->domain;
825 return; 866 const struct tomoyo_profile *profile = tomoyo_profile(domain->profile);
826 while (1) { 867 switch (r->mode) {
827 int len2; 868 case TOMOYO_CONFIG_ENFORCING:
828 buffer = kmalloc(len, GFP_NOFS); 869 if (!profile->enforcing->enforcing_verbose)
829 if (!buffer)
830 return; 870 return;
831 va_start(args, fmt); 871 break;
832 len2 = vsnprintf(buffer, len - 1, fmt, args); 872 case TOMOYO_CONFIG_PERMISSIVE:
833 va_end(args); 873 if (!profile->permissive->permissive_verbose)
834 if (len2 <= len - 1) { 874 return;
835 buffer[len2] = '\0'; 875 break;
836 break; 876 case TOMOYO_CONFIG_LEARNING:
837 } 877 if (!profile->learning->learning_verbose)
838 len = len2 + 1; 878 return;
839 kfree(buffer); 879 break;
840 } 880 }
841 printk(KERN_WARNING "TOMOYO-%s: Access %s denied for %s\n", 881 buffer = kmalloc(4096, GFP_NOFS);
842 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING", 882 if (!buffer)
843 buffer, tomoyo_get_last_name(r->domain)); 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));
844 kfree(buffer); 891 kfree(buffer);
845} 892}
846 893
@@ -903,7 +950,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
903 count++; 950 count++;
904 } 951 }
905 } 952 }
906 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 953 if (count < tomoyo_profile(domain->profile)->learning->
954 learning_max_entry)
907 return true; 955 return true;
908 if (!domain->quota_warned) { 956 if (!domain->quota_warned) {
909 domain->quota_warned = true; 957 domain->quota_warned = true;