aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 10:19:52 -0400
committerJames Morris <jmorris@namei.org>2011-06-28 19:31:21 -0400
commitbd03a3e4c9a9df0c6b007045fa7fc8889111a478 (patch)
tree9d78290c878e6466fe3e0bda7ee5989c0dc39e40 /security
parent32997144fd9925fc4d506a16990a0c405f766526 (diff)
TOMOYO: Add policy namespace support.
Mauras Olivier reported that it is difficult to use TOMOYO in LXC environments, for TOMOYO cannot distinguish between environments outside the container and environments inside the container since LXC environments are created using pivot_root(). To address this problem, this patch introduces policy namespace. Each policy namespace has its own set of domain policy, exception policy and profiles, which are all independent of other namespaces. This independency allows users to develop policy without worrying interference among namespaces. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/audit.c8
-rw-r--r--security/tomoyo/common.c383
-rw-r--r--security/tomoyo/common.h63
-rw-r--r--security/tomoyo/domain.c360
-rw-r--r--security/tomoyo/file.c2
-rw-r--r--security/tomoyo/gc.c73
-rw-r--r--security/tomoyo/memory.c21
-rw-r--r--security/tomoyo/util.c58
8 files changed, 669 insertions, 299 deletions
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index e882f17065f2..ef2172f29583 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -151,13 +151,15 @@ static unsigned int tomoyo_log_count;
151/** 151/**
152 * tomoyo_get_audit - Get audit mode. 152 * tomoyo_get_audit - Get audit mode.
153 * 153 *
154 * @ns: Pointer to "struct tomoyo_policy_namespace".
154 * @profile: Profile number. 155 * @profile: Profile number.
155 * @index: Index number of functionality. 156 * @index: Index number of functionality.
156 * @is_granted: True if granted log, false otherwise. 157 * @is_granted: True if granted log, false otherwise.
157 * 158 *
158 * Returns true if this request should be audited, false otherwise. 159 * Returns true if this request should be audited, false otherwise.
159 */ 160 */
160static bool tomoyo_get_audit(const u8 profile, const u8 index, 161static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
162 const u8 profile, const u8 index,
161 const bool is_granted) 163 const bool is_granted)
162{ 164{
163 u8 mode; 165 u8 mode;
@@ -165,7 +167,7 @@ static bool tomoyo_get_audit(const u8 profile, const u8 index,
165 struct tomoyo_profile *p; 167 struct tomoyo_profile *p;
166 if (!tomoyo_policy_loaded) 168 if (!tomoyo_policy_loaded)
167 return false; 169 return false;
168 p = tomoyo_profile(profile); 170 p = tomoyo_profile(ns, profile);
169 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG]) 171 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
170 return false; 172 return false;
171 mode = p->config[index]; 173 mode = p->config[index];
@@ -194,7 +196,7 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
194 char *buf; 196 char *buf;
195 struct tomoyo_log *entry; 197 struct tomoyo_log *entry;
196 bool quota_exceeded = false; 198 bool quota_exceeded = false;
197 if (!tomoyo_get_audit(r->profile, r->type, r->granted)) 199 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
198 goto out; 200 goto out;
199 buf = tomoyo_init_log(r, len, fmt, args); 201 buf = tomoyo_init_log(r, len, fmt, args);
200 if (!buf) 202 if (!buf)
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 507ebf01e43b..50481d2cf970 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -11,12 +11,6 @@
11#include <linux/security.h> 11#include <linux/security.h>
12#include "common.h" 12#include "common.h"
13 13
14/* Profile version. Currently only 20090903 is defined. */
15static unsigned int tomoyo_profile_version;
16
17/* Profile table. Memory is allocated as needed. */
18static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
19
20/* String table for operation mode. */ 14/* String table for operation mode. */
21const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = { 15const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
22 [TOMOYO_CONFIG_DISABLED] = "disabled", 16 [TOMOYO_CONFIG_DISABLED] = "disabled",
@@ -216,6 +210,50 @@ static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
216 tomoyo_set_string(head, "/"); 210 tomoyo_set_string(head, "/");
217} 211}
218 212
213/* List of namespaces. */
214LIST_HEAD(tomoyo_namespace_list);
215/* True if namespace other than tomoyo_kernel_namespace is defined. */
216static bool tomoyo_namespace_enabled;
217
218/**
219 * tomoyo_init_policy_namespace - Initialize namespace.
220 *
221 * @ns: Pointer to "struct tomoyo_policy_namespace".
222 *
223 * Returns nothing.
224 */
225void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
226{
227 unsigned int idx;
228 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
229 INIT_LIST_HEAD(&ns->acl_group[idx]);
230 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
231 INIT_LIST_HEAD(&ns->group_list[idx]);
232 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
233 INIT_LIST_HEAD(&ns->policy_list[idx]);
234 ns->profile_version = 20100903;
235 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
236 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
237}
238
239/**
240 * tomoyo_print_namespace - Print namespace header.
241 *
242 * @head: Pointer to "struct tomoyo_io_buffer".
243 *
244 * Returns nothing.
245 */
246static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
247{
248 if (!tomoyo_namespace_enabled)
249 return;
250 tomoyo_set_string(head,
251 container_of(head->r.ns,
252 struct tomoyo_policy_namespace,
253 namespace_list)->name);
254 tomoyo_set_space(head);
255}
256
219/** 257/**
220 * tomoyo_print_name_union - Print a tomoyo_name_union. 258 * tomoyo_print_name_union - Print a tomoyo_name_union.
221 * 259 *
@@ -283,23 +321,25 @@ static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
283/** 321/**
284 * tomoyo_assign_profile - Create a new profile. 322 * tomoyo_assign_profile - Create a new profile.
285 * 323 *
324 * @ns: Pointer to "struct tomoyo_policy_namespace".
286 * @profile: Profile number to create. 325 * @profile: Profile number to create.
287 * 326 *
288 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 327 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
289 */ 328 */
290static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile) 329static struct tomoyo_profile *tomoyo_assign_profile
330(struct tomoyo_policy_namespace *ns, const unsigned int profile)
291{ 331{
292 struct tomoyo_profile *ptr; 332 struct tomoyo_profile *ptr;
293 struct tomoyo_profile *entry; 333 struct tomoyo_profile *entry;
294 if (profile >= TOMOYO_MAX_PROFILES) 334 if (profile >= TOMOYO_MAX_PROFILES)
295 return NULL; 335 return NULL;
296 ptr = tomoyo_profile_ptr[profile]; 336 ptr = ns->profile_ptr[profile];
297 if (ptr) 337 if (ptr)
298 return ptr; 338 return ptr;
299 entry = kzalloc(sizeof(*entry), GFP_NOFS); 339 entry = kzalloc(sizeof(*entry), GFP_NOFS);
300 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 340 if (mutex_lock_interruptible(&tomoyo_policy_lock))
301 goto out; 341 goto out;
302 ptr = tomoyo_profile_ptr[profile]; 342 ptr = ns->profile_ptr[profile];
303 if (!ptr && tomoyo_memory_ok(entry)) { 343 if (!ptr && tomoyo_memory_ok(entry)) {
304 ptr = entry; 344 ptr = entry;
305 ptr->default_config = TOMOYO_CONFIG_DISABLED | 345 ptr->default_config = TOMOYO_CONFIG_DISABLED |
@@ -310,7 +350,7 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
310 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024; 350 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024;
311 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048; 351 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
312 mb(); /* Avoid out-of-order execution. */ 352 mb(); /* Avoid out-of-order execution. */
313 tomoyo_profile_ptr[profile] = ptr; 353 ns->profile_ptr[profile] = ptr;
314 entry = NULL; 354 entry = NULL;
315 } 355 }
316 mutex_unlock(&tomoyo_policy_lock); 356 mutex_unlock(&tomoyo_policy_lock);
@@ -322,14 +362,16 @@ static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
322/** 362/**
323 * tomoyo_profile - Find a profile. 363 * tomoyo_profile - Find a profile.
324 * 364 *
365 * @ns: Pointer to "struct tomoyo_policy_namespace".
325 * @profile: Profile number to find. 366 * @profile: Profile number to find.
326 * 367 *
327 * Returns pointer to "struct tomoyo_profile". 368 * Returns pointer to "struct tomoyo_profile".
328 */ 369 */
329struct tomoyo_profile *tomoyo_profile(const u8 profile) 370struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
371 const u8 profile)
330{ 372{
331 static struct tomoyo_profile tomoyo_null_profile; 373 static struct tomoyo_profile tomoyo_null_profile;
332 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile]; 374 struct tomoyo_profile *ptr = ns->profile_ptr[profile];
333 if (!ptr) 375 if (!ptr)
334 ptr = &tomoyo_null_profile; 376 ptr = &tomoyo_null_profile;
335 return ptr; 377 return ptr;
@@ -454,13 +496,14 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
454 unsigned int i; 496 unsigned int i;
455 char *cp; 497 char *cp;
456 struct tomoyo_profile *profile; 498 struct tomoyo_profile *profile;
457 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1) 499 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
500 == 1)
458 return 0; 501 return 0;
459 i = simple_strtoul(data, &cp, 10); 502 i = simple_strtoul(data, &cp, 10);
460 if (*cp != '-') 503 if (*cp != '-')
461 return -EINVAL; 504 return -EINVAL;
462 data = cp + 1; 505 data = cp + 1;
463 profile = tomoyo_assign_profile(i); 506 profile = tomoyo_assign_profile(head->w.ns, i);
464 if (!profile) 507 if (!profile)
465 return -EINVAL; 508 return -EINVAL;
466 cp = strchr(data, '='); 509 cp = strchr(data, '=');
@@ -518,19 +561,25 @@ static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
518static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 561static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
519{ 562{
520 u8 index; 563 u8 index;
564 struct tomoyo_policy_namespace *ns =
565 container_of(head->r.ns, typeof(*ns), namespace_list);
521 const struct tomoyo_profile *profile; 566 const struct tomoyo_profile *profile;
567 if (head->r.eof)
568 return;
522 next: 569 next:
523 index = head->r.index; 570 index = head->r.index;
524 profile = tomoyo_profile_ptr[index]; 571 profile = ns->profile_ptr[index];
525 switch (head->r.step) { 572 switch (head->r.step) {
526 case 0: 573 case 0:
527 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n", 20090903); 574 tomoyo_print_namespace(head);
575 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
576 ns->profile_version);
528 head->r.step++; 577 head->r.step++;
529 break; 578 break;
530 case 1: 579 case 1:
531 for ( ; head->r.index < TOMOYO_MAX_PROFILES; 580 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
532 head->r.index++) 581 head->r.index++)
533 if (tomoyo_profile_ptr[head->r.index]) 582 if (ns->profile_ptr[head->r.index])
534 break; 583 break;
535 if (head->r.index == TOMOYO_MAX_PROFILES) 584 if (head->r.index == TOMOYO_MAX_PROFILES)
536 return; 585 return;
@@ -541,6 +590,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
541 u8 i; 590 u8 i;
542 const struct tomoyo_path_info *comment = 591 const struct tomoyo_path_info *comment =
543 profile->comment; 592 profile->comment;
593 tomoyo_print_namespace(head);
544 tomoyo_io_printf(head, "%u-COMMENT=", index); 594 tomoyo_io_printf(head, "%u-COMMENT=", index);
545 tomoyo_set_string(head, comment ? comment->name : ""); 595 tomoyo_set_string(head, comment ? comment->name : "");
546 tomoyo_set_lf(head); 596 tomoyo_set_lf(head);
@@ -555,6 +605,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
555 break; 605 break;
556 case 3: 606 case 3:
557 { 607 {
608 tomoyo_print_namespace(head);
558 tomoyo_io_printf(head, "%u-%s", index, "CONFIG"); 609 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
559 tomoyo_print_config(head, profile->default_config); 610 tomoyo_print_config(head, profile->default_config);
560 head->r.bit = 0; 611 head->r.bit = 0;
@@ -568,6 +619,7 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
568 const u8 config = profile->config[i]; 619 const u8 config = profile->config[i];
569 if (config == TOMOYO_CONFIG_USE_DEFAULT) 620 if (config == TOMOYO_CONFIG_USE_DEFAULT)
570 continue; 621 continue;
622 tomoyo_print_namespace(head);
571 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::", 623 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::",
572 tomoyo_mac_keywords[i]); 624 tomoyo_mac_keywords[i]);
573 tomoyo_print_config(head, config); 625 tomoyo_print_config(head, config);
@@ -607,8 +659,10 @@ static int tomoyo_update_manager_entry(const char *manager,
607{ 659{
608 struct tomoyo_manager e = { }; 660 struct tomoyo_manager e = { };
609 struct tomoyo_acl_param param = { 661 struct tomoyo_acl_param param = {
662 /* .ns = &tomoyo_kernel_namespace, */
610 .is_delete = is_delete, 663 .is_delete = is_delete,
611 .list = &tomoyo_policy_list[TOMOYO_ID_MANAGER], 664 .list = &tomoyo_kernel_namespace.
665 policy_list[TOMOYO_ID_MANAGER],
612 }; 666 };
613 int error = is_delete ? -ENOENT : -ENOMEM; 667 int error = is_delete ? -ENOENT : -ENOMEM;
614 if (tomoyo_domain_def(manager)) { 668 if (tomoyo_domain_def(manager)) {
@@ -640,13 +694,12 @@ static int tomoyo_update_manager_entry(const char *manager,
640static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 694static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
641{ 695{
642 char *data = head->write_buf; 696 char *data = head->write_buf;
643 bool is_delete = tomoyo_str_starts(&data, "delete ");
644 697
645 if (!strcmp(data, "manage_by_non_root")) { 698 if (!strcmp(data, "manage_by_non_root")) {
646 tomoyo_manage_by_non_root = !is_delete; 699 tomoyo_manage_by_non_root = !head->w.is_delete;
647 return 0; 700 return 0;
648 } 701 }
649 return tomoyo_update_manager_entry(data, is_delete); 702 return tomoyo_update_manager_entry(data, head->w.is_delete);
650} 703}
651 704
652/** 705/**
@@ -660,8 +713,8 @@ static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
660{ 713{
661 if (head->r.eof) 714 if (head->r.eof)
662 return; 715 return;
663 list_for_each_cookie(head->r.acl, 716 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
664 &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { 717 policy_list[TOMOYO_ID_MANAGER]) {
665 struct tomoyo_manager *ptr = 718 struct tomoyo_manager *ptr =
666 list_entry(head->r.acl, typeof(*ptr), head.list); 719 list_entry(head->r.acl, typeof(*ptr), head.list);
667 if (ptr->head.is_deleted) 720 if (ptr->head.is_deleted)
@@ -694,8 +747,8 @@ static bool tomoyo_manager(void)
694 return true; 747 return true;
695 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 748 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
696 return false; 749 return false;
697 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 750 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
698 head.list) { 751 policy_list[TOMOYO_ID_MANAGER], head.list) {
699 if (!ptr->head.is_deleted && ptr->is_domain 752 if (!ptr->head.is_deleted && ptr->is_domain
700 && !tomoyo_pathcmp(domainname, ptr->manager)) { 753 && !tomoyo_pathcmp(domainname, ptr->manager)) {
701 found = true; 754 found = true;
@@ -707,8 +760,8 @@ static bool tomoyo_manager(void)
707 exe = tomoyo_get_exe(); 760 exe = tomoyo_get_exe();
708 if (!exe) 761 if (!exe)
709 return false; 762 return false;
710 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER], 763 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
711 head.list) { 764 policy_list[TOMOYO_ID_MANAGER], head.list) {
712 if (!ptr->head.is_deleted && !ptr->is_domain 765 if (!ptr->head.is_deleted && !ptr->is_domain
713 && !strcmp(exe, ptr->manager->name)) { 766 && !strcmp(exe, ptr->manager->name)) {
714 found = true; 767 found = true;
@@ -729,7 +782,7 @@ static bool tomoyo_manager(void)
729} 782}
730 783
731/** 784/**
732 * tomoyo_select_one - Parse select command. 785 * tomoyo_select_domain - Parse select command.
733 * 786 *
734 * @head: Pointer to "struct tomoyo_io_buffer". 787 * @head: Pointer to "struct tomoyo_io_buffer".
735 * @data: String to parse. 788 * @data: String to parse.
@@ -738,16 +791,15 @@ static bool tomoyo_manager(void)
738 * 791 *
739 * Caller holds tomoyo_read_lock(). 792 * Caller holds tomoyo_read_lock().
740 */ 793 */
741static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data) 794static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
795 const char *data)
742{ 796{
743 unsigned int pid; 797 unsigned int pid;
744 struct tomoyo_domain_info *domain = NULL; 798 struct tomoyo_domain_info *domain = NULL;
745 bool global_pid = false; 799 bool global_pid = false;
746 800 if (strncmp(data, "select ", 7))
747 if (!strcmp(data, "allow_execute")) { 801 return false;
748 head->r.print_execute_only = true; 802 data += 7;
749 return true;
750 }
751 if (sscanf(data, "pid=%u", &pid) == 1 || 803 if (sscanf(data, "pid=%u", &pid) == 1 ||
752 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 804 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
753 struct task_struct *p; 805 struct task_struct *p;
@@ -818,6 +870,7 @@ static int tomoyo_delete_domain(char *domainname)
818/** 870/**
819 * tomoyo_write_domain2 - Write domain policy. 871 * tomoyo_write_domain2 - Write domain policy.
820 * 872 *
873 * @ns: Pointer to "struct tomoyo_policy_namespace".
821 * @list: Pointer to "struct list_head". 874 * @list: Pointer to "struct list_head".
822 * @data: Policy to be interpreted. 875 * @data: Policy to be interpreted.
823 * @is_delete: True if it is a delete request. 876 * @is_delete: True if it is a delete request.
@@ -826,10 +879,12 @@ static int tomoyo_delete_domain(char *domainname)
826 * 879 *
827 * Caller holds tomoyo_read_lock(). 880 * Caller holds tomoyo_read_lock().
828 */ 881 */
829static int tomoyo_write_domain2(struct list_head *list, char *data, 882static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
883 struct list_head *list, char *data,
830 const bool is_delete) 884 const bool is_delete)
831{ 885{
832 struct tomoyo_acl_param param = { 886 struct tomoyo_acl_param param = {
887 .ns = ns,
833 .list = list, 888 .list = list,
834 .data = data, 889 .data = data,
835 .is_delete = is_delete, 890 .is_delete = is_delete,
@@ -862,37 +917,28 @@ static int tomoyo_write_domain2(struct list_head *list, char *data,
862static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 917static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
863{ 918{
864 char *data = head->write_buf; 919 char *data = head->write_buf;
920 struct tomoyo_policy_namespace *ns;
865 struct tomoyo_domain_info *domain = head->w.domain; 921 struct tomoyo_domain_info *domain = head->w.domain;
866 bool is_delete = false; 922 const bool is_delete = head->w.is_delete;
867 bool is_select = false; 923 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
868 unsigned int profile; 924 unsigned int profile;
869 925 if (*data == '<') {
870 if (tomoyo_str_starts(&data, "delete "))
871 is_delete = true;
872 else if (tomoyo_str_starts(&data, "select "))
873 is_select = true;
874 if (is_select && tomoyo_select_one(head, data))
875 return 0;
876 /* Don't allow updating policies by non manager programs. */
877 if (!tomoyo_manager())
878 return -EPERM;
879 if (tomoyo_domain_def(data)) {
880 domain = NULL; 926 domain = NULL;
881 if (is_delete) 927 if (is_delete)
882 tomoyo_delete_domain(data); 928 tomoyo_delete_domain(data);
883 else if (is_select) 929 else if (is_select)
884 domain = tomoyo_find_domain(data); 930 domain = tomoyo_find_domain(data);
885 else 931 else
886 domain = tomoyo_assign_domain(data, 0); 932 domain = tomoyo_assign_domain(data, false);
887 head->w.domain = domain; 933 head->w.domain = domain;
888 return 0; 934 return 0;
889 } 935 }
890 if (!domain) 936 if (!domain)
891 return -EINVAL; 937 return -EINVAL;
892 938 ns = domain->ns;
893 if (sscanf(data, "use_profile %u", &profile) == 1 939 if (sscanf(data, "use_profile %u", &profile) == 1
894 && profile < TOMOYO_MAX_PROFILES) { 940 && profile < TOMOYO_MAX_PROFILES) {
895 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 941 if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
896 domain->profile = (u8) profile; 942 domain->profile = (u8) profile;
897 return 0; 943 return 0;
898 } 944 }
@@ -910,7 +956,8 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
910 domain->transition_failed = !is_delete; 956 domain->transition_failed = !is_delete;
911 return 0; 957 return 0;
912 } 958 }
913 return tomoyo_write_domain2(&domain->acl_info_list, data, is_delete); 959 return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
960 is_delete);
914} 961}
915 962
916/** 963/**
@@ -924,9 +971,11 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
924static void tomoyo_set_group(struct tomoyo_io_buffer *head, 971static void tomoyo_set_group(struct tomoyo_io_buffer *head,
925 const char *category) 972 const char *category)
926{ 973{
927 if (head->type == TOMOYO_EXCEPTIONPOLICY) 974 if (head->type == TOMOYO_EXCEPTIONPOLICY) {
975 tomoyo_print_namespace(head);
928 tomoyo_io_printf(head, "acl_group %u ", 976 tomoyo_io_printf(head, "acl_group %u ",
929 head->r.acl_group_index); 977 head->r.acl_group_index);
978 }
930 tomoyo_set_string(head, category); 979 tomoyo_set_string(head, category);
931} 980}
932 981
@@ -956,7 +1005,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
956 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 1005 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
957 if (!(perm & (1 << bit))) 1006 if (!(perm & (1 << bit)))
958 continue; 1007 continue;
959 if (head->r.print_execute_only && 1008 if (head->r.print_transition_related_only &&
960 bit != TOMOYO_TYPE_EXECUTE) 1009 bit != TOMOYO_TYPE_EXECUTE)
961 continue; 1010 continue;
962 if (first) { 1011 if (first) {
@@ -970,7 +1019,7 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
970 if (first) 1019 if (first)
971 return true; 1020 return true;
972 tomoyo_print_name_union(head, &ptr->name); 1021 tomoyo_print_name_union(head, &ptr->name);
973 } else if (head->r.print_execute_only) { 1022 } else if (head->r.print_transition_related_only) {
974 return true; 1023 return true;
975 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1024 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
976 struct tomoyo_path2_acl *ptr = 1025 struct tomoyo_path2_acl *ptr =
@@ -1147,8 +1196,8 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1147 domain = tomoyo_find_domain(cp + 1); 1196 domain = tomoyo_find_domain(cp + 1);
1148 if (strict_strtoul(data, 10, &profile)) 1197 if (strict_strtoul(data, 10, &profile))
1149 return -EINVAL; 1198 return -EINVAL;
1150 if (domain && profile < TOMOYO_MAX_PROFILES 1199 if (domain && (!tomoyo_policy_loaded ||
1151 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)) 1200 head->w.ns->profile_ptr[(u8) profile]))
1152 domain->profile = (u8) profile; 1201 domain->profile = (u8) profile;
1153 return 0; 1202 return 0;
1154} 1203}
@@ -1246,10 +1295,12 @@ static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1246} 1295}
1247 1296
1248static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1297static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1249 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain", 1298 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
1250 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain", 1299 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
1251 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain", 1300 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1252 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain", 1301 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
1302 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
1303 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ",
1253}; 1304};
1254 1305
1255static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1306static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
@@ -1268,19 +1319,13 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1268 */ 1319 */
1269static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1320static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1270{ 1321{
1322 const bool is_delete = head->w.is_delete;
1271 struct tomoyo_acl_param param = { 1323 struct tomoyo_acl_param param = {
1324 .ns = head->w.ns,
1325 .is_delete = is_delete,
1272 .data = head->write_buf, 1326 .data = head->write_buf,
1273 }; 1327 };
1274 u8 i; 1328 u8 i;
1275 param.is_delete = tomoyo_str_starts(&param.data, "delete ");
1276 if (!param.is_delete && tomoyo_str_starts(&param.data, "select ") &&
1277 !strcmp(param.data, "execute_only")) {
1278 head->r.print_execute_only = true;
1279 return 0;
1280 }
1281 /* Don't allow updating policies by non manager programs. */
1282 if (!tomoyo_manager())
1283 return -EPERM;
1284 if (tomoyo_str_starts(&param.data, "aggregator ")) 1329 if (tomoyo_str_starts(&param.data, "aggregator "))
1285 return tomoyo_write_aggregator(&param); 1330 return tomoyo_write_aggregator(&param);
1286 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1331 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
@@ -1294,8 +1339,9 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1294 char *data; 1339 char *data;
1295 group = simple_strtoul(param.data, &data, 10); 1340 group = simple_strtoul(param.data, &data, 10);
1296 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') 1341 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1297 return tomoyo_write_domain2(&tomoyo_acl_group[group], 1342 return tomoyo_write_domain2
1298 data, param.is_delete); 1343 (head->w.ns, &head->w.ns->acl_group[group],
1344 data, is_delete);
1299 } 1345 }
1300 return -EINVAL; 1346 return -EINVAL;
1301} 1347}
@@ -1312,7 +1358,10 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1312 */ 1358 */
1313static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1359static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1314{ 1360{
1315 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) { 1361 struct tomoyo_policy_namespace *ns =
1362 container_of(head->r.ns, typeof(*ns), namespace_list);
1363 struct list_head *list = &ns->group_list[idx];
1364 list_for_each_cookie(head->r.group, list) {
1316 struct tomoyo_group *group = 1365 struct tomoyo_group *group =
1317 list_entry(head->r.group, typeof(*group), head.list); 1366 list_entry(head->r.group, typeof(*group), head.list);
1318 list_for_each_cookie(head->r.acl, &group->member_list) { 1367 list_for_each_cookie(head->r.acl, &group->member_list) {
@@ -1322,6 +1371,7 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1322 continue; 1371 continue;
1323 if (!tomoyo_flush(head)) 1372 if (!tomoyo_flush(head))
1324 return false; 1373 return false;
1374 tomoyo_print_namespace(head);
1325 tomoyo_set_string(head, tomoyo_group_name[idx]); 1375 tomoyo_set_string(head, tomoyo_group_name[idx]);
1326 tomoyo_set_string(head, group->group_name->name); 1376 tomoyo_set_string(head, group->group_name->name);
1327 if (idx == TOMOYO_PATH_GROUP) { 1377 if (idx == TOMOYO_PATH_GROUP) {
@@ -1355,7 +1405,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1355 */ 1405 */
1356static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1406static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1357{ 1407{
1358 list_for_each_cookie(head->r.acl, &tomoyo_policy_list[idx]) { 1408 struct tomoyo_policy_namespace *ns =
1409 container_of(head->r.ns, typeof(*ns), namespace_list);
1410 struct list_head *list = &ns->policy_list[idx];
1411 list_for_each_cookie(head->r.acl, list) {
1359 struct tomoyo_acl_head *acl = 1412 struct tomoyo_acl_head *acl =
1360 container_of(head->r.acl, typeof(*acl), list); 1413 container_of(head->r.acl, typeof(*acl), list);
1361 if (acl->is_deleted) 1414 if (acl->is_deleted)
@@ -1367,6 +1420,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1367 { 1420 {
1368 struct tomoyo_transition_control *ptr = 1421 struct tomoyo_transition_control *ptr =
1369 container_of(acl, typeof(*ptr), head); 1422 container_of(acl, typeof(*ptr), head);
1423 tomoyo_print_namespace(head);
1370 tomoyo_set_string(head, tomoyo_transition_type 1424 tomoyo_set_string(head, tomoyo_transition_type
1371 [ptr->type]); 1425 [ptr->type]);
1372 tomoyo_set_string(head, ptr->program ? 1426 tomoyo_set_string(head, ptr->program ?
@@ -1381,6 +1435,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1381 { 1435 {
1382 struct tomoyo_aggregator *ptr = 1436 struct tomoyo_aggregator *ptr =
1383 container_of(acl, typeof(*ptr), head); 1437 container_of(acl, typeof(*ptr), head);
1438 tomoyo_print_namespace(head);
1384 tomoyo_set_string(head, "aggregator "); 1439 tomoyo_set_string(head, "aggregator ");
1385 tomoyo_set_string(head, 1440 tomoyo_set_string(head,
1386 ptr->original_name->name); 1441 ptr->original_name->name);
@@ -1407,6 +1462,8 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1407 */ 1462 */
1408static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1463static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1409{ 1464{
1465 struct tomoyo_policy_namespace *ns =
1466 container_of(head->r.ns, typeof(*ns), namespace_list);
1410 if (head->r.eof) 1467 if (head->r.eof)
1411 return; 1468 return;
1412 while (head->r.step < TOMOYO_MAX_POLICY && 1469 while (head->r.step < TOMOYO_MAX_POLICY &&
@@ -1423,7 +1480,7 @@ static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1423 + TOMOYO_MAX_ACL_GROUPS) { 1480 + TOMOYO_MAX_ACL_GROUPS) {
1424 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY 1481 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1425 - TOMOYO_MAX_GROUP; 1482 - TOMOYO_MAX_GROUP;
1426 if (!tomoyo_read_domain2(head, &tomoyo_acl_group 1483 if (!tomoyo_read_domain2(head, &ns->acl_group
1427 [head->r.acl_group_index])) 1484 [head->r.acl_group_index]))
1428 return; 1485 return;
1429 head->r.step++; 1486 head->r.step++;
@@ -1484,7 +1541,8 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1484 return; 1541 return;
1485 snprintf(buffer, len - 1, "%s", cp); 1542 snprintf(buffer, len - 1, "%s", cp);
1486 tomoyo_normalize_line(buffer); 1543 tomoyo_normalize_line(buffer);
1487 tomoyo_write_domain2(&domain->acl_info_list, buffer, false); 1544 tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1545 false);
1488 kfree(buffer); 1546 kfree(buffer);
1489} 1547}
1490 1548
@@ -1896,6 +1954,45 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1896} 1954}
1897 1955
1898/** 1956/**
1957 * tomoyo_set_namespace_cursor - Set namespace to read.
1958 *
1959 * @head: Pointer to "struct tomoyo_io_buffer".
1960 *
1961 * Returns nothing.
1962 */
1963static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
1964{
1965 struct list_head *ns;
1966 if (head->type != TOMOYO_EXCEPTIONPOLICY &&
1967 head->type != TOMOYO_PROFILE)
1968 return;
1969 /*
1970 * If this is the first read, or reading previous namespace finished
1971 * and has more namespaces to read, update the namespace cursor.
1972 */
1973 ns = head->r.ns;
1974 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
1975 /* Clearing is OK because tomoyo_flush() returned true. */
1976 memset(&head->r, 0, sizeof(head->r));
1977 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
1978 }
1979}
1980
1981/**
1982 * tomoyo_has_more_namespace - Check for unread namespaces.
1983 *
1984 * @head: Pointer to "struct tomoyo_io_buffer".
1985 *
1986 * Returns true if we have more entries to print, false otherwise.
1987 */
1988static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
1989{
1990 return (head->type == TOMOYO_EXCEPTIONPOLICY ||
1991 head->type == TOMOYO_PROFILE) && head->r.eof &&
1992 head->r.ns->next != &tomoyo_namespace_list;
1993}
1994
1995/**
1899 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 1996 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1900 * 1997 *
1901 * @head: Pointer to "struct tomoyo_io_buffer". 1998 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1919,14 +2016,54 @@ int tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
1919 head->read_user_buf_avail = buffer_len; 2016 head->read_user_buf_avail = buffer_len;
1920 if (tomoyo_flush(head)) 2017 if (tomoyo_flush(head))
1921 /* Call the policy handler. */ 2018 /* Call the policy handler. */
1922 head->read(head); 2019 do {
1923 tomoyo_flush(head); 2020 tomoyo_set_namespace_cursor(head);
2021 head->read(head);
2022 } while (tomoyo_flush(head) &&
2023 tomoyo_has_more_namespace(head));
1924 len = head->read_user_buf - buffer; 2024 len = head->read_user_buf - buffer;
1925 mutex_unlock(&head->io_sem); 2025 mutex_unlock(&head->io_sem);
1926 return len; 2026 return len;
1927} 2027}
1928 2028
1929/** 2029/**
2030 * tomoyo_parse_policy - Parse a policy line.
2031 *
2032 * @head: Poiter to "struct tomoyo_io_buffer".
2033 * @line: Line to parse.
2034 *
2035 * Returns 0 on success, negative value otherwise.
2036 *
2037 * Caller holds tomoyo_read_lock().
2038 */
2039static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2040{
2041 /* Delete request? */
2042 head->w.is_delete = !strncmp(line, "delete ", 7);
2043 if (head->w.is_delete)
2044 memmove(line, line + 7, strlen(line + 7) + 1);
2045 /* Selecting namespace to update. */
2046 if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2047 head->type == TOMOYO_PROFILE) {
2048 if (*line == '<') {
2049 char *cp = strchr(line, ' ');
2050 if (cp) {
2051 *cp++ = '\0';
2052 head->w.ns = tomoyo_assign_namespace(line);
2053 memmove(line, cp, strlen(cp) + 1);
2054 } else
2055 head->w.ns = NULL;
2056 } else
2057 head->w.ns = &tomoyo_kernel_namespace;
2058 /* Don't allow updating if namespace is invalid. */
2059 if (!head->w.ns)
2060 return -ENOENT;
2061 }
2062 /* Do the update. */
2063 return head->write(head);
2064}
2065
2066/**
1930 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2067 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1931 * 2068 *
1932 * @head: Pointer to "struct tomoyo_io_buffer". 2069 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1941,27 +2078,31 @@ int tomoyo_write_control(struct tomoyo_io_buffer *head,
1941 const char __user *buffer, const int buffer_len) 2078 const char __user *buffer, const int buffer_len)
1942{ 2079{
1943 int error = buffer_len; 2080 int error = buffer_len;
1944 int avail_len = buffer_len; 2081 size_t avail_len = buffer_len;
1945 char *cp0 = head->write_buf; 2082 char *cp0 = head->write_buf;
1946
1947 if (!head->write) 2083 if (!head->write)
1948 return -ENOSYS; 2084 return -ENOSYS;
1949 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2085 if (!access_ok(VERIFY_READ, buffer, buffer_len))
1950 return -EFAULT; 2086 return -EFAULT;
1951 /* Don't allow updating policies by non manager programs. */
1952 if (head->write != tomoyo_write_pid &&
1953 head->write != tomoyo_write_domain &&
1954 head->write != tomoyo_write_exception && !tomoyo_manager())
1955 return -EPERM;
1956 if (mutex_lock_interruptible(&head->io_sem)) 2087 if (mutex_lock_interruptible(&head->io_sem))
1957 return -EINTR; 2088 return -EINTR;
1958 /* Read a line and dispatch it to the policy handler. */ 2089 /* Read a line and dispatch it to the policy handler. */
1959 while (avail_len > 0) { 2090 while (avail_len > 0) {
1960 char c; 2091 char c;
1961 if (head->w.avail >= head->writebuf_size - 1) { 2092 if (head->w.avail >= head->writebuf_size - 1) {
1962 error = -ENOMEM; 2093 const int len = head->writebuf_size * 2;
1963 break; 2094 char *cp = kzalloc(len, GFP_NOFS);
1964 } else if (get_user(c, buffer)) { 2095 if (!cp) {
2096 error = -ENOMEM;
2097 break;
2098 }
2099 memmove(cp, cp0, head->w.avail);
2100 kfree(cp0);
2101 head->write_buf = cp;
2102 cp0 = cp;
2103 head->writebuf_size = len;
2104 }
2105 if (get_user(c, buffer)) {
1965 error = -EFAULT; 2106 error = -EFAULT;
1966 break; 2107 break;
1967 } 2108 }
@@ -1973,8 +2114,40 @@ int tomoyo_write_control(struct tomoyo_io_buffer *head,
1973 cp0[head->w.avail - 1] = '\0'; 2114 cp0[head->w.avail - 1] = '\0';
1974 head->w.avail = 0; 2115 head->w.avail = 0;
1975 tomoyo_normalize_line(cp0); 2116 tomoyo_normalize_line(cp0);
1976 head->write(head); 2117 if (!strcmp(cp0, "reset")) {
2118 head->w.ns = &tomoyo_kernel_namespace;
2119 head->w.domain = NULL;
2120 memset(&head->r, 0, sizeof(head->r));
2121 continue;
2122 }
2123 /* Don't allow updating policies by non manager programs. */
2124 switch (head->type) {
2125 case TOMOYO_PROCESS_STATUS:
2126 /* This does not write anything. */
2127 break;
2128 case TOMOYO_DOMAINPOLICY:
2129 if (tomoyo_select_domain(head, cp0))
2130 continue;
2131 /* fall through */
2132 case TOMOYO_EXCEPTIONPOLICY:
2133 if (!strcmp(cp0, "select transition_only")) {
2134 head->r.print_transition_related_only = true;
2135 continue;
2136 }
2137 /* fall through */
2138 default:
2139 if (!tomoyo_manager()) {
2140 error = -EPERM;
2141 goto out;
2142 }
2143 }
2144 switch (tomoyo_parse_policy(head, cp0)) {
2145 case -EPERM:
2146 error = -EPERM;
2147 goto out;
2148 }
1977 } 2149 }
2150out:
1978 mutex_unlock(&head->io_sem); 2151 mutex_unlock(&head->io_sem);
1979 return error; 2152 return error;
1980} 2153}
@@ -2019,27 +2192,27 @@ void tomoyo_check_profile(void)
2019 struct tomoyo_domain_info *domain; 2192 struct tomoyo_domain_info *domain;
2020 const int idx = tomoyo_read_lock(); 2193 const int idx = tomoyo_read_lock();
2021 tomoyo_policy_loaded = true; 2194 tomoyo_policy_loaded = true;
2022 /* Check all profiles currently assigned to domains are defined. */ 2195 printk(KERN_INFO "TOMOYO: 2.4.0\n");
2023 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2196 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2024 const u8 profile = domain->profile; 2197 const u8 profile = domain->profile;
2025 if (tomoyo_profile_ptr[profile]) 2198 const struct tomoyo_policy_namespace *ns = domain->ns;
2199 if (ns->profile_version != 20100903)
2200 printk(KERN_ERR
2201 "Profile version %u is not supported.\n",
2202 ns->profile_version);
2203 else if (!ns->profile_ptr[profile])
2204 printk(KERN_ERR
2205 "Profile %u (used by '%s') is not defined.\n",
2206 profile, domain->domainname->name);
2207 else
2026 continue; 2208 continue;
2027 printk(KERN_ERR "You need to define profile %u before using it.\n", 2209 printk(KERN_ERR
2028 profile); 2210 "Userland tools for TOMOYO 2.4 must be installed and "
2029 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ " 2211 "policy must be initialized.\n");
2212 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ "
2030 "for more information.\n"); 2213 "for more information.\n");
2031 panic("Profile %u (used by '%s') not defined.\n", 2214 panic("STOP!");
2032 profile, domain->domainname->name);
2033 } 2215 }
2034 tomoyo_read_unlock(idx); 2216 tomoyo_read_unlock(idx);
2035 if (tomoyo_profile_version != 20090903) {
2036 printk(KERN_ERR "You need to install userland programs for "
2037 "TOMOYO 2.3 and initialize policy configuration.\n");
2038 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ "
2039 "for more information.\n");
2040 panic("Profile version %u is not supported.\n",
2041 tomoyo_profile_version);
2042 }
2043 printk(KERN_INFO "TOMOYO: 2.3.0\n");
2044 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2217 printk(KERN_INFO "Mandatory Access Control activated.\n");
2045} 2218}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 4bc3975516cb..53c8798e38b7 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -74,10 +74,6 @@ enum tomoyo_group_id {
74 TOMOYO_MAX_GROUP 74 TOMOYO_MAX_GROUP
75}; 75};
76 76
77/* A domain definition starts with <kernel>. */
78#define TOMOYO_ROOT_NAME "<kernel>"
79#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
80
81/* Index numbers for type of numeric values. */ 77/* Index numbers for type of numeric values. */
82enum tomoyo_value_type { 78enum tomoyo_value_type {
83 TOMOYO_VALUE_TYPE_INVALID, 79 TOMOYO_VALUE_TYPE_INVALID,
@@ -89,6 +85,8 @@ enum tomoyo_value_type {
89/* Index numbers for domain transition control keywords. */ 85/* Index numbers for domain transition control keywords. */
90enum tomoyo_transition_type { 86enum tomoyo_transition_type {
91 /* Do not change this order, */ 87 /* Do not change this order, */
88 TOMOYO_TRANSITION_CONTROL_NO_RESET,
89 TOMOYO_TRANSITION_CONTROL_RESET,
92 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE, 90 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
93 TOMOYO_TRANSITION_CONTROL_INITIALIZE, 91 TOMOYO_TRANSITION_CONTROL_INITIALIZE,
94 TOMOYO_TRANSITION_CONTROL_NO_KEEP, 92 TOMOYO_TRANSITION_CONTROL_NO_KEEP,
@@ -246,6 +244,8 @@ struct tomoyo_shared_acl_head {
246 atomic_t users; 244 atomic_t users;
247} __packed; 245} __packed;
248 246
247struct tomoyo_policy_namespace;
248
249/* Structure for request info. */ 249/* Structure for request info. */
250struct tomoyo_request_info { 250struct tomoyo_request_info {
251 struct tomoyo_domain_info *domain; 251 struct tomoyo_domain_info *domain;
@@ -359,6 +359,8 @@ struct tomoyo_domain_info {
359 struct list_head acl_info_list; 359 struct list_head acl_info_list;
360 /* Name of this domain. Never NULL. */ 360 /* Name of this domain. Never NULL. */
361 const struct tomoyo_path_info *domainname; 361 const struct tomoyo_path_info *domainname;
362 /* Namespace for this domain. Never NULL. */
363 struct tomoyo_policy_namespace *ns;
362 u8 profile; /* Profile number to use. */ 364 u8 profile; /* Profile number to use. */
363 u8 group; /* Group number to use. */ 365 u8 group; /* Group number to use. */
364 bool is_deleted; /* Delete flag. */ 366 bool is_deleted; /* Delete flag. */
@@ -423,6 +425,7 @@ struct tomoyo_mount_acl {
423struct tomoyo_acl_param { 425struct tomoyo_acl_param {
424 char *data; 426 char *data;
425 struct list_head *list; 427 struct list_head *list;
428 struct tomoyo_policy_namespace *ns;
426 bool is_delete; 429 bool is_delete;
427}; 430};
428 431
@@ -443,6 +446,7 @@ struct tomoyo_io_buffer {
443 char __user *read_user_buf; 446 char __user *read_user_buf;
444 int read_user_buf_avail; 447 int read_user_buf_avail;
445 struct { 448 struct {
449 struct list_head *ns;
446 struct list_head *domain; 450 struct list_head *domain;
447 struct list_head *group; 451 struct list_head *group;
448 struct list_head *acl; 452 struct list_head *acl;
@@ -455,14 +459,16 @@ struct tomoyo_io_buffer {
455 u8 w_pos; 459 u8 w_pos;
456 bool eof; 460 bool eof;
457 bool print_this_domain_only; 461 bool print_this_domain_only;
458 bool print_execute_only; 462 bool print_transition_related_only;
459 const char *w[TOMOYO_MAX_IO_READ_QUEUE]; 463 const char *w[TOMOYO_MAX_IO_READ_QUEUE];
460 } r; 464 } r;
461 struct { 465 struct {
466 struct tomoyo_policy_namespace *ns;
462 /* The position currently writing to. */ 467 /* The position currently writing to. */
463 struct tomoyo_domain_info *domain; 468 struct tomoyo_domain_info *domain;
464 /* Bytes available for writing. */ 469 /* Bytes available for writing. */
465 int avail; 470 int avail;
471 bool is_delete;
466 } w; 472 } w;
467 /* Buffer for reading. */ 473 /* Buffer for reading. */
468 char *read_buf; 474 char *read_buf;
@@ -533,8 +539,27 @@ struct tomoyo_time {
533 u8 sec; 539 u8 sec;
534}; 540};
535 541
542/* Structure for policy namespace. */
543struct tomoyo_policy_namespace {
544 /* Profile table. Memory is allocated as needed. */
545 struct tomoyo_profile *profile_ptr[TOMOYO_MAX_PROFILES];
546 /* List of "struct tomoyo_group". */
547 struct list_head group_list[TOMOYO_MAX_GROUP];
548 /* List of policy. */
549 struct list_head policy_list[TOMOYO_MAX_POLICY];
550 /* The global ACL referred by "use_group" keyword. */
551 struct list_head acl_group[TOMOYO_MAX_ACL_GROUPS];
552 /* List for connecting to tomoyo_namespace_list list. */
553 struct list_head namespace_list;
554 /* Profile version. Currently only 20100903 is defined. */
555 unsigned int profile_version;
556 /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
557 const char *name;
558};
559
536/********** Function prototypes. **********/ 560/********** Function prototypes. **********/
537 561
562void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
538bool tomoyo_str_starts(char **src, const char *find); 563bool tomoyo_str_starts(char **src, const char *find);
539const char *tomoyo_get_exe(void); 564const char *tomoyo_get_exe(void);
540void tomoyo_normalize_line(unsigned char *buffer); 565void tomoyo_normalize_line(unsigned char *buffer);
@@ -553,7 +578,8 @@ tomoyo_compare_name_union(const struct tomoyo_path_info *name,
553 const struct tomoyo_name_union *ptr); 578 const struct tomoyo_name_union *ptr);
554bool tomoyo_compare_number_union(const unsigned long value, 579bool tomoyo_compare_number_union(const unsigned long value,
555 const struct tomoyo_number_union *ptr); 580 const struct tomoyo_number_union *ptr);
556int tomoyo_get_mode(const u8 profile, const u8 index); 581int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
582 const u8 index);
557void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 583void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
558 __attribute__ ((format(printf, 2, 3))); 584 __attribute__ ((format(printf, 2, 3)));
559bool tomoyo_correct_domain(const unsigned char *domainname); 585bool tomoyo_correct_domain(const unsigned char *domainname);
@@ -589,8 +615,11 @@ int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
589 __attribute__ ((format(printf, 2, 3))); 615 __attribute__ ((format(printf, 2, 3)));
590struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname); 616struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
591struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 617struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
592 const u8 profile); 618 const bool transit);
593struct tomoyo_profile *tomoyo_profile(const u8 profile); 619struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
620 const u8 profile);
621struct tomoyo_policy_namespace *tomoyo_assign_namespace
622(const char *domainname);
594struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param, 623struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
595 const u8 idx); 624 const u8 idx);
596unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 625unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
@@ -646,6 +675,8 @@ char *tomoyo_read_token(struct tomoyo_acl_param *param);
646bool tomoyo_permstr(const char *string, const char *keyword); 675bool tomoyo_permstr(const char *string, const char *keyword);
647 676
648const char *tomoyo_yesno(const unsigned int value); 677const char *tomoyo_yesno(const unsigned int value);
678void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
679 __attribute__ ((format(printf, 2, 3)));
649void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, 680void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
650 va_list args); 681 va_list args);
651void tomoyo_read_log(struct tomoyo_io_buffer *head); 682void tomoyo_read_log(struct tomoyo_io_buffer *head);
@@ -661,8 +692,6 @@ extern struct srcu_struct tomoyo_ss;
661/* The list for "struct tomoyo_domain_info". */ 692/* The list for "struct tomoyo_domain_info". */
662extern struct list_head tomoyo_domain_list; 693extern struct list_head tomoyo_domain_list;
663 694
664extern struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
665extern struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
666extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 695extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
667 696
668/* Lock for protecting policy. */ 697/* Lock for protecting policy. */
@@ -671,10 +700,10 @@ extern struct mutex tomoyo_policy_lock;
671/* Has /sbin/init started? */ 700/* Has /sbin/init started? */
672extern bool tomoyo_policy_loaded; 701extern bool tomoyo_policy_loaded;
673 702
674extern struct list_head tomoyo_acl_group[TOMOYO_MAX_ACL_GROUPS];
675
676/* The kernel's domain. */ 703/* The kernel's domain. */
677extern struct tomoyo_domain_info tomoyo_kernel_domain; 704extern struct tomoyo_domain_info tomoyo_kernel_domain;
705extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
706extern struct list_head tomoyo_namespace_list;
678 707
679extern const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION]; 708extern const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
680extern const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION]; 709extern const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION];
@@ -809,6 +838,16 @@ static inline bool tomoyo_same_number_union
809 a->value_type[1] == b->value_type[1]; 838 a->value_type[1] == b->value_type[1];
810} 839}
811 840
841/**
842 * tomoyo_current_namespace - Get "struct tomoyo_policy_namespace" for current thread.
843 *
844 * Returns pointer to "struct tomoyo_policy_namespace" for current thread.
845 */
846static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
847{
848 return tomoyo_domain()->ns;
849}
850
812#if defined(CONFIG_SLOB) 851#if defined(CONFIG_SLOB)
813 852
814/** 853/**
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index af5f325e2f33..71acebc747c3 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -12,9 +12,6 @@
12 12
13/* Variables definitions.*/ 13/* Variables definitions.*/
14 14
15/* The global ACL referred by "use_group" keyword. */
16struct list_head tomoyo_acl_group[TOMOYO_MAX_ACL_GROUPS];
17
18/* The initial domain. */ 15/* The initial domain. */
19struct tomoyo_domain_info tomoyo_kernel_domain; 16struct tomoyo_domain_info tomoyo_kernel_domain;
20 17
@@ -158,7 +155,7 @@ retry:
158 } 155 }
159 if (!retried) { 156 if (!retried) {
160 retried = true; 157 retried = true;
161 list = &tomoyo_acl_group[domain->group]; 158 list = &domain->ns->acl_group[domain->group];
162 goto retry; 159 goto retry;
163 } 160 }
164 r->granted = false; 161 r->granted = false;
@@ -167,13 +164,10 @@ retry:
167/* The list for "struct tomoyo_domain_info". */ 164/* The list for "struct tomoyo_domain_info". */
168LIST_HEAD(tomoyo_domain_list); 165LIST_HEAD(tomoyo_domain_list);
169 166
170struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
171struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
172
173/** 167/**
174 * tomoyo_last_word - Get last component of a domainname. 168 * tomoyo_last_word - Get last component of a domainname.
175 * 169 *
176 * @domainname: Domainname to check. 170 * @name: Domainname to check.
177 * 171 *
178 * Returns the last word of @domainname. 172 * Returns the last word of @domainname.
179 */ 173 */
@@ -247,7 +241,7 @@ int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
247 if (!e.domainname) 241 if (!e.domainname)
248 goto out; 242 goto out;
249 } 243 }
250 param->list = &tomoyo_policy_list[TOMOYO_ID_TRANSITION_CONTROL]; 244 param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
251 error = tomoyo_update_policy(&e.head, sizeof(e), param, 245 error = tomoyo_update_policy(&e.head, sizeof(e), param,
252 tomoyo_same_transition_control); 246 tomoyo_same_transition_control);
253out: 247out:
@@ -257,59 +251,88 @@ out:
257} 251}
258 252
259/** 253/**
260 * tomoyo_transition_type - Get domain transition type. 254 * tomoyo_scan_transition - Try to find specific domain transition type.
261 * 255 *
262 * @domainname: The name of domain. 256 * @list: Pointer to "struct list_head".
263 * @program: The name of program. 257 * @domainname: The name of current domain.
258 * @program: The name of requested program.
259 * @last_name: The last component of @domainname.
260 * @type: One of values in "enum tomoyo_transition_type".
264 * 261 *
265 * Returns TOMOYO_TRANSITION_CONTROL_INITIALIZE if executing @program 262 * Returns true if found one, false otherwise.
266 * reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing
267 * @program suppresses domain transition, others otherwise.
268 * 263 *
269 * Caller holds tomoyo_read_lock(). 264 * Caller holds tomoyo_read_lock().
270 */ 265 */
271static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname, 266static inline bool tomoyo_scan_transition
272 const struct tomoyo_path_info *program) 267(const struct list_head *list, const struct tomoyo_path_info *domainname,
268 const struct tomoyo_path_info *program, const char *last_name,
269 const enum tomoyo_transition_type type)
273{ 270{
274 const struct tomoyo_transition_control *ptr; 271 const struct tomoyo_transition_control *ptr;
275 const char *last_name = tomoyo_last_word(domainname->name); 272 list_for_each_entry_rcu(ptr, list, head.list) {
276 u8 type; 273 if (ptr->head.is_deleted || ptr->type != type)
277 for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) { 274 continue;
278 next: 275 if (ptr->domainname) {
279 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 276 if (!ptr->is_last_name) {
280 [TOMOYO_ID_TRANSITION_CONTROL], 277 if (ptr->domainname != domainname)
281 head.list) { 278 continue;
282 if (ptr->head.is_deleted || ptr->type != type) 279 } else {
283 continue;
284 if (ptr->domainname) {
285 if (!ptr->is_last_name) {
286 if (ptr->domainname != domainname)
287 continue;
288 } else {
289 /*
290 * Use direct strcmp() since this is
291 * unlikely used.
292 */
293 if (strcmp(ptr->domainname->name,
294 last_name))
295 continue;
296 }
297 }
298 if (ptr->program &&
299 tomoyo_pathcmp(ptr->program, program))
300 continue;
301 if (type == TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) {
302 /* 280 /*
303 * Do not check for initialize_domain if 281 * Use direct strcmp() since this is
304 * no_initialize_domain matched. 282 * unlikely used.
305 */ 283 */
306 type = TOMOYO_TRANSITION_CONTROL_NO_KEEP; 284 if (strcmp(ptr->domainname->name, last_name))
307 goto next; 285 continue;
308 } 286 }
309 goto done;
310 } 287 }
288 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
289 continue;
290 return true;
291 }
292 return false;
293}
294
295/**
296 * tomoyo_transition_type - Get domain transition type.
297 *
298 * @ns: Pointer to "struct tomoyo_policy_namespace".
299 * @domainname: The name of current domain.
300 * @program: The name of requested program.
301 *
302 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes
303 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if
304 * executing @program reinitializes domain transition within that namespace,
305 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
306 * others otherwise.
307 *
308 * Caller holds tomoyo_read_lock().
309 */
310static enum tomoyo_transition_type tomoyo_transition_type
311(const struct tomoyo_policy_namespace *ns,
312 const struct tomoyo_path_info *domainname,
313 const struct tomoyo_path_info *program)
314{
315 const char *last_name = tomoyo_last_word(domainname->name);
316 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
317 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
318 const struct list_head * const list =
319 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
320 if (!tomoyo_scan_transition(list, domainname, program,
321 last_name, type)) {
322 type++;
323 continue;
324 }
325 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
326 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
327 break;
328 /*
329 * Do not check for reset_domain if no_reset_domain matched.
330 * Do not check for initialize_domain if no_initialize_domain
331 * matched.
332 */
333 type++;
334 type++;
311 } 335 }
312 done:
313 return type; 336 return type;
314} 337}
315 338
@@ -355,7 +378,7 @@ int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
355 if (!e.original_name || !e.aggregated_name || 378 if (!e.original_name || !e.aggregated_name ||
356 e.aggregated_name->is_patterned) /* No patterns allowed. */ 379 e.aggregated_name->is_patterned) /* No patterns allowed. */
357 goto out; 380 goto out;
358 param->list = &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR]; 381 param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
359 error = tomoyo_update_policy(&e.head, sizeof(e), param, 382 error = tomoyo_update_policy(&e.head, sizeof(e), param,
360 tomoyo_same_aggregator); 383 tomoyo_same_aggregator);
361out: 384out:
@@ -365,53 +388,171 @@ out:
365} 388}
366 389
367/** 390/**
368 * tomoyo_assign_domain - Create a domain. 391 * tomoyo_find_namespace - Find specified namespace.
369 * 392 *
370 * @domainname: The name of domain. 393 * @name: Name of namespace to find.
371 * @profile: Profile number to assign if the domain was newly created. 394 * @len: Length of @name.
372 * 395 *
373 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 396 * Returns pointer to "struct tomoyo_policy_namespace" if found,
397 * NULL otherwise.
374 * 398 *
375 * Caller holds tomoyo_read_lock(). 399 * Caller holds tomoyo_read_lock().
376 */ 400 */
377struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 401static struct tomoyo_policy_namespace *tomoyo_find_namespace
378 const u8 profile) 402(const char *name, const unsigned int len)
379{ 403{
380 struct tomoyo_domain_info *entry; 404 struct tomoyo_policy_namespace *ns;
381 struct tomoyo_domain_info *domain = NULL; 405 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
382 const struct tomoyo_path_info *saved_domainname; 406 if (strncmp(name, ns->name, len) ||
383 bool found = false; 407 (name[len] && name[len] != ' '))
408 continue;
409 return ns;
410 }
411 return NULL;
412}
384 413
385 if (!tomoyo_correct_domain(domainname)) 414/**
415 * tomoyo_assign_namespace - Create a new namespace.
416 *
417 * @domainname: Name of namespace to create.
418 *
419 * Returns pointer to "struct tomoyo_policy_namespace" on success,
420 * NULL otherwise.
421 *
422 * Caller holds tomoyo_read_lock().
423 */
424struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
425{
426 struct tomoyo_policy_namespace *ptr;
427 struct tomoyo_policy_namespace *entry;
428 const char *cp = domainname;
429 unsigned int len = 0;
430 while (*cp && *cp++ != ' ')
431 len++;
432 ptr = tomoyo_find_namespace(domainname, len);
433 if (ptr)
434 return ptr;
435 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
386 return NULL; 436 return NULL;
387 saved_domainname = tomoyo_get_name(domainname); 437 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
388 if (!saved_domainname) 438 if (!entry)
389 return NULL; 439 return NULL;
390 entry = kzalloc(sizeof(*entry), GFP_NOFS);
391 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 440 if (mutex_lock_interruptible(&tomoyo_policy_lock))
392 goto out; 441 goto out;
393 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 442 ptr = tomoyo_find_namespace(domainname, len);
394 if (domain->is_deleted || 443 if (!ptr && tomoyo_memory_ok(entry)) {
395 tomoyo_pathcmp(saved_domainname, domain->domainname)) 444 char *name = (char *) (entry + 1);
396 continue; 445 ptr = entry;
397 found = true; 446 memmove(name, domainname, len);
398 break; 447 name[len] = '\0';
399 } 448 entry->name = name;
400 if (!found && tomoyo_memory_ok(entry)) { 449 tomoyo_init_policy_namespace(entry);
401 INIT_LIST_HEAD(&entry->acl_info_list);
402 entry->domainname = saved_domainname;
403 saved_domainname = NULL;
404 entry->profile = profile;
405 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
406 domain = entry;
407 entry = NULL; 450 entry = NULL;
408 found = true;
409 } 451 }
410 mutex_unlock(&tomoyo_policy_lock); 452 mutex_unlock(&tomoyo_policy_lock);
411 out: 453out:
412 tomoyo_put_name(saved_domainname);
413 kfree(entry); 454 kfree(entry);
414 return found ? domain : NULL; 455 return ptr;
456}
457
458/**
459 * tomoyo_namespace_jump - Check for namespace jump.
460 *
461 * @domainname: Name of domain.
462 *
463 * Returns true if namespace differs, false otherwise.
464 */
465static bool tomoyo_namespace_jump(const char *domainname)
466{
467 const char *namespace = tomoyo_current_namespace()->name;
468 const int len = strlen(namespace);
469 return strncmp(domainname, namespace, len) ||
470 (domainname[len] && domainname[len] != ' ');
471}
472
473/**
474 * tomoyo_assign_domain - Create a domain or a namespace.
475 *
476 * @domainname: The name of domain.
477 * @transit: True if transit to domain found or created.
478 *
479 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
480 *
481 * Caller holds tomoyo_read_lock().
482 */
483struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
484 const bool transit)
485{
486 struct tomoyo_domain_info e = { };
487 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
488 bool created = false;
489 if (entry) {
490 if (transit) {
491 /*
492 * Since namespace is created at runtime, profiles may
493 * not be created by the moment the process transits to
494 * that domain. Do not perform domain transition if
495 * profile for that domain is not yet created.
496 */
497 if (!entry->ns->profile_ptr[entry->profile])
498 return NULL;
499 }
500 return entry;
501 }
502 /* Requested domain does not exist. */
503 /* Don't create requested domain if domainname is invalid. */
504 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
505 !tomoyo_correct_domain(domainname))
506 return NULL;
507 /*
508 * Since definition of profiles and acl_groups may differ across
509 * namespaces, do not inherit "use_profile" and "use_group" settings
510 * by automatically creating requested domain upon domain transition.
511 */
512 if (transit && tomoyo_namespace_jump(domainname))
513 return NULL;
514 e.ns = tomoyo_assign_namespace(domainname);
515 if (!e.ns)
516 return NULL;
517 /*
518 * "use_profile" and "use_group" settings for automatically created
519 * domains are inherited from current domain. These are 0 for manually
520 * created domains.
521 */
522 if (transit) {
523 const struct tomoyo_domain_info *domain = tomoyo_domain();
524 e.profile = domain->profile;
525 e.group = domain->group;
526 }
527 e.domainname = tomoyo_get_name(domainname);
528 if (!e.domainname)
529 return NULL;
530 if (mutex_lock_interruptible(&tomoyo_policy_lock))
531 goto out;
532 entry = tomoyo_find_domain(domainname);
533 if (!entry) {
534 entry = tomoyo_commit_ok(&e, sizeof(e));
535 if (entry) {
536 INIT_LIST_HEAD(&entry->acl_info_list);
537 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
538 created = true;
539 }
540 }
541 mutex_unlock(&tomoyo_policy_lock);
542out:
543 tomoyo_put_name(e.domainname);
544 if (entry && transit) {
545 if (created) {
546 struct tomoyo_request_info r;
547 tomoyo_init_request_info(&r, entry,
548 TOMOYO_MAC_FILE_EXECUTE);
549 r.granted = false;
550 tomoyo_write_log(&r, "use_profile %u\n",
551 entry->profile);
552 tomoyo_write_log(&r, "use_group %u\n", entry->group);
553 }
554 }
555 return entry;
415} 556}
416 557
417/** 558/**
@@ -434,6 +575,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
434 bool is_enforce; 575 bool is_enforce;
435 int retval = -ENOMEM; 576 int retval = -ENOMEM;
436 bool need_kfree = false; 577 bool need_kfree = false;
578 bool reject_on_transition_failure = false;
437 struct tomoyo_path_info rn = { }; /* real name */ 579 struct tomoyo_path_info rn = { }; /* real name */
438 580
439 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); 581 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
@@ -457,8 +599,10 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
457 /* Check 'aggregator' directive. */ 599 /* Check 'aggregator' directive. */
458 { 600 {
459 struct tomoyo_aggregator *ptr; 601 struct tomoyo_aggregator *ptr;
460 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 602 struct list_head *list =
461 [TOMOYO_ID_AGGREGATOR], head.list) { 603 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
604 /* Check 'aggregator' directive. */
605 list_for_each_entry_rcu(ptr, list, head.list) {
462 if (ptr->head.is_deleted || 606 if (ptr->head.is_deleted ||
463 !tomoyo_path_matches_pattern(&rn, 607 !tomoyo_path_matches_pattern(&rn,
464 ptr->original_name)) 608 ptr->original_name))
@@ -492,11 +636,21 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
492 } 636 }
493 637
494 /* Calculate domain to transit to. */ 638 /* Calculate domain to transit to. */
495 switch (tomoyo_transition_type(old_domain->domainname, &rn)) { 639 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
640 &rn)) {
641 case TOMOYO_TRANSITION_CONTROL_RESET:
642 /* Transit to the root of specified namespace. */
643 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name);
644 /*
645 * Make do_execve() fail if domain transition across namespaces
646 * has failed.
647 */
648 reject_on_transition_failure = true;
649 break;
496 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 650 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
497 /* Transit to the child of tomoyo_kernel_domain domain. */ 651 /* Transit to the child of current namespace's root. */
498 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " " 652 snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
499 "%s", rn.name); 653 old_domain->ns->name, rn.name);
500 break; 654 break;
501 case TOMOYO_TRANSITION_CONTROL_KEEP: 655 case TOMOYO_TRANSITION_CONTROL_KEEP:
502 /* Keep current domain. */ 656 /* Keep current domain. */
@@ -519,19 +673,25 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
519 } 673 }
520 break; 674 break;
521 } 675 }
522 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
523 goto done;
524 domain = tomoyo_find_domain(tmp);
525 if (!domain) 676 if (!domain)
526 domain = tomoyo_assign_domain(tmp, old_domain->profile); 677 domain = tomoyo_assign_domain(tmp, true);
527 done:
528 if (domain) 678 if (domain)
529 goto out; 679 retval = 0;
530 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp); 680 else if (reject_on_transition_failure) {
531 if (is_enforce) 681 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", tmp);
532 retval = -EPERM; 682 retval = -ENOMEM;
533 else 683 } else if (r.mode == TOMOYO_CONFIG_ENFORCING)
534 old_domain->transition_failed = true; 684 retval = -ENOMEM;
685 else {
686 retval = 0;
687 if (!old_domain->transition_failed) {
688 old_domain->transition_failed = true;
689 r.granted = false;
690 tomoyo_write_log(&r, "%s", "transition_failed\n");
691 printk(KERN_WARNING
692 "ERROR: Domain '%s' not defined.\n", tmp);
693 }
694 }
535 out: 695 out:
536 if (!domain) 696 if (!domain)
537 domain = old_domain; 697 domain = old_domain;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 4f8526af9069..323ddc73a125 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -603,7 +603,7 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
603 int error; 603 int error;
604 604
605 r->type = tomoyo_p2mac[operation]; 605 r->type = tomoyo_p2mac[operation];
606 r->mode = tomoyo_get_mode(r->profile, r->type); 606 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
607 if (r->mode == TOMOYO_CONFIG_DISABLED) 607 if (r->mode == TOMOYO_CONFIG_DISABLED)
608 return 0; 608 return 0;
609 r->param_type = TOMOYO_TYPE_PATH_ACL; 609 r->param_type = TOMOYO_TYPE_PATH_ACL;
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 412ee8309c23..782e844dca7f 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -292,15 +292,12 @@ static bool tomoyo_collect_acl(struct list_head *list)
292static void tomoyo_collect_entry(void) 292static void tomoyo_collect_entry(void)
293{ 293{
294 int i; 294 int i;
295 enum tomoyo_policy_id id;
296 struct tomoyo_policy_namespace *ns;
297 int idx;
295 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 298 if (mutex_lock_interruptible(&tomoyo_policy_lock))
296 return; 299 return;
297 for (i = 0; i < TOMOYO_MAX_POLICY; i++) { 300 idx = tomoyo_read_lock();
298 if (!tomoyo_collect_member(i, &tomoyo_policy_list[i]))
299 goto unlock;
300 }
301 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
302 if (!tomoyo_collect_acl(&tomoyo_acl_group[i]))
303 goto unlock;
304 { 301 {
305 struct tomoyo_domain_info *domain; 302 struct tomoyo_domain_info *domain;
306 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 303 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
@@ -317,39 +314,49 @@ static void tomoyo_collect_entry(void)
317 goto unlock; 314 goto unlock;
318 } 315 }
319 } 316 }
320 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 317 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
321 struct tomoyo_name *ptr; 318 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
322 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], head.list) { 319 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
323 if (atomic_read(&ptr->head.users))
324 continue;
325 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->head.list))
326 goto unlock; 320 goto unlock;
321 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
322 if (!tomoyo_collect_acl(&ns->acl_group[i]))
323 goto unlock;
324 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
325 struct list_head *list = &ns->group_list[i];
326 struct tomoyo_group *group;
327 switch (i) {
328 case 0:
329 id = TOMOYO_ID_PATH_GROUP;
330 break;
331 default:
332 id = TOMOYO_ID_NUMBER_GROUP;
333 break;
334 }
335 list_for_each_entry(group, list, head.list) {
336 if (!tomoyo_collect_member
337 (id, &group->member_list))
338 goto unlock;
339 if (!list_empty(&group->member_list) ||
340 atomic_read(&group->head.users))
341 continue;
342 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
343 &group->head.list))
344 goto unlock;
345 }
327 } 346 }
328 } 347 }
329 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 348 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
330 struct list_head *list = &tomoyo_group_list[i]; 349 struct list_head *list = &tomoyo_name_list[i];
331 int id; 350 struct tomoyo_shared_acl_head *ptr;
332 struct tomoyo_group *group; 351 list_for_each_entry(ptr, list, list) {
333 switch (i) { 352 if (atomic_read(&ptr->users))
334 case 0:
335 id = TOMOYO_ID_PATH_GROUP;
336 break;
337 default:
338 id = TOMOYO_ID_NUMBER_GROUP;
339 break;
340 }
341 list_for_each_entry(group, list, head.list) {
342 if (!tomoyo_collect_member(id, &group->member_list))
343 goto unlock;
344 if (!list_empty(&group->member_list) ||
345 atomic_read(&group->head.users))
346 continue; 353 continue;
347 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, 354 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
348 &group->head.list))
349 goto unlock; 355 goto unlock;
350 } 356 }
351 } 357 }
352 unlock: 358unlock:
359 tomoyo_read_unlock(idx);
353 mutex_unlock(&tomoyo_policy_lock); 360 mutex_unlock(&tomoyo_policy_lock);
354} 361}
355 362
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 7a0493943d6d..39d012823f84 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -118,7 +118,7 @@ struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
118 return NULL; 118 return NULL;
119 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 119 if (mutex_lock_interruptible(&tomoyo_policy_lock))
120 goto out; 120 goto out;
121 list = &tomoyo_group_list[idx]; 121 list = &param->ns->group_list[idx];
122 list_for_each_entry(group, list, head.list) { 122 list_for_each_entry(group, list, head.list) {
123 if (e.group_name != group->group_name) 123 if (e.group_name != group->group_name)
124 continue; 124 continue;
@@ -199,27 +199,23 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
199 return ptr ? &ptr->entry : NULL; 199 return ptr ? &ptr->entry : NULL;
200} 200}
201 201
202/* Initial namespace.*/
203struct tomoyo_policy_namespace tomoyo_kernel_namespace;
204
202/** 205/**
203 * tomoyo_mm_init - Initialize mm related code. 206 * tomoyo_mm_init - Initialize mm related code.
204 */ 207 */
205void __init tomoyo_mm_init(void) 208void __init tomoyo_mm_init(void)
206{ 209{
207 int idx; 210 int idx;
208
209 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
210 INIT_LIST_HEAD(&tomoyo_policy_list[idx]);
211 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
212 INIT_LIST_HEAD(&tomoyo_group_list[idx]);
213 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++) 211 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
214 INIT_LIST_HEAD(&tomoyo_name_list[idx]); 212 INIT_LIST_HEAD(&tomoyo_name_list[idx]);
213 tomoyo_kernel_namespace.name = "<kernel>";
214 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
215 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
215 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 216 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
216 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) 217 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
217 INIT_LIST_HEAD(&tomoyo_acl_group[idx]);
218 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
219 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 218 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
220 idx = tomoyo_read_lock();
221 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
222 panic("Can't register tomoyo_kernel_domain");
223#if 0 219#if 0
224 /* Will be replaced with tomoyo_load_builtin_policy(). */ 220 /* Will be replaced with tomoyo_load_builtin_policy(). */
225 { 221 {
@@ -230,7 +226,6 @@ void __init tomoyo_mm_init(void)
230 TOMOYO_TRANSITION_CONTROL_INITIALIZE); 226 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
231 } 227 }
232#endif 228#endif
233 tomoyo_read_unlock(idx);
234} 229}
235 230
236 231
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index bc71528ff440..fda15c1fc1c0 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -416,26 +416,21 @@ bool tomoyo_correct_path(const char *filename)
416 */ 416 */
417bool tomoyo_correct_domain(const unsigned char *domainname) 417bool tomoyo_correct_domain(const unsigned char *domainname)
418{ 418{
419 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 419 if (!domainname || !tomoyo_domain_def(domainname))
420 TOMOYO_ROOT_NAME_LEN)) 420 return false;
421 goto out; 421 domainname = strchr(domainname, ' ');
422 domainname += TOMOYO_ROOT_NAME_LEN; 422 if (!domainname++)
423 if (!*domainname)
424 return true; 423 return true;
425 if (*domainname++ != ' ')
426 goto out;
427 while (1) { 424 while (1) {
428 const unsigned char *cp = strchr(domainname, ' '); 425 const unsigned char *cp = strchr(domainname, ' ');
429 if (!cp) 426 if (!cp)
430 break; 427 break;
431 if (*domainname != '/' || 428 if (*domainname != '/' ||
432 !tomoyo_correct_word2(domainname, cp - domainname)) 429 !tomoyo_correct_word2(domainname, cp - domainname))
433 goto out; 430 return false;
434 domainname = cp + 1; 431 domainname = cp + 1;
435 } 432 }
436 return tomoyo_correct_path(domainname); 433 return tomoyo_correct_path(domainname);
437 out:
438 return false;
439} 434}
440 435
441/** 436/**
@@ -447,7 +442,19 @@ bool tomoyo_correct_domain(const unsigned char *domainname)
447 */ 442 */
448bool tomoyo_domain_def(const unsigned char *buffer) 443bool tomoyo_domain_def(const unsigned char *buffer)
449{ 444{
450 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN); 445 const unsigned char *cp;
446 int len;
447 if (*buffer != '<')
448 return false;
449 cp = strchr(buffer, ' ');
450 if (!cp)
451 len = strlen(buffer);
452 else
453 len = cp - buffer;
454 if (buffer[len - 1] != '>' ||
455 !tomoyo_correct_word2(buffer + 1, len - 2))
456 return false;
457 return true;
451} 458}
452 459
453/** 460/**
@@ -833,22 +840,24 @@ const char *tomoyo_get_exe(void)
833/** 840/**
834 * tomoyo_get_mode - Get MAC mode. 841 * tomoyo_get_mode - Get MAC mode.
835 * 842 *
843 * @ns: Pointer to "struct tomoyo_policy_namespace".
836 * @profile: Profile number. 844 * @profile: Profile number.
837 * @index: Index number of functionality. 845 * @index: Index number of functionality.
838 * 846 *
839 * Returns mode. 847 * Returns mode.
840 */ 848 */
841int tomoyo_get_mode(const u8 profile, const u8 index) 849int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
850 const u8 index)
842{ 851{
843 u8 mode; 852 u8 mode;
844 const u8 category = TOMOYO_MAC_CATEGORY_FILE; 853 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
845 if (!tomoyo_policy_loaded) 854 if (!tomoyo_policy_loaded)
846 return TOMOYO_CONFIG_DISABLED; 855 return TOMOYO_CONFIG_DISABLED;
847 mode = tomoyo_profile(profile)->config[index]; 856 mode = tomoyo_profile(ns, profile)->config[index];
848 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 857 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
849 mode = tomoyo_profile(profile)->config[category]; 858 mode = tomoyo_profile(ns, profile)->config[category];
850 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 859 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
851 mode = tomoyo_profile(profile)->default_config; 860 mode = tomoyo_profile(ns, profile)->default_config;
852 return mode & 3; 861 return mode & 3;
853} 862}
854 863
@@ -872,26 +881,11 @@ int tomoyo_init_request_info(struct tomoyo_request_info *r,
872 profile = domain->profile; 881 profile = domain->profile;
873 r->profile = profile; 882 r->profile = profile;
874 r->type = index; 883 r->type = index;
875 r->mode = tomoyo_get_mode(profile, index); 884 r->mode = tomoyo_get_mode(domain->ns, profile, index);
876 return r->mode; 885 return r->mode;
877} 886}
878 887
879/** 888/**
880 * tomoyo_last_word - Get last component of a line.
881 *
882 * @line: A line.
883 *
884 * Returns the last word of a line.
885 */
886const char *tomoyo_last_word(const char *name)
887{
888 const char *cp = strrchr(name, ' ');
889 if (cp)
890 return cp + 1;
891 return name;
892}
893
894/**
895 * tomoyo_domain_quota_is_ok - Check for domain's quota. 889 * tomoyo_domain_quota_is_ok - Check for domain's quota.
896 * 890 *
897 * @r: Pointer to "struct tomoyo_request_info". 891 * @r: Pointer to "struct tomoyo_request_info".
@@ -939,7 +933,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
939 if (perm & (1 << i)) 933 if (perm & (1 << i))
940 count++; 934 count++;
941 } 935 }
942 if (count < tomoyo_profile(domain->profile)-> 936 if (count < tomoyo_profile(domain->ns, domain->profile)->
943 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY]) 937 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
944 return true; 938 return true;
945 if (!domain->quota_warned) { 939 if (!domain->quota_warned) {