diff options
Diffstat (limited to 'security/tomoyo/common.h')
-rw-r--r-- | security/tomoyo/common.h | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h new file mode 100644 index 000000000000..6dcb7cc0ed1d --- /dev/null +++ b/security/tomoyo/common.h | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * security/tomoyo/common.h | ||
3 | * | ||
4 | * Common functions for TOMOYO. | ||
5 | * | ||
6 | * Copyright (C) 2005-2009 NTT DATA CORPORATION | ||
7 | * | ||
8 | * Version: 2.2.0-pre 2009/02/01 | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef _SECURITY_TOMOYO_COMMON_H | ||
13 | #define _SECURITY_TOMOYO_COMMON_H | ||
14 | |||
15 | #include <linux/ctype.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include <linux/file.h> | ||
19 | #include <linux/kmod.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/namei.h> | ||
23 | #include <linux/mount.h> | ||
24 | #include <linux/list.h> | ||
25 | |||
26 | struct dentry; | ||
27 | struct vfsmount; | ||
28 | |||
29 | /* Temporary buffer for holding pathnames. */ | ||
30 | struct tomoyo_page_buffer { | ||
31 | char buffer[4096]; | ||
32 | }; | ||
33 | |||
34 | /* Structure for holding a token. */ | ||
35 | struct tomoyo_path_info { | ||
36 | const char *name; | ||
37 | u32 hash; /* = full_name_hash(name, strlen(name)) */ | ||
38 | u16 total_len; /* = strlen(name) */ | ||
39 | u16 const_len; /* = tomoyo_const_part_length(name) */ | ||
40 | bool is_dir; /* = tomoyo_strendswith(name, "/") */ | ||
41 | bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ | ||
42 | u16 depth; /* = tomoyo_path_depth(name) */ | ||
43 | }; | ||
44 | |||
45 | /* | ||
46 | * This is the max length of a token. | ||
47 | * | ||
48 | * A token consists of only ASCII printable characters. | ||
49 | * Non printable characters in a token is represented in \ooo style | ||
50 | * octal string. Thus, \ itself is represented as \\. | ||
51 | */ | ||
52 | #define TOMOYO_MAX_PATHNAME_LEN 4000 | ||
53 | |||
54 | /* Structure for holding requested pathname. */ | ||
55 | struct tomoyo_path_info_with_data { | ||
56 | /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ | ||
57 | struct tomoyo_path_info head; | ||
58 | char bariier1[16]; /* Safeguard for overrun. */ | ||
59 | char body[TOMOYO_MAX_PATHNAME_LEN]; | ||
60 | char barrier2[16]; /* Safeguard for overrun. */ | ||
61 | }; | ||
62 | |||
63 | /* | ||
64 | * Common header for holding ACL entries. | ||
65 | * | ||
66 | * Packing "struct tomoyo_acl_info" allows | ||
67 | * "struct tomoyo_single_path_acl_record" to embed "u16" and | ||
68 | * "struct tomoyo_double_path_acl_record" to embed "u8" | ||
69 | * without enlarging their structure size. | ||
70 | */ | ||
71 | struct tomoyo_acl_info { | ||
72 | struct list_head list; | ||
73 | /* | ||
74 | * Type of this ACL entry. | ||
75 | * | ||
76 | * MSB is is_deleted flag. | ||
77 | */ | ||
78 | u8 type; | ||
79 | } __packed; | ||
80 | |||
81 | /* This ACL entry is deleted. */ | ||
82 | #define TOMOYO_ACL_DELETED 0x80 | ||
83 | |||
84 | /* Structure for domain information. */ | ||
85 | struct tomoyo_domain_info { | ||
86 | struct list_head list; | ||
87 | struct list_head acl_info_list; | ||
88 | /* Name of this domain. Never NULL. */ | ||
89 | const struct tomoyo_path_info *domainname; | ||
90 | u8 profile; /* Profile number to use. */ | ||
91 | u8 is_deleted; /* Delete flag. | ||
92 | 0 = active. | ||
93 | 1 = deleted but undeletable. | ||
94 | 255 = deleted and no longer undeletable. */ | ||
95 | bool quota_warned; /* Quota warnning flag. */ | ||
96 | /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ | ||
97 | u8 flags; | ||
98 | }; | ||
99 | |||
100 | /* Profile number is an integer between 0 and 255. */ | ||
101 | #define TOMOYO_MAX_PROFILES 256 | ||
102 | |||
103 | /* Ignore "allow_read" directive in exception policy. */ | ||
104 | #define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1 | ||
105 | /* | ||
106 | * This domain was unable to create a new domain at tomoyo_find_next_domain() | ||
107 | * because the name of the domain to be created was too long or | ||
108 | * it could not allocate memory. | ||
109 | * More than one process continued execve() without domain transition. | ||
110 | */ | ||
111 | #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 | ||
112 | |||
113 | /* | ||
114 | * Structure for "allow_read/write", "allow_execute", "allow_read", | ||
115 | * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", | ||
116 | * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", | ||
117 | * "allow_truncate", "allow_symlink" and "allow_rewrite" directive. | ||
118 | */ | ||
119 | struct tomoyo_single_path_acl_record { | ||
120 | struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ | ||
121 | u16 perm; | ||
122 | /* Pointer to single pathname. */ | ||
123 | const struct tomoyo_path_info *filename; | ||
124 | }; | ||
125 | |||
126 | /* Structure for "allow_rename" and "allow_link" directive. */ | ||
127 | struct tomoyo_double_path_acl_record { | ||
128 | struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ | ||
129 | u8 perm; | ||
130 | /* Pointer to single pathname. */ | ||
131 | const struct tomoyo_path_info *filename1; | ||
132 | /* Pointer to single pathname. */ | ||
133 | const struct tomoyo_path_info *filename2; | ||
134 | }; | ||
135 | |||
136 | /* Keywords for ACLs. */ | ||
137 | #define TOMOYO_KEYWORD_ALIAS "alias " | ||
138 | #define TOMOYO_KEYWORD_ALLOW_READ "allow_read " | ||
139 | #define TOMOYO_KEYWORD_DELETE "delete " | ||
140 | #define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite " | ||
141 | #define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern " | ||
142 | #define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain " | ||
143 | #define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain " | ||
144 | #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " | ||
145 | #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain " | ||
146 | #define TOMOYO_KEYWORD_SELECT "select " | ||
147 | #define TOMOYO_KEYWORD_UNDELETE "undelete " | ||
148 | #define TOMOYO_KEYWORD_USE_PROFILE "use_profile " | ||
149 | #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read" | ||
150 | /* A domain definition starts with <kernel>. */ | ||
151 | #define TOMOYO_ROOT_NAME "<kernel>" | ||
152 | #define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1) | ||
153 | |||
154 | /* Index numbers for Access Controls. */ | ||
155 | #define TOMOYO_MAC_FOR_FILE 0 /* domain_policy.conf */ | ||
156 | #define TOMOYO_MAX_ACCEPT_ENTRY 1 | ||
157 | #define TOMOYO_VERBOSE 2 | ||
158 | #define TOMOYO_MAX_CONTROL_INDEX 3 | ||
159 | |||
160 | /* Structure for reading/writing policy via securityfs interfaces. */ | ||
161 | struct tomoyo_io_buffer { | ||
162 | int (*read) (struct tomoyo_io_buffer *); | ||
163 | int (*write) (struct tomoyo_io_buffer *); | ||
164 | /* Exclusive lock for this structure. */ | ||
165 | struct mutex io_sem; | ||
166 | /* The position currently reading from. */ | ||
167 | struct list_head *read_var1; | ||
168 | /* Extra variables for reading. */ | ||
169 | struct list_head *read_var2; | ||
170 | /* The position currently writing to. */ | ||
171 | struct tomoyo_domain_info *write_var1; | ||
172 | /* The step for reading. */ | ||
173 | int read_step; | ||
174 | /* Buffer for reading. */ | ||
175 | char *read_buf; | ||
176 | /* EOF flag for reading. */ | ||
177 | bool read_eof; | ||
178 | /* Read domain ACL of specified PID? */ | ||
179 | bool read_single_domain; | ||
180 | /* Extra variable for reading. */ | ||
181 | u8 read_bit; | ||
182 | /* Bytes available for reading. */ | ||
183 | int read_avail; | ||
184 | /* Size of read buffer. */ | ||
185 | int readbuf_size; | ||
186 | /* Buffer for writing. */ | ||
187 | char *write_buf; | ||
188 | /* Bytes available for writing. */ | ||
189 | int write_avail; | ||
190 | /* Size of write buffer. */ | ||
191 | int writebuf_size; | ||
192 | }; | ||
193 | |||
194 | /* Check whether the domain has too many ACL entries to hold. */ | ||
195 | bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain); | ||
196 | /* Transactional sprintf() for policy dump. */ | ||
197 | bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) | ||
198 | __attribute__ ((format(printf, 2, 3))); | ||
199 | /* Check whether the domainname is correct. */ | ||
200 | bool tomoyo_is_correct_domain(const unsigned char *domainname, | ||
201 | const char *function); | ||
202 | /* Check whether the token is correct. */ | ||
203 | bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | ||
204 | const s8 pattern_type, const s8 end_type, | ||
205 | const char *function); | ||
206 | /* Check whether the token can be a domainname. */ | ||
207 | bool tomoyo_is_domain_def(const unsigned char *buffer); | ||
208 | /* Check whether the given filename matches the given pattern. */ | ||
209 | bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, | ||
210 | const struct tomoyo_path_info *pattern); | ||
211 | /* Read "alias" entry in exception policy. */ | ||
212 | bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head); | ||
213 | /* | ||
214 | * Read "initialize_domain" and "no_initialize_domain" entry | ||
215 | * in exception policy. | ||
216 | */ | ||
217 | bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head); | ||
218 | /* Read "keep_domain" and "no_keep_domain" entry in exception policy. */ | ||
219 | bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head); | ||
220 | /* Read "file_pattern" entry in exception policy. */ | ||
221 | bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head); | ||
222 | /* Read "allow_read" entry in exception policy. */ | ||
223 | bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head); | ||
224 | /* Read "deny_rewrite" entry in exception policy. */ | ||
225 | bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head); | ||
226 | /* Write domain policy violation warning message to console? */ | ||
227 | bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain); | ||
228 | /* Convert double path operation to operation name. */ | ||
229 | const char *tomoyo_dp2keyword(const u8 operation); | ||
230 | /* Get the last component of the given domainname. */ | ||
231 | const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); | ||
232 | /* Get warning message. */ | ||
233 | const char *tomoyo_get_msg(const bool is_enforce); | ||
234 | /* Convert single path operation to operation name. */ | ||
235 | const char *tomoyo_sp2keyword(const u8 operation); | ||
236 | /* Delete a domain. */ | ||
237 | int tomoyo_delete_domain(char *data); | ||
238 | /* Create "alias" entry in exception policy. */ | ||
239 | int tomoyo_write_alias_policy(char *data, const bool is_delete); | ||
240 | /* | ||
241 | * Create "initialize_domain" and "no_initialize_domain" entry | ||
242 | * in exception policy. | ||
243 | */ | ||
244 | int tomoyo_write_domain_initializer_policy(char *data, const bool is_not, | ||
245 | const bool is_delete); | ||
246 | /* Create "keep_domain" and "no_keep_domain" entry in exception policy. */ | ||
247 | int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, | ||
248 | const bool is_delete); | ||
249 | /* | ||
250 | * Create "allow_read/write", "allow_execute", "allow_read", "allow_write", | ||
251 | * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", | ||
252 | * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", | ||
253 | * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and | ||
254 | * "allow_link" entry in domain policy. | ||
255 | */ | ||
256 | int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, | ||
257 | const bool is_delete); | ||
258 | /* Create "allow_read" entry in exception policy. */ | ||
259 | int tomoyo_write_globally_readable_policy(char *data, const bool is_delete); | ||
260 | /* Create "deny_rewrite" entry in exception policy. */ | ||
261 | int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete); | ||
262 | /* Create "file_pattern" entry in exception policy. */ | ||
263 | int tomoyo_write_pattern_policy(char *data, const bool is_delete); | ||
264 | /* Find a domain by the given name. */ | ||
265 | struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname); | ||
266 | /* Find or create a domain by the given name. */ | ||
267 | struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | ||
268 | domainname, | ||
269 | const u8 profile); | ||
270 | /* Undelete a domain. */ | ||
271 | struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname); | ||
272 | /* Check mode for specified functionality. */ | ||
273 | unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, | ||
274 | const u8 index); | ||
275 | /* Allocate memory for structures. */ | ||
276 | void *tomoyo_alloc_acl_element(const u8 acl_type); | ||
277 | /* Fill in "struct tomoyo_path_info" members. */ | ||
278 | void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); | ||
279 | /* Run policy loader when /sbin/init starts. */ | ||
280 | void tomoyo_load_policy(const char *filename); | ||
281 | /* Change "struct tomoyo_domain_info"->flags. */ | ||
282 | void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain, | ||
283 | const bool is_delete, const u8 flags); | ||
284 | |||
285 | /* strcmp() for "struct tomoyo_path_info" structure. */ | ||
286 | static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, | ||
287 | const struct tomoyo_path_info *b) | ||
288 | { | ||
289 | return a->hash != b->hash || strcmp(a->name, b->name); | ||
290 | } | ||
291 | |||
292 | /* Get type of an ACL entry. */ | ||
293 | static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr) | ||
294 | { | ||
295 | return ptr->type & ~TOMOYO_ACL_DELETED; | ||
296 | } | ||
297 | |||
298 | /* Get type of an ACL entry. */ | ||
299 | static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr) | ||
300 | { | ||
301 | return ptr->type; | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * tomoyo_is_valid - Check whether the character is a valid char. | ||
306 | * | ||
307 | * @c: The character to check. | ||
308 | * | ||
309 | * Returns true if @c is a valid character, false otherwise. | ||
310 | */ | ||
311 | static inline bool tomoyo_is_valid(const unsigned char c) | ||
312 | { | ||
313 | return c > ' ' && c < 127; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * tomoyo_is_invalid - Check whether the character is an invalid char. | ||
318 | * | ||
319 | * @c: The character to check. | ||
320 | * | ||
321 | * Returns true if @c is an invalid character, false otherwise. | ||
322 | */ | ||
323 | static inline bool tomoyo_is_invalid(const unsigned char c) | ||
324 | { | ||
325 | return c && (c <= ' ' || c >= 127); | ||
326 | } | ||
327 | |||
328 | /* The list for "struct tomoyo_domain_info". */ | ||
329 | extern struct list_head tomoyo_domain_list; | ||
330 | extern struct rw_semaphore tomoyo_domain_list_lock; | ||
331 | |||
332 | /* Lock for domain->acl_info_list. */ | ||
333 | extern struct rw_semaphore tomoyo_domain_acl_info_list_lock; | ||
334 | |||
335 | /* Has /sbin/init started? */ | ||
336 | extern bool tomoyo_policy_loaded; | ||
337 | |||
338 | /* The kernel's domain. */ | ||
339 | extern struct tomoyo_domain_info tomoyo_kernel_domain; | ||
340 | |||
341 | /** | ||
342 | * list_for_each_cookie - iterate over a list with cookie. | ||
343 | * @pos: the &struct list_head to use as a loop cursor. | ||
344 | * @cookie: the &struct list_head to use as a cookie. | ||
345 | * @head: the head for your list. | ||
346 | * | ||
347 | * Same with list_for_each() except that this primitive uses @cookie | ||
348 | * so that we can continue iteration. | ||
349 | * @cookie must be NULL when iteration starts, and @cookie will become | ||
350 | * NULL when iteration finishes. | ||
351 | */ | ||
352 | #define list_for_each_cookie(pos, cookie, head) \ | ||
353 | for (({ if (!cookie) \ | ||
354 | cookie = head; }), \ | ||
355 | pos = (cookie)->next; \ | ||
356 | prefetch(pos->next), pos != (head) || ((cookie) = NULL); \ | ||
357 | (cookie) = pos, pos = pos->next) | ||
358 | |||
359 | #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ | ||