aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.c69
-rw-r--r--security/tomoyo/common.h133
-rw-r--r--security/tomoyo/domain.c192
-rw-r--r--security/tomoyo/file.c121
-rw-r--r--security/tomoyo/realpath.c19
-rw-r--r--security/tomoyo/tomoyo.c4
6 files changed, 504 insertions, 34 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a44f655b3913..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;
@@ -1006,7 +1018,19 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1006 return 0; 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 */
1010struct tomoyo_policy_manager_entry { 1034struct tomoyo_policy_manager_entry {
1011 struct list_head list; 1035 struct list_head list;
1012 /* A path to program or a domainname. */ 1036 /* A path to program or a domainname. */
@@ -1015,7 +1039,36 @@ struct tomoyo_policy_manager_entry {
1015 bool is_deleted; /* True if this entry is deleted. */ 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 */
1019static LIST_HEAD(tomoyo_policy_manager_list); 1072static LIST_HEAD(tomoyo_policy_manager_list);
1020static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); 1073static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1021 1074
@@ -2124,7 +2177,13 @@ static ssize_t tomoyo_write(struct file *file, const char __user *buf,
2124 return tomoyo_write_control(file, buf, count); 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 */
2128static const struct file_operations tomoyo_operations = { 2187static const struct file_operations tomoyo_operations = {
2129 .open = tomoyo_open, 2188 .open = tomoyo_open,
2130 .release = tomoyo_release, 2189 .release = tomoyo_release,
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index d8b95047cb9d..6d6ba09af457 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -26,12 +26,40 @@
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)) */
@@ -50,7 +78,20 @@ struct tomoyo_path_info {
50 */ 78 */
51#define TOMOYO_MAX_PATHNAME_LEN 4000 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 */
54struct tomoyo_path_info_with_data { 95struct tomoyo_path_info_with_data {
55 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 96 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */
56 struct tomoyo_path_info head; 97 struct tomoyo_path_info head;
@@ -60,7 +101,15 @@ struct tomoyo_path_info_with_data {
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
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".
64 * 113 *
65 * Packing "struct tomoyo_acl_info" allows 114 * Packing "struct tomoyo_acl_info" allows
66 * "struct tomoyo_single_path_acl_record" to embed "u16" and 115 * "struct tomoyo_single_path_acl_record" to embed "u16" and
@@ -80,7 +129,28 @@ struct tomoyo_acl_info {
80/* This ACL entry is deleted. */ 129/* This ACL entry is deleted. */
81#define TOMOYO_ACL_DELETED 0x80 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 */
84struct tomoyo_domain_info { 154struct tomoyo_domain_info {
85 struct list_head list; 155 struct list_head list;
86 struct list_head acl_info_list; 156 struct list_head acl_info_list;
@@ -107,10 +177,18 @@ struct tomoyo_domain_info {
107#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 177#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
108 178
109/* 179/*
110 * Structure for "allow_read/write", "allow_execute", "allow_read", 180 * tomoyo_single_path_acl_record is a structure which is used for holding an
111 * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 181 * entry with one pathname operation (e.g. open(), mkdir()).
112 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 182 * It has following fields.
113 * "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".
114 */ 192 */
115struct tomoyo_single_path_acl_record { 193struct tomoyo_single_path_acl_record {
116 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ 194 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
@@ -119,7 +197,18 @@ struct tomoyo_single_path_acl_record {
119 const struct tomoyo_path_info *filename; 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 */
123struct tomoyo_double_path_acl_record { 212struct tomoyo_double_path_acl_record {
124 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 213 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
125 u8 perm; 214 u8 perm;
@@ -152,7 +241,29 @@ struct tomoyo_double_path_acl_record {
152#define TOMOYO_VERBOSE 2 241#define TOMOYO_VERBOSE 2
153#define TOMOYO_MAX_CONTROL_INDEX 3 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 */
156struct tomoyo_io_buffer { 267struct tomoyo_io_buffer {
157 int (*read) (struct tomoyo_io_buffer *); 268 int (*read) (struct tomoyo_io_buffer *);
158 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 eb75401fd6b0..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;
@@ -92,7 +169,42 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
92 return cp0; 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 */
96static LIST_HEAD(tomoyo_domain_initializer_list); 208static LIST_HEAD(tomoyo_domain_initializer_list);
97static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); 209static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
98 210
@@ -268,7 +380,44 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
268 return flag; 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 */
272static LIST_HEAD(tomoyo_domain_keeper_list); 421static LIST_HEAD(tomoyo_domain_keeper_list);
273static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); 422static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
274 423
@@ -437,7 +586,36 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
437 return flag; 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 */
441static LIST_HEAD(tomoyo_alias_list); 619static LIST_HEAD(tomoyo_alias_list);
442static DECLARE_RWSEM(tomoyo_alias_list_lock); 620static DECLARE_RWSEM(tomoyo_alias_list_lock);
443 621
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index ab0cd3538510..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
@@ -256,7 +309,35 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
256 return done; 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 */
260static LIST_HEAD(tomoyo_pattern_list); 341static LIST_HEAD(tomoyo_pattern_list);
261static DECLARE_RWSEM(tomoyo_pattern_list_lock); 342static DECLARE_RWSEM(tomoyo_pattern_list_lock);
262 343
@@ -377,7 +458,35 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
377 return done; 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 */
381static LIST_HEAD(tomoyo_no_rewrite_list); 490static LIST_HEAD(tomoyo_no_rewrite_list);
382static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock); 491static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
383 492
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 3948f6b56ae2..5f2e33263371 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -265,7 +265,16 @@ static unsigned int tomoyo_quota_for_savename;
265 */ 265 */
266#define TOMOYO_MAX_HASH 256 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 */
269struct tomoyo_name_entry { 278struct tomoyo_name_entry {
270 struct list_head list; 279 struct list_head list;
271 struct tomoyo_path_info entry; 280 struct tomoyo_path_info entry;
@@ -279,10 +288,10 @@ struct tomoyo_free_memory_block_list {
279}; 288};
280 289
281/* 290/*
282 * The list for "struct tomoyo_name_entry". 291 * tomoyo_name_list is used for holding string data used by TOMOYO.
283 * 292 * Since same string data is likely used for multiple times (e.g.
284 * This list is updated only inside tomoyo_save_name(), thus 293 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
285 * no global mutex exists. 294 * "const struct tomoyo_path_info *".
286 */ 295 */
287static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 296static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
288 297
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,