aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo')
-rw-r--r--security/tomoyo/common.c119
-rw-r--r--security/tomoyo/common.h134
-rw-r--r--security/tomoyo/domain.c240
-rw-r--r--security/tomoyo/file.c156
-rw-r--r--security/tomoyo/realpath.c23
-rw-r--r--security/tomoyo/tomoyo.c4
-rw-r--r--security/tomoyo/tomoyo.h13
7 files changed, 549 insertions, 140 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ddfb9cccf468..fdd1f4b8c448 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -28,7 +28,13 @@ static const char *tomoyo_mode_2[4] = {
28 "disabled", "enabled", "enabled", "enabled" 28 "disabled", "enabled", "enabled", "enabled"
29}; 29};
30 30
31/* Table for profile. */ 31/*
32 * tomoyo_control_array is a static data which contains
33 *
34 * (1) functionality name used by /sys/kernel/security/tomoyo/profile .
35 * (2) initial values for "struct tomoyo_profile".
36 * (3) max values for "struct tomoyo_profile".
37 */
32static struct { 38static struct {
33 const char *keyword; 39 const char *keyword;
34 unsigned int current_value; 40 unsigned int current_value;
@@ -39,7 +45,13 @@ static struct {
39 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 45 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
40}; 46};
41 47
42/* Profile table. Memory is allocated as needed. */ 48/*
49 * tomoyo_profile is a structure which is used for holding the mode of access
50 * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
51 * An administrator can define up to 256 profiles.
52 * The ->profile of "struct tomoyo_domain_info" is used for remembering
53 * the profile's number (0 - 255) assigned to that domain.
54 */
43static struct tomoyo_profile { 55static struct tomoyo_profile {
44 unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; 56 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
45 const struct tomoyo_path_info *comment; 57 const struct tomoyo_path_info *comment;
@@ -428,7 +440,6 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
428 const char *name = ptr->name; 440 const char *name = ptr->name;
429 const int len = strlen(name); 441 const int len = strlen(name);
430 442
431 ptr->total_len = len;
432 ptr->const_len = tomoyo_const_part_length(name); 443 ptr->const_len = tomoyo_const_part_length(name);
433 ptr->is_dir = len && (name[len - 1] == '/'); 444 ptr->is_dir = len && (name[len - 1] == '/');
434 ptr->is_patterned = (ptr->const_len < len); 445 ptr->is_patterned = (ptr->const_len < len);
@@ -866,7 +877,6 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
866 877
867 if (profile >= TOMOYO_MAX_PROFILES) 878 if (profile >= TOMOYO_MAX_PROFILES)
868 return NULL; 879 return NULL;
869 /***** EXCLUSIVE SECTION START *****/
870 mutex_lock(&lock); 880 mutex_lock(&lock);
871 ptr = tomoyo_profile_ptr[profile]; 881 ptr = tomoyo_profile_ptr[profile];
872 if (ptr) 882 if (ptr)
@@ -880,7 +890,6 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
880 tomoyo_profile_ptr[profile] = ptr; 890 tomoyo_profile_ptr[profile] = ptr;
881 ok: 891 ok:
882 mutex_unlock(&lock); 892 mutex_unlock(&lock);
883 /***** EXCLUSIVE SECTION END *****/
884 return ptr; 893 return ptr;
885} 894}
886 895
@@ -1009,7 +1018,19 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1009 return 0; 1018 return 0;
1010} 1019}
1011 1020
1012/* Structure for policy manager. */ 1021/*
1022 * tomoyo_policy_manager_entry is a structure which is used for holding list of
1023 * domainnames or programs which are permitted to modify configuration via
1024 * /sys/kernel/security/tomoyo/ interface.
1025 * It has following fields.
1026 *
1027 * (1) "list" which is linked to tomoyo_policy_manager_list .
1028 * (2) "manager" is a domainname or a program's pathname.
1029 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false
1030 * otherwise.
1031 * (4) "is_deleted" is a bool which is true if marked as deleted, false
1032 * otherwise.
1033 */
1013struct tomoyo_policy_manager_entry { 1034struct tomoyo_policy_manager_entry {
1014 struct list_head list; 1035 struct list_head list;
1015 /* A path to program or a domainname. */ 1036 /* A path to program or a domainname. */
@@ -1018,7 +1039,36 @@ struct tomoyo_policy_manager_entry {
1018 bool is_deleted; /* True if this entry is deleted. */ 1039 bool is_deleted; /* True if this entry is deleted. */
1019}; 1040};
1020 1041
1021/* The list for "struct tomoyo_policy_manager_entry". */ 1042/*
1043 * tomoyo_policy_manager_list is used for holding list of domainnames or
1044 * programs which are permitted to modify configuration via
1045 * /sys/kernel/security/tomoyo/ interface.
1046 *
1047 * An entry is added by
1048 *
1049 * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
1050 * /sys/kernel/security/tomoyo/manager
1051 * (if you want to specify by a domainname)
1052 *
1053 * or
1054 *
1055 * # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager
1056 * (if you want to specify by a program's location)
1057 *
1058 * and is deleted by
1059 *
1060 * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
1061 * /sys/kernel/security/tomoyo/manager
1062 *
1063 * or
1064 *
1065 * # echo 'delete /usr/lib/ccs/editpolicy' > \
1066 * /sys/kernel/security/tomoyo/manager
1067 *
1068 * and all entries are retrieved by
1069 *
1070 * # cat /sys/kernel/security/tomoyo/manager
1071 */
1022static LIST_HEAD(tomoyo_policy_manager_list); 1072static LIST_HEAD(tomoyo_policy_manager_list);
1023static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); 1073static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1024 1074
@@ -1050,7 +1100,6 @@ static int tomoyo_update_manager_entry(const char *manager,
1050 saved_manager = tomoyo_save_name(manager); 1100 saved_manager = tomoyo_save_name(manager);
1051 if (!saved_manager) 1101 if (!saved_manager)
1052 return -ENOMEM; 1102 return -ENOMEM;
1053 /***** EXCLUSIVE SECTION START *****/
1054 down_write(&tomoyo_policy_manager_list_lock); 1103 down_write(&tomoyo_policy_manager_list_lock);
1055 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1104 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1056 if (ptr->manager != saved_manager) 1105 if (ptr->manager != saved_manager)
@@ -1072,7 +1121,6 @@ static int tomoyo_update_manager_entry(const char *manager,
1072 error = 0; 1121 error = 0;
1073 out: 1122 out:
1074 up_write(&tomoyo_policy_manager_list_lock); 1123 up_write(&tomoyo_policy_manager_list_lock);
1075 /***** EXCLUSIVE SECTION END *****/
1076 return error; 1124 return error;
1077} 1125}
1078 1126
@@ -1117,10 +1165,9 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1117 list); 1165 list);
1118 if (ptr->is_deleted) 1166 if (ptr->is_deleted)
1119 continue; 1167 continue;
1120 if (!tomoyo_io_printf(head, "%s\n", ptr->manager->name)) { 1168 done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
1121 done = false; 1169 if (!done)
1122 break; 1170 break;
1123 }
1124 } 1171 }
1125 up_read(&tomoyo_policy_manager_list_lock); 1172 up_read(&tomoyo_policy_manager_list_lock);
1126 head->read_eof = done; 1173 head->read_eof = done;
@@ -1197,13 +1244,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1197 1244
1198 if (sscanf(data, "pid=%u", &pid) == 1) { 1245 if (sscanf(data, "pid=%u", &pid) == 1) {
1199 struct task_struct *p; 1246 struct task_struct *p;
1200 /***** CRITICAL SECTION START *****/
1201 read_lock(&tasklist_lock); 1247 read_lock(&tasklist_lock);
1202 p = find_task_by_vpid(pid); 1248 p = find_task_by_vpid(pid);
1203 if (p) 1249 if (p)
1204 domain = tomoyo_real_domain(p); 1250 domain = tomoyo_real_domain(p);
1205 read_unlock(&tasklist_lock); 1251 read_unlock(&tasklist_lock);
1206 /***** CRITICAL SECTION END *****/
1207 } else if (!strncmp(data, "domain=", 7)) { 1252 } else if (!strncmp(data, "domain=", 7)) {
1208 if (tomoyo_is_domain_def(data + 7)) { 1253 if (tomoyo_is_domain_def(data + 7)) {
1209 down_read(&tomoyo_domain_list_lock); 1254 down_read(&tomoyo_domain_list_lock);
@@ -1447,15 +1492,14 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1447 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) 1492 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1448 ignore_global_allow_read 1493 ignore_global_allow_read
1449 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1494 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1450 if (!tomoyo_io_printf(head, 1495 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
1451 "%s\n" TOMOYO_KEYWORD_USE_PROFILE "%u\n" 1496 "%u\n%s%s%s\n",
1452 "%s%s%s\n", domain->domainname->name, 1497 domain->domainname->name,
1453 domain->profile, quota_exceeded, 1498 domain->profile, quota_exceeded,
1454 transition_failed, 1499 transition_failed,
1455 ignore_global_allow_read)) { 1500 ignore_global_allow_read);
1456 done = false; 1501 if (!done)
1457 break; 1502 break;
1458 }
1459 head->read_step = 2; 1503 head->read_step = 2;
1460acl_loop: 1504acl_loop:
1461 if (head->read_step == 3) 1505 if (head->read_step == 3)
@@ -1463,24 +1507,22 @@ acl_loop:
1463 /* Print ACL entries in the domain. */ 1507 /* Print ACL entries in the domain. */
1464 down_read(&tomoyo_domain_acl_info_list_lock); 1508 down_read(&tomoyo_domain_acl_info_list_lock);
1465 list_for_each_cookie(apos, head->read_var2, 1509 list_for_each_cookie(apos, head->read_var2,
1466 &domain->acl_info_list) { 1510 &domain->acl_info_list) {
1467 struct tomoyo_acl_info *ptr 1511 struct tomoyo_acl_info *ptr
1468 = list_entry(apos, struct tomoyo_acl_info, 1512 = list_entry(apos, struct tomoyo_acl_info,
1469 list); 1513 list);
1470 if (!tomoyo_print_entry(head, ptr)) { 1514 done = tomoyo_print_entry(head, ptr);
1471 done = false; 1515 if (!done)
1472 break; 1516 break;
1473 }
1474 } 1517 }
1475 up_read(&tomoyo_domain_acl_info_list_lock); 1518 up_read(&tomoyo_domain_acl_info_list_lock);
1476 if (!done) 1519 if (!done)
1477 break; 1520 break;
1478 head->read_step = 3; 1521 head->read_step = 3;
1479tail_mark: 1522tail_mark:
1480 if (!tomoyo_io_printf(head, "\n")) { 1523 done = tomoyo_io_printf(head, "\n");
1481 done = false; 1524 if (!done)
1482 break; 1525 break;
1483 }
1484 head->read_step = 1; 1526 head->read_step = 1;
1485 if (head->read_single_domain) 1527 if (head->read_single_domain)
1486 break; 1528 break;
@@ -1550,11 +1592,10 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1550 domain = list_entry(pos, struct tomoyo_domain_info, list); 1592 domain = list_entry(pos, struct tomoyo_domain_info, list);
1551 if (domain->is_deleted) 1593 if (domain->is_deleted)
1552 continue; 1594 continue;
1553 if (!tomoyo_io_printf(head, "%u %s\n", domain->profile, 1595 done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
1554 domain->domainname->name)) { 1596 domain->domainname->name);
1555 done = false; 1597 if (!done)
1556 break; 1598 break;
1557 }
1558 } 1599 }
1559 up_read(&tomoyo_domain_list_lock); 1600 up_read(&tomoyo_domain_list_lock);
1560 head->read_eof = done; 1601 head->read_eof = done;
@@ -1594,13 +1635,11 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1594 const int pid = head->read_step; 1635 const int pid = head->read_step;
1595 struct task_struct *p; 1636 struct task_struct *p;
1596 struct tomoyo_domain_info *domain = NULL; 1637 struct tomoyo_domain_info *domain = NULL;
1597 /***** CRITICAL SECTION START *****/
1598 read_lock(&tasklist_lock); 1638 read_lock(&tasklist_lock);
1599 p = find_task_by_vpid(pid); 1639 p = find_task_by_vpid(pid);
1600 if (p) 1640 if (p)
1601 domain = tomoyo_real_domain(p); 1641 domain = tomoyo_real_domain(p);
1602 read_unlock(&tasklist_lock); 1642 read_unlock(&tasklist_lock);
1603 /***** CRITICAL SECTION END *****/
1604 if (domain) 1643 if (domain)
1605 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1644 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1606 domain->domainname->name); 1645 domain->domainname->name);
@@ -2138,7 +2177,13 @@ static ssize_t tomoyo_write(struct file *file, const char __user *buf,
2138 return tomoyo_write_control(file, buf, count); 2177 return tomoyo_write_control(file, buf, count);
2139} 2178}
2140 2179
2141/* Operations for /sys/kernel/security/tomoyo/ interface. */ 2180/*
2181 * tomoyo_operations is a "struct file_operations" which is used for handling
2182 * /sys/kernel/security/tomoyo/ interface.
2183 *
2184 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
2185 * See tomoyo_io_buffer for internals.
2186 */
2142static const struct file_operations tomoyo_operations = { 2187static const struct file_operations tomoyo_operations = {
2143 .open = tomoyo_open, 2188 .open = tomoyo_open,
2144 .release = tomoyo_release, 2189 .release = tomoyo_release,
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 678f4ff16aa4..6d6ba09af457 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -26,16 +26,43 @@
26struct dentry; 26struct dentry;
27struct vfsmount; 27struct vfsmount;
28 28
29/* Temporary buffer for holding pathnames. */ 29/*
30 * tomoyo_page_buffer is a structure which is used for holding a pathname
31 * obtained from "struct dentry" and "struct vfsmount" pair.
32 * As of now, it is 4096 bytes. If users complain that 4096 bytes is too small
33 * (because TOMOYO escapes non ASCII printable characters using \ooo format),
34 * we will make the buffer larger.
35 */
30struct tomoyo_page_buffer { 36struct tomoyo_page_buffer {
31 char buffer[4096]; 37 char buffer[4096];
32}; 38};
33 39
34/* Structure for holding a token. */ 40/*
41 * tomoyo_path_info is a structure which is used for holding a string data
42 * used by TOMOYO.
43 * This structure has several fields for supporting pattern matching.
44 *
45 * (1) "name" is the '\0' terminated string data.
46 * (2) "hash" is full_name_hash(name, strlen(name)).
47 * This allows tomoyo_pathcmp() to compare by hash before actually compare
48 * using strcmp().
49 * (3) "const_len" is the length of the initial segment of "name" which
50 * consists entirely of non wildcard characters. In other words, the length
51 * which we can compare two strings using strncmp().
52 * (4) "is_dir" is a bool which is true if "name" ends with "/",
53 * false otherwise.
54 * TOMOYO distinguishes directory and non-directory. A directory ends with
55 * "/" and non-directory does not end with "/".
56 * (5) "is_patterned" is a bool which is true if "name" contains wildcard
57 * characters, false otherwise. This allows TOMOYO to use "hash" and
58 * strcmp() for string comparison if "is_patterned" is false.
59 * (6) "depth" is calculated using the number of "/" characters in "name".
60 * This allows TOMOYO to avoid comparing two pathnames which never match
61 * (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
62 */
35struct tomoyo_path_info { 63struct tomoyo_path_info {
36 const char *name; 64 const char *name;
37 u32 hash; /* = full_name_hash(name, strlen(name)) */ 65 u32 hash; /* = full_name_hash(name, strlen(name)) */
38 u16 total_len; /* = strlen(name) */
39 u16 const_len; /* = tomoyo_const_part_length(name) */ 66 u16 const_len; /* = tomoyo_const_part_length(name) */
40 bool is_dir; /* = tomoyo_strendswith(name, "/") */ 67 bool is_dir; /* = tomoyo_strendswith(name, "/") */
41 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 68 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
@@ -51,7 +78,20 @@ struct tomoyo_path_info {
51 */ 78 */
52#define TOMOYO_MAX_PATHNAME_LEN 4000 79#define TOMOYO_MAX_PATHNAME_LEN 4000
53 80
54/* Structure for holding requested pathname. */ 81/*
82 * tomoyo_path_info_with_data is a structure which is used for holding a
83 * pathname obtained from "struct dentry" and "struct vfsmount" pair.
84 *
85 * "struct tomoyo_path_info_with_data" consists of "struct tomoyo_path_info"
86 * and buffer for the pathname, while "struct tomoyo_page_buffer" consists of
87 * buffer for the pathname only.
88 *
89 * "struct tomoyo_path_info_with_data" is intended to allow TOMOYO to release
90 * both "struct tomoyo_path_info" and buffer for the pathname by single kfree()
91 * so that we don't need to return two pointers to the caller. If the caller
92 * puts "struct tomoyo_path_info" on stack memory, we will be able to remove
93 * "struct tomoyo_path_info_with_data".
94 */
55struct tomoyo_path_info_with_data { 95struct tomoyo_path_info_with_data {
56 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 96 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */
57 struct tomoyo_path_info head; 97 struct tomoyo_path_info head;
@@ -61,7 +101,15 @@ struct tomoyo_path_info_with_data {
61}; 101};
62 102
63/* 103/*
64 * Common header for holding ACL entries. 104 * tomoyo_acl_info is a structure which is used for holding
105 *
106 * (1) "list" which is linked to the ->acl_info_list of
107 * "struct tomoyo_domain_info"
108 * (2) "type" which tells
109 * (a) type & 0x7F : type of the entry (either
110 * "struct tomoyo_single_path_acl_record" or
111 * "struct tomoyo_double_path_acl_record")
112 * (b) type & 0x80 : whether the entry is marked as "deleted".
65 * 113 *
66 * Packing "struct tomoyo_acl_info" allows 114 * Packing "struct tomoyo_acl_info" allows
67 * "struct tomoyo_single_path_acl_record" to embed "u16" and 115 * "struct tomoyo_single_path_acl_record" to embed "u16" and
@@ -81,7 +129,28 @@ struct tomoyo_acl_info {
81/* This ACL entry is deleted. */ 129/* This ACL entry is deleted. */
82#define TOMOYO_ACL_DELETED 0x80 130#define TOMOYO_ACL_DELETED 0x80
83 131
84/* Structure for domain information. */ 132/*
133 * tomoyo_domain_info is a structure which is used for holding permissions
134 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
135 * It has following fields.
136 *
137 * (1) "list" which is linked to tomoyo_domain_list .
138 * (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
139 * (3) "domainname" which holds the name of the domain.
140 * (4) "profile" which remembers profile number assigned to this domain.
141 * (5) "is_deleted" is a bool which is true if this domain is marked as
142 * "deleted", false otherwise.
143 * (6) "quota_warned" is a bool which is used for suppressing warning message
144 * when learning mode learned too much entries.
145 * (7) "flags" which remembers this domain's attributes.
146 *
147 * A domain's lifecycle is an analogy of files on / directory.
148 * Multiple domains with the same domainname cannot be created (as with
149 * creating files with the same filename fails with -EEXIST).
150 * If a process reached a domain, that process can reside in that domain after
151 * that domain is marked as "deleted" (as with a process can access an already
152 * open()ed file after that file was unlink()ed).
153 */
85struct tomoyo_domain_info { 154struct tomoyo_domain_info {
86 struct list_head list; 155 struct list_head list;
87 struct list_head acl_info_list; 156 struct list_head acl_info_list;
@@ -108,10 +177,18 @@ struct tomoyo_domain_info {
108#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 177#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
109 178
110/* 179/*
111 * Structure for "allow_read/write", "allow_execute", "allow_read", 180 * tomoyo_single_path_acl_record is a structure which is used for holding an
112 * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 181 * entry with one pathname operation (e.g. open(), mkdir()).
113 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 182 * It has following fields.
114 * "allow_truncate", "allow_symlink" and "allow_rewrite" directive. 183 *
184 * (1) "head" which is a "struct tomoyo_acl_info".
185 * (2) "perm" which is a bitmask of permitted operations.
186 * (3) "filename" is the pathname.
187 *
188 * Directives held by this structure are "allow_read/write", "allow_execute",
189 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
190 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
191 * "allow_mkchar", "allow_truncate", "allow_symlink" and "allow_rewrite".
115 */ 192 */
116struct tomoyo_single_path_acl_record { 193struct tomoyo_single_path_acl_record {
117 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ 194 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
@@ -120,7 +197,18 @@ struct tomoyo_single_path_acl_record {
120 const struct tomoyo_path_info *filename; 197 const struct tomoyo_path_info *filename;
121}; 198};
122 199
123/* Structure for "allow_rename" and "allow_link" directive. */ 200/*
201 * tomoyo_double_path_acl_record is a structure which is used for holding an
202 * entry with two pathnames operation (i.e. link() and rename()).
203 * It has following fields.
204 *
205 * (1) "head" which is a "struct tomoyo_acl_info".
206 * (2) "perm" which is a bitmask of permitted operations.
207 * (3) "filename1" is the source/old pathname.
208 * (4) "filename2" is the destination/new pathname.
209 *
210 * Directives held by this structure are "allow_rename" and "allow_link".
211 */
124struct tomoyo_double_path_acl_record { 212struct tomoyo_double_path_acl_record {
125 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 213 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
126 u8 perm; 214 u8 perm;
@@ -153,7 +241,29 @@ struct tomoyo_double_path_acl_record {
153#define TOMOYO_VERBOSE 2 241#define TOMOYO_VERBOSE 2
154#define TOMOYO_MAX_CONTROL_INDEX 3 242#define TOMOYO_MAX_CONTROL_INDEX 3
155 243
156/* Structure for reading/writing policy via securityfs interfaces. */ 244/*
245 * tomoyo_io_buffer is a structure which is used for reading and modifying
246 * configuration via /sys/kernel/security/tomoyo/ interface.
247 * It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as
248 * cursors.
249 *
250 * Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of
251 * "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info"
252 * entry has a list of "struct tomoyo_acl_info", we need two cursors when
253 * reading (one is for traversing tomoyo_domain_list and the other is for
254 * traversing "struct tomoyo_acl_info"->acl_info_list ).
255 *
256 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
257 * "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the
258 * domain with the domainname specified by the rest of that line (NULL is set
259 * if seek failed).
260 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
261 * "delete ", TOMOYO deletes an entry or a domain specified by the rest of that
262 * line (->write_var1 is set to NULL if a domain was deleted).
263 * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
264 * neither "select " nor "delete ", an entry or a domain specified by that line
265 * is appended.
266 */
157struct tomoyo_io_buffer { 267struct tomoyo_io_buffer {
158 int (*read) (struct tomoyo_io_buffer *); 268 int (*read) (struct tomoyo_io_buffer *);
159 int (*write) (struct tomoyo_io_buffer *); 269 int (*write) (struct tomoyo_io_buffer *);
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 2d6748741a26..1d8b16960576 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -19,11 +19,63 @@
19/* The initial domain. */ 19/* The initial domain. */
20struct tomoyo_domain_info tomoyo_kernel_domain; 20struct tomoyo_domain_info tomoyo_kernel_domain;
21 21
22/* The list for "struct tomoyo_domain_info". */ 22/*
23 * tomoyo_domain_list is used for holding list of domains.
24 * The ->acl_info_list of "struct tomoyo_domain_info" is used for holding
25 * permissions (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
26 *
27 * An entry is added by
28 *
29 * # ( echo "<kernel>"; echo "allow_execute /sbin/init" ) > \
30 * /sys/kernel/security/tomoyo/domain_policy
31 *
32 * and is deleted by
33 *
34 * # ( echo "<kernel>"; echo "delete allow_execute /sbin/init" ) > \
35 * /sys/kernel/security/tomoyo/domain_policy
36 *
37 * and all entries are retrieved by
38 *
39 * # cat /sys/kernel/security/tomoyo/domain_policy
40 *
41 * A domain is added by
42 *
43 * # echo "<kernel>" > /sys/kernel/security/tomoyo/domain_policy
44 *
45 * and is deleted by
46 *
47 * # echo "delete <kernel>" > /sys/kernel/security/tomoyo/domain_policy
48 *
49 * and all domains are retrieved by
50 *
51 * # grep '^<kernel>' /sys/kernel/security/tomoyo/domain_policy
52 *
53 * Normally, a domainname is monotonically getting longer because a domainname
54 * which the process will belong to if an execve() operation succeeds is
55 * defined as a concatenation of "current domainname" + "pathname passed to
56 * execve()".
57 * See tomoyo_domain_initializer_list and tomoyo_domain_keeper_list for
58 * exceptions.
59 */
23LIST_HEAD(tomoyo_domain_list); 60LIST_HEAD(tomoyo_domain_list);
24DECLARE_RWSEM(tomoyo_domain_list_lock); 61DECLARE_RWSEM(tomoyo_domain_list_lock);
25 62
26/* Structure for "initialize_domain" and "no_initialize_domain" keyword. */ 63/*
64 * tomoyo_domain_initializer_entry is a structure which is used for holding
65 * "initialize_domain" and "no_initialize_domain" entries.
66 * It has following fields.
67 *
68 * (1) "list" which is linked to tomoyo_domain_initializer_list .
69 * (2) "domainname" which is "a domainname" or "the last component of a
70 * domainname". This field is NULL if "from" clause is not specified.
71 * (3) "program" which is a program's pathname.
72 * (4) "is_deleted" is a bool which is true if marked as deleted, false
73 * otherwise.
74 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
75 * otherwise.
76 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
77 * component of a domainname", false otherwise.
78 */
27struct tomoyo_domain_initializer_entry { 79struct tomoyo_domain_initializer_entry {
28 struct list_head list; 80 struct list_head list;
29 const struct tomoyo_path_info *domainname; /* This may be NULL */ 81 const struct tomoyo_path_info *domainname; /* This may be NULL */
@@ -34,7 +86,23 @@ struct tomoyo_domain_initializer_entry {
34 bool is_last_name; 86 bool is_last_name;
35}; 87};
36 88
37/* Structure for "keep_domain" and "no_keep_domain" keyword. */ 89/*
90 * tomoyo_domain_keeper_entry is a structure which is used for holding
91 * "keep_domain" and "no_keep_domain" entries.
92 * It has following fields.
93 *
94 * (1) "list" which is linked to tomoyo_domain_keeper_list .
95 * (2) "domainname" which is "a domainname" or "the last component of a
96 * domainname".
97 * (3) "program" which is a program's pathname.
98 * This field is NULL if "from" clause is not specified.
99 * (4) "is_deleted" is a bool which is true if marked as deleted, false
100 * otherwise.
101 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
102 * otherwise.
103 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
104 * component of a domainname", false otherwise.
105 */
38struct tomoyo_domain_keeper_entry { 106struct tomoyo_domain_keeper_entry {
39 struct list_head list; 107 struct list_head list;
40 const struct tomoyo_path_info *domainname; 108 const struct tomoyo_path_info *domainname;
@@ -45,7 +113,16 @@ struct tomoyo_domain_keeper_entry {
45 bool is_last_name; 113 bool is_last_name;
46}; 114};
47 115
48/* Structure for "alias" keyword. */ 116/*
117 * tomoyo_alias_entry is a structure which is used for holding "alias" entries.
118 * It has following fields.
119 *
120 * (1) "list" which is linked to tomoyo_alias_list .
121 * (2) "original_name" which is a dereferenced pathname.
122 * (3) "aliased_name" which is a symlink's pathname.
123 * (4) "is_deleted" is a bool which is true if marked as deleted, false
124 * otherwise.
125 */
49struct tomoyo_alias_entry { 126struct tomoyo_alias_entry {
50 struct list_head list; 127 struct list_head list;
51 const struct tomoyo_path_info *original_name; 128 const struct tomoyo_path_info *original_name;
@@ -67,14 +144,12 @@ void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
67{ 144{
68 /* We need to serialize because this is bitfield operation. */ 145 /* We need to serialize because this is bitfield operation. */
69 static DEFINE_SPINLOCK(lock); 146 static DEFINE_SPINLOCK(lock);
70 /***** CRITICAL SECTION START *****/
71 spin_lock(&lock); 147 spin_lock(&lock);
72 if (!is_delete) 148 if (!is_delete)
73 domain->flags |= flags; 149 domain->flags |= flags;
74 else 150 else
75 domain->flags &= ~flags; 151 domain->flags &= ~flags;
76 spin_unlock(&lock); 152 spin_unlock(&lock);
77 /***** CRITICAL SECTION END *****/
78} 153}
79 154
80/** 155/**
@@ -94,7 +169,42 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
94 return cp0; 169 return cp0;
95} 170}
96 171
97/* The list for "struct tomoyo_domain_initializer_entry". */ 172/*
173 * tomoyo_domain_initializer_list is used for holding list of programs which
174 * triggers reinitialization of domainname. Normally, a domainname is
175 * monotonically getting longer. But sometimes, we restart daemon programs.
176 * It would be convenient for us that "a daemon started upon system boot" and
177 * "the daemon restarted from console" belong to the same domain. Thus, TOMOYO
178 * provides a way to shorten domainnames.
179 *
180 * An entry is added by
181 *
182 * # echo 'initialize_domain /usr/sbin/httpd' > \
183 * /sys/kernel/security/tomoyo/exception_policy
184 *
185 * and is deleted by
186 *
187 * # echo 'delete initialize_domain /usr/sbin/httpd' > \
188 * /sys/kernel/security/tomoyo/exception_policy
189 *
190 * and all entries are retrieved by
191 *
192 * # grep ^initialize_domain /sys/kernel/security/tomoyo/exception_policy
193 *
194 * In the example above, /usr/sbin/httpd will belong to
195 * "<kernel> /usr/sbin/httpd" domain.
196 *
197 * You may specify a domainname using "from" keyword.
198 * "initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
199 * will cause "/usr/sbin/httpd" executed from "<kernel> /etc/rc.d/init.d/httpd"
200 * domain to belong to "<kernel> /usr/sbin/httpd" domain.
201 *
202 * You may add "no_" prefix to "initialize_domain".
203 * "initialize_domain /usr/sbin/httpd" and
204 * "no_initialize_domain /usr/sbin/httpd from <kernel> /etc/rc.d/init.d/httpd"
205 * will cause "/usr/sbin/httpd" to belong to "<kernel> /usr/sbin/httpd" domain
206 * unless executed from "<kernel> /etc/rc.d/init.d/httpd" domain.
207 */
98static LIST_HEAD(tomoyo_domain_initializer_list); 208static LIST_HEAD(tomoyo_domain_initializer_list);
99static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); 209static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
100 210
@@ -135,7 +245,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
135 saved_program = tomoyo_save_name(program); 245 saved_program = tomoyo_save_name(program);
136 if (!saved_program) 246 if (!saved_program)
137 return -ENOMEM; 247 return -ENOMEM;
138 /***** EXCLUSIVE SECTION START *****/
139 down_write(&tomoyo_domain_initializer_list_lock); 248 down_write(&tomoyo_domain_initializer_list_lock);
140 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 249 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
141 if (ptr->is_not != is_not || 250 if (ptr->is_not != is_not ||
@@ -161,7 +270,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
161 error = 0; 270 error = 0;
162 out: 271 out:
163 up_write(&tomoyo_domain_initializer_list_lock); 272 up_write(&tomoyo_domain_initializer_list_lock);
164 /***** EXCLUSIVE SECTION END *****/
165 return error; 273 return error;
166} 274}
167 275
@@ -193,13 +301,12 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
193 from = " from "; 301 from = " from ";
194 domain = ptr->domainname->name; 302 domain = ptr->domainname->name;
195 } 303 }
196 if (!tomoyo_io_printf(head, 304 done = tomoyo_io_printf(head,
197 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN 305 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN
198 "%s%s%s\n", no, ptr->program->name, from, 306 "%s%s%s\n", no, ptr->program->name,
199 domain)) { 307 from, domain);
200 done = false; 308 if (!done)
201 break; 309 break;
202 }
203 } 310 }
204 up_read(&tomoyo_domain_initializer_list_lock); 311 up_read(&tomoyo_domain_initializer_list_lock);
205 return done; 312 return done;
@@ -273,7 +380,44 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
273 return flag; 380 return flag;
274} 381}
275 382
276/* The list for "struct tomoyo_domain_keeper_entry". */ 383/*
384 * tomoyo_domain_keeper_list is used for holding list of domainnames which
385 * suppresses domain transition. Normally, a domainname is monotonically
386 * getting longer. But sometimes, we want to suppress domain transition.
387 * It would be convenient for us that programs executed from a login session
388 * belong to the same domain. Thus, TOMOYO provides a way to suppress domain
389 * transition.
390 *
391 * An entry is added by
392 *
393 * # echo 'keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
394 * /sys/kernel/security/tomoyo/exception_policy
395 *
396 * and is deleted by
397 *
398 * # echo 'delete keep_domain <kernel> /usr/sbin/sshd /bin/bash' > \
399 * /sys/kernel/security/tomoyo/exception_policy
400 *
401 * and all entries are retrieved by
402 *
403 * # grep ^keep_domain /sys/kernel/security/tomoyo/exception_policy
404 *
405 * In the example above, any process which belongs to
406 * "<kernel> /usr/sbin/sshd /bin/bash" domain will remain in that domain,
407 * unless explicitly specified by "initialize_domain" or "no_keep_domain".
408 *
409 * You may specify a program using "from" keyword.
410 * "keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash"
411 * will cause "/bin/pwd" executed from "<kernel> /usr/sbin/sshd /bin/bash"
412 * domain to remain in "<kernel> /usr/sbin/sshd /bin/bash" domain.
413 *
414 * You may add "no_" prefix to "keep_domain".
415 * "keep_domain <kernel> /usr/sbin/sshd /bin/bash" and
416 * "no_keep_domain /usr/bin/passwd from <kernel> /usr/sbin/sshd /bin/bash" will
417 * cause "/usr/bin/passwd" to belong to
418 * "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain, unless
419 * explicitly specified by "initialize_domain".
420 */
277static LIST_HEAD(tomoyo_domain_keeper_list); 421static LIST_HEAD(tomoyo_domain_keeper_list);
278static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); 422static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
279 423
@@ -296,7 +440,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
296 struct tomoyo_domain_keeper_entry *ptr; 440 struct tomoyo_domain_keeper_entry *ptr;
297 const struct tomoyo_path_info *saved_domainname; 441 const struct tomoyo_path_info *saved_domainname;
298 const struct tomoyo_path_info *saved_program = NULL; 442 const struct tomoyo_path_info *saved_program = NULL;
299 static DEFINE_MUTEX(lock);
300 int error = -ENOMEM; 443 int error = -ENOMEM;
301 bool is_last_name = false; 444 bool is_last_name = false;
302 445
@@ -315,7 +458,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
315 saved_domainname = tomoyo_save_name(domainname); 458 saved_domainname = tomoyo_save_name(domainname);
316 if (!saved_domainname) 459 if (!saved_domainname)
317 return -ENOMEM; 460 return -ENOMEM;
318 /***** EXCLUSIVE SECTION START *****/
319 down_write(&tomoyo_domain_keeper_list_lock); 461 down_write(&tomoyo_domain_keeper_list_lock);
320 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 462 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
321 if (ptr->is_not != is_not || 463 if (ptr->is_not != is_not ||
@@ -341,7 +483,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
341 error = 0; 483 error = 0;
342 out: 484 out:
343 up_write(&tomoyo_domain_keeper_list_lock); 485 up_write(&tomoyo_domain_keeper_list_lock);
344 /***** EXCLUSIVE SECTION END *****/
345 return error; 486 return error;
346} 487}
347 488
@@ -394,13 +535,12 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
394 from = " from "; 535 from = " from ";
395 program = ptr->program->name; 536 program = ptr->program->name;
396 } 537 }
397 if (!tomoyo_io_printf(head, 538 done = tomoyo_io_printf(head,
398 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN 539 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN
399 "%s%s%s\n", no, program, from, 540 "%s%s%s\n", no, program, from,
400 ptr->domainname->name)) { 541 ptr->domainname->name);
401 done = false; 542 if (!done)
402 break; 543 break;
403 }
404 } 544 }
405 up_read(&tomoyo_domain_keeper_list_lock); 545 up_read(&tomoyo_domain_keeper_list_lock);
406 return done; 546 return done;
@@ -446,7 +586,36 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
446 return flag; 586 return flag;
447} 587}
448 588
449/* The list for "struct tomoyo_alias_entry". */ 589/*
590 * tomoyo_alias_list is used for holding list of symlink's pathnames which are
591 * allowed to be passed to an execve() request. Normally, the domainname which
592 * the current process will belong to after execve() succeeds is calculated
593 * using dereferenced pathnames. But some programs behave differently depending
594 * on the name passed to argv[0]. For busybox, calculating domainname using
595 * dereferenced pathnames will cause all programs in the busybox to belong to
596 * the same domain. Thus, TOMOYO provides a way to allow use of symlink's
597 * pathname for checking execve()'s permission and calculating domainname which
598 * the current process will belong to after execve() succeeds.
599 *
600 * An entry is added by
601 *
602 * # echo 'alias /bin/busybox /bin/cat' > \
603 * /sys/kernel/security/tomoyo/exception_policy
604 *
605 * and is deleted by
606 *
607 * # echo 'delete alias /bin/busybox /bin/cat' > \
608 * /sys/kernel/security/tomoyo/exception_policy
609 *
610 * and all entries are retrieved by
611 *
612 * # grep ^alias /sys/kernel/security/tomoyo/exception_policy
613 *
614 * In the example above, if /bin/cat is a symlink to /bin/busybox and execution
615 * of /bin/cat is requested, permission is checked for /bin/cat rather than
616 * /bin/busybox and domainname which the current process will belong to after
617 * execve() succeeds is calculated using /bin/cat rather than /bin/busybox .
618 */
450static LIST_HEAD(tomoyo_alias_list); 619static LIST_HEAD(tomoyo_alias_list);
451static DECLARE_RWSEM(tomoyo_alias_list_lock); 620static DECLARE_RWSEM(tomoyo_alias_list_lock);
452 621
@@ -476,7 +645,6 @@ static int tomoyo_update_alias_entry(const char *original_name,
476 saved_aliased_name = tomoyo_save_name(aliased_name); 645 saved_aliased_name = tomoyo_save_name(aliased_name);
477 if (!saved_original_name || !saved_aliased_name) 646 if (!saved_original_name || !saved_aliased_name)
478 return -ENOMEM; 647 return -ENOMEM;
479 /***** EXCLUSIVE SECTION START *****/
480 down_write(&tomoyo_alias_list_lock); 648 down_write(&tomoyo_alias_list_lock);
481 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 649 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
482 if (ptr->original_name != saved_original_name || 650 if (ptr->original_name != saved_original_name ||
@@ -499,7 +667,6 @@ static int tomoyo_update_alias_entry(const char *original_name,
499 error = 0; 667 error = 0;
500 out: 668 out:
501 up_write(&tomoyo_alias_list_lock); 669 up_write(&tomoyo_alias_list_lock);
502 /***** EXCLUSIVE SECTION END *****/
503 return error; 670 return error;
504} 671}
505 672
@@ -522,12 +689,11 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
522 ptr = list_entry(pos, struct tomoyo_alias_entry, list); 689 ptr = list_entry(pos, struct tomoyo_alias_entry, list);
523 if (ptr->is_deleted) 690 if (ptr->is_deleted)
524 continue; 691 continue;
525 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n", 692 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n",
526 ptr->original_name->name, 693 ptr->original_name->name,
527 ptr->aliased_name->name)) { 694 ptr->aliased_name->name);
528 done = false; 695 if (!done)
529 break; 696 break;
530 }
531 } 697 }
532 up_read(&tomoyo_alias_list_lock); 698 up_read(&tomoyo_alias_list_lock);
533 return done; 699 return done;
@@ -567,7 +733,6 @@ int tomoyo_delete_domain(char *domainname)
567 733
568 name.name = domainname; 734 name.name = domainname;
569 tomoyo_fill_path_info(&name); 735 tomoyo_fill_path_info(&name);
570 /***** EXCLUSIVE SECTION START *****/
571 down_write(&tomoyo_domain_list_lock); 736 down_write(&tomoyo_domain_list_lock);
572 /* Is there an active domain? */ 737 /* Is there an active domain? */
573 list_for_each_entry(domain, &tomoyo_domain_list, list) { 738 list_for_each_entry(domain, &tomoyo_domain_list, list) {
@@ -581,7 +746,6 @@ int tomoyo_delete_domain(char *domainname)
581 break; 746 break;
582 } 747 }
583 up_write(&tomoyo_domain_list_lock); 748 up_write(&tomoyo_domain_list_lock);
584 /***** EXCLUSIVE SECTION END *****/
585 return 0; 749 return 0;
586} 750}
587 751
@@ -600,7 +764,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
600 struct tomoyo_domain_info *domain = NULL; 764 struct tomoyo_domain_info *domain = NULL;
601 const struct tomoyo_path_info *saved_domainname; 765 const struct tomoyo_path_info *saved_domainname;
602 766
603 /***** EXCLUSIVE SECTION START *****/
604 down_write(&tomoyo_domain_list_lock); 767 down_write(&tomoyo_domain_list_lock);
605 domain = tomoyo_find_domain(domainname); 768 domain = tomoyo_find_domain(domainname);
606 if (domain) 769 if (domain)
@@ -619,7 +782,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
619 domain->domainname != saved_domainname) 782 domain->domainname != saved_domainname)
620 continue; 783 continue;
621 flag = false; 784 flag = false;
622 /***** CRITICAL SECTION START *****/
623 read_lock(&tasklist_lock); 785 read_lock(&tasklist_lock);
624 for_each_process(p) { 786 for_each_process(p) {
625 if (tomoyo_real_domain(p) != domain) 787 if (tomoyo_real_domain(p) != domain)
@@ -628,7 +790,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
628 break; 790 break;
629 } 791 }
630 read_unlock(&tasklist_lock); 792 read_unlock(&tasklist_lock);
631 /***** CRITICAL SECTION END *****/
632 if (flag) 793 if (flag)
633 continue; 794 continue;
634 list_for_each_entry(ptr, &domain->acl_info_list, list) { 795 list_for_each_entry(ptr, &domain->acl_info_list, list) {
@@ -651,7 +812,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
651 } 812 }
652 out: 813 out:
653 up_write(&tomoyo_domain_list_lock); 814 up_write(&tomoyo_domain_list_lock);
654 /***** EXCLUSIVE SECTION END *****/
655 return domain; 815 return domain;
656} 816}
657 817
@@ -739,7 +899,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm,
739 } 899 }
740 900
741 /* Check execute permission. */ 901 /* Check execute permission. */
742 retval = tomoyo_check_exec_perm(old_domain, &r, tmp); 902 retval = tomoyo_check_exec_perm(old_domain, &r);
743 if (retval < 0) 903 if (retval < 0)
744 goto out; 904 goto out;
745 905
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 2316da8ec5bc..5ae3a571559f 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -14,21 +14,50 @@
14#include "realpath.h" 14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) 15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16 16
17/* Structure for "allow_read" keyword. */ 17/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding
19 * "allow_read" entries.
20 * It has following fields.
21 *
22 * (1) "list" which is linked to tomoyo_globally_readable_list .
23 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
24 * (3) "is_deleted" is a bool which is true if marked as deleted, false
25 * otherwise.
26 */
18struct tomoyo_globally_readable_file_entry { 27struct tomoyo_globally_readable_file_entry {
19 struct list_head list; 28 struct list_head list;
20 const struct tomoyo_path_info *filename; 29 const struct tomoyo_path_info *filename;
21 bool is_deleted; 30 bool is_deleted;
22}; 31};
23 32
24/* Structure for "file_pattern" keyword. */ 33/*
34 * tomoyo_pattern_entry is a structure which is used for holding
35 * "tomoyo_pattern_list" entries.
36 * It has following fields.
37 *
38 * (1) "list" which is linked to tomoyo_pattern_list .
39 * (2) "pattern" is a pathname pattern which is used for converting pathnames
40 * to pathname patterns during learning mode.
41 * (3) "is_deleted" is a bool which is true if marked as deleted, false
42 * otherwise.
43 */
25struct tomoyo_pattern_entry { 44struct tomoyo_pattern_entry {
26 struct list_head list; 45 struct list_head list;
27 const struct tomoyo_path_info *pattern; 46 const struct tomoyo_path_info *pattern;
28 bool is_deleted; 47 bool is_deleted;
29}; 48};
30 49
31/* Structure for "deny_rewrite" keyword. */ 50/*
51 * tomoyo_no_rewrite_entry is a structure which is used for holding
52 * "deny_rewrite" entries.
53 * It has following fields.
54 *
55 * (1) "list" which is linked to tomoyo_no_rewrite_list .
56 * (2) "pattern" is a pathname which is by default not permitted to modify
57 * already existing content.
58 * (3) "is_deleted" is a bool which is true if marked as deleted, false
59 * otherwise.
60 */
32struct tomoyo_no_rewrite_entry { 61struct tomoyo_no_rewrite_entry {
33 struct list_head list; 62 struct list_head list;
34 const struct tomoyo_path_info *pattern; 63 const struct tomoyo_path_info *pattern;
@@ -141,7 +170,31 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
141 struct tomoyo_domain_info * 170 struct tomoyo_domain_info *
142 const domain, const bool is_delete); 171 const domain, const bool is_delete);
143 172
144/* The list for "struct tomoyo_globally_readable_file_entry". */ 173/*
174 * tomoyo_globally_readable_list is used for holding list of pathnames which
175 * are by default allowed to be open()ed for reading by any process.
176 *
177 * An entry is added by
178 *
179 * # echo 'allow_read /lib/libc-2.5.so' > \
180 * /sys/kernel/security/tomoyo/exception_policy
181 *
182 * and is deleted by
183 *
184 * # echo 'delete allow_read /lib/libc-2.5.so' > \
185 * /sys/kernel/security/tomoyo/exception_policy
186 *
187 * and all entries are retrieved by
188 *
189 * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy
190 *
191 * In the example above, any process is allowed to
192 * open("/lib/libc-2.5.so", O_RDONLY).
193 * One exception is, if the domain which current process belongs to is marked
194 * as "ignore_global_allow_read", current process can't do so unless explicitly
195 * given "allow_read /lib/libc-2.5.so" to the domain which current process
196 * belongs to.
197 */
145static LIST_HEAD(tomoyo_globally_readable_list); 198static LIST_HEAD(tomoyo_globally_readable_list);
146static DECLARE_RWSEM(tomoyo_globally_readable_list_lock); 199static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
147 200
@@ -166,7 +219,6 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
166 saved_filename = tomoyo_save_name(filename); 219 saved_filename = tomoyo_save_name(filename);
167 if (!saved_filename) 220 if (!saved_filename)
168 return -ENOMEM; 221 return -ENOMEM;
169 /***** EXCLUSIVE SECTION START *****/
170 down_write(&tomoyo_globally_readable_list_lock); 222 down_write(&tomoyo_globally_readable_list_lock);
171 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 223 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
172 if (ptr->filename != saved_filename) 224 if (ptr->filename != saved_filename)
@@ -187,7 +239,6 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
187 error = 0; 239 error = 0;
188 out: 240 out:
189 up_write(&tomoyo_globally_readable_list_lock); 241 up_write(&tomoyo_globally_readable_list_lock);
190 /***** EXCLUSIVE SECTION END *****/
191 return error; 242 return error;
192} 243}
193 244
@@ -249,17 +300,44 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
249 list); 300 list);
250 if (ptr->is_deleted) 301 if (ptr->is_deleted)
251 continue; 302 continue;
252 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n", 303 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n",
253 ptr->filename->name)) { 304 ptr->filename->name);
254 done = false; 305 if (!done)
255 break; 306 break;
256 }
257 } 307 }
258 up_read(&tomoyo_globally_readable_list_lock); 308 up_read(&tomoyo_globally_readable_list_lock);
259 return done; 309 return done;
260} 310}
261 311
262/* The list for "struct tomoyo_pattern_entry". */ 312/* tomoyo_pattern_list is used for holding list of pathnames which are used for
313 * converting pathnames to pathname patterns during learning mode.
314 *
315 * An entry is added by
316 *
317 * # echo 'file_pattern /proc/\$/mounts' > \
318 * /sys/kernel/security/tomoyo/exception_policy
319 *
320 * and is deleted by
321 *
322 * # echo 'delete file_pattern /proc/\$/mounts' > \
323 * /sys/kernel/security/tomoyo/exception_policy
324 *
325 * and all entries are retrieved by
326 *
327 * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy
328 *
329 * In the example above, if a process which belongs to a domain which is in
330 * learning mode requested open("/proc/1/mounts", O_RDONLY),
331 * "allow_read /proc/\$/mounts" is automatically added to the domain which that
332 * process belongs to.
333 *
334 * It is not a desirable behavior that we have to use /proc/\$/ instead of
335 * /proc/self/ when current process needs to access only current process's
336 * information. As of now, LSM version of TOMOYO is using __d_path() for
337 * calculating pathname. Non LSM version of TOMOYO is using its own function
338 * which pretends as if /proc/self/ is not a symlink; so that we can forbid
339 * current process from accessing other process's information.
340 */
263static LIST_HEAD(tomoyo_pattern_list); 341static LIST_HEAD(tomoyo_pattern_list);
264static DECLARE_RWSEM(tomoyo_pattern_list_lock); 342static DECLARE_RWSEM(tomoyo_pattern_list_lock);
265 343
@@ -284,7 +362,6 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
284 saved_pattern = tomoyo_save_name(pattern); 362 saved_pattern = tomoyo_save_name(pattern);
285 if (!saved_pattern) 363 if (!saved_pattern)
286 return -ENOMEM; 364 return -ENOMEM;
287 /***** EXCLUSIVE SECTION START *****/
288 down_write(&tomoyo_pattern_list_lock); 365 down_write(&tomoyo_pattern_list_lock);
289 list_for_each_entry(ptr, &tomoyo_pattern_list, list) { 366 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
290 if (saved_pattern != ptr->pattern) 367 if (saved_pattern != ptr->pattern)
@@ -305,7 +382,6 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
305 error = 0; 382 error = 0;
306 out: 383 out:
307 up_write(&tomoyo_pattern_list_lock); 384 up_write(&tomoyo_pattern_list_lock);
308 /***** EXCLUSIVE SECTION END *****/
309 return error; 385 return error;
310} 386}
311 387
@@ -373,17 +449,44 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
373 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 449 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
374 if (ptr->is_deleted) 450 if (ptr->is_deleted)
375 continue; 451 continue;
376 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN "%s\n", 452 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN
377 ptr->pattern->name)) { 453 "%s\n", ptr->pattern->name);
378 done = false; 454 if (!done)
379 break; 455 break;
380 }
381 } 456 }
382 up_read(&tomoyo_pattern_list_lock); 457 up_read(&tomoyo_pattern_list_lock);
383 return done; 458 return done;
384} 459}
385 460
386/* The list for "struct tomoyo_no_rewrite_entry". */ 461/*
462 * tomoyo_no_rewrite_list is used for holding list of pathnames which are by
463 * default forbidden to modify already written content of a file.
464 *
465 * An entry is added by
466 *
467 * # echo 'deny_rewrite /var/log/messages' > \
468 * /sys/kernel/security/tomoyo/exception_policy
469 *
470 * and is deleted by
471 *
472 * # echo 'delete deny_rewrite /var/log/messages' > \
473 * /sys/kernel/security/tomoyo/exception_policy
474 *
475 * and all entries are retrieved by
476 *
477 * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy
478 *
479 * In the example above, if a process requested to rewrite /var/log/messages ,
480 * the process can't rewrite unless the domain which that process belongs to
481 * has "allow_rewrite /var/log/messages" entry.
482 *
483 * It is not a desirable behavior that we have to add "\040(deleted)" suffix
484 * when we want to allow rewriting already unlink()ed file. As of now,
485 * LSM version of TOMOYO is using __d_path() for calculating pathname.
486 * Non LSM version of TOMOYO is using its own function which doesn't append
487 * " (deleted)" suffix if the file is already unlink()ed; so that we don't
488 * need to worry whether the file is already unlink()ed or not.
489 */
387static LIST_HEAD(tomoyo_no_rewrite_list); 490static LIST_HEAD(tomoyo_no_rewrite_list);
388static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock); 491static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
389 492
@@ -407,7 +510,6 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
407 saved_pattern = tomoyo_save_name(pattern); 510 saved_pattern = tomoyo_save_name(pattern);
408 if (!saved_pattern) 511 if (!saved_pattern)
409 return -ENOMEM; 512 return -ENOMEM;
410 /***** EXCLUSIVE SECTION START *****/
411 down_write(&tomoyo_no_rewrite_list_lock); 513 down_write(&tomoyo_no_rewrite_list_lock);
412 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { 514 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
413 if (ptr->pattern != saved_pattern) 515 if (ptr->pattern != saved_pattern)
@@ -428,7 +530,6 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
428 error = 0; 530 error = 0;
429 out: 531 out:
430 up_write(&tomoyo_no_rewrite_list_lock); 532 up_write(&tomoyo_no_rewrite_list_lock);
431 /***** EXCLUSIVE SECTION END *****/
432 return error; 533 return error;
433} 534}
434 535
@@ -489,11 +590,10 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
489 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 590 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
490 if (ptr->is_deleted) 591 if (ptr->is_deleted)
491 continue; 592 continue;
492 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE "%s\n", 593 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE
493 ptr->pattern->name)) { 594 "%s\n", ptr->pattern->name);
494 done = false; 595 if (!done)
495 break; 596 break;
496 }
497 } 597 }
498 up_read(&tomoyo_no_rewrite_list_lock); 598 up_read(&tomoyo_no_rewrite_list_lock);
499 return done; 599 return done;
@@ -745,7 +845,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
745 saved_filename = tomoyo_save_name(filename); 845 saved_filename = tomoyo_save_name(filename);
746 if (!saved_filename) 846 if (!saved_filename)
747 return -ENOMEM; 847 return -ENOMEM;
748 /***** EXCLUSIVE SECTION START *****/
749 down_write(&tomoyo_domain_acl_info_list_lock); 848 down_write(&tomoyo_domain_acl_info_list_lock);
750 if (is_delete) 849 if (is_delete)
751 goto delete; 850 goto delete;
@@ -800,7 +899,6 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
800 } 899 }
801 out: 900 out:
802 up_write(&tomoyo_domain_acl_info_list_lock); 901 up_write(&tomoyo_domain_acl_info_list_lock);
803 /***** EXCLUSIVE SECTION END *****/
804 return error; 902 return error;
805} 903}
806 904
@@ -836,7 +934,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
836 saved_filename2 = tomoyo_save_name(filename2); 934 saved_filename2 = tomoyo_save_name(filename2);
837 if (!saved_filename1 || !saved_filename2) 935 if (!saved_filename1 || !saved_filename2)
838 return -ENOMEM; 936 return -ENOMEM;
839 /***** EXCLUSIVE SECTION START *****/
840 down_write(&tomoyo_domain_acl_info_list_lock); 937 down_write(&tomoyo_domain_acl_info_list_lock);
841 if (is_delete) 938 if (is_delete)
842 goto delete; 939 goto delete;
@@ -884,7 +981,6 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
884 } 981 }
885 out: 982 out:
886 up_write(&tomoyo_domain_acl_info_list_lock); 983 up_write(&tomoyo_domain_acl_info_list_lock);
887 /***** EXCLUSIVE SECTION END *****/
888 return error; 984 return error;
889} 985}
890 986
@@ -1025,13 +1121,11 @@ int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
1025 * 1121 *
1026 * @domain: Pointer to "struct tomoyo_domain_info". 1122 * @domain: Pointer to "struct tomoyo_domain_info".
1027 * @filename: Check permission for "execute". 1123 * @filename: Check permission for "execute".
1028 * @tmp: Buffer for temporary use.
1029 * 1124 *
1030 * Returns 0 on success, negativevalue otherwise. 1125 * Returns 0 on success, negativevalue otherwise.
1031 */ 1126 */
1032int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1127int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1033 const struct tomoyo_path_info *filename, 1128 const struct tomoyo_path_info *filename)
1034 struct tomoyo_page_buffer *tmp)
1035{ 1129{
1036 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1130 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1037 1131
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 40927a84cb6e..5f2e33263371 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -220,7 +220,6 @@ void *tomoyo_alloc_element(const unsigned int size)
220 = roundup(size, max(sizeof(void *), sizeof(long))); 220 = roundup(size, max(sizeof(void *), sizeof(long)));
221 if (word_aligned_size > PATH_MAX) 221 if (word_aligned_size > PATH_MAX)
222 return NULL; 222 return NULL;
223 /***** EXCLUSIVE SECTION START *****/
224 mutex_lock(&lock); 223 mutex_lock(&lock);
225 if (buf_used_len + word_aligned_size > PATH_MAX) { 224 if (buf_used_len + word_aligned_size > PATH_MAX) {
226 if (!tomoyo_quota_for_elements || 225 if (!tomoyo_quota_for_elements ||
@@ -251,7 +250,6 @@ void *tomoyo_alloc_element(const unsigned int size)
251 } 250 }
252 } 251 }
253 mutex_unlock(&lock); 252 mutex_unlock(&lock);
254 /***** EXCLUSIVE SECTION END *****/
255 return ptr; 253 return ptr;
256} 254}
257 255
@@ -267,7 +265,16 @@ static unsigned int tomoyo_quota_for_savename;
267 */ 265 */
268#define TOMOYO_MAX_HASH 256 266#define TOMOYO_MAX_HASH 256
269 267
270/* Structure for string data. */ 268/*
269 * tomoyo_name_entry is a structure which is used for linking
270 * "struct tomoyo_path_info" into tomoyo_name_list .
271 *
272 * Since tomoyo_name_list manages a list of strings which are shared by
273 * multiple processes (whereas "struct tomoyo_path_info" inside
274 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will
275 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
276 * when TOMOYO starts supporting garbage collector.
277 */
271struct tomoyo_name_entry { 278struct tomoyo_name_entry {
272 struct list_head list; 279 struct list_head list;
273 struct tomoyo_path_info entry; 280 struct tomoyo_path_info entry;
@@ -281,10 +288,10 @@ struct tomoyo_free_memory_block_list {
281}; 288};
282 289
283/* 290/*
284 * The list for "struct tomoyo_name_entry". 291 * tomoyo_name_list is used for holding string data used by TOMOYO.
285 * 292 * Since same string data is likely used for multiple times (e.g.
286 * This list is updated only inside tomoyo_save_name(), thus 293 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
287 * no global mutex exists. 294 * "const struct tomoyo_path_info *".
288 */ 295 */
289static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 296static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
290 297
@@ -318,7 +325,6 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
318 return NULL; 325 return NULL;
319 } 326 }
320 hash = full_name_hash((const unsigned char *) name, len - 1); 327 hash = full_name_hash((const unsigned char *) name, len - 1);
321 /***** EXCLUSIVE SECTION START *****/
322 mutex_lock(&lock); 328 mutex_lock(&lock);
323 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 329 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH],
324 list) { 330 list) {
@@ -366,7 +372,6 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
366 } 372 }
367 out: 373 out:
368 mutex_unlock(&lock); 374 mutex_unlock(&lock);
369 /***** EXCLUSIVE SECTION END *****/
370 return ptr ? &ptr->entry : NULL; 375 return ptr ? &ptr->entry : NULL;
371} 376}
372 377
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index e42be5c4f055..3194d09fe0f4 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -262,6 +262,10 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
262 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 262 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
263} 263}
264 264
265/*
266 * tomoyo_security_ops is a "struct security_operations" which is used for
267 * registering TOMOYO.
268 */
265static struct security_operations tomoyo_security_ops = { 269static struct security_operations tomoyo_security_ops = {
266 .name = "tomoyo", 270 .name = "tomoyo",
267 .cred_prepare = tomoyo_cred_prepare, 271 .cred_prepare = tomoyo_cred_prepare,
diff --git a/security/tomoyo/tomoyo.h b/security/tomoyo/tomoyo.h
index 41c6ebafb9c5..0fd588a629cf 100644
--- a/security/tomoyo/tomoyo.h
+++ b/security/tomoyo/tomoyo.h
@@ -17,13 +17,11 @@ struct path;
17struct inode; 17struct inode;
18struct linux_binprm; 18struct linux_binprm;
19struct pt_regs; 19struct pt_regs;
20struct tomoyo_page_buffer;
21 20
22int tomoyo_check_file_perm(struct tomoyo_domain_info *domain, 21int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
23 const char *filename, const u8 perm); 22 const char *filename, const u8 perm);
24int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 23int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
25 const struct tomoyo_path_info *filename, 24 const struct tomoyo_path_info *filename);
26 struct tomoyo_page_buffer *buf);
27int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 25int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
28 struct path *path, const int flag); 26 struct path *path, const int flag);
29int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, 27int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
@@ -90,17 +88,10 @@ static inline struct tomoyo_domain_info *tomoyo_domain(void)
90 return current_cred()->security; 88 return current_cred()->security;
91} 89}
92 90
93/* Caller holds tasklist_lock spinlock. */
94static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct 91static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
95 *task) 92 *task)
96{ 93{
97 /***** CRITICAL SECTION START *****/ 94 return task_cred_xxx(task, security);
98 const struct cred *cred = get_task_cred(task);
99 struct tomoyo_domain_info *domain = cred->security;
100
101 put_cred(cred);
102 return domain;
103 /***** CRITICAL SECTION END *****/
104} 95}
105 96
106#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */ 97#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */