aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 10:18:21 -0400
committerJames Morris <jmorris@namei.org>2011-06-28 19:31:20 -0400
commitd5ca1725ac9ba876c2dd614bb9826d0c4e13d818 (patch)
treefbff7fe1e39597c5bac981f63a2be659f4ec84e7 /security/tomoyo
parent0d2171d711cbfca84cc0001121be8a6cc8e4d148 (diff)
TOMOYO: Simplify profile structure.
Remove global preference from profile structure in order to make code simpler. Due to this structure change, printk() warnings upon policy violation are temporarily disabled. They will be replaced by /sys/kernel/security/tomoyo/audit by next patch. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo')
-rw-r--r--security/tomoyo/common.c205
-rw-r--r--security/tomoyo/common.h7
-rw-r--r--security/tomoyo/util.c39
3 files changed, 83 insertions, 168 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 465df022c211..2b280350708f 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -11,16 +11,6 @@
11#include <linux/security.h> 11#include <linux/security.h>
12#include "common.h" 12#include "common.h"
13 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. */ 14/* Profile version. Currently only 20090903 is defined. */
25static unsigned int tomoyo_profile_version; 15static unsigned int tomoyo_profile_version;
26 16
@@ -61,6 +51,11 @@ static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
61 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", 51 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
62}; 52};
63 53
54/* String table for PREFERENCE keyword. */
55static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
56 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
57};
58
64/* Permit policy management by non-root user? */ 59/* Permit policy management by non-root user? */
65static bool tomoyo_manage_by_non_root; 60static bool tomoyo_manage_by_non_root;
66 61
@@ -71,11 +66,22 @@ static bool tomoyo_manage_by_non_root;
71 * 66 *
72 * @value: Bool value. 67 * @value: Bool value.
73 */ 68 */
69/*
74static const char *tomoyo_yesno(const unsigned int value) 70static const char *tomoyo_yesno(const unsigned int value)
75{ 71{
76 return value ? "yes" : "no"; 72 return value ? "yes" : "no";
77} 73}
74*/
78 75
76/**
77 * tomoyo_addprintf - strncat()-like-snprintf().
78 *
79 * @buffer: Buffer to write to. Must be '\0'-terminated.
80 * @len: Size of @buffer.
81 * @fmt: The printf()'s format string, followed by parameters.
82 *
83 * Returns nothing.
84 */
79static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) 85static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
80{ 86{
81 va_list args; 87 va_list args;
@@ -294,12 +300,10 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
294 ptr = tomoyo_profile_ptr[profile]; 300 ptr = tomoyo_profile_ptr[profile];
295 if (!ptr && tomoyo_memory_ok(entry)) { 301 if (!ptr && tomoyo_memory_ok(entry)) {
296 ptr = entry; 302 ptr = entry;
297 ptr->learning = &tomoyo_default_profile.preference;
298 ptr->permissive = &tomoyo_default_profile.preference;
299 ptr->enforcing = &tomoyo_default_profile.preference;
300 ptr->default_config = TOMOYO_CONFIG_DISABLED; 303 ptr->default_config = TOMOYO_CONFIG_DISABLED;
301 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 304 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
302 sizeof(ptr->config)); 305 sizeof(ptr->config));
306 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
303 mb(); /* Avoid out-of-order execution. */ 307 mb(); /* Avoid out-of-order execution. */
304 tomoyo_profile_ptr[profile] = ptr; 308 tomoyo_profile_ptr[profile] = ptr;
305 entry = NULL; 309 entry = NULL;
@@ -319,13 +323,22 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
319 */ 323 */
320struct tomoyo_profile *tomoyo_profile(const u8 profile) 324struct tomoyo_profile *tomoyo_profile(const u8 profile)
321{ 325{
326 static struct tomoyo_profile tomoyo_null_profile;
322 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile]; 327 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile];
323 if (!tomoyo_policy_loaded) 328 if (!ptr)
324 return &tomoyo_default_profile; 329 ptr = &tomoyo_null_profile;
325 BUG_ON(!ptr);
326 return ptr; 330 return ptr;
327} 331}
328 332
333/**
334 * tomoyo_find_yesno - Find values for specified keyword.
335 *
336 * @string: String to check.
337 * @find: Name of keyword.
338 *
339 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
340 */
341/*
329static s8 tomoyo_find_yesno(const char *string, const char *find) 342static s8 tomoyo_find_yesno(const char *string, const char *find)
330{ 343{
331 const char *cp = strstr(string, find); 344 const char *cp = strstr(string, find);
@@ -338,19 +351,17 @@ static s8 tomoyo_find_yesno(const char *string, const char *find)
338 } 351 }
339 return -1; 352 return -1;
340} 353}
354*/
341 355
342static void tomoyo_set_bool(bool *b, const char *string, const char *find) 356/**
343{ 357 * tomoyo_set_uint - Set value for specified preference.
344 switch (tomoyo_find_yesno(string, find)) { 358 *
345 case 1: 359 * @i: Pointer to "unsigned int".
346 *b = true; 360 * @string: String to check.
347 break; 361 * @find: Name of keyword.
348 case 0: 362 *
349 *b = false; 363 * Returns nothing.
350 break; 364 */
351 }
352}
353
354static void tomoyo_set_uint(unsigned int *i, const char *string, 365static void tomoyo_set_uint(unsigned int *i, const char *string,
355 const char *find) 366 const char *find)
356{ 367{
@@ -359,51 +370,16 @@ static void tomoyo_set_uint(unsigned int *i, const char *string,
359 sscanf(cp + strlen(find), "=%u", i); 370 sscanf(cp + strlen(find), "=%u", i);
360} 371}
361 372
362static void tomoyo_set_pref(const char *name, const char *value, 373/**
363 const bool use_default, 374 * tomoyo_set_mode - Set mode for specified profile.
364 struct tomoyo_profile *profile) 375 *
365{ 376 * @name: Name of functionality.
366 struct tomoyo_preference **pref; 377 * @value: Mode for @name.
367 bool *verbose; 378 * @profile: Pointer to "struct tomoyo_profile".
368 if (!strcmp(name, "enforcing")) { 379 *
369 if (use_default) { 380 * Returns 0 on success, negative value otherwise.
370 pref = &profile->enforcing; 381 */
371 goto set_default;
372 }
373 profile->enforcing = &profile->preference;
374 verbose = &profile->preference.enforcing_verbose;
375 goto set_verbose;
376 }
377 if (!strcmp(name, "permissive")) {
378 if (use_default) {
379 pref = &profile->permissive;
380 goto set_default;
381 }
382 profile->permissive = &profile->preference;
383 verbose = &profile->preference.permissive_verbose;
384 goto set_verbose;
385 }
386 if (!strcmp(name, "learning")) {
387 if (use_default) {
388 pref = &profile->learning;
389 goto set_default;
390 }
391 profile->learning = &profile->preference;
392 tomoyo_set_uint(&profile->preference.learning_max_entry, value,
393 "max_entry");
394 verbose = &profile->preference.learning_verbose;
395 goto set_verbose;
396 }
397 return;
398 set_default:
399 *pref = &tomoyo_default_profile.preference;
400 return;
401 set_verbose:
402 tomoyo_set_bool(verbose, value, "verbose");
403}
404
405static int tomoyo_set_mode(char *name, const char *value, 382static int tomoyo_set_mode(char *name, const char *value,
406 const bool use_default,
407 struct tomoyo_profile *profile) 383 struct tomoyo_profile *profile)
408{ 384{
409 u8 i; 385 u8 i;
@@ -425,7 +401,7 @@ static int tomoyo_set_mode(char *name, const char *value,
425 } else { 401 } else {
426 return -EINVAL; 402 return -EINVAL;
427 } 403 }
428 if (use_default) { 404 if (strstr(value, "use_default")) {
429 config = TOMOYO_CONFIG_USE_DEFAULT; 405 config = TOMOYO_CONFIG_USE_DEFAULT;
430 } else { 406 } else {
431 u8 mode; 407 u8 mode;
@@ -455,34 +431,21 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
455{ 431{
456 char *data = head->write_buf; 432 char *data = head->write_buf;
457 unsigned int i; 433 unsigned int i;
458 bool use_default = false;
459 char *cp; 434 char *cp;
460 struct tomoyo_profile *profile; 435 struct tomoyo_profile *profile;
461 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1) 436 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1)
462 return 0; 437 return 0;
463 i = simple_strtoul(data, &cp, 10); 438 i = simple_strtoul(data, &cp, 10);
464 if (data == cp) { 439 if (*cp != '-')
465 profile = &tomoyo_default_profile; 440 return -EINVAL;
466 } else { 441 data = cp + 1;
467 if (*cp != '-') 442 profile = tomoyo_assign_profile(i);
468 return -EINVAL; 443 if (!profile)
469 data = cp + 1; 444 return -EINVAL;
470 profile = tomoyo_assign_profile(i);
471 if (!profile)
472 return -EINVAL;
473 }
474 cp = strchr(data, '='); 445 cp = strchr(data, '=');
475 if (!cp) 446 if (!cp)
476 return -EINVAL; 447 return -EINVAL;
477 *cp++ = '\0'; 448 *cp++ = '\0';
478 if (profile != &tomoyo_default_profile)
479 use_default = strstr(cp, "use_default") != NULL;
480 if (tomoyo_str_starts(&data, "PREFERENCE::")) {
481 tomoyo_set_pref(data, cp, use_default, profile);
482 return 0;
483 }
484 if (profile == &tomoyo_default_profile)
485 return -EINVAL;
486 if (!strcmp(data, "COMMENT")) { 449 if (!strcmp(data, "COMMENT")) {
487 static DEFINE_SPINLOCK(lock); 450 static DEFINE_SPINLOCK(lock);
488 const struct tomoyo_path_info *new_comment 451 const struct tomoyo_path_info *new_comment
@@ -497,48 +460,13 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
497 tomoyo_put_name(old_comment); 460 tomoyo_put_name(old_comment);
498 return 0; 461 return 0;
499 } 462 }
500 return tomoyo_set_mode(data, cp, use_default, profile); 463 if (!strcmp(data, "PREFERENCE")) {
501} 464 for (i = 0; i < TOMOYO_MAX_PREF; i++)
502 465 tomoyo_set_uint(&profile->pref[i], cp,
503static void tomoyo_print_preference(struct tomoyo_io_buffer *head, 466 tomoyo_pref_keywords[i]);
504 const int idx) 467 return 0;
505{
506 struct tomoyo_preference *pref = &tomoyo_default_profile.preference;
507 const struct tomoyo_profile *profile = idx >= 0 ?
508 tomoyo_profile_ptr[idx] : NULL;
509 char buffer[16] = "";
510 if (profile) {
511 buffer[sizeof(buffer) - 1] = '\0';
512 snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
513 }
514 if (profile) {
515 pref = profile->learning;
516 if (pref == &tomoyo_default_profile.preference)
517 goto skip1;
518 }
519 tomoyo_io_printf(head, "%sPREFERENCE::%s={ "
520 "verbose=%s max_entry=%u }\n",
521 buffer, "learning",
522 tomoyo_yesno(pref->learning_verbose),
523 pref->learning_max_entry);
524 skip1:
525 if (profile) {
526 pref = profile->permissive;
527 if (pref == &tomoyo_default_profile.preference)
528 goto skip2;
529 }
530 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
531 buffer, "permissive",
532 tomoyo_yesno(pref->permissive_verbose));
533 skip2:
534 if (profile) {
535 pref = profile->enforcing;
536 if (pref == &tomoyo_default_profile.preference)
537 return;
538 } 468 }
539 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n", 469 return tomoyo_set_mode(data, cp, profile);
540 buffer, "enforcing",
541 tomoyo_yesno(pref->enforcing_verbose));
542} 470}
543 471
544static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 472static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
@@ -561,7 +489,6 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
561 switch (head->r.step) { 489 switch (head->r.step) {
562 case 0: 490 case 0:
563 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); 491 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
564 tomoyo_print_preference(head, -1);
565 head->r.step++; 492 head->r.step++;
566 break; 493 break;
567 case 1: 494 case 1:
@@ -575,11 +502,18 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
575 break; 502 break;
576 case 2: 503 case 2:
577 { 504 {
505 u8 i;
578 const struct tomoyo_path_info *comment = 506 const struct tomoyo_path_info *comment =
579 profile->comment; 507 profile->comment;
580 tomoyo_io_printf(head, "%u-COMMENT=", index); 508 tomoyo_io_printf(head, "%u-COMMENT=", index);
581 tomoyo_set_string(head, comment ? comment->name : ""); 509 tomoyo_set_string(head, comment ? comment->name : "");
582 tomoyo_set_lf(head); 510 tomoyo_set_lf(head);
511 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
512 for (i = 0; i < TOMOYO_MAX_PREF; i++)
513 tomoyo_io_printf(head, "%s=%u ",
514 tomoyo_pref_keywords[i],
515 profile->pref[i]);
516 tomoyo_set_string(head, "}\n");
583 head->r.step++; 517 head->r.step++;
584 } 518 }
585 break; 519 break;
@@ -606,7 +540,6 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
606 } 540 }
607 if (head->r.bit == TOMOYO_MAX_MAC_INDEX 541 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
608 + TOMOYO_MAX_MAC_CATEGORY_INDEX) { 542 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
609 tomoyo_print_preference(head, index);
610 head->r.index++; 543 head->r.index++;
611 head->r.step = 1; 544 head->r.step = 1;
612 } 545 }
@@ -1777,7 +1710,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1777static void tomoyo_read_version(struct tomoyo_io_buffer *head) 1710static void tomoyo_read_version(struct tomoyo_io_buffer *head)
1778{ 1711{
1779 if (!head->r.eof) { 1712 if (!head->r.eof) {
1780 tomoyo_io_printf(head, "2.3.0"); 1713 tomoyo_io_printf(head, "2.4.0");
1781 head->r.eof = true; 1714 head->r.eof = true;
1782 } 1715 }
1783} 1716}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 139ad7544460..2b39e63234c8 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -211,6 +211,12 @@ enum tomoyo_mac_category_index {
211 */ 211 */
212#define TOMOYO_RETRY_REQUEST 1 212#define TOMOYO_RETRY_REQUEST 1
213 213
214/* Index numbers for profile's PREFERENCE values. */
215enum tomoyo_pref_index {
216 TOMOYO_PREF_MAX_LEARNING_ENTRY,
217 TOMOYO_MAX_PREF
218};
219
214/********** Structure definitions. **********/ 220/********** Structure definitions. **********/
215 221
216/* Common header for holding ACL entries. */ 222/* Common header for holding ACL entries. */
@@ -497,6 +503,7 @@ struct tomoyo_profile {
497 struct tomoyo_preference preference; 503 struct tomoyo_preference preference;
498 u8 default_config; 504 u8 default_config;
499 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX]; 505 u8 config[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX];
506 unsigned int pref[TOMOYO_MAX_PREF];
500}; 507};
501 508
502/********** Function prototypes. **********/ 509/********** Function prototypes. **********/
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 72cd2b97cae8..adcbdebd7352 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -899,35 +899,10 @@ const char *tomoyo_last_word(const char *name)
899 */ 899 */
900void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...) 900void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
901{ 901{
902 va_list args; 902 /*
903 char *buffer; 903 * Temporarily disabled.
904 const struct tomoyo_domain_info * const domain = r->domain; 904 * Will be replaced with /sys/kernel/security/tomoyo/audit interface.
905 const struct tomoyo_profile *profile = tomoyo_profile(domain->profile); 905 */
906 switch (r->mode) {
907 case TOMOYO_CONFIG_ENFORCING:
908 if (!profile->enforcing->enforcing_verbose)
909 return;
910 break;
911 case TOMOYO_CONFIG_PERMISSIVE:
912 if (!profile->permissive->permissive_verbose)
913 return;
914 break;
915 case TOMOYO_CONFIG_LEARNING:
916 if (!profile->learning->learning_verbose)
917 return;
918 break;
919 }
920 buffer = kmalloc(4096, GFP_NOFS);
921 if (!buffer)
922 return;
923 va_start(args, fmt);
924 vsnprintf(buffer, 4095, fmt, args);
925 va_end(args);
926 buffer[4095] = '\0';
927 printk(KERN_WARNING "%s: Access %s denied for %s\n",
928 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING", buffer,
929 tomoyo_last_word(domain->domainname->name));
930 kfree(buffer);
931} 906}
932 907
933/** 908/**
@@ -978,13 +953,13 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
978 if (perm & (1 << i)) 953 if (perm & (1 << i))
979 count++; 954 count++;
980 } 955 }
981 if (count < tomoyo_profile(domain->profile)->learning-> 956 if (count < tomoyo_profile(domain->profile)->
982 learning_max_entry) 957 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
983 return true; 958 return true;
984 if (!domain->quota_warned) { 959 if (!domain->quota_warned) {
985 domain->quota_warned = true; 960 domain->quota_warned = true;
986 printk(KERN_WARNING "TOMOYO-WARNING: " 961 printk(KERN_WARNING "TOMOYO-WARNING: "
987 "Domain '%s' has so many ACLs to hold. " 962 "Domain '%s' has too many ACLs to hold. "
988 "Stopped learning mode.\n", domain->domainname->name); 963 "Stopped learning mode.\n", domain->domainname->name);
989 } 964 }
990 return false; 965 return false;