aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;