Commit c3fa109a5894077d1eaf8731ea741a15dd117b3c
Committed by
James Morris
1 parent
5bf1692f65
Exists in
master
and in
39 other branches
TOMOYO: Add description of lists and structures.
This patch adds some descriptions of lists and structures. This patch contains no code changes. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Showing 6 changed files with 504 additions and 34 deletions Side-by-side Diff
security/tomoyo/common.c
... | ... | @@ -28,7 +28,13 @@ |
28 | 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 | + */ | |
32 | 38 | static struct { |
33 | 39 | const char *keyword; |
34 | 40 | unsigned int current_value; |
... | ... | @@ -39,7 +45,13 @@ |
39 | 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 | + */ | |
43 | 55 | static struct tomoyo_profile { |
44 | 56 | unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; |
45 | 57 | const struct tomoyo_path_info *comment; |
... | ... | @@ -1006,7 +1018,19 @@ |
1006 | 1018 | return 0; |
1007 | 1019 | } |
1008 | 1020 | |
1009 | -/* 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 | + */ | |
1010 | 1034 | struct tomoyo_policy_manager_entry { |
1011 | 1035 | struct list_head list; |
1012 | 1036 | /* A path to program or a domainname. */ |
... | ... | @@ -1015,7 +1039,36 @@ |
1015 | 1039 | bool is_deleted; /* True if this entry is deleted. */ |
1016 | 1040 | }; |
1017 | 1041 | |
1018 | -/* 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 | + */ | |
1019 | 1072 | static LIST_HEAD(tomoyo_policy_manager_list); |
1020 | 1073 | static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); |
1021 | 1074 | |
... | ... | @@ -2124,7 +2177,13 @@ |
2124 | 2177 | return tomoyo_write_control(file, buf, count); |
2125 | 2178 | } |
2126 | 2179 | |
2127 | -/* 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 | + */ | |
2128 | 2187 | static const struct file_operations tomoyo_operations = { |
2129 | 2188 | .open = tomoyo_open, |
2130 | 2189 | .release = tomoyo_release, |
security/tomoyo/common.h
... | ... | @@ -26,12 +26,40 @@ |
26 | 26 | struct dentry; |
27 | 27 | struct 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 | + */ | |
30 | 36 | struct tomoyo_page_buffer { |
31 | 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 | + */ | |
35 | 63 | struct tomoyo_path_info { |
36 | 64 | const char *name; |
37 | 65 | u32 hash; /* = full_name_hash(name, strlen(name)) */ |
... | ... | @@ -50,7 +78,20 @@ |
50 | 78 | */ |
51 | 79 | #define TOMOYO_MAX_PATHNAME_LEN 4000 |
52 | 80 | |
53 | -/* 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 | + */ | |
54 | 95 | struct tomoyo_path_info_with_data { |
55 | 96 | /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ |
56 | 97 | struct tomoyo_path_info head; |
57 | 98 | |
... | ... | @@ -60,8 +101,16 @@ |
60 | 101 | }; |
61 | 102 | |
62 | 103 | /* |
63 | - * Common header for holding ACL entries. | |
104 | + * tomoyo_acl_info is a structure which is used for holding | |
64 | 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". | |
113 | + * | |
65 | 114 | * Packing "struct tomoyo_acl_info" allows |
66 | 115 | * "struct tomoyo_single_path_acl_record" to embed "u16" and |
67 | 116 | * "struct tomoyo_double_path_acl_record" to embed "u8" |
... | ... | @@ -80,7 +129,28 @@ |
80 | 129 | /* This ACL entry is deleted. */ |
81 | 130 | #define TOMOYO_ACL_DELETED 0x80 |
82 | 131 | |
83 | -/* 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 | + */ | |
84 | 154 | struct tomoyo_domain_info { |
85 | 155 | struct list_head list; |
86 | 156 | struct list_head acl_info_list; |
... | ... | @@ -107,10 +177,18 @@ |
107 | 177 | #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 |
108 | 178 | |
109 | 179 | /* |
110 | - * Structure for "allow_read/write", "allow_execute", "allow_read", | |
111 | - * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", | |
112 | - * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", | |
113 | - * "allow_truncate", "allow_symlink" and "allow_rewrite" directive. | |
180 | + * tomoyo_single_path_acl_record is a structure which is used for holding an | |
181 | + * entry with one pathname operation (e.g. open(), mkdir()). | |
182 | + * It has following fields. | |
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". | |
114 | 192 | */ |
115 | 193 | struct tomoyo_single_path_acl_record { |
116 | 194 | struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ |
... | ... | @@ -119,7 +197,18 @@ |
119 | 197 | const struct tomoyo_path_info *filename; |
120 | 198 | }; |
121 | 199 | |
122 | -/* 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 | + */ | |
123 | 212 | struct tomoyo_double_path_acl_record { |
124 | 213 | struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ |
125 | 214 | u8 perm; |
... | ... | @@ -152,7 +241,29 @@ |
152 | 241 | #define TOMOYO_VERBOSE 2 |
153 | 242 | #define TOMOYO_MAX_CONTROL_INDEX 3 |
154 | 243 | |
155 | -/* 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 | + */ | |
156 | 267 | struct tomoyo_io_buffer { |
157 | 268 | int (*read) (struct tomoyo_io_buffer *); |
158 | 269 | int (*write) (struct tomoyo_io_buffer *); |
security/tomoyo/domain.c
... | ... | @@ -19,11 +19,63 @@ |
19 | 19 | /* The initial domain. */ |
20 | 20 | struct 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 | + */ | |
23 | 60 | LIST_HEAD(tomoyo_domain_list); |
24 | 61 | DECLARE_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 | + */ | |
27 | 79 | struct tomoyo_domain_initializer_entry { |
28 | 80 | struct list_head list; |
29 | 81 | const struct tomoyo_path_info *domainname; /* This may be NULL */ |
... | ... | @@ -34,7 +86,23 @@ |
34 | 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 | + */ | |
38 | 106 | struct tomoyo_domain_keeper_entry { |
39 | 107 | struct list_head list; |
40 | 108 | const struct tomoyo_path_info *domainname; |
... | ... | @@ -45,7 +113,16 @@ |
45 | 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 | + */ | |
49 | 126 | struct tomoyo_alias_entry { |
50 | 127 | struct list_head list; |
51 | 128 | const struct tomoyo_path_info *original_name; |
... | ... | @@ -92,7 +169,42 @@ |
92 | 169 | return cp0; |
93 | 170 | } |
94 | 171 | |
95 | -/* 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 | + */ | |
96 | 208 | static LIST_HEAD(tomoyo_domain_initializer_list); |
97 | 209 | static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); |
98 | 210 | |
... | ... | @@ -268,7 +380,44 @@ |
268 | 380 | return flag; |
269 | 381 | } |
270 | 382 | |
271 | -/* 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 | + */ | |
272 | 421 | static LIST_HEAD(tomoyo_domain_keeper_list); |
273 | 422 | static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); |
274 | 423 | |
... | ... | @@ -437,7 +586,36 @@ |
437 | 586 | return flag; |
438 | 587 | } |
439 | 588 | |
440 | -/* 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 | + */ | |
441 | 619 | static LIST_HEAD(tomoyo_alias_list); |
442 | 620 | static DECLARE_RWSEM(tomoyo_alias_list_lock); |
443 | 621 |
security/tomoyo/file.c
... | ... | @@ -14,21 +14,50 @@ |
14 | 14 | #include "realpath.h" |
15 | 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 | + */ | |
18 | 27 | struct tomoyo_globally_readable_file_entry { |
19 | 28 | struct list_head list; |
20 | 29 | const struct tomoyo_path_info *filename; |
21 | 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 | + */ | |
25 | 44 | struct tomoyo_pattern_entry { |
26 | 45 | struct list_head list; |
27 | 46 | const struct tomoyo_path_info *pattern; |
28 | 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 | + */ | |
32 | 61 | struct tomoyo_no_rewrite_entry { |
33 | 62 | struct list_head list; |
34 | 63 | const struct tomoyo_path_info *pattern; |
... | ... | @@ -141,7 +170,31 @@ |
141 | 170 | struct tomoyo_domain_info * |
142 | 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 | + */ | |
145 | 198 | static LIST_HEAD(tomoyo_globally_readable_list); |
146 | 199 | static DECLARE_RWSEM(tomoyo_globally_readable_list_lock); |
147 | 200 | |
... | ... | @@ -256,7 +309,35 @@ |
256 | 309 | return done; |
257 | 310 | } |
258 | 311 | |
259 | -/* 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 | + */ | |
260 | 341 | static LIST_HEAD(tomoyo_pattern_list); |
261 | 342 | static DECLARE_RWSEM(tomoyo_pattern_list_lock); |
262 | 343 | |
... | ... | @@ -377,7 +458,35 @@ |
377 | 458 | return done; |
378 | 459 | } |
379 | 460 | |
380 | -/* 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 | + */ | |
381 | 490 | static LIST_HEAD(tomoyo_no_rewrite_list); |
382 | 491 | static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock); |
383 | 492 |
security/tomoyo/realpath.c
... | ... | @@ -265,7 +265,16 @@ |
265 | 265 | */ |
266 | 266 | #define TOMOYO_MAX_HASH 256 |
267 | 267 | |
268 | -/* 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 | + */ | |
269 | 278 | struct tomoyo_name_entry { |
270 | 279 | struct list_head list; |
271 | 280 | struct tomoyo_path_info entry; |
... | ... | @@ -279,10 +288,10 @@ |
279 | 288 | }; |
280 | 289 | |
281 | 290 | /* |
282 | - * The list for "struct tomoyo_name_entry". | |
283 | - * | |
284 | - * This list is updated only inside tomoyo_save_name(), thus | |
285 | - * no global mutex exists. | |
291 | + * tomoyo_name_list is used for holding string data used by TOMOYO. | |
292 | + * Since same string data is likely used for multiple times (e.g. | |
293 | + * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of | |
294 | + * "const struct tomoyo_path_info *". | |
286 | 295 | */ |
287 | 296 | static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; |
288 | 297 |
security/tomoyo/tomoyo.c
... | ... | @@ -262,6 +262,10 @@ |
262 | 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 | + */ | |
265 | 269 | static struct security_operations tomoyo_security_ops = { |
266 | 270 | .name = "tomoyo", |
267 | 271 | .cred_prepare = tomoyo_cred_prepare, |