Commit bd03a3e4c9a9df0c6b007045fa7fc8889111a478

Authored by Tetsuo Handa
Committed by James Morris
1 parent 32997144fd

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>

Showing 8 changed files with 669 additions and 299 deletions Side-by-side Diff

security/tomoyo/audit.c
... ... @@ -151,13 +151,15 @@
151 151 /**
152 152 * tomoyo_get_audit - Get audit mode.
153 153 *
  154 + * @ns: Pointer to "struct tomoyo_policy_namespace".
154 155 * @profile: Profile number.
155 156 * @index: Index number of functionality.
156 157 * @is_granted: True if granted log, false otherwise.
157 158 *
158 159 * Returns true if this request should be audited, false otherwise.
159 160 */
160   -static bool tomoyo_get_audit(const u8 profile, const u8 index,
  161 +static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
  162 + const u8 profile, const u8 index,
161 163 const bool is_granted)
162 164 {
163 165 u8 mode;
... ... @@ -165,7 +167,7 @@
165 167 struct tomoyo_profile *p;
166 168 if (!tomoyo_policy_loaded)
167 169 return false;
168   - p = tomoyo_profile(profile);
  170 + p = tomoyo_profile(ns, profile);
169 171 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
170 172 return false;
171 173 mode = p->config[index];
... ... @@ -194,7 +196,7 @@
194 196 char *buf;
195 197 struct tomoyo_log *entry;
196 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 200 goto out;
199 201 buf = tomoyo_init_log(r, len, fmt, args);
200 202 if (!buf)
security/tomoyo/common.c
... ... @@ -11,12 +11,6 @@
11 11 #include <linux/security.h>
12 12 #include "common.h"
13 13  
14   -/* Profile version. Currently only 20090903 is defined. */
15   -static unsigned int tomoyo_profile_version;
16   -
17   -/* Profile table. Memory is allocated as needed. */
18   -static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
19   -
20 14 /* String table for operation mode. */
21 15 const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
22 16 [TOMOYO_CONFIG_DISABLED] = "disabled",
23 17  
... ... @@ -216,7 +210,51 @@
216 210 tomoyo_set_string(head, "/");
217 211 }
218 212  
  213 +/* List of namespaces. */
  214 +LIST_HEAD(tomoyo_namespace_list);
  215 +/* True if namespace other than tomoyo_kernel_namespace is defined. */
  216 +static bool tomoyo_namespace_enabled;
  217 +
219 218 /**
  219 + * tomoyo_init_policy_namespace - Initialize namespace.
  220 + *
  221 + * @ns: Pointer to "struct tomoyo_policy_namespace".
  222 + *
  223 + * Returns nothing.
  224 + */
  225 +void 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 + */
  246 +static 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 +
  257 +/**
220 258 * tomoyo_print_name_union - Print a tomoyo_name_union.
221 259 *
222 260 * @head: Pointer to "struct tomoyo_io_buffer".
223 261  
224 262  
225 263  
... ... @@ -283,23 +321,25 @@
283 321 /**
284 322 * tomoyo_assign_profile - Create a new profile.
285 323 *
  324 + * @ns: Pointer to "struct tomoyo_policy_namespace".
286 325 * @profile: Profile number to create.
287 326 *
288 327 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
289 328 */
290   -static struct tomoyo_profile *tomoyo_assign_profile(const unsigned int profile)
  329 +static struct tomoyo_profile *tomoyo_assign_profile
  330 +(struct tomoyo_policy_namespace *ns, const unsigned int profile)
291 331 {
292 332 struct tomoyo_profile *ptr;
293 333 struct tomoyo_profile *entry;
294 334 if (profile >= TOMOYO_MAX_PROFILES)
295 335 return NULL;
296   - ptr = tomoyo_profile_ptr[profile];
  336 + ptr = ns->profile_ptr[profile];
297 337 if (ptr)
298 338 return ptr;
299 339 entry = kzalloc(sizeof(*entry), GFP_NOFS);
300 340 if (mutex_lock_interruptible(&tomoyo_policy_lock))
301 341 goto out;
302   - ptr = tomoyo_profile_ptr[profile];
  342 + ptr = ns->profile_ptr[profile];
303 343 if (!ptr && tomoyo_memory_ok(entry)) {
304 344 ptr = entry;
305 345 ptr->default_config = TOMOYO_CONFIG_DISABLED |
... ... @@ -310,7 +350,7 @@
310 350 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024;
311 351 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
312 352 mb(); /* Avoid out-of-order execution. */
313   - tomoyo_profile_ptr[profile] = ptr;
  353 + ns->profile_ptr[profile] = ptr;
314 354 entry = NULL;
315 355 }
316 356 mutex_unlock(&tomoyo_policy_lock);
317 357  
318 358  
... ... @@ -322,14 +362,16 @@
322 362 /**
323 363 * tomoyo_profile - Find a profile.
324 364 *
  365 + * @ns: Pointer to "struct tomoyo_policy_namespace".
325 366 * @profile: Profile number to find.
326 367 *
327 368 * Returns pointer to "struct tomoyo_profile".
328 369 */
329   -struct tomoyo_profile *tomoyo_profile(const u8 profile)
  370 +struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
  371 + const u8 profile)
330 372 {
331 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 375 if (!ptr)
334 376 ptr = &tomoyo_null_profile;
335 377 return ptr;
336 378  
... ... @@ -454,13 +496,14 @@
454 496 unsigned int i;
455 497 char *cp;
456 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 501 return 0;
459 502 i = simple_strtoul(data, &cp, 10);
460 503 if (*cp != '-')
461 504 return -EINVAL;
462 505 data = cp + 1;
463   - profile = tomoyo_assign_profile(i);
  506 + profile = tomoyo_assign_profile(head->w.ns, i);
464 507 if (!profile)
465 508 return -EINVAL;
466 509 cp = strchr(data, '=');
467 510  
468 511  
469 512  
470 513  
... ... @@ -518,19 +561,25 @@
518 561 static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
519 562 {
520 563 u8 index;
  564 + struct tomoyo_policy_namespace *ns =
  565 + container_of(head->r.ns, typeof(*ns), namespace_list);
521 566 const struct tomoyo_profile *profile;
  567 + if (head->r.eof)
  568 + return;
522 569 next:
523 570 index = head->r.index;
524   - profile = tomoyo_profile_ptr[index];
  571 + profile = ns->profile_ptr[index];
525 572 switch (head->r.step) {
526 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 577 head->r.step++;
529 578 break;
530 579 case 1:
531 580 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
532 581 head->r.index++)
533   - if (tomoyo_profile_ptr[head->r.index])
  582 + if (ns->profile_ptr[head->r.index])
534 583 break;
535 584 if (head->r.index == TOMOYO_MAX_PROFILES)
536 585 return;
... ... @@ -541,6 +590,7 @@
541 590 u8 i;
542 591 const struct tomoyo_path_info *comment =
543 592 profile->comment;
  593 + tomoyo_print_namespace(head);
544 594 tomoyo_io_printf(head, "%u-COMMENT=", index);
545 595 tomoyo_set_string(head, comment ? comment->name : "");
546 596 tomoyo_set_lf(head);
... ... @@ -555,6 +605,7 @@
555 605 break;
556 606 case 3:
557 607 {
  608 + tomoyo_print_namespace(head);
558 609 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
559 610 tomoyo_print_config(head, profile->default_config);
560 611 head->r.bit = 0;
... ... @@ -568,6 +619,7 @@
568 619 const u8 config = profile->config[i];
569 620 if (config == TOMOYO_CONFIG_USE_DEFAULT)
570 621 continue;
  622 + tomoyo_print_namespace(head);
571 623 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::",
572 624 tomoyo_mac_keywords[i]);
573 625 tomoyo_print_config(head, config);
574 626  
... ... @@ -607,8 +659,10 @@
607 659 {
608 660 struct tomoyo_manager e = { };
609 661 struct tomoyo_acl_param param = {
  662 + /* .ns = &tomoyo_kernel_namespace, */
610 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 667 int error = is_delete ? -ENOENT : -ENOMEM;
614 668 if (tomoyo_domain_def(manager)) {
615 669  
616 670  
... ... @@ -640,13 +694,12 @@
640 694 static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
641 695 {
642 696 char *data = head->write_buf;
643   - bool is_delete = tomoyo_str_starts(&data, "delete ");
644 697  
645 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 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 @@
660 713 {
661 714 if (head->r.eof)
662 715 return;
663   - list_for_each_cookie(head->r.acl,
664   - &tomoyo_policy_list[TOMOYO_ID_MANAGER]) {
  716 + list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
  717 + policy_list[TOMOYO_ID_MANAGER]) {
665 718 struct tomoyo_manager *ptr =
666 719 list_entry(head->r.acl, typeof(*ptr), head.list);
667 720 if (ptr->head.is_deleted)
... ... @@ -694,8 +747,8 @@
694 747 return true;
695 748 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
696 749 return false;
697   - list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER],
698   - head.list) {
  750 + list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
  751 + policy_list[TOMOYO_ID_MANAGER], head.list) {
699 752 if (!ptr->head.is_deleted && ptr->is_domain
700 753 && !tomoyo_pathcmp(domainname, ptr->manager)) {
701 754 found = true;
... ... @@ -707,8 +760,8 @@
707 760 exe = tomoyo_get_exe();
708 761 if (!exe)
709 762 return false;
710   - list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER],
711   - head.list) {
  763 + list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
  764 + policy_list[TOMOYO_ID_MANAGER], head.list) {
712 765 if (!ptr->head.is_deleted && !ptr->is_domain
713 766 && !strcmp(exe, ptr->manager->name)) {
714 767 found = true;
... ... @@ -729,7 +782,7 @@
729 782 }
730 783  
731 784 /**
732   - * tomoyo_select_one - Parse select command.
  785 + * tomoyo_select_domain - Parse select command.
733 786 *
734 787 * @head: Pointer to "struct tomoyo_io_buffer".
735 788 * @data: String to parse.
736 789  
... ... @@ -738,16 +791,15 @@
738 791 *
739 792 * Caller holds tomoyo_read_lock().
740 793 */
741   -static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
  794 +static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
  795 + const char *data)
742 796 {
743 797 unsigned int pid;
744 798 struct tomoyo_domain_info *domain = NULL;
745 799 bool global_pid = false;
746   -
747   - if (!strcmp(data, "allow_execute")) {
748   - head->r.print_execute_only = true;
749   - return true;
750   - }
  800 + if (strncmp(data, "select ", 7))
  801 + return false;
  802 + data += 7;
751 803 if (sscanf(data, "pid=%u", &pid) == 1 ||
752 804 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
753 805 struct task_struct *p;
... ... @@ -818,6 +870,7 @@
818 870 /**
819 871 * tomoyo_write_domain2 - Write domain policy.
820 872 *
  873 + * @ns: Pointer to "struct tomoyo_policy_namespace".
821 874 * @list: Pointer to "struct list_head".
822 875 * @data: Policy to be interpreted.
823 876 * @is_delete: True if it is a delete request.
824 877  
... ... @@ -826,10 +879,12 @@
826 879 *
827 880 * Caller holds tomoyo_read_lock().
828 881 */
829   -static int tomoyo_write_domain2(struct list_head *list, char *data,
  882 +static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
  883 + struct list_head *list, char *data,
830 884 const bool is_delete)
831 885 {
832 886 struct tomoyo_acl_param param = {
  887 + .ns = ns,
833 888 .list = list,
834 889 .data = data,
835 890 .is_delete = is_delete,
836 891  
837 892  
838 893  
839 894  
840 895  
... ... @@ -862,37 +917,28 @@
862 917 static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
863 918 {
864 919 char *data = head->write_buf;
  920 + struct tomoyo_policy_namespace *ns;
865 921 struct tomoyo_domain_info *domain = head->w.domain;
866   - bool is_delete = false;
867   - bool is_select = false;
  922 + const bool is_delete = head->w.is_delete;
  923 + bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
868 924 unsigned int profile;
869   -
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)) {
  925 + if (*data == '<') {
880 926 domain = NULL;
881 927 if (is_delete)
882 928 tomoyo_delete_domain(data);
883 929 else if (is_select)
884 930 domain = tomoyo_find_domain(data);
885 931 else
886   - domain = tomoyo_assign_domain(data, 0);
  932 + domain = tomoyo_assign_domain(data, false);
887 933 head->w.domain = domain;
888 934 return 0;
889 935 }
890 936 if (!domain)
891 937 return -EINVAL;
892   -
  938 + ns = domain->ns;
893 939 if (sscanf(data, "use_profile %u", &profile) == 1
894 940 && profile < TOMOYO_MAX_PROFILES) {
895   - if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)
  941 + if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
896 942 domain->profile = (u8) profile;
897 943 return 0;
898 944 }
... ... @@ -910,7 +956,8 @@
910 956 domain->transition_failed = !is_delete;
911 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 /**
917 964  
... ... @@ -924,9 +971,11 @@
924 971 static void tomoyo_set_group(struct tomoyo_io_buffer *head,
925 972 const char *category)
926 973 {
927   - if (head->type == TOMOYO_EXCEPTIONPOLICY)
  974 + if (head->type == TOMOYO_EXCEPTIONPOLICY) {
  975 + tomoyo_print_namespace(head);
928 976 tomoyo_io_printf(head, "acl_group %u ",
929 977 head->r.acl_group_index);
  978 + }
930 979 tomoyo_set_string(head, category);
931 980 }
932 981  
... ... @@ -956,7 +1005,7 @@
956 1005 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
957 1006 if (!(perm & (1 << bit)))
958 1007 continue;
959   - if (head->r.print_execute_only &&
  1008 + if (head->r.print_transition_related_only &&
960 1009 bit != TOMOYO_TYPE_EXECUTE)
961 1010 continue;
962 1011 if (first) {
... ... @@ -970,7 +1019,7 @@
970 1019 if (first)
971 1020 return true;
972 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 1023 return true;
975 1024 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
976 1025 struct tomoyo_path2_acl *ptr =
... ... @@ -1147,8 +1196,8 @@
1147 1196 domain = tomoyo_find_domain(cp + 1);
1148 1197 if (strict_strtoul(data, 10, &profile))
1149 1198 return -EINVAL;
1150   - if (domain && profile < TOMOYO_MAX_PROFILES
1151   - && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
  1199 + if (domain && (!tomoyo_policy_loaded ||
  1200 + head->w.ns->profile_ptr[(u8) profile]))
1152 1201 domain->profile = (u8) profile;
1153 1202 return 0;
1154 1203 }
... ... @@ -1246,10 +1295,12 @@
1246 1295 }
1247 1296  
1248 1297 static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1249   - [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain",
1250   - [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain",
1251   - [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain",
1252   - [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain",
  1298 + [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
  1299 + [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
  1300 + [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_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  
1255 1306 static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1256 1307  
1257 1308  
... ... @@ -1268,19 +1319,13 @@
1268 1319 */
1269 1320 static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1270 1321 {
  1322 + const bool is_delete = head->w.is_delete;
1271 1323 struct tomoyo_acl_param param = {
  1324 + .ns = head->w.ns,
  1325 + .is_delete = is_delete,
1272 1326 .data = head->write_buf,
1273 1327 };
1274 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 1329 if (tomoyo_str_starts(&param.data, "aggregator "))
1285 1330 return tomoyo_write_aggregator(&param);
1286 1331 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
... ... @@ -1294,8 +1339,9 @@
1294 1339 char *data;
1295 1340 group = simple_strtoul(param.data, &data, 10);
1296 1341 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1297   - return tomoyo_write_domain2(&tomoyo_acl_group[group],
1298   - data, param.is_delete);
  1342 + return tomoyo_write_domain2
  1343 + (head->w.ns, &head->w.ns->acl_group[group],
  1344 + data, is_delete);
1299 1345 }
1300 1346 return -EINVAL;
1301 1347 }
... ... @@ -1312,7 +1358,10 @@
1312 1358 */
1313 1359 static 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 1365 struct tomoyo_group *group =
1317 1366 list_entry(head->r.group, typeof(*group), head.list);
1318 1367 list_for_each_cookie(head->r.acl, &group->member_list) {
... ... @@ -1322,6 +1371,7 @@
1322 1371 continue;
1323 1372 if (!tomoyo_flush(head))
1324 1373 return false;
  1374 + tomoyo_print_namespace(head);
1325 1375 tomoyo_set_string(head, tomoyo_group_name[idx]);
1326 1376 tomoyo_set_string(head, group->group_name->name);
1327 1377 if (idx == TOMOYO_PATH_GROUP) {
... ... @@ -1355,7 +1405,10 @@
1355 1405 */
1356 1406 static 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 1412 struct tomoyo_acl_head *acl =
1360 1413 container_of(head->r.acl, typeof(*acl), list);
1361 1414 if (acl->is_deleted)
... ... @@ -1367,6 +1420,7 @@
1367 1420 {
1368 1421 struct tomoyo_transition_control *ptr =
1369 1422 container_of(acl, typeof(*ptr), head);
  1423 + tomoyo_print_namespace(head);
1370 1424 tomoyo_set_string(head, tomoyo_transition_type
1371 1425 [ptr->type]);
1372 1426 tomoyo_set_string(head, ptr->program ?
... ... @@ -1381,6 +1435,7 @@
1381 1435 {
1382 1436 struct tomoyo_aggregator *ptr =
1383 1437 container_of(acl, typeof(*ptr), head);
  1438 + tomoyo_print_namespace(head);
1384 1439 tomoyo_set_string(head, "aggregator ");
1385 1440 tomoyo_set_string(head,
1386 1441 ptr->original_name->name);
... ... @@ -1407,6 +1462,8 @@
1407 1462 */
1408 1463 static 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 1467 if (head->r.eof)
1411 1468 return;
1412 1469 while (head->r.step < TOMOYO_MAX_POLICY &&
... ... @@ -1423,7 +1480,7 @@
1423 1480 + TOMOYO_MAX_ACL_GROUPS) {
1424 1481 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1425 1482 - TOMOYO_MAX_GROUP;
1426   - if (!tomoyo_read_domain2(head, &tomoyo_acl_group
  1483 + if (!tomoyo_read_domain2(head, &ns->acl_group
1427 1484 [head->r.acl_group_index]))
1428 1485 return;
1429 1486 head->r.step++;
... ... @@ -1484,7 +1541,8 @@
1484 1541 return;
1485 1542 snprintf(buffer, len - 1, "%s", cp);
1486 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 1546 kfree(buffer);
1489 1547 }
1490 1548  
... ... @@ -1896,6 +1954,45 @@
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 + */
  1963 +static 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 + */
  1988 +static 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 1996 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1900 1997 *
1901 1998 * @head: Pointer to "struct tomoyo_io_buffer".
1902 1999  
... ... @@ -1919,14 +2016,54 @@
1919 2016 head->read_user_buf_avail = buffer_len;
1920 2017 if (tomoyo_flush(head))
1921 2018 /* Call the policy handler. */
1922   - head->read(head);
1923   - tomoyo_flush(head);
  2019 + do {
  2020 + tomoyo_set_namespace_cursor(head);
  2021 + head->read(head);
  2022 + } while (tomoyo_flush(head) &&
  2023 + tomoyo_has_more_namespace(head));
1924 2024 len = head->read_user_buf - buffer;
1925 2025 mutex_unlock(&head->io_sem);
1926 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 + */
  2039 +static 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 2067 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1931 2068 *
1932 2069 * @head: Pointer to "struct tomoyo_io_buffer".
1933 2070  
1934 2071  
1935 2072  
... ... @@ -1941,27 +2078,31 @@
1941 2078 const char __user *buffer, const int buffer_len)
1942 2079 {
1943 2080 int error = buffer_len;
1944   - int avail_len = buffer_len;
  2081 + size_t avail_len = buffer_len;
1945 2082 char *cp0 = head->write_buf;
1946   -
1947 2083 if (!head->write)
1948 2084 return -ENOSYS;
1949 2085 if (!access_ok(VERIFY_READ, buffer, buffer_len))
1950 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 2087 if (mutex_lock_interruptible(&head->io_sem))
1957 2088 return -EINTR;
1958 2089 /* Read a line and dispatch it to the policy handler. */
1959 2090 while (avail_len > 0) {
1960 2091 char c;
1961 2092 if (head->w.avail >= head->writebuf_size - 1) {
1962   - error = -ENOMEM;
1963   - break;
1964   - } else if (get_user(c, buffer)) {
  2093 + const int len = head->writebuf_size * 2;
  2094 + char *cp = kzalloc(len, GFP_NOFS);
  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 2106 error = -EFAULT;
1966 2107 break;
1967 2108 }
1968 2109  
... ... @@ -1973,8 +2114,40 @@
1973 2114 cp0[head->w.avail - 1] = '\0';
1974 2115 head->w.avail = 0;
1975 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 }
  2150 +out:
1978 2151 mutex_unlock(&head->io_sem);
1979 2152 return error;
1980 2153 }
1981 2154  
1982 2155  
1983 2156  
1984 2157  
... ... @@ -2019,28 +2192,28 @@
2019 2192 struct tomoyo_domain_info *domain;
2020 2193 const int idx = tomoyo_read_lock();
2021 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 2196 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2024 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 2208 continue;
2027   - printk(KERN_ERR "You need to define profile %u before using it.\n",
2028   - profile);
2029   - printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.3/ "
  2209 + printk(KERN_ERR
  2210 + "Userland tools for TOMOYO 2.4 must be installed and "
  2211 + "policy must be initialized.\n");
  2212 + printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ "
2030 2213 "for more information.\n");
2031   - panic("Profile %u (used by '%s') not defined.\n",
2032   - profile, domain->domainname->name);
  2214 + panic("STOP!");
2033 2215 }
2034 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 2217 printk(KERN_INFO "Mandatory Access Control activated.\n");
2045 2218 }
security/tomoyo/common.h
... ... @@ -74,10 +74,6 @@
74 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 77 /* Index numbers for type of numeric values. */
82 78 enum tomoyo_value_type {
83 79 TOMOYO_VALUE_TYPE_INVALID,
... ... @@ -89,6 +85,8 @@
89 85 /* Index numbers for domain transition control keywords. */
90 86 enum tomoyo_transition_type {
91 87 /* Do not change this order, */
  88 + TOMOYO_TRANSITION_CONTROL_NO_RESET,
  89 + TOMOYO_TRANSITION_CONTROL_RESET,
92 90 TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE,
93 91 TOMOYO_TRANSITION_CONTROL_INITIALIZE,
94 92 TOMOYO_TRANSITION_CONTROL_NO_KEEP,
... ... @@ -246,6 +244,8 @@
246 244 atomic_t users;
247 245 } __packed;
248 246  
  247 +struct tomoyo_policy_namespace;
  248 +
249 249 /* Structure for request info. */
250 250 struct tomoyo_request_info {
251 251 struct tomoyo_domain_info *domain;
... ... @@ -359,6 +359,8 @@
359 359 struct list_head acl_info_list;
360 360 /* Name of this domain. Never NULL. */
361 361 const struct tomoyo_path_info *domainname;
  362 + /* Namespace for this domain. Never NULL. */
  363 + struct tomoyo_policy_namespace *ns;
362 364 u8 profile; /* Profile number to use. */
363 365 u8 group; /* Group number to use. */
364 366 bool is_deleted; /* Delete flag. */
... ... @@ -423,6 +425,7 @@
423 425 struct tomoyo_acl_param {
424 426 char *data;
425 427 struct list_head *list;
  428 + struct tomoyo_policy_namespace *ns;
426 429 bool is_delete;
427 430 };
428 431  
... ... @@ -443,6 +446,7 @@
443 446 char __user *read_user_buf;
444 447 int read_user_buf_avail;
445 448 struct {
  449 + struct list_head *ns;
446 450 struct list_head *domain;
447 451 struct list_head *group;
448 452 struct list_head *acl;
449 453  
450 454  
... ... @@ -455,14 +459,16 @@
455 459 u8 w_pos;
456 460 bool eof;
457 461 bool print_this_domain_only;
458   - bool print_execute_only;
  462 + bool print_transition_related_only;
459 463 const char *w[TOMOYO_MAX_IO_READ_QUEUE];
460 464 } r;
461 465 struct {
  466 + struct tomoyo_policy_namespace *ns;
462 467 /* The position currently writing to. */
463 468 struct tomoyo_domain_info *domain;
464 469 /* Bytes available for writing. */
465 470 int avail;
  471 + bool is_delete;
466 472 } w;
467 473 /* Buffer for reading. */
468 474 char *read_buf;
469 475  
... ... @@ -533,8 +539,27 @@
533 539 u8 sec;
534 540 };
535 541  
  542 +/* Structure for policy namespace. */
  543 +struct 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 560 /********** Function prototypes. **********/
537 561  
  562 +void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
538 563 bool tomoyo_str_starts(char **src, const char *find);
539 564 const char *tomoyo_get_exe(void);
540 565 void tomoyo_normalize_line(unsigned char *buffer);
... ... @@ -553,7 +578,8 @@
553 578 const struct tomoyo_name_union *ptr);
554 579 bool tomoyo_compare_number_union(const unsigned long value,
555 580 const struct tomoyo_number_union *ptr);
556   -int tomoyo_get_mode(const u8 profile, const u8 index);
  581 +int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
  582 + const u8 index);
557 583 void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
558 584 __attribute__ ((format(printf, 2, 3)));
559 585 bool tomoyo_correct_domain(const unsigned char *domainname);
... ... @@ -589,8 +615,11 @@
589 615 __attribute__ ((format(printf, 2, 3)));
590 616 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
591 617 struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
592   - const u8 profile);
593   -struct tomoyo_profile *tomoyo_profile(const u8 profile);
  618 + const bool transit);
  619 +struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
  620 + const u8 profile);
  621 +struct tomoyo_policy_namespace *tomoyo_assign_namespace
  622 +(const char *domainname);
594 623 struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
595 624 const u8 idx);
596 625 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
... ... @@ -646,6 +675,8 @@
646 675 bool tomoyo_permstr(const char *string, const char *keyword);
647 676  
648 677 const char *tomoyo_yesno(const unsigned int value);
  678 +void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
  679 + __attribute__ ((format(printf, 2, 3)));
649 680 void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
650 681 va_list args);
651 682 void tomoyo_read_log(struct tomoyo_io_buffer *head);
... ... @@ -661,8 +692,6 @@
661 692 /* The list for "struct tomoyo_domain_info". */
662 693 extern struct list_head tomoyo_domain_list;
663 694  
664   -extern struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
665   -extern struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
666 695 extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
667 696  
668 697 /* Lock for protecting policy. */
669 698  
... ... @@ -671,10 +700,10 @@
671 700 /* Has /sbin/init started? */
672 701 extern bool tomoyo_policy_loaded;
673 702  
674   -extern struct list_head tomoyo_acl_group[TOMOYO_MAX_ACL_GROUPS];
675   -
676 703 /* The kernel's domain. */
677 704 extern struct tomoyo_domain_info tomoyo_kernel_domain;
  705 +extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
  706 +extern struct list_head tomoyo_namespace_list;
678 707  
679 708 extern const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION];
680 709 extern const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION];
... ... @@ -807,6 +836,16 @@
807 836 return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
808 837 a->group == b->group && a->value_type[0] == b->value_type[0] &&
809 838 a->value_type[1] == b->value_type[1];
  839 +}
  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 + */
  846 +static inline struct tomoyo_policy_namespace *tomoyo_current_namespace(void)
  847 +{
  848 + return tomoyo_domain()->ns;
810 849 }
811 850  
812 851 #if defined(CONFIG_SLOB)
security/tomoyo/domain.c
... ... @@ -12,9 +12,6 @@
12 12  
13 13 /* Variables definitions.*/
14 14  
15   -/* The global ACL referred by "use_group" keyword. */
16   -struct list_head tomoyo_acl_group[TOMOYO_MAX_ACL_GROUPS];
17   -
18 15 /* The initial domain. */
19 16 struct tomoyo_domain_info tomoyo_kernel_domain;
20 17  
... ... @@ -158,7 +155,7 @@
158 155 }
159 156 if (!retried) {
160 157 retried = true;
161   - list = &tomoyo_acl_group[domain->group];
  158 + list = &domain->ns->acl_group[domain->group];
162 159 goto retry;
163 160 }
164 161 r->granted = false;
165 162  
... ... @@ -167,13 +164,10 @@
167 164 /* The list for "struct tomoyo_domain_info". */
168 165 LIST_HEAD(tomoyo_domain_list);
169 166  
170   -struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
171   -struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
172   -
173 167 /**
174 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 172 * Returns the last word of @domainname.
179 173 */
... ... @@ -247,7 +241,7 @@
247 241 if (!e.domainname)
248 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 245 error = tomoyo_update_policy(&e.head, sizeof(e), param,
252 246 tomoyo_same_transition_control);
253 247 out:
254 248  
255 249  
256 250  
257 251  
258 252  
259 253  
260 254  
261 255  
262 256  
... ... @@ -257,59 +251,88 @@
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.
263   - * @program: The name of program.
  256 + * @list: Pointer to "struct list_head".
  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
266   - * reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing
267   - * @program suppresses domain transition, others otherwise.
  262 + * Returns true if found one, false otherwise.
268 263 *
269 264 * Caller holds tomoyo_read_lock().
270 265 */
271   -static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname,
272   - const struct tomoyo_path_info *program)
  266 +static inline bool tomoyo_scan_transition
  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 271 const struct tomoyo_transition_control *ptr;
275   - const char *last_name = tomoyo_last_word(domainname->name);
276   - u8 type;
277   - for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) {
278   - next:
279   - list_for_each_entry_rcu(ptr, &tomoyo_policy_list
280   - [TOMOYO_ID_TRANSITION_CONTROL],
281   - head.list) {
282   - if (ptr->head.is_deleted || ptr->type != type)
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) {
  272 + list_for_each_entry_rcu(ptr, list, head.list) {
  273 + if (ptr->head.is_deleted || ptr->type != type)
  274 + continue;
  275 + if (ptr->domainname) {
  276 + if (!ptr->is_last_name) {
  277 + if (ptr->domainname != domainname)
  278 + continue;
  279 + } else {
302 280 /*
303   - * Do not check for initialize_domain if
304   - * no_initialize_domain matched.
  281 + * Use direct strcmp() since this is
  282 + * unlikely used.
305 283 */
306   - type = TOMOYO_TRANSITION_CONTROL_NO_KEEP;
307   - goto next;
  284 + if (strcmp(ptr->domainname->name, last_name))
  285 + continue;
308 286 }
309   - goto done;
310 287 }
  288 + if (ptr->program && tomoyo_pathcmp(ptr->program, program))
  289 + continue;
  290 + return true;
311 291 }
312   - done:
  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 + */
  310 +static 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++;
  335 + }
313 336 return type;
314 337 }
315 338  
... ... @@ -355,7 +378,7 @@
355 378 if (!e.original_name || !e.aggregated_name ||
356 379 e.aggregated_name->is_patterned) /* No patterns allowed. */
357 380 goto out;
358   - param->list = &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR];
  381 + param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
359 382 error = tomoyo_update_policy(&e.head, sizeof(e), param,
360 383 tomoyo_same_aggregator);
361 384 out:
362 385  
363 386  
364 387  
365 388  
366 389  
367 390  
368 391  
369 392  
370 393  
371 394  
372 395  
373 396  
... ... @@ -365,56 +388,174 @@
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.
371   - * @profile: Profile number to assign if the domain was newly created.
  393 + * @name: Name of namespace to find.
  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 399 * Caller holds tomoyo_read_lock().
376 400 */
377   -struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
378   - const u8 profile)
  401 +static struct tomoyo_policy_namespace *tomoyo_find_namespace
  402 +(const char *name, const unsigned int len)
379 403 {
380   - struct tomoyo_domain_info *entry;
381   - struct tomoyo_domain_info *domain = NULL;
382   - const struct tomoyo_path_info *saved_domainname;
383   - bool found = false;
  404 + struct tomoyo_policy_namespace *ns;
  405 + list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
  406 + if (strncmp(name, ns->name, len) ||
  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 + */
  424 +struct 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 436 return NULL;
387   - saved_domainname = tomoyo_get_name(domainname);
388   - if (!saved_domainname)
  437 + entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
  438 + if (!entry)
389 439 return NULL;
390   - entry = kzalloc(sizeof(*entry), GFP_NOFS);
391 440 if (mutex_lock_interruptible(&tomoyo_policy_lock))
392 441 goto out;
393   - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
394   - if (domain->is_deleted ||
395   - tomoyo_pathcmp(saved_domainname, domain->domainname))
396   - continue;
397   - found = true;
398   - break;
399   - }
400   - if (!found && tomoyo_memory_ok(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;
  442 + ptr = tomoyo_find_namespace(domainname, len);
  443 + if (!ptr && tomoyo_memory_ok(entry)) {
  444 + char *name = (char *) (entry + 1);
  445 + ptr = entry;
  446 + memmove(name, domainname, len);
  447 + name[len] = '\0';
  448 + entry->name = name;
  449 + tomoyo_init_policy_namespace(entry);
407 450 entry = NULL;
408   - found = true;
409 451 }
410 452 mutex_unlock(&tomoyo_policy_lock);
411   - out:
412   - tomoyo_put_name(saved_domainname);
  453 +out:
413 454 kfree(entry);
414   - return found ? domain : NULL;
  455 + return ptr;
415 456 }
416 457  
417 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 + */
  465 +static 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 + */
  483 +struct 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);
  542 +out:
  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;
  556 +}
  557 +
  558 +/**
418 559 * tomoyo_find_next_domain - Find a domain.
419 560 *
420 561 * @bprm: Pointer to "struct linux_binprm".
... ... @@ -434,6 +575,7 @@
434 575 bool is_enforce;
435 576 int retval = -ENOMEM;
436 577 bool need_kfree = false;
  578 + bool reject_on_transition_failure = false;
437 579 struct tomoyo_path_info rn = { }; /* real name */
438 580  
439 581 mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
... ... @@ -457,8 +599,10 @@
457 599 /* Check 'aggregator' directive. */
458 600 {
459 601 struct tomoyo_aggregator *ptr;
460   - list_for_each_entry_rcu(ptr, &tomoyo_policy_list
461   - [TOMOYO_ID_AGGREGATOR], head.list) {
  602 + struct list_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 606 if (ptr->head.is_deleted ||
463 607 !tomoyo_path_matches_pattern(&rn,
464 608 ptr->original_name))
465 609  
... ... @@ -492,11 +636,21 @@
492 636 }
493 637  
494 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 650 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
497   - /* Transit to the child of tomoyo_kernel_domain domain. */
498   - snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " "
499   - "%s", rn.name);
  651 + /* Transit to the child of current namespace's root. */
  652 + snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
  653 + old_domain->ns->name, rn.name);
500 654 break;
501 655 case TOMOYO_TRANSITION_CONTROL_KEEP:
502 656 /* Keep current domain. */
503 657  
504 658  
... ... @@ -519,19 +673,25 @@
519 673 }
520 674 break;
521 675 }
522   - if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
523   - goto done;
524   - domain = tomoyo_find_domain(tmp);
525 676 if (!domain)
526   - domain = tomoyo_assign_domain(tmp, old_domain->profile);
527   - done:
  677 + domain = tomoyo_assign_domain(tmp, true);
528 678 if (domain)
529   - goto out;
530   - printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp);
531   - if (is_enforce)
532   - retval = -EPERM;
533   - else
534   - old_domain->transition_failed = true;
  679 + retval = 0;
  680 + else if (reject_on_transition_failure) {
  681 + printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", tmp);
  682 + retval = -ENOMEM;
  683 + } else if (r.mode == TOMOYO_CONFIG_ENFORCING)
  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 695 out:
536 696 if (!domain)
537 697 domain = old_domain;
security/tomoyo/file.c
... ... @@ -603,7 +603,7 @@
603 603 int error;
604 604  
605 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 607 if (r->mode == TOMOYO_CONFIG_DISABLED)
608 608 return 0;
609 609 r->param_type = TOMOYO_TYPE_PATH_ACL;
security/tomoyo/gc.c
... ... @@ -292,15 +292,12 @@
292 292 static void tomoyo_collect_entry(void)
293 293 {
294 294 int i;
  295 + enum tomoyo_policy_id id;
  296 + struct tomoyo_policy_namespace *ns;
  297 + int idx;
295 298 if (mutex_lock_interruptible(&tomoyo_policy_lock))
296 299 return;
297   - for (i = 0; i < TOMOYO_MAX_POLICY; i++) {
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;
  300 + idx = tomoyo_read_lock();
304 301 {
305 302 struct tomoyo_domain_info *domain;
306 303 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
307 304  
308 305  
309 306  
310 307  
... ... @@ -317,39 +314,49 @@
317 314 goto unlock;
318 315 }
319 316 }
320   - for (i = 0; i < TOMOYO_MAX_HASH; i++) {
321   - struct tomoyo_name *ptr;
322   - list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], head.list) {
323   - if (atomic_read(&ptr->head.users))
324   - continue;
325   - if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->head.list))
  317 + list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
  318 + for (id = 0; id < TOMOYO_MAX_POLICY; id++)
  319 + if (!tomoyo_collect_member(id, &ns->policy_list[id]))
326 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++) {
330   - struct list_head *list = &tomoyo_group_list[i];
331   - int id;
332   - struct tomoyo_group *group;
333   - switch (i) {
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))
  348 + for (i = 0; i < TOMOYO_MAX_HASH; i++) {
  349 + struct list_head *list = &tomoyo_name_list[i];
  350 + struct tomoyo_shared_acl_head *ptr;
  351 + list_for_each_entry(ptr, list, list) {
  352 + if (atomic_read(&ptr->users))
346 353 continue;
347   - if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
348   - &group->head.list))
  354 + if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
349 355 goto unlock;
350 356 }
351 357 }
352   - unlock:
  358 +unlock:
  359 + tomoyo_read_unlock(idx);
353 360 mutex_unlock(&tomoyo_policy_lock);
354 361 }
355 362  
security/tomoyo/memory.c
... ... @@ -118,7 +118,7 @@
118 118 return NULL;
119 119 if (mutex_lock_interruptible(&tomoyo_policy_lock))
120 120 goto out;
121   - list = &tomoyo_group_list[idx];
  121 + list = &param->ns->group_list[idx];
122 122 list_for_each_entry(group, list, head.list) {
123 123 if (e.group_name != group->group_name)
124 124 continue;
125 125  
126 126  
127 127  
128 128  
... ... @@ -199,27 +199,23 @@
199 199 return ptr ? &ptr->entry : NULL;
200 200 }
201 201  
  202 +/* Initial namespace.*/
  203 +struct tomoyo_policy_namespace tomoyo_kernel_namespace;
  204 +
202 205 /**
203 206 * tomoyo_mm_init - Initialize mm related code.
204 207 */
205 208 void __init tomoyo_mm_init(void)
206 209 {
207 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 211 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
214 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 216 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
216   - for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
217   - INIT_LIST_HEAD(&tomoyo_acl_group[idx]);
218   - tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
  217 + tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
219 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 219 #if 0
224 220 /* Will be replaced with tomoyo_load_builtin_policy(). */
225 221 {
... ... @@ -230,7 +226,6 @@
230 226 TOMOYO_TRANSITION_CONTROL_INITIALIZE);
231 227 }
232 228 #endif
233   - tomoyo_read_unlock(idx);
234 229 }
235 230  
236 231  
security/tomoyo/util.c
... ... @@ -416,26 +416,21 @@
416 416 */
417 417 bool tomoyo_correct_domain(const unsigned char *domainname)
418 418 {
419   - if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
420   - TOMOYO_ROOT_NAME_LEN))
421   - goto out;
422   - domainname += TOMOYO_ROOT_NAME_LEN;
423   - if (!*domainname)
  419 + if (!domainname || !tomoyo_domain_def(domainname))
  420 + return false;
  421 + domainname = strchr(domainname, ' ');
  422 + if (!domainname++)
424 423 return true;
425   - if (*domainname++ != ' ')
426   - goto out;
427 424 while (1) {
428 425 const unsigned char *cp = strchr(domainname, ' ');
429 426 if (!cp)
430 427 break;
431 428 if (*domainname != '/' ||
432 429 !tomoyo_correct_word2(domainname, cp - domainname))
433   - goto out;
  430 + return false;
434 431 domainname = cp + 1;
435 432 }
436 433 return tomoyo_correct_path(domainname);
437   - out:
438   - return false;
439 434 }
440 435  
441 436 /**
... ... @@ -447,7 +442,19 @@
447 442 */
448 443 bool 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 /**
454 461  
455 462  
456 463  
457 464  
... ... @@ -833,22 +840,24 @@
833 840 /**
834 841 * tomoyo_get_mode - Get MAC mode.
835 842 *
  843 + * @ns: Pointer to "struct tomoyo_policy_namespace".
836 844 * @profile: Profile number.
837 845 * @index: Index number of functionality.
838 846 *
839 847 * Returns mode.
840 848 */
841   -int tomoyo_get_mode(const u8 profile, const u8 index)
  849 +int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
  850 + const u8 index)
842 851 {
843 852 u8 mode;
844 853 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
845 854 if (!tomoyo_policy_loaded)
846 855 return TOMOYO_CONFIG_DISABLED;
847   - mode = tomoyo_profile(profile)->config[index];
  856 + mode = tomoyo_profile(ns, profile)->config[index];
848 857 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
849   - mode = tomoyo_profile(profile)->config[category];
  858 + mode = tomoyo_profile(ns, profile)->config[category];
850 859 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
851   - mode = tomoyo_profile(profile)->default_config;
  860 + mode = tomoyo_profile(ns, profile)->default_config;
852 861 return mode & 3;
853 862 }
854 863  
855 864  
... ... @@ -872,26 +881,11 @@
872 881 profile = domain->profile;
873 882 r->profile = profile;
874 883 r->type = index;
875   - r->mode = tomoyo_get_mode(profile, index);
  884 + r->mode = tomoyo_get_mode(domain->ns, profile, index);
876 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   - */
886   -const 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 889 * tomoyo_domain_quota_is_ok - Check for domain's quota.
896 890 *
897 891 * @r: Pointer to "struct tomoyo_request_info".
... ... @@ -939,7 +933,7 @@
939 933 if (perm & (1 << i))
940 934 count++;
941 935 }
942   - if (count < tomoyo_profile(domain->profile)->
  936 + if (count < tomoyo_profile(domain->ns, domain->profile)->
943 937 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
944 938 return true;
945 939 if (!domain->quota_warned) {