Commit a0558fc3491c0494feb8472cf6c0119e43fd9484

Authored by Tetsuo Handa
Committed by James Morris
1 parent d508afb437

tomoyo: remove "undelete domain" command.

Since TOMOYO's policy management tools does not use the "undelete domain"
command, we decided to remove that command.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Toshiharu Harada <haradats@nttdata.co.jp>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 3 changed files with 5 additions and 100 deletions Inline Diff

security/tomoyo/common.c
1 /* 1 /*
2 * security/tomoyo/common.c 2 * security/tomoyo/common.c
3 * 3 *
4 * Common functions for TOMOYO. 4 * Common functions for TOMOYO.
5 * 5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 * 7 *
8 * Version: 2.2.0-pre 2009/02/01 8 * Version: 2.2.0-pre 2009/02/01
9 * 9 *
10 */ 10 */
11 11
12 #include <linux/uaccess.h> 12 #include <linux/uaccess.h>
13 #include <linux/security.h> 13 #include <linux/security.h>
14 #include <linux/hardirq.h> 14 #include <linux/hardirq.h>
15 #include "realpath.h" 15 #include "realpath.h"
16 #include "common.h" 16 #include "common.h"
17 #include "tomoyo.h" 17 #include "tomoyo.h"
18 18
19 /* Has loading policy done? */ 19 /* Has loading policy done? */
20 bool tomoyo_policy_loaded; 20 bool tomoyo_policy_loaded;
21 21
22 /* String table for functionality that takes 4 modes. */ 22 /* String table for functionality that takes 4 modes. */
23 static const char *tomoyo_mode_4[4] = { 23 static const char *tomoyo_mode_4[4] = {
24 "disabled", "learning", "permissive", "enforcing" 24 "disabled", "learning", "permissive", "enforcing"
25 }; 25 };
26 /* String table for functionality that takes 2 modes. */ 26 /* String table for functionality that takes 2 modes. */
27 static const char *tomoyo_mode_2[4] = { 27 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 /* Table for profile. */
32 static struct { 32 static struct {
33 const char *keyword; 33 const char *keyword;
34 unsigned int current_value; 34 unsigned int current_value;
35 const unsigned int max_value; 35 const unsigned int max_value;
36 } tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = { 36 } tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = {
37 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 }, 37 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
38 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX }, 38 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX },
39 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 39 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
40 }; 40 };
41 41
42 /* Profile table. Memory is allocated as needed. */ 42 /* Profile table. Memory is allocated as needed. */
43 static struct tomoyo_profile { 43 static struct tomoyo_profile {
44 unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; 44 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
45 const struct tomoyo_path_info *comment; 45 const struct tomoyo_path_info *comment;
46 } *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; 46 } *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
47 47
48 /* Permit policy management by non-root user? */ 48 /* Permit policy management by non-root user? */
49 static bool tomoyo_manage_by_non_root; 49 static bool tomoyo_manage_by_non_root;
50 50
51 /* Utility functions. */ 51 /* Utility functions. */
52 52
53 /* Open operation for /sys/kernel/security/tomoyo/ interface. */ 53 /* Open operation for /sys/kernel/security/tomoyo/ interface. */
54 static int tomoyo_open_control(const u8 type, struct file *file); 54 static int tomoyo_open_control(const u8 type, struct file *file);
55 /* Close /sys/kernel/security/tomoyo/ interface. */ 55 /* Close /sys/kernel/security/tomoyo/ interface. */
56 static int tomoyo_close_control(struct file *file); 56 static int tomoyo_close_control(struct file *file);
57 /* Read operation for /sys/kernel/security/tomoyo/ interface. */ 57 /* Read operation for /sys/kernel/security/tomoyo/ interface. */
58 static int tomoyo_read_control(struct file *file, char __user *buffer, 58 static int tomoyo_read_control(struct file *file, char __user *buffer,
59 const int buffer_len); 59 const int buffer_len);
60 /* Write operation for /sys/kernel/security/tomoyo/ interface. */ 60 /* Write operation for /sys/kernel/security/tomoyo/ interface. */
61 static int tomoyo_write_control(struct file *file, const char __user *buffer, 61 static int tomoyo_write_control(struct file *file, const char __user *buffer,
62 const int buffer_len); 62 const int buffer_len);
63 63
64 /** 64 /**
65 * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. 65 * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
66 * 66 *
67 * @str: Pointer to the string. 67 * @str: Pointer to the string.
68 * 68 *
69 * Returns true if @str is a \ooo style octal value, false otherwise. 69 * Returns true if @str is a \ooo style octal value, false otherwise.
70 * 70 *
71 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF. 71 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
72 * This function verifies that \ooo is in valid range. 72 * This function verifies that \ooo is in valid range.
73 */ 73 */
74 static inline bool tomoyo_is_byte_range(const char *str) 74 static inline bool tomoyo_is_byte_range(const char *str)
75 { 75 {
76 return *str >= '0' && *str++ <= '3' && 76 return *str >= '0' && *str++ <= '3' &&
77 *str >= '0' && *str++ <= '7' && 77 *str >= '0' && *str++ <= '7' &&
78 *str >= '0' && *str <= '7'; 78 *str >= '0' && *str <= '7';
79 } 79 }
80 80
81 /** 81 /**
82 * tomoyo_is_alphabet_char - Check whether the character is an alphabet. 82 * tomoyo_is_alphabet_char - Check whether the character is an alphabet.
83 * 83 *
84 * @c: The character to check. 84 * @c: The character to check.
85 * 85 *
86 * Returns true if @c is an alphabet character, false otherwise. 86 * Returns true if @c is an alphabet character, false otherwise.
87 */ 87 */
88 static inline bool tomoyo_is_alphabet_char(const char c) 88 static inline bool tomoyo_is_alphabet_char(const char c)
89 { 89 {
90 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); 90 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
91 } 91 }
92 92
93 /** 93 /**
94 * tomoyo_make_byte - Make byte value from three octal characters. 94 * tomoyo_make_byte - Make byte value from three octal characters.
95 * 95 *
96 * @c1: The first character. 96 * @c1: The first character.
97 * @c2: The second character. 97 * @c2: The second character.
98 * @c3: The third character. 98 * @c3: The third character.
99 * 99 *
100 * Returns byte value. 100 * Returns byte value.
101 */ 101 */
102 static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3) 102 static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
103 { 103 {
104 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0'); 104 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
105 } 105 }
106 106
107 /** 107 /**
108 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 108 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
109 * 109 *
110 * @src: Pointer to pointer to the string. 110 * @src: Pointer to pointer to the string.
111 * @find: Pointer to the keyword. 111 * @find: Pointer to the keyword.
112 * 112 *
113 * Returns true if @src starts with @find, false otherwise. 113 * Returns true if @src starts with @find, false otherwise.
114 * 114 *
115 * The @src is updated to point the first character after the @find 115 * The @src is updated to point the first character after the @find
116 * if @src starts with @find. 116 * if @src starts with @find.
117 */ 117 */
118 static bool tomoyo_str_starts(char **src, const char *find) 118 static bool tomoyo_str_starts(char **src, const char *find)
119 { 119 {
120 const int len = strlen(find); 120 const int len = strlen(find);
121 char *tmp = *src; 121 char *tmp = *src;
122 122
123 if (strncmp(tmp, find, len)) 123 if (strncmp(tmp, find, len))
124 return false; 124 return false;
125 tmp += len; 125 tmp += len;
126 *src = tmp; 126 *src = tmp;
127 return true; 127 return true;
128 } 128 }
129 129
130 /** 130 /**
131 * tomoyo_normalize_line - Format string. 131 * tomoyo_normalize_line - Format string.
132 * 132 *
133 * @buffer: The line to normalize. 133 * @buffer: The line to normalize.
134 * 134 *
135 * Leading and trailing whitespaces are removed. 135 * Leading and trailing whitespaces are removed.
136 * Multiple whitespaces are packed into single space. 136 * Multiple whitespaces are packed into single space.
137 * 137 *
138 * Returns nothing. 138 * Returns nothing.
139 */ 139 */
140 static void tomoyo_normalize_line(unsigned char *buffer) 140 static void tomoyo_normalize_line(unsigned char *buffer)
141 { 141 {
142 unsigned char *sp = buffer; 142 unsigned char *sp = buffer;
143 unsigned char *dp = buffer; 143 unsigned char *dp = buffer;
144 bool first = true; 144 bool first = true;
145 145
146 while (tomoyo_is_invalid(*sp)) 146 while (tomoyo_is_invalid(*sp))
147 sp++; 147 sp++;
148 while (*sp) { 148 while (*sp) {
149 if (!first) 149 if (!first)
150 *dp++ = ' '; 150 *dp++ = ' ';
151 first = false; 151 first = false;
152 while (tomoyo_is_valid(*sp)) 152 while (tomoyo_is_valid(*sp))
153 *dp++ = *sp++; 153 *dp++ = *sp++;
154 while (tomoyo_is_invalid(*sp)) 154 while (tomoyo_is_invalid(*sp))
155 sp++; 155 sp++;
156 } 156 }
157 *dp = '\0'; 157 *dp = '\0';
158 } 158 }
159 159
160 /** 160 /**
161 * tomoyo_is_correct_path - Validate a pathname. 161 * tomoyo_is_correct_path - Validate a pathname.
162 * @filename: The pathname to check. 162 * @filename: The pathname to check.
163 * @start_type: Should the pathname start with '/'? 163 * @start_type: Should the pathname start with '/'?
164 * 1 = must / -1 = must not / 0 = don't care 164 * 1 = must / -1 = must not / 0 = don't care
165 * @pattern_type: Can the pathname contain a wildcard? 165 * @pattern_type: Can the pathname contain a wildcard?
166 * 1 = must / -1 = must not / 0 = don't care 166 * 1 = must / -1 = must not / 0 = don't care
167 * @end_type: Should the pathname end with '/'? 167 * @end_type: Should the pathname end with '/'?
168 * 1 = must / -1 = must not / 0 = don't care 168 * 1 = must / -1 = must not / 0 = don't care
169 * @function: The name of function calling me. 169 * @function: The name of function calling me.
170 * 170 *
171 * Check whether the given filename follows the naming rules. 171 * Check whether the given filename follows the naming rules.
172 * Returns true if @filename follows the naming rules, false otherwise. 172 * Returns true if @filename follows the naming rules, false otherwise.
173 */ 173 */
174 bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 174 bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
175 const s8 pattern_type, const s8 end_type, 175 const s8 pattern_type, const s8 end_type,
176 const char *function) 176 const char *function)
177 { 177 {
178 bool contains_pattern = false; 178 bool contains_pattern = false;
179 unsigned char c; 179 unsigned char c;
180 unsigned char d; 180 unsigned char d;
181 unsigned char e; 181 unsigned char e;
182 const char *original_filename = filename; 182 const char *original_filename = filename;
183 183
184 if (!filename) 184 if (!filename)
185 goto out; 185 goto out;
186 c = *filename; 186 c = *filename;
187 if (start_type == 1) { /* Must start with '/' */ 187 if (start_type == 1) { /* Must start with '/' */
188 if (c != '/') 188 if (c != '/')
189 goto out; 189 goto out;
190 } else if (start_type == -1) { /* Must not start with '/' */ 190 } else if (start_type == -1) { /* Must not start with '/' */
191 if (c == '/') 191 if (c == '/')
192 goto out; 192 goto out;
193 } 193 }
194 if (c) 194 if (c)
195 c = *(filename + strlen(filename) - 1); 195 c = *(filename + strlen(filename) - 1);
196 if (end_type == 1) { /* Must end with '/' */ 196 if (end_type == 1) { /* Must end with '/' */
197 if (c != '/') 197 if (c != '/')
198 goto out; 198 goto out;
199 } else if (end_type == -1) { /* Must not end with '/' */ 199 } else if (end_type == -1) { /* Must not end with '/' */
200 if (c == '/') 200 if (c == '/')
201 goto out; 201 goto out;
202 } 202 }
203 while ((c = *filename++) != '\0') { 203 while ((c = *filename++) != '\0') {
204 if (c == '\\') { 204 if (c == '\\') {
205 switch ((c = *filename++)) { 205 switch ((c = *filename++)) {
206 case '\\': /* "\\" */ 206 case '\\': /* "\\" */
207 continue; 207 continue;
208 case '$': /* "\$" */ 208 case '$': /* "\$" */
209 case '+': /* "\+" */ 209 case '+': /* "\+" */
210 case '?': /* "\?" */ 210 case '?': /* "\?" */
211 case '*': /* "\*" */ 211 case '*': /* "\*" */
212 case '@': /* "\@" */ 212 case '@': /* "\@" */
213 case 'x': /* "\x" */ 213 case 'x': /* "\x" */
214 case 'X': /* "\X" */ 214 case 'X': /* "\X" */
215 case 'a': /* "\a" */ 215 case 'a': /* "\a" */
216 case 'A': /* "\A" */ 216 case 'A': /* "\A" */
217 case '-': /* "\-" */ 217 case '-': /* "\-" */
218 if (pattern_type == -1) 218 if (pattern_type == -1)
219 break; /* Must not contain pattern */ 219 break; /* Must not contain pattern */
220 contains_pattern = true; 220 contains_pattern = true;
221 continue; 221 continue;
222 case '0': /* "\ooo" */ 222 case '0': /* "\ooo" */
223 case '1': 223 case '1':
224 case '2': 224 case '2':
225 case '3': 225 case '3':
226 d = *filename++; 226 d = *filename++;
227 if (d < '0' || d > '7') 227 if (d < '0' || d > '7')
228 break; 228 break;
229 e = *filename++; 229 e = *filename++;
230 if (e < '0' || e > '7') 230 if (e < '0' || e > '7')
231 break; 231 break;
232 c = tomoyo_make_byte(c, d, e); 232 c = tomoyo_make_byte(c, d, e);
233 if (tomoyo_is_invalid(c)) 233 if (tomoyo_is_invalid(c))
234 continue; /* pattern is not \000 */ 234 continue; /* pattern is not \000 */
235 } 235 }
236 goto out; 236 goto out;
237 } else if (tomoyo_is_invalid(c)) { 237 } else if (tomoyo_is_invalid(c)) {
238 goto out; 238 goto out;
239 } 239 }
240 } 240 }
241 if (pattern_type == 1) { /* Must contain pattern */ 241 if (pattern_type == 1) { /* Must contain pattern */
242 if (!contains_pattern) 242 if (!contains_pattern)
243 goto out; 243 goto out;
244 } 244 }
245 return true; 245 return true;
246 out: 246 out:
247 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, 247 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
248 original_filename); 248 original_filename);
249 return false; 249 return false;
250 } 250 }
251 251
252 /** 252 /**
253 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules. 253 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules.
254 * @domainname: The domainname to check. 254 * @domainname: The domainname to check.
255 * @function: The name of function calling me. 255 * @function: The name of function calling me.
256 * 256 *
257 * Returns true if @domainname follows the naming rules, false otherwise. 257 * Returns true if @domainname follows the naming rules, false otherwise.
258 */ 258 */
259 bool tomoyo_is_correct_domain(const unsigned char *domainname, 259 bool tomoyo_is_correct_domain(const unsigned char *domainname,
260 const char *function) 260 const char *function)
261 { 261 {
262 unsigned char c; 262 unsigned char c;
263 unsigned char d; 263 unsigned char d;
264 unsigned char e; 264 unsigned char e;
265 const char *org_domainname = domainname; 265 const char *org_domainname = domainname;
266 266
267 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 267 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
268 TOMOYO_ROOT_NAME_LEN)) 268 TOMOYO_ROOT_NAME_LEN))
269 goto out; 269 goto out;
270 domainname += TOMOYO_ROOT_NAME_LEN; 270 domainname += TOMOYO_ROOT_NAME_LEN;
271 if (!*domainname) 271 if (!*domainname)
272 return true; 272 return true;
273 do { 273 do {
274 if (*domainname++ != ' ') 274 if (*domainname++ != ' ')
275 goto out; 275 goto out;
276 if (*domainname++ != '/') 276 if (*domainname++ != '/')
277 goto out; 277 goto out;
278 while ((c = *domainname) != '\0' && c != ' ') { 278 while ((c = *domainname) != '\0' && c != ' ') {
279 domainname++; 279 domainname++;
280 if (c == '\\') { 280 if (c == '\\') {
281 c = *domainname++; 281 c = *domainname++;
282 switch ((c)) { 282 switch ((c)) {
283 case '\\': /* "\\" */ 283 case '\\': /* "\\" */
284 continue; 284 continue;
285 case '0': /* "\ooo" */ 285 case '0': /* "\ooo" */
286 case '1': 286 case '1':
287 case '2': 287 case '2':
288 case '3': 288 case '3':
289 d = *domainname++; 289 d = *domainname++;
290 if (d < '0' || d > '7') 290 if (d < '0' || d > '7')
291 break; 291 break;
292 e = *domainname++; 292 e = *domainname++;
293 if (e < '0' || e > '7') 293 if (e < '0' || e > '7')
294 break; 294 break;
295 c = tomoyo_make_byte(c, d, e); 295 c = tomoyo_make_byte(c, d, e);
296 if (tomoyo_is_invalid(c)) 296 if (tomoyo_is_invalid(c))
297 /* pattern is not \000 */ 297 /* pattern is not \000 */
298 continue; 298 continue;
299 } 299 }
300 goto out; 300 goto out;
301 } else if (tomoyo_is_invalid(c)) { 301 } else if (tomoyo_is_invalid(c)) {
302 goto out; 302 goto out;
303 } 303 }
304 } 304 }
305 } while (*domainname); 305 } while (*domainname);
306 return true; 306 return true;
307 out: 307 out:
308 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function, 308 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function,
309 org_domainname); 309 org_domainname);
310 return false; 310 return false;
311 } 311 }
312 312
313 /** 313 /**
314 * tomoyo_is_domain_def - Check whether the given token can be a domainname. 314 * tomoyo_is_domain_def - Check whether the given token can be a domainname.
315 * 315 *
316 * @buffer: The token to check. 316 * @buffer: The token to check.
317 * 317 *
318 * Returns true if @buffer possibly be a domainname, false otherwise. 318 * Returns true if @buffer possibly be a domainname, false otherwise.
319 */ 319 */
320 bool tomoyo_is_domain_def(const unsigned char *buffer) 320 bool tomoyo_is_domain_def(const unsigned char *buffer)
321 { 321 {
322 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN); 322 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN);
323 } 323 }
324 324
325 /** 325 /**
326 * tomoyo_find_domain - Find a domain by the given name. 326 * tomoyo_find_domain - Find a domain by the given name.
327 * 327 *
328 * @domainname: The domainname to find. 328 * @domainname: The domainname to find.
329 * 329 *
330 * Caller must call down_read(&tomoyo_domain_list_lock); or 330 * Caller must call down_read(&tomoyo_domain_list_lock); or
331 * down_write(&tomoyo_domain_list_lock); . 331 * down_write(&tomoyo_domain_list_lock); .
332 * 332 *
333 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. 333 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
334 */ 334 */
335 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 335 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
336 { 336 {
337 struct tomoyo_domain_info *domain; 337 struct tomoyo_domain_info *domain;
338 struct tomoyo_path_info name; 338 struct tomoyo_path_info name;
339 339
340 name.name = domainname; 340 name.name = domainname;
341 tomoyo_fill_path_info(&name); 341 tomoyo_fill_path_info(&name);
342 list_for_each_entry(domain, &tomoyo_domain_list, list) { 342 list_for_each_entry(domain, &tomoyo_domain_list, list) {
343 if (!domain->is_deleted && 343 if (!domain->is_deleted &&
344 !tomoyo_pathcmp(&name, domain->domainname)) 344 !tomoyo_pathcmp(&name, domain->domainname))
345 return domain; 345 return domain;
346 } 346 }
347 return NULL; 347 return NULL;
348 } 348 }
349 349
350 /** 350 /**
351 * tomoyo_path_depth - Evaluate the number of '/' in a string. 351 * tomoyo_path_depth - Evaluate the number of '/' in a string.
352 * 352 *
353 * @pathname: The string to evaluate. 353 * @pathname: The string to evaluate.
354 * 354 *
355 * Returns path depth of the string. 355 * Returns path depth of the string.
356 * 356 *
357 * I score 2 for each of the '/' in the @pathname 357 * I score 2 for each of the '/' in the @pathname
358 * and score 1 if the @pathname ends with '/'. 358 * and score 1 if the @pathname ends with '/'.
359 */ 359 */
360 static int tomoyo_path_depth(const char *pathname) 360 static int tomoyo_path_depth(const char *pathname)
361 { 361 {
362 int i = 0; 362 int i = 0;
363 363
364 if (pathname) { 364 if (pathname) {
365 const char *ep = pathname + strlen(pathname); 365 const char *ep = pathname + strlen(pathname);
366 if (pathname < ep--) { 366 if (pathname < ep--) {
367 if (*ep != '/') 367 if (*ep != '/')
368 i++; 368 i++;
369 while (pathname <= ep) 369 while (pathname <= ep)
370 if (*ep-- == '/') 370 if (*ep-- == '/')
371 i += 2; 371 i += 2;
372 } 372 }
373 } 373 }
374 return i; 374 return i;
375 } 375 }
376 376
377 /** 377 /**
378 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. 378 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
379 * 379 *
380 * @filename: The string to evaluate. 380 * @filename: The string to evaluate.
381 * 381 *
382 * Returns the initial length without a pattern in @filename. 382 * Returns the initial length without a pattern in @filename.
383 */ 383 */
384 static int tomoyo_const_part_length(const char *filename) 384 static int tomoyo_const_part_length(const char *filename)
385 { 385 {
386 char c; 386 char c;
387 int len = 0; 387 int len = 0;
388 388
389 if (!filename) 389 if (!filename)
390 return 0; 390 return 0;
391 while ((c = *filename++) != '\0') { 391 while ((c = *filename++) != '\0') {
392 if (c != '\\') { 392 if (c != '\\') {
393 len++; 393 len++;
394 continue; 394 continue;
395 } 395 }
396 c = *filename++; 396 c = *filename++;
397 switch (c) { 397 switch (c) {
398 case '\\': /* "\\" */ 398 case '\\': /* "\\" */
399 len += 2; 399 len += 2;
400 continue; 400 continue;
401 case '0': /* "\ooo" */ 401 case '0': /* "\ooo" */
402 case '1': 402 case '1':
403 case '2': 403 case '2':
404 case '3': 404 case '3':
405 c = *filename++; 405 c = *filename++;
406 if (c < '0' || c > '7') 406 if (c < '0' || c > '7')
407 break; 407 break;
408 c = *filename++; 408 c = *filename++;
409 if (c < '0' || c > '7') 409 if (c < '0' || c > '7')
410 break; 410 break;
411 len += 4; 411 len += 4;
412 continue; 412 continue;
413 } 413 }
414 break; 414 break;
415 } 415 }
416 return len; 416 return len;
417 } 417 }
418 418
419 /** 419 /**
420 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members. 420 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
421 * 421 *
422 * @ptr: Pointer to "struct tomoyo_path_info" to fill in. 422 * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
423 * 423 *
424 * The caller sets "struct tomoyo_path_info"->name. 424 * The caller sets "struct tomoyo_path_info"->name.
425 */ 425 */
426 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) 426 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
427 { 427 {
428 const char *name = ptr->name; 428 const char *name = ptr->name;
429 const int len = strlen(name); 429 const int len = strlen(name);
430 430
431 ptr->total_len = len; 431 ptr->total_len = len;
432 ptr->const_len = tomoyo_const_part_length(name); 432 ptr->const_len = tomoyo_const_part_length(name);
433 ptr->is_dir = len && (name[len - 1] == '/'); 433 ptr->is_dir = len && (name[len - 1] == '/');
434 ptr->is_patterned = (ptr->const_len < len); 434 ptr->is_patterned = (ptr->const_len < len);
435 ptr->hash = full_name_hash(name, len); 435 ptr->hash = full_name_hash(name, len);
436 ptr->depth = tomoyo_path_depth(name); 436 ptr->depth = tomoyo_path_depth(name);
437 } 437 }
438 438
439 /** 439 /**
440 * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character 440 * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character
441 * and "\-" pattern. 441 * and "\-" pattern.
442 * 442 *
443 * @filename: The start of string to check. 443 * @filename: The start of string to check.
444 * @filename_end: The end of string to check. 444 * @filename_end: The end of string to check.
445 * @pattern: The start of pattern to compare. 445 * @pattern: The start of pattern to compare.
446 * @pattern_end: The end of pattern to compare. 446 * @pattern_end: The end of pattern to compare.
447 * 447 *
448 * Returns true if @filename matches @pattern, false otherwise. 448 * Returns true if @filename matches @pattern, false otherwise.
449 */ 449 */
450 static bool tomoyo_file_matches_to_pattern2(const char *filename, 450 static bool tomoyo_file_matches_to_pattern2(const char *filename,
451 const char *filename_end, 451 const char *filename_end,
452 const char *pattern, 452 const char *pattern,
453 const char *pattern_end) 453 const char *pattern_end)
454 { 454 {
455 while (filename < filename_end && pattern < pattern_end) { 455 while (filename < filename_end && pattern < pattern_end) {
456 char c; 456 char c;
457 if (*pattern != '\\') { 457 if (*pattern != '\\') {
458 if (*filename++ != *pattern++) 458 if (*filename++ != *pattern++)
459 return false; 459 return false;
460 continue; 460 continue;
461 } 461 }
462 c = *filename; 462 c = *filename;
463 pattern++; 463 pattern++;
464 switch (*pattern) { 464 switch (*pattern) {
465 int i; 465 int i;
466 int j; 466 int j;
467 case '?': 467 case '?':
468 if (c == '/') { 468 if (c == '/') {
469 return false; 469 return false;
470 } else if (c == '\\') { 470 } else if (c == '\\') {
471 if (filename[1] == '\\') 471 if (filename[1] == '\\')
472 filename++; 472 filename++;
473 else if (tomoyo_is_byte_range(filename + 1)) 473 else if (tomoyo_is_byte_range(filename + 1))
474 filename += 3; 474 filename += 3;
475 else 475 else
476 return false; 476 return false;
477 } 477 }
478 break; 478 break;
479 case '\\': 479 case '\\':
480 if (c != '\\') 480 if (c != '\\')
481 return false; 481 return false;
482 if (*++filename != '\\') 482 if (*++filename != '\\')
483 return false; 483 return false;
484 break; 484 break;
485 case '+': 485 case '+':
486 if (!isdigit(c)) 486 if (!isdigit(c))
487 return false; 487 return false;
488 break; 488 break;
489 case 'x': 489 case 'x':
490 if (!isxdigit(c)) 490 if (!isxdigit(c))
491 return false; 491 return false;
492 break; 492 break;
493 case 'a': 493 case 'a':
494 if (!tomoyo_is_alphabet_char(c)) 494 if (!tomoyo_is_alphabet_char(c))
495 return false; 495 return false;
496 break; 496 break;
497 case '0': 497 case '0':
498 case '1': 498 case '1':
499 case '2': 499 case '2':
500 case '3': 500 case '3':
501 if (c == '\\' && tomoyo_is_byte_range(filename + 1) 501 if (c == '\\' && tomoyo_is_byte_range(filename + 1)
502 && strncmp(filename + 1, pattern, 3) == 0) { 502 && strncmp(filename + 1, pattern, 3) == 0) {
503 filename += 3; 503 filename += 3;
504 pattern += 2; 504 pattern += 2;
505 break; 505 break;
506 } 506 }
507 return false; /* Not matched. */ 507 return false; /* Not matched. */
508 case '*': 508 case '*':
509 case '@': 509 case '@':
510 for (i = 0; i <= filename_end - filename; i++) { 510 for (i = 0; i <= filename_end - filename; i++) {
511 if (tomoyo_file_matches_to_pattern2( 511 if (tomoyo_file_matches_to_pattern2(
512 filename + i, filename_end, 512 filename + i, filename_end,
513 pattern + 1, pattern_end)) 513 pattern + 1, pattern_end))
514 return true; 514 return true;
515 c = filename[i]; 515 c = filename[i];
516 if (c == '.' && *pattern == '@') 516 if (c == '.' && *pattern == '@')
517 break; 517 break;
518 if (c != '\\') 518 if (c != '\\')
519 continue; 519 continue;
520 if (filename[i + 1] == '\\') 520 if (filename[i + 1] == '\\')
521 i++; 521 i++;
522 else if (tomoyo_is_byte_range(filename + i + 1)) 522 else if (tomoyo_is_byte_range(filename + i + 1))
523 i += 3; 523 i += 3;
524 else 524 else
525 break; /* Bad pattern. */ 525 break; /* Bad pattern. */
526 } 526 }
527 return false; /* Not matched. */ 527 return false; /* Not matched. */
528 default: 528 default:
529 j = 0; 529 j = 0;
530 c = *pattern; 530 c = *pattern;
531 if (c == '$') { 531 if (c == '$') {
532 while (isdigit(filename[j])) 532 while (isdigit(filename[j]))
533 j++; 533 j++;
534 } else if (c == 'X') { 534 } else if (c == 'X') {
535 while (isxdigit(filename[j])) 535 while (isxdigit(filename[j]))
536 j++; 536 j++;
537 } else if (c == 'A') { 537 } else if (c == 'A') {
538 while (tomoyo_is_alphabet_char(filename[j])) 538 while (tomoyo_is_alphabet_char(filename[j]))
539 j++; 539 j++;
540 } 540 }
541 for (i = 1; i <= j; i++) { 541 for (i = 1; i <= j; i++) {
542 if (tomoyo_file_matches_to_pattern2( 542 if (tomoyo_file_matches_to_pattern2(
543 filename + i, filename_end, 543 filename + i, filename_end,
544 pattern + 1, pattern_end)) 544 pattern + 1, pattern_end))
545 return true; 545 return true;
546 } 546 }
547 return false; /* Not matched or bad pattern. */ 547 return false; /* Not matched or bad pattern. */
548 } 548 }
549 filename++; 549 filename++;
550 pattern++; 550 pattern++;
551 } 551 }
552 while (*pattern == '\\' && 552 while (*pattern == '\\' &&
553 (*(pattern + 1) == '*' || *(pattern + 1) == '@')) 553 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
554 pattern += 2; 554 pattern += 2;
555 return filename == filename_end && pattern == pattern_end; 555 return filename == filename_end && pattern == pattern_end;
556 } 556 }
557 557
558 /** 558 /**
559 * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character. 559 * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character.
560 * 560 *
561 * @filename: The start of string to check. 561 * @filename: The start of string to check.
562 * @filename_end: The end of string to check. 562 * @filename_end: The end of string to check.
563 * @pattern: The start of pattern to compare. 563 * @pattern: The start of pattern to compare.
564 * @pattern_end: The end of pattern to compare. 564 * @pattern_end: The end of pattern to compare.
565 * 565 *
566 * Returns true if @filename matches @pattern, false otherwise. 566 * Returns true if @filename matches @pattern, false otherwise.
567 */ 567 */
568 static bool tomoyo_file_matches_to_pattern(const char *filename, 568 static bool tomoyo_file_matches_to_pattern(const char *filename,
569 const char *filename_end, 569 const char *filename_end,
570 const char *pattern, 570 const char *pattern,
571 const char *pattern_end) 571 const char *pattern_end)
572 { 572 {
573 const char *pattern_start = pattern; 573 const char *pattern_start = pattern;
574 bool first = true; 574 bool first = true;
575 bool result; 575 bool result;
576 576
577 while (pattern < pattern_end - 1) { 577 while (pattern < pattern_end - 1) {
578 /* Split at "\-" pattern. */ 578 /* Split at "\-" pattern. */
579 if (*pattern++ != '\\' || *pattern++ != '-') 579 if (*pattern++ != '\\' || *pattern++ != '-')
580 continue; 580 continue;
581 result = tomoyo_file_matches_to_pattern2(filename, 581 result = tomoyo_file_matches_to_pattern2(filename,
582 filename_end, 582 filename_end,
583 pattern_start, 583 pattern_start,
584 pattern - 2); 584 pattern - 2);
585 if (first) 585 if (first)
586 result = !result; 586 result = !result;
587 if (result) 587 if (result)
588 return false; 588 return false;
589 first = false; 589 first = false;
590 pattern_start = pattern; 590 pattern_start = pattern;
591 } 591 }
592 result = tomoyo_file_matches_to_pattern2(filename, filename_end, 592 result = tomoyo_file_matches_to_pattern2(filename, filename_end,
593 pattern_start, pattern_end); 593 pattern_start, pattern_end);
594 return first ? result : !result; 594 return first ? result : !result;
595 } 595 }
596 596
597 /** 597 /**
598 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. 598 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
599 * @filename: The filename to check. 599 * @filename: The filename to check.
600 * @pattern: The pattern to compare. 600 * @pattern: The pattern to compare.
601 * 601 *
602 * Returns true if matches, false otherwise. 602 * Returns true if matches, false otherwise.
603 * 603 *
604 * The following patterns are available. 604 * The following patterns are available.
605 * \\ \ itself. 605 * \\ \ itself.
606 * \ooo Octal representation of a byte. 606 * \ooo Octal representation of a byte.
607 * \* More than or equals to 0 character other than '/'. 607 * \* More than or equals to 0 character other than '/'.
608 * \@ More than or equals to 0 character other than '/' or '.'. 608 * \@ More than or equals to 0 character other than '/' or '.'.
609 * \? 1 byte character other than '/'. 609 * \? 1 byte character other than '/'.
610 * \$ More than or equals to 1 decimal digit. 610 * \$ More than or equals to 1 decimal digit.
611 * \+ 1 decimal digit. 611 * \+ 1 decimal digit.
612 * \X More than or equals to 1 hexadecimal digit. 612 * \X More than or equals to 1 hexadecimal digit.
613 * \x 1 hexadecimal digit. 613 * \x 1 hexadecimal digit.
614 * \A More than or equals to 1 alphabet character. 614 * \A More than or equals to 1 alphabet character.
615 * \a 1 alphabet character. 615 * \a 1 alphabet character.
616 * \- Subtraction operator. 616 * \- Subtraction operator.
617 */ 617 */
618 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 618 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
619 const struct tomoyo_path_info *pattern) 619 const struct tomoyo_path_info *pattern)
620 { 620 {
621 /* 621 /*
622 if (!filename || !pattern) 622 if (!filename || !pattern)
623 return false; 623 return false;
624 */ 624 */
625 const char *f = filename->name; 625 const char *f = filename->name;
626 const char *p = pattern->name; 626 const char *p = pattern->name;
627 const int len = pattern->const_len; 627 const int len = pattern->const_len;
628 628
629 /* If @pattern doesn't contain pattern, I can use strcmp(). */ 629 /* If @pattern doesn't contain pattern, I can use strcmp(). */
630 if (!pattern->is_patterned) 630 if (!pattern->is_patterned)
631 return !tomoyo_pathcmp(filename, pattern); 631 return !tomoyo_pathcmp(filename, pattern);
632 /* Dont compare if the number of '/' differs. */ 632 /* Dont compare if the number of '/' differs. */
633 if (filename->depth != pattern->depth) 633 if (filename->depth != pattern->depth)
634 return false; 634 return false;
635 /* Compare the initial length without patterns. */ 635 /* Compare the initial length without patterns. */
636 if (strncmp(f, p, len)) 636 if (strncmp(f, p, len))
637 return false; 637 return false;
638 f += len; 638 f += len;
639 p += len; 639 p += len;
640 /* Main loop. Compare each directory component. */ 640 /* Main loop. Compare each directory component. */
641 while (*f && *p) { 641 while (*f && *p) {
642 const char *f_delimiter = strchr(f, '/'); 642 const char *f_delimiter = strchr(f, '/');
643 const char *p_delimiter = strchr(p, '/'); 643 const char *p_delimiter = strchr(p, '/');
644 if (!f_delimiter) 644 if (!f_delimiter)
645 f_delimiter = f + strlen(f); 645 f_delimiter = f + strlen(f);
646 if (!p_delimiter) 646 if (!p_delimiter)
647 p_delimiter = p + strlen(p); 647 p_delimiter = p + strlen(p);
648 if (!tomoyo_file_matches_to_pattern(f, f_delimiter, 648 if (!tomoyo_file_matches_to_pattern(f, f_delimiter,
649 p, p_delimiter)) 649 p, p_delimiter))
650 return false; 650 return false;
651 f = f_delimiter; 651 f = f_delimiter;
652 if (*f) 652 if (*f)
653 f++; 653 f++;
654 p = p_delimiter; 654 p = p_delimiter;
655 if (*p) 655 if (*p)
656 p++; 656 p++;
657 } 657 }
658 /* Ignore trailing "\*" and "\@" in @pattern. */ 658 /* Ignore trailing "\*" and "\@" in @pattern. */
659 while (*p == '\\' && 659 while (*p == '\\' &&
660 (*(p + 1) == '*' || *(p + 1) == '@')) 660 (*(p + 1) == '*' || *(p + 1) == '@'))
661 p += 2; 661 p += 2;
662 return !*f && !*p; 662 return !*f && !*p;
663 } 663 }
664 664
665 /** 665 /**
666 * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure. 666 * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure.
667 * 667 *
668 * @head: Pointer to "struct tomoyo_io_buffer". 668 * @head: Pointer to "struct tomoyo_io_buffer".
669 * @fmt: The printf()'s format string, followed by parameters. 669 * @fmt: The printf()'s format string, followed by parameters.
670 * 670 *
671 * Returns true if output was written, false otherwise. 671 * Returns true if output was written, false otherwise.
672 * 672 *
673 * The snprintf() will truncate, but tomoyo_io_printf() won't. 673 * The snprintf() will truncate, but tomoyo_io_printf() won't.
674 */ 674 */
675 bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 675 bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
676 { 676 {
677 va_list args; 677 va_list args;
678 int len; 678 int len;
679 int pos = head->read_avail; 679 int pos = head->read_avail;
680 int size = head->readbuf_size - pos; 680 int size = head->readbuf_size - pos;
681 681
682 if (size <= 0) 682 if (size <= 0)
683 return false; 683 return false;
684 va_start(args, fmt); 684 va_start(args, fmt);
685 len = vsnprintf(head->read_buf + pos, size, fmt, args); 685 len = vsnprintf(head->read_buf + pos, size, fmt, args);
686 va_end(args); 686 va_end(args);
687 if (pos + len >= head->readbuf_size) 687 if (pos + len >= head->readbuf_size)
688 return false; 688 return false;
689 head->read_avail += len; 689 head->read_avail += len;
690 return true; 690 return true;
691 } 691 }
692 692
693 /** 693 /**
694 * tomoyo_get_exe - Get tomoyo_realpath() of current process. 694 * tomoyo_get_exe - Get tomoyo_realpath() of current process.
695 * 695 *
696 * Returns the tomoyo_realpath() of current process on success, NULL otherwise. 696 * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
697 * 697 *
698 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free() 698 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free()
699 * if this function didn't return NULL. 699 * if this function didn't return NULL.
700 */ 700 */
701 static const char *tomoyo_get_exe(void) 701 static const char *tomoyo_get_exe(void)
702 { 702 {
703 struct mm_struct *mm = current->mm; 703 struct mm_struct *mm = current->mm;
704 struct vm_area_struct *vma; 704 struct vm_area_struct *vma;
705 const char *cp = NULL; 705 const char *cp = NULL;
706 706
707 if (!mm) 707 if (!mm)
708 return NULL; 708 return NULL;
709 down_read(&mm->mmap_sem); 709 down_read(&mm->mmap_sem);
710 for (vma = mm->mmap; vma; vma = vma->vm_next) { 710 for (vma = mm->mmap; vma; vma = vma->vm_next) {
711 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { 711 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
712 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path); 712 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
713 break; 713 break;
714 } 714 }
715 } 715 }
716 up_read(&mm->mmap_sem); 716 up_read(&mm->mmap_sem);
717 return cp; 717 return cp;
718 } 718 }
719 719
720 /** 720 /**
721 * tomoyo_get_msg - Get warning message. 721 * tomoyo_get_msg - Get warning message.
722 * 722 *
723 * @is_enforce: Is it enforcing mode? 723 * @is_enforce: Is it enforcing mode?
724 * 724 *
725 * Returns "ERROR" or "WARNING". 725 * Returns "ERROR" or "WARNING".
726 */ 726 */
727 const char *tomoyo_get_msg(const bool is_enforce) 727 const char *tomoyo_get_msg(const bool is_enforce)
728 { 728 {
729 if (is_enforce) 729 if (is_enforce)
730 return "ERROR"; 730 return "ERROR";
731 else 731 else
732 return "WARNING"; 732 return "WARNING";
733 } 733 }
734 734
735 /** 735 /**
736 * tomoyo_check_flags - Check mode for specified functionality. 736 * tomoyo_check_flags - Check mode for specified functionality.
737 * 737 *
738 * @domain: Pointer to "struct tomoyo_domain_info". 738 * @domain: Pointer to "struct tomoyo_domain_info".
739 * @index: The functionality to check mode. 739 * @index: The functionality to check mode.
740 * 740 *
741 * TOMOYO checks only process context. 741 * TOMOYO checks only process context.
742 * This code disables TOMOYO's enforcement in case the function is called from 742 * This code disables TOMOYO's enforcement in case the function is called from
743 * interrupt context. 743 * interrupt context.
744 */ 744 */
745 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 745 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
746 const u8 index) 746 const u8 index)
747 { 747 {
748 const u8 profile = domain->profile; 748 const u8 profile = domain->profile;
749 749
750 if (WARN_ON(in_interrupt())) 750 if (WARN_ON(in_interrupt()))
751 return 0; 751 return 0;
752 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX 752 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX
753 #if TOMOYO_MAX_PROFILES != 256 753 #if TOMOYO_MAX_PROFILES != 256
754 && profile < TOMOYO_MAX_PROFILES 754 && profile < TOMOYO_MAX_PROFILES
755 #endif 755 #endif
756 && tomoyo_profile_ptr[profile] ? 756 && tomoyo_profile_ptr[profile] ?
757 tomoyo_profile_ptr[profile]->value[index] : 0; 757 tomoyo_profile_ptr[profile]->value[index] : 0;
758 } 758 }
759 759
760 /** 760 /**
761 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode. 761 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode.
762 * 762 *
763 * @domain: Pointer to "struct tomoyo_domain_info". 763 * @domain: Pointer to "struct tomoyo_domain_info".
764 * 764 *
765 * Returns true if domain policy violation warning should be printed to 765 * Returns true if domain policy violation warning should be printed to
766 * console. 766 * console.
767 */ 767 */
768 bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain) 768 bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
769 { 769 {
770 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0; 770 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0;
771 } 771 }
772 772
773 /** 773 /**
774 * tomoyo_domain_quota_is_ok - Check for domain's quota. 774 * tomoyo_domain_quota_is_ok - Check for domain's quota.
775 * 775 *
776 * @domain: Pointer to "struct tomoyo_domain_info". 776 * @domain: Pointer to "struct tomoyo_domain_info".
777 * 777 *
778 * Returns true if the domain is not exceeded quota, false otherwise. 778 * Returns true if the domain is not exceeded quota, false otherwise.
779 */ 779 */
780 bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 780 bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
781 { 781 {
782 unsigned int count = 0; 782 unsigned int count = 0;
783 struct tomoyo_acl_info *ptr; 783 struct tomoyo_acl_info *ptr;
784 784
785 if (!domain) 785 if (!domain)
786 return true; 786 return true;
787 down_read(&tomoyo_domain_acl_info_list_lock); 787 down_read(&tomoyo_domain_acl_info_list_lock);
788 list_for_each_entry(ptr, &domain->acl_info_list, list) { 788 list_for_each_entry(ptr, &domain->acl_info_list, list) {
789 if (ptr->type & TOMOYO_ACL_DELETED) 789 if (ptr->type & TOMOYO_ACL_DELETED)
790 continue; 790 continue;
791 switch (tomoyo_acl_type2(ptr)) { 791 switch (tomoyo_acl_type2(ptr)) {
792 struct tomoyo_single_path_acl_record *acl1; 792 struct tomoyo_single_path_acl_record *acl1;
793 struct tomoyo_double_path_acl_record *acl2; 793 struct tomoyo_double_path_acl_record *acl2;
794 u16 perm; 794 u16 perm;
795 case TOMOYO_TYPE_SINGLE_PATH_ACL: 795 case TOMOYO_TYPE_SINGLE_PATH_ACL:
796 acl1 = container_of(ptr, 796 acl1 = container_of(ptr,
797 struct tomoyo_single_path_acl_record, 797 struct tomoyo_single_path_acl_record,
798 head); 798 head);
799 perm = acl1->perm; 799 perm = acl1->perm;
800 if (perm & (1 << TOMOYO_TYPE_EXECUTE_ACL)) 800 if (perm & (1 << TOMOYO_TYPE_EXECUTE_ACL))
801 count++; 801 count++;
802 if (perm & 802 if (perm &
803 ((1 << TOMOYO_TYPE_READ_ACL) | 803 ((1 << TOMOYO_TYPE_READ_ACL) |
804 (1 << TOMOYO_TYPE_WRITE_ACL))) 804 (1 << TOMOYO_TYPE_WRITE_ACL)))
805 count++; 805 count++;
806 if (perm & (1 << TOMOYO_TYPE_CREATE_ACL)) 806 if (perm & (1 << TOMOYO_TYPE_CREATE_ACL))
807 count++; 807 count++;
808 if (perm & (1 << TOMOYO_TYPE_UNLINK_ACL)) 808 if (perm & (1 << TOMOYO_TYPE_UNLINK_ACL))
809 count++; 809 count++;
810 if (perm & (1 << TOMOYO_TYPE_MKDIR_ACL)) 810 if (perm & (1 << TOMOYO_TYPE_MKDIR_ACL))
811 count++; 811 count++;
812 if (perm & (1 << TOMOYO_TYPE_RMDIR_ACL)) 812 if (perm & (1 << TOMOYO_TYPE_RMDIR_ACL))
813 count++; 813 count++;
814 if (perm & (1 << TOMOYO_TYPE_MKFIFO_ACL)) 814 if (perm & (1 << TOMOYO_TYPE_MKFIFO_ACL))
815 count++; 815 count++;
816 if (perm & (1 << TOMOYO_TYPE_MKSOCK_ACL)) 816 if (perm & (1 << TOMOYO_TYPE_MKSOCK_ACL))
817 count++; 817 count++;
818 if (perm & (1 << TOMOYO_TYPE_MKBLOCK_ACL)) 818 if (perm & (1 << TOMOYO_TYPE_MKBLOCK_ACL))
819 count++; 819 count++;
820 if (perm & (1 << TOMOYO_TYPE_MKCHAR_ACL)) 820 if (perm & (1 << TOMOYO_TYPE_MKCHAR_ACL))
821 count++; 821 count++;
822 if (perm & (1 << TOMOYO_TYPE_TRUNCATE_ACL)) 822 if (perm & (1 << TOMOYO_TYPE_TRUNCATE_ACL))
823 count++; 823 count++;
824 if (perm & (1 << TOMOYO_TYPE_SYMLINK_ACL)) 824 if (perm & (1 << TOMOYO_TYPE_SYMLINK_ACL))
825 count++; 825 count++;
826 if (perm & (1 << TOMOYO_TYPE_REWRITE_ACL)) 826 if (perm & (1 << TOMOYO_TYPE_REWRITE_ACL))
827 count++; 827 count++;
828 break; 828 break;
829 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 829 case TOMOYO_TYPE_DOUBLE_PATH_ACL:
830 acl2 = container_of(ptr, 830 acl2 = container_of(ptr,
831 struct tomoyo_double_path_acl_record, 831 struct tomoyo_double_path_acl_record,
832 head); 832 head);
833 perm = acl2->perm; 833 perm = acl2->perm;
834 if (perm & (1 << TOMOYO_TYPE_LINK_ACL)) 834 if (perm & (1 << TOMOYO_TYPE_LINK_ACL))
835 count++; 835 count++;
836 if (perm & (1 << TOMOYO_TYPE_RENAME_ACL)) 836 if (perm & (1 << TOMOYO_TYPE_RENAME_ACL))
837 count++; 837 count++;
838 break; 838 break;
839 } 839 }
840 } 840 }
841 up_read(&tomoyo_domain_acl_info_list_lock); 841 up_read(&tomoyo_domain_acl_info_list_lock);
842 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 842 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
843 return true; 843 return true;
844 if (!domain->quota_warned) { 844 if (!domain->quota_warned) {
845 domain->quota_warned = true; 845 domain->quota_warned = true;
846 printk(KERN_WARNING "TOMOYO-WARNING: " 846 printk(KERN_WARNING "TOMOYO-WARNING: "
847 "Domain '%s' has so many ACLs to hold. " 847 "Domain '%s' has so many ACLs to hold. "
848 "Stopped learning mode.\n", domain->domainname->name); 848 "Stopped learning mode.\n", domain->domainname->name);
849 } 849 }
850 return false; 850 return false;
851 } 851 }
852 852
853 /** 853 /**
854 * tomoyo_find_or_assign_new_profile - Create a new profile. 854 * tomoyo_find_or_assign_new_profile - Create a new profile.
855 * 855 *
856 * @profile: Profile number to create. 856 * @profile: Profile number to create.
857 * 857 *
858 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 858 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
859 */ 859 */
860 static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned 860 static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
861 int profile) 861 int profile)
862 { 862 {
863 static DEFINE_MUTEX(lock); 863 static DEFINE_MUTEX(lock);
864 struct tomoyo_profile *ptr = NULL; 864 struct tomoyo_profile *ptr = NULL;
865 int i; 865 int i;
866 866
867 if (profile >= TOMOYO_MAX_PROFILES) 867 if (profile >= TOMOYO_MAX_PROFILES)
868 return NULL; 868 return NULL;
869 /***** EXCLUSIVE SECTION START *****/ 869 /***** EXCLUSIVE SECTION START *****/
870 mutex_lock(&lock); 870 mutex_lock(&lock);
871 ptr = tomoyo_profile_ptr[profile]; 871 ptr = tomoyo_profile_ptr[profile];
872 if (ptr) 872 if (ptr)
873 goto ok; 873 goto ok;
874 ptr = tomoyo_alloc_element(sizeof(*ptr)); 874 ptr = tomoyo_alloc_element(sizeof(*ptr));
875 if (!ptr) 875 if (!ptr)
876 goto ok; 876 goto ok;
877 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 877 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
878 ptr->value[i] = tomoyo_control_array[i].current_value; 878 ptr->value[i] = tomoyo_control_array[i].current_value;
879 mb(); /* Avoid out-of-order execution. */ 879 mb(); /* Avoid out-of-order execution. */
880 tomoyo_profile_ptr[profile] = ptr; 880 tomoyo_profile_ptr[profile] = ptr;
881 ok: 881 ok:
882 mutex_unlock(&lock); 882 mutex_unlock(&lock);
883 /***** EXCLUSIVE SECTION END *****/ 883 /***** EXCLUSIVE SECTION END *****/
884 return ptr; 884 return ptr;
885 } 885 }
886 886
887 /** 887 /**
888 * tomoyo_write_profile - Write to profile table. 888 * tomoyo_write_profile - Write to profile table.
889 * 889 *
890 * @head: Pointer to "struct tomoyo_io_buffer". 890 * @head: Pointer to "struct tomoyo_io_buffer".
891 * 891 *
892 * Returns 0 on success, negative value otherwise. 892 * Returns 0 on success, negative value otherwise.
893 */ 893 */
894 static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 894 static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
895 { 895 {
896 char *data = head->write_buf; 896 char *data = head->write_buf;
897 unsigned int i; 897 unsigned int i;
898 unsigned int value; 898 unsigned int value;
899 char *cp; 899 char *cp;
900 struct tomoyo_profile *profile; 900 struct tomoyo_profile *profile;
901 unsigned long num; 901 unsigned long num;
902 902
903 cp = strchr(data, '-'); 903 cp = strchr(data, '-');
904 if (cp) 904 if (cp)
905 *cp = '\0'; 905 *cp = '\0';
906 if (strict_strtoul(data, 10, &num)) 906 if (strict_strtoul(data, 10, &num))
907 return -EINVAL; 907 return -EINVAL;
908 if (cp) 908 if (cp)
909 data = cp + 1; 909 data = cp + 1;
910 profile = tomoyo_find_or_assign_new_profile(num); 910 profile = tomoyo_find_or_assign_new_profile(num);
911 if (!profile) 911 if (!profile)
912 return -EINVAL; 912 return -EINVAL;
913 cp = strchr(data, '='); 913 cp = strchr(data, '=');
914 if (!cp) 914 if (!cp)
915 return -EINVAL; 915 return -EINVAL;
916 *cp = '\0'; 916 *cp = '\0';
917 if (!strcmp(data, "COMMENT")) { 917 if (!strcmp(data, "COMMENT")) {
918 profile->comment = tomoyo_save_name(cp + 1); 918 profile->comment = tomoyo_save_name(cp + 1);
919 return 0; 919 return 0;
920 } 920 }
921 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 921 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
922 if (strcmp(data, tomoyo_control_array[i].keyword)) 922 if (strcmp(data, tomoyo_control_array[i].keyword))
923 continue; 923 continue;
924 if (sscanf(cp + 1, "%u", &value) != 1) { 924 if (sscanf(cp + 1, "%u", &value) != 1) {
925 int j; 925 int j;
926 const char **modes; 926 const char **modes;
927 switch (i) { 927 switch (i) {
928 case TOMOYO_VERBOSE: 928 case TOMOYO_VERBOSE:
929 modes = tomoyo_mode_2; 929 modes = tomoyo_mode_2;
930 break; 930 break;
931 default: 931 default:
932 modes = tomoyo_mode_4; 932 modes = tomoyo_mode_4;
933 break; 933 break;
934 } 934 }
935 for (j = 0; j < 4; j++) { 935 for (j = 0; j < 4; j++) {
936 if (strcmp(cp + 1, modes[j])) 936 if (strcmp(cp + 1, modes[j]))
937 continue; 937 continue;
938 value = j; 938 value = j;
939 break; 939 break;
940 } 940 }
941 if (j == 4) 941 if (j == 4)
942 return -EINVAL; 942 return -EINVAL;
943 } else if (value > tomoyo_control_array[i].max_value) { 943 } else if (value > tomoyo_control_array[i].max_value) {
944 value = tomoyo_control_array[i].max_value; 944 value = tomoyo_control_array[i].max_value;
945 } 945 }
946 profile->value[i] = value; 946 profile->value[i] = value;
947 return 0; 947 return 0;
948 } 948 }
949 return -EINVAL; 949 return -EINVAL;
950 } 950 }
951 951
952 /** 952 /**
953 * tomoyo_read_profile - Read from profile table. 953 * tomoyo_read_profile - Read from profile table.
954 * 954 *
955 * @head: Pointer to "struct tomoyo_io_buffer". 955 * @head: Pointer to "struct tomoyo_io_buffer".
956 * 956 *
957 * Returns 0. 957 * Returns 0.
958 */ 958 */
959 static int tomoyo_read_profile(struct tomoyo_io_buffer *head) 959 static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
960 { 960 {
961 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; 961 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1;
962 int step; 962 int step;
963 963
964 if (head->read_eof) 964 if (head->read_eof)
965 return 0; 965 return 0;
966 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; 966 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total;
967 step++) { 967 step++) {
968 const u8 index = step / total; 968 const u8 index = step / total;
969 u8 type = step % total; 969 u8 type = step % total;
970 const struct tomoyo_profile *profile 970 const struct tomoyo_profile *profile
971 = tomoyo_profile_ptr[index]; 971 = tomoyo_profile_ptr[index];
972 head->read_step = step; 972 head->read_step = step;
973 if (!profile) 973 if (!profile)
974 continue; 974 continue;
975 if (!type) { /* Print profile' comment tag. */ 975 if (!type) { /* Print profile' comment tag. */
976 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", 976 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n",
977 index, profile->comment ? 977 index, profile->comment ?
978 profile->comment->name : "")) 978 profile->comment->name : ""))
979 break; 979 break;
980 continue; 980 continue;
981 } 981 }
982 type--; 982 type--;
983 if (type < TOMOYO_MAX_CONTROL_INDEX) { 983 if (type < TOMOYO_MAX_CONTROL_INDEX) {
984 const unsigned int value = profile->value[type]; 984 const unsigned int value = profile->value[type];
985 const char **modes = NULL; 985 const char **modes = NULL;
986 const char *keyword 986 const char *keyword
987 = tomoyo_control_array[type].keyword; 987 = tomoyo_control_array[type].keyword;
988 switch (tomoyo_control_array[type].max_value) { 988 switch (tomoyo_control_array[type].max_value) {
989 case 3: 989 case 3:
990 modes = tomoyo_mode_4; 990 modes = tomoyo_mode_4;
991 break; 991 break;
992 case 1: 992 case 1:
993 modes = tomoyo_mode_2; 993 modes = tomoyo_mode_2;
994 break; 994 break;
995 } 995 }
996 if (modes) { 996 if (modes) {
997 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index, 997 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index,
998 keyword, modes[value])) 998 keyword, modes[value]))
999 break; 999 break;
1000 } else { 1000 } else {
1001 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index, 1001 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index,
1002 keyword, value)) 1002 keyword, value))
1003 break; 1003 break;
1004 } 1004 }
1005 } 1005 }
1006 } 1006 }
1007 if (step == TOMOYO_MAX_PROFILES * total) 1007 if (step == TOMOYO_MAX_PROFILES * total)
1008 head->read_eof = true; 1008 head->read_eof = true;
1009 return 0; 1009 return 0;
1010 } 1010 }
1011 1011
1012 /* Structure for policy manager. */ 1012 /* Structure for policy manager. */
1013 struct tomoyo_policy_manager_entry { 1013 struct tomoyo_policy_manager_entry {
1014 struct list_head list; 1014 struct list_head list;
1015 /* A path to program or a domainname. */ 1015 /* A path to program or a domainname. */
1016 const struct tomoyo_path_info *manager; 1016 const struct tomoyo_path_info *manager;
1017 bool is_domain; /* True if manager is a domainname. */ 1017 bool is_domain; /* True if manager is a domainname. */
1018 bool is_deleted; /* True if this entry is deleted. */ 1018 bool is_deleted; /* True if this entry is deleted. */
1019 }; 1019 };
1020 1020
1021 /* The list for "struct tomoyo_policy_manager_entry". */ 1021 /* The list for "struct tomoyo_policy_manager_entry". */
1022 static LIST_HEAD(tomoyo_policy_manager_list); 1022 static LIST_HEAD(tomoyo_policy_manager_list);
1023 static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); 1023 static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1024 1024
1025 /** 1025 /**
1026 * tomoyo_update_manager_entry - Add a manager entry. 1026 * tomoyo_update_manager_entry - Add a manager entry.
1027 * 1027 *
1028 * @manager: The path to manager or the domainnamme. 1028 * @manager: The path to manager or the domainnamme.
1029 * @is_delete: True if it is a delete request. 1029 * @is_delete: True if it is a delete request.
1030 * 1030 *
1031 * Returns 0 on success, negative value otherwise. 1031 * Returns 0 on success, negative value otherwise.
1032 */ 1032 */
1033 static int tomoyo_update_manager_entry(const char *manager, 1033 static int tomoyo_update_manager_entry(const char *manager,
1034 const bool is_delete) 1034 const bool is_delete)
1035 { 1035 {
1036 struct tomoyo_policy_manager_entry *new_entry; 1036 struct tomoyo_policy_manager_entry *new_entry;
1037 struct tomoyo_policy_manager_entry *ptr; 1037 struct tomoyo_policy_manager_entry *ptr;
1038 const struct tomoyo_path_info *saved_manager; 1038 const struct tomoyo_path_info *saved_manager;
1039 int error = -ENOMEM; 1039 int error = -ENOMEM;
1040 bool is_domain = false; 1040 bool is_domain = false;
1041 1041
1042 if (tomoyo_is_domain_def(manager)) { 1042 if (tomoyo_is_domain_def(manager)) {
1043 if (!tomoyo_is_correct_domain(manager, __func__)) 1043 if (!tomoyo_is_correct_domain(manager, __func__))
1044 return -EINVAL; 1044 return -EINVAL;
1045 is_domain = true; 1045 is_domain = true;
1046 } else { 1046 } else {
1047 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1047 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__))
1048 return -EINVAL; 1048 return -EINVAL;
1049 } 1049 }
1050 saved_manager = tomoyo_save_name(manager); 1050 saved_manager = tomoyo_save_name(manager);
1051 if (!saved_manager) 1051 if (!saved_manager)
1052 return -ENOMEM; 1052 return -ENOMEM;
1053 /***** EXCLUSIVE SECTION START *****/ 1053 /***** EXCLUSIVE SECTION START *****/
1054 down_write(&tomoyo_policy_manager_list_lock); 1054 down_write(&tomoyo_policy_manager_list_lock);
1055 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1055 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1056 if (ptr->manager != saved_manager) 1056 if (ptr->manager != saved_manager)
1057 continue; 1057 continue;
1058 ptr->is_deleted = is_delete; 1058 ptr->is_deleted = is_delete;
1059 error = 0; 1059 error = 0;
1060 goto out; 1060 goto out;
1061 } 1061 }
1062 if (is_delete) { 1062 if (is_delete) {
1063 error = -ENOENT; 1063 error = -ENOENT;
1064 goto out; 1064 goto out;
1065 } 1065 }
1066 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 1066 new_entry = tomoyo_alloc_element(sizeof(*new_entry));
1067 if (!new_entry) 1067 if (!new_entry)
1068 goto out; 1068 goto out;
1069 new_entry->manager = saved_manager; 1069 new_entry->manager = saved_manager;
1070 new_entry->is_domain = is_domain; 1070 new_entry->is_domain = is_domain;
1071 list_add_tail(&new_entry->list, &tomoyo_policy_manager_list); 1071 list_add_tail(&new_entry->list, &tomoyo_policy_manager_list);
1072 error = 0; 1072 error = 0;
1073 out: 1073 out:
1074 up_write(&tomoyo_policy_manager_list_lock); 1074 up_write(&tomoyo_policy_manager_list_lock);
1075 /***** EXCLUSIVE SECTION END *****/ 1075 /***** EXCLUSIVE SECTION END *****/
1076 return error; 1076 return error;
1077 } 1077 }
1078 1078
1079 /** 1079 /**
1080 * tomoyo_write_manager_policy - Write manager policy. 1080 * tomoyo_write_manager_policy - Write manager policy.
1081 * 1081 *
1082 * @head: Pointer to "struct tomoyo_io_buffer". 1082 * @head: Pointer to "struct tomoyo_io_buffer".
1083 * 1083 *
1084 * Returns 0 on success, negative value otherwise. 1084 * Returns 0 on success, negative value otherwise.
1085 */ 1085 */
1086 static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1086 static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1087 { 1087 {
1088 char *data = head->write_buf; 1088 char *data = head->write_buf;
1089 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1089 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
1090 1090
1091 if (!strcmp(data, "manage_by_non_root")) { 1091 if (!strcmp(data, "manage_by_non_root")) {
1092 tomoyo_manage_by_non_root = !is_delete; 1092 tomoyo_manage_by_non_root = !is_delete;
1093 return 0; 1093 return 0;
1094 } 1094 }
1095 return tomoyo_update_manager_entry(data, is_delete); 1095 return tomoyo_update_manager_entry(data, is_delete);
1096 } 1096 }
1097 1097
1098 /** 1098 /**
1099 * tomoyo_read_manager_policy - Read manager policy. 1099 * tomoyo_read_manager_policy - Read manager policy.
1100 * 1100 *
1101 * @head: Pointer to "struct tomoyo_io_buffer". 1101 * @head: Pointer to "struct tomoyo_io_buffer".
1102 * 1102 *
1103 * Returns 0. 1103 * Returns 0.
1104 */ 1104 */
1105 static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1105 static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1106 { 1106 {
1107 struct list_head *pos; 1107 struct list_head *pos;
1108 bool done = true; 1108 bool done = true;
1109 1109
1110 if (head->read_eof) 1110 if (head->read_eof)
1111 return 0; 1111 return 0;
1112 down_read(&tomoyo_policy_manager_list_lock); 1112 down_read(&tomoyo_policy_manager_list_lock);
1113 list_for_each_cookie(pos, head->read_var2, 1113 list_for_each_cookie(pos, head->read_var2,
1114 &tomoyo_policy_manager_list) { 1114 &tomoyo_policy_manager_list) {
1115 struct tomoyo_policy_manager_entry *ptr; 1115 struct tomoyo_policy_manager_entry *ptr;
1116 ptr = list_entry(pos, struct tomoyo_policy_manager_entry, 1116 ptr = list_entry(pos, struct tomoyo_policy_manager_entry,
1117 list); 1117 list);
1118 if (ptr->is_deleted) 1118 if (ptr->is_deleted)
1119 continue; 1119 continue;
1120 if (!tomoyo_io_printf(head, "%s\n", ptr->manager->name)) { 1120 if (!tomoyo_io_printf(head, "%s\n", ptr->manager->name)) {
1121 done = false; 1121 done = false;
1122 break; 1122 break;
1123 } 1123 }
1124 } 1124 }
1125 up_read(&tomoyo_policy_manager_list_lock); 1125 up_read(&tomoyo_policy_manager_list_lock);
1126 head->read_eof = done; 1126 head->read_eof = done;
1127 return 0; 1127 return 0;
1128 } 1128 }
1129 1129
1130 /** 1130 /**
1131 * tomoyo_is_policy_manager - Check whether the current process is a policy manager. 1131 * tomoyo_is_policy_manager - Check whether the current process is a policy manager.
1132 * 1132 *
1133 * Returns true if the current process is permitted to modify policy 1133 * Returns true if the current process is permitted to modify policy
1134 * via /sys/kernel/security/tomoyo/ interface. 1134 * via /sys/kernel/security/tomoyo/ interface.
1135 */ 1135 */
1136 static bool tomoyo_is_policy_manager(void) 1136 static bool tomoyo_is_policy_manager(void)
1137 { 1137 {
1138 struct tomoyo_policy_manager_entry *ptr; 1138 struct tomoyo_policy_manager_entry *ptr;
1139 const char *exe; 1139 const char *exe;
1140 const struct task_struct *task = current; 1140 const struct task_struct *task = current;
1141 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; 1141 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
1142 bool found = false; 1142 bool found = false;
1143 1143
1144 if (!tomoyo_policy_loaded) 1144 if (!tomoyo_policy_loaded)
1145 return true; 1145 return true;
1146 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 1146 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
1147 return false; 1147 return false;
1148 down_read(&tomoyo_policy_manager_list_lock); 1148 down_read(&tomoyo_policy_manager_list_lock);
1149 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1149 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1150 if (!ptr->is_deleted && ptr->is_domain 1150 if (!ptr->is_deleted && ptr->is_domain
1151 && !tomoyo_pathcmp(domainname, ptr->manager)) { 1151 && !tomoyo_pathcmp(domainname, ptr->manager)) {
1152 found = true; 1152 found = true;
1153 break; 1153 break;
1154 } 1154 }
1155 } 1155 }
1156 up_read(&tomoyo_policy_manager_list_lock); 1156 up_read(&tomoyo_policy_manager_list_lock);
1157 if (found) 1157 if (found)
1158 return true; 1158 return true;
1159 exe = tomoyo_get_exe(); 1159 exe = tomoyo_get_exe();
1160 if (!exe) 1160 if (!exe)
1161 return false; 1161 return false;
1162 down_read(&tomoyo_policy_manager_list_lock); 1162 down_read(&tomoyo_policy_manager_list_lock);
1163 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1163 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1164 if (!ptr->is_deleted && !ptr->is_domain 1164 if (!ptr->is_deleted && !ptr->is_domain
1165 && !strcmp(exe, ptr->manager->name)) { 1165 && !strcmp(exe, ptr->manager->name)) {
1166 found = true; 1166 found = true;
1167 break; 1167 break;
1168 } 1168 }
1169 } 1169 }
1170 up_read(&tomoyo_policy_manager_list_lock); 1170 up_read(&tomoyo_policy_manager_list_lock);
1171 if (!found) { /* Reduce error messages. */ 1171 if (!found) { /* Reduce error messages. */
1172 static pid_t last_pid; 1172 static pid_t last_pid;
1173 const pid_t pid = current->pid; 1173 const pid_t pid = current->pid;
1174 if (last_pid != pid) { 1174 if (last_pid != pid) {
1175 printk(KERN_WARNING "%s ( %s ) is not permitted to " 1175 printk(KERN_WARNING "%s ( %s ) is not permitted to "
1176 "update policies.\n", domainname->name, exe); 1176 "update policies.\n", domainname->name, exe);
1177 last_pid = pid; 1177 last_pid = pid;
1178 } 1178 }
1179 } 1179 }
1180 tomoyo_free(exe); 1180 tomoyo_free(exe);
1181 return found; 1181 return found;
1182 } 1182 }
1183 1183
1184 /** 1184 /**
1185 * tomoyo_is_select_one - Parse select command. 1185 * tomoyo_is_select_one - Parse select command.
1186 * 1186 *
1187 * @head: Pointer to "struct tomoyo_io_buffer". 1187 * @head: Pointer to "struct tomoyo_io_buffer".
1188 * @data: String to parse. 1188 * @data: String to parse.
1189 * 1189 *
1190 * Returns true on success, false otherwise. 1190 * Returns true on success, false otherwise.
1191 */ 1191 */
1192 static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1192 static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1193 const char *data) 1193 const char *data)
1194 { 1194 {
1195 unsigned int pid; 1195 unsigned int pid;
1196 struct tomoyo_domain_info *domain = NULL; 1196 struct tomoyo_domain_info *domain = NULL;
1197 1197
1198 if (sscanf(data, "pid=%u", &pid) == 1) { 1198 if (sscanf(data, "pid=%u", &pid) == 1) {
1199 struct task_struct *p; 1199 struct task_struct *p;
1200 /***** CRITICAL SECTION START *****/ 1200 /***** CRITICAL SECTION START *****/
1201 read_lock(&tasklist_lock); 1201 read_lock(&tasklist_lock);
1202 p = find_task_by_vpid(pid); 1202 p = find_task_by_vpid(pid);
1203 if (p) 1203 if (p)
1204 domain = tomoyo_real_domain(p); 1204 domain = tomoyo_real_domain(p);
1205 read_unlock(&tasklist_lock); 1205 read_unlock(&tasklist_lock);
1206 /***** CRITICAL SECTION END *****/ 1206 /***** CRITICAL SECTION END *****/
1207 } else if (!strncmp(data, "domain=", 7)) { 1207 } else if (!strncmp(data, "domain=", 7)) {
1208 if (tomoyo_is_domain_def(data + 7)) { 1208 if (tomoyo_is_domain_def(data + 7)) {
1209 down_read(&tomoyo_domain_list_lock); 1209 down_read(&tomoyo_domain_list_lock);
1210 domain = tomoyo_find_domain(data + 7); 1210 domain = tomoyo_find_domain(data + 7);
1211 up_read(&tomoyo_domain_list_lock); 1211 up_read(&tomoyo_domain_list_lock);
1212 } 1212 }
1213 } else 1213 } else
1214 return false; 1214 return false;
1215 head->write_var1 = domain; 1215 head->write_var1 = domain;
1216 /* Accessing read_buf is safe because head->io_sem is held. */ 1216 /* Accessing read_buf is safe because head->io_sem is held. */
1217 if (!head->read_buf) 1217 if (!head->read_buf)
1218 return true; /* Do nothing if open(O_WRONLY). */ 1218 return true; /* Do nothing if open(O_WRONLY). */
1219 head->read_avail = 0; 1219 head->read_avail = 0;
1220 tomoyo_io_printf(head, "# select %s\n", data); 1220 tomoyo_io_printf(head, "# select %s\n", data);
1221 head->read_single_domain = true; 1221 head->read_single_domain = true;
1222 head->read_eof = !domain; 1222 head->read_eof = !domain;
1223 if (domain) { 1223 if (domain) {
1224 struct tomoyo_domain_info *d; 1224 struct tomoyo_domain_info *d;
1225 head->read_var1 = NULL; 1225 head->read_var1 = NULL;
1226 down_read(&tomoyo_domain_list_lock); 1226 down_read(&tomoyo_domain_list_lock);
1227 list_for_each_entry(d, &tomoyo_domain_list, list) { 1227 list_for_each_entry(d, &tomoyo_domain_list, list) {
1228 if (d == domain) 1228 if (d == domain)
1229 break; 1229 break;
1230 head->read_var1 = &d->list; 1230 head->read_var1 = &d->list;
1231 } 1231 }
1232 up_read(&tomoyo_domain_list_lock); 1232 up_read(&tomoyo_domain_list_lock);
1233 head->read_var2 = NULL; 1233 head->read_var2 = NULL;
1234 head->read_bit = 0; 1234 head->read_bit = 0;
1235 head->read_step = 0; 1235 head->read_step = 0;
1236 if (domain->is_deleted) 1236 if (domain->is_deleted)
1237 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 1237 tomoyo_io_printf(head, "# This is a deleted domain.\n");
1238 } 1238 }
1239 return true; 1239 return true;
1240 } 1240 }
1241 1241
1242 /** 1242 /**
1243 * tomoyo_write_domain_policy - Write domain policy. 1243 * tomoyo_write_domain_policy - Write domain policy.
1244 * 1244 *
1245 * @head: Pointer to "struct tomoyo_io_buffer". 1245 * @head: Pointer to "struct tomoyo_io_buffer".
1246 * 1246 *
1247 * Returns 0 on success, negative value otherwise. 1247 * Returns 0 on success, negative value otherwise.
1248 */ 1248 */
1249 static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1249 static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1250 { 1250 {
1251 char *data = head->write_buf; 1251 char *data = head->write_buf;
1252 struct tomoyo_domain_info *domain = head->write_var1; 1252 struct tomoyo_domain_info *domain = head->write_var1;
1253 bool is_delete = false; 1253 bool is_delete = false;
1254 bool is_select = false; 1254 bool is_select = false;
1255 bool is_undelete = false;
1256 unsigned int profile; 1255 unsigned int profile;
1257 1256
1258 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) 1257 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
1259 is_delete = true; 1258 is_delete = true;
1260 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) 1259 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
1261 is_select = true; 1260 is_select = true;
1262 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_UNDELETE))
1263 is_undelete = true;
1264 if (is_select && tomoyo_is_select_one(head, data)) 1261 if (is_select && tomoyo_is_select_one(head, data))
1265 return 0; 1262 return 0;
1266 /* Don't allow updating policies by non manager programs. */ 1263 /* Don't allow updating policies by non manager programs. */
1267 if (!tomoyo_is_policy_manager()) 1264 if (!tomoyo_is_policy_manager())
1268 return -EPERM; 1265 return -EPERM;
1269 if (tomoyo_is_domain_def(data)) { 1266 if (tomoyo_is_domain_def(data)) {
1270 domain = NULL; 1267 domain = NULL;
1271 if (is_delete) 1268 if (is_delete)
1272 tomoyo_delete_domain(data); 1269 tomoyo_delete_domain(data);
1273 else if (is_select) { 1270 else if (is_select) {
1274 down_read(&tomoyo_domain_list_lock); 1271 down_read(&tomoyo_domain_list_lock);
1275 domain = tomoyo_find_domain(data); 1272 domain = tomoyo_find_domain(data);
1276 up_read(&tomoyo_domain_list_lock); 1273 up_read(&tomoyo_domain_list_lock);
1277 } else if (is_undelete) 1274 } else
1278 domain = tomoyo_undelete_domain(data);
1279 else
1280 domain = tomoyo_find_or_assign_new_domain(data, 0); 1275 domain = tomoyo_find_or_assign_new_domain(data, 0);
1281 head->write_var1 = domain; 1276 head->write_var1 = domain;
1282 return 0; 1277 return 0;
1283 } 1278 }
1284 if (!domain) 1279 if (!domain)
1285 return -EINVAL; 1280 return -EINVAL;
1286 1281
1287 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1 1282 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1
1288 && profile < TOMOYO_MAX_PROFILES) { 1283 && profile < TOMOYO_MAX_PROFILES) {
1289 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 1284 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)
1290 domain->profile = (u8) profile; 1285 domain->profile = (u8) profile;
1291 return 0; 1286 return 0;
1292 } 1287 }
1293 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1288 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1294 tomoyo_set_domain_flag(domain, is_delete, 1289 tomoyo_set_domain_flag(domain, is_delete,
1295 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ); 1290 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
1296 return 0; 1291 return 0;
1297 } 1292 }
1298 return tomoyo_write_file_policy(data, domain, is_delete); 1293 return tomoyo_write_file_policy(data, domain, is_delete);
1299 } 1294 }
1300 1295
1301 /** 1296 /**
1302 * tomoyo_print_single_path_acl - Print a single path ACL entry. 1297 * tomoyo_print_single_path_acl - Print a single path ACL entry.
1303 * 1298 *
1304 * @head: Pointer to "struct tomoyo_io_buffer". 1299 * @head: Pointer to "struct tomoyo_io_buffer".
1305 * @ptr: Pointer to "struct tomoyo_single_path_acl_record". 1300 * @ptr: Pointer to "struct tomoyo_single_path_acl_record".
1306 * 1301 *
1307 * Returns true on success, false otherwise. 1302 * Returns true on success, false otherwise.
1308 */ 1303 */
1309 static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head, 1304 static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head,
1310 struct tomoyo_single_path_acl_record * 1305 struct tomoyo_single_path_acl_record *
1311 ptr) 1306 ptr)
1312 { 1307 {
1313 int pos; 1308 int pos;
1314 u8 bit; 1309 u8 bit;
1315 const char *atmark = ""; 1310 const char *atmark = "";
1316 const char *filename; 1311 const char *filename;
1317 const u16 perm = ptr->perm; 1312 const u16 perm = ptr->perm;
1318 1313
1319 filename = ptr->filename->name; 1314 filename = ptr->filename->name;
1320 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION; 1315 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION;
1321 bit++) { 1316 bit++) {
1322 const char *msg; 1317 const char *msg;
1323 if (!(perm & (1 << bit))) 1318 if (!(perm & (1 << bit)))
1324 continue; 1319 continue;
1325 /* Print "read/write" instead of "read" and "write". */ 1320 /* Print "read/write" instead of "read" and "write". */
1326 if ((bit == TOMOYO_TYPE_READ_ACL || 1321 if ((bit == TOMOYO_TYPE_READ_ACL ||
1327 bit == TOMOYO_TYPE_WRITE_ACL) 1322 bit == TOMOYO_TYPE_WRITE_ACL)
1328 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) 1323 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
1329 continue; 1324 continue;
1330 msg = tomoyo_sp2keyword(bit); 1325 msg = tomoyo_sp2keyword(bit);
1331 pos = head->read_avail; 1326 pos = head->read_avail;
1332 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg, 1327 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg,
1333 atmark, filename)) 1328 atmark, filename))
1334 goto out; 1329 goto out;
1335 } 1330 }
1336 head->read_bit = 0; 1331 head->read_bit = 0;
1337 return true; 1332 return true;
1338 out: 1333 out:
1339 head->read_bit = bit; 1334 head->read_bit = bit;
1340 head->read_avail = pos; 1335 head->read_avail = pos;
1341 return false; 1336 return false;
1342 } 1337 }
1343 1338
1344 /** 1339 /**
1345 * tomoyo_print_double_path_acl - Print a double path ACL entry. 1340 * tomoyo_print_double_path_acl - Print a double path ACL entry.
1346 * 1341 *
1347 * @head: Pointer to "struct tomoyo_io_buffer". 1342 * @head: Pointer to "struct tomoyo_io_buffer".
1348 * @ptr: Pointer to "struct tomoyo_double_path_acl_record". 1343 * @ptr: Pointer to "struct tomoyo_double_path_acl_record".
1349 * 1344 *
1350 * Returns true on success, false otherwise. 1345 * Returns true on success, false otherwise.
1351 */ 1346 */
1352 static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, 1347 static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
1353 struct tomoyo_double_path_acl_record * 1348 struct tomoyo_double_path_acl_record *
1354 ptr) 1349 ptr)
1355 { 1350 {
1356 int pos; 1351 int pos;
1357 const char *atmark1 = ""; 1352 const char *atmark1 = "";
1358 const char *atmark2 = ""; 1353 const char *atmark2 = "";
1359 const char *filename1; 1354 const char *filename1;
1360 const char *filename2; 1355 const char *filename2;
1361 const u8 perm = ptr->perm; 1356 const u8 perm = ptr->perm;
1362 u8 bit; 1357 u8 bit;
1363 1358
1364 filename1 = ptr->filename1->name; 1359 filename1 = ptr->filename1->name;
1365 filename2 = ptr->filename2->name; 1360 filename2 = ptr->filename2->name;
1366 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION; 1361 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION;
1367 bit++) { 1362 bit++) {
1368 const char *msg; 1363 const char *msg;
1369 if (!(perm & (1 << bit))) 1364 if (!(perm & (1 << bit)))
1370 continue; 1365 continue;
1371 msg = tomoyo_dp2keyword(bit); 1366 msg = tomoyo_dp2keyword(bit);
1372 pos = head->read_avail; 1367 pos = head->read_avail;
1373 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg, 1368 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg,
1374 atmark1, filename1, atmark2, filename2)) 1369 atmark1, filename1, atmark2, filename2))
1375 goto out; 1370 goto out;
1376 } 1371 }
1377 head->read_bit = 0; 1372 head->read_bit = 0;
1378 return true; 1373 return true;
1379 out: 1374 out:
1380 head->read_bit = bit; 1375 head->read_bit = bit;
1381 head->read_avail = pos; 1376 head->read_avail = pos;
1382 return false; 1377 return false;
1383 } 1378 }
1384 1379
1385 /** 1380 /**
1386 * tomoyo_print_entry - Print an ACL entry. 1381 * tomoyo_print_entry - Print an ACL entry.
1387 * 1382 *
1388 * @head: Pointer to "struct tomoyo_io_buffer". 1383 * @head: Pointer to "struct tomoyo_io_buffer".
1389 * @ptr: Pointer to an ACL entry. 1384 * @ptr: Pointer to an ACL entry.
1390 * 1385 *
1391 * Returns true on success, false otherwise. 1386 * Returns true on success, false otherwise.
1392 */ 1387 */
1393 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1388 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1394 struct tomoyo_acl_info *ptr) 1389 struct tomoyo_acl_info *ptr)
1395 { 1390 {
1396 const u8 acl_type = tomoyo_acl_type2(ptr); 1391 const u8 acl_type = tomoyo_acl_type2(ptr);
1397 1392
1398 if (acl_type & TOMOYO_ACL_DELETED) 1393 if (acl_type & TOMOYO_ACL_DELETED)
1399 return true; 1394 return true;
1400 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { 1395 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) {
1401 struct tomoyo_single_path_acl_record *acl 1396 struct tomoyo_single_path_acl_record *acl
1402 = container_of(ptr, 1397 = container_of(ptr,
1403 struct tomoyo_single_path_acl_record, 1398 struct tomoyo_single_path_acl_record,
1404 head); 1399 head);
1405 return tomoyo_print_single_path_acl(head, acl); 1400 return tomoyo_print_single_path_acl(head, acl);
1406 } 1401 }
1407 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) { 1402 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) {
1408 struct tomoyo_double_path_acl_record *acl 1403 struct tomoyo_double_path_acl_record *acl
1409 = container_of(ptr, 1404 = container_of(ptr,
1410 struct tomoyo_double_path_acl_record, 1405 struct tomoyo_double_path_acl_record,
1411 head); 1406 head);
1412 return tomoyo_print_double_path_acl(head, acl); 1407 return tomoyo_print_double_path_acl(head, acl);
1413 } 1408 }
1414 BUG(); /* This must not happen. */ 1409 BUG(); /* This must not happen. */
1415 return false; 1410 return false;
1416 } 1411 }
1417 1412
1418 /** 1413 /**
1419 * tomoyo_read_domain_policy - Read domain policy. 1414 * tomoyo_read_domain_policy - Read domain policy.
1420 * 1415 *
1421 * @head: Pointer to "struct tomoyo_io_buffer". 1416 * @head: Pointer to "struct tomoyo_io_buffer".
1422 * 1417 *
1423 * Returns 0. 1418 * Returns 0.
1424 */ 1419 */
1425 static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1420 static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1426 { 1421 {
1427 struct list_head *dpos; 1422 struct list_head *dpos;
1428 struct list_head *apos; 1423 struct list_head *apos;
1429 bool done = true; 1424 bool done = true;
1430 1425
1431 if (head->read_eof) 1426 if (head->read_eof)
1432 return 0; 1427 return 0;
1433 if (head->read_step == 0) 1428 if (head->read_step == 0)
1434 head->read_step = 1; 1429 head->read_step = 1;
1435 down_read(&tomoyo_domain_list_lock); 1430 down_read(&tomoyo_domain_list_lock);
1436 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { 1431 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
1437 struct tomoyo_domain_info *domain; 1432 struct tomoyo_domain_info *domain;
1438 const char *quota_exceeded = ""; 1433 const char *quota_exceeded = "";
1439 const char *transition_failed = ""; 1434 const char *transition_failed = "";
1440 const char *ignore_global_allow_read = ""; 1435 const char *ignore_global_allow_read = "";
1441 domain = list_entry(dpos, struct tomoyo_domain_info, list); 1436 domain = list_entry(dpos, struct tomoyo_domain_info, list);
1442 if (head->read_step != 1) 1437 if (head->read_step != 1)
1443 goto acl_loop; 1438 goto acl_loop;
1444 if (domain->is_deleted && !head->read_single_domain) 1439 if (domain->is_deleted && !head->read_single_domain)
1445 continue; 1440 continue;
1446 /* Print domainname and flags. */ 1441 /* Print domainname and flags. */
1447 if (domain->quota_warned) 1442 if (domain->quota_warned)
1448 quota_exceeded = "quota_exceeded\n"; 1443 quota_exceeded = "quota_exceeded\n";
1449 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) 1444 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED)
1450 transition_failed = "transition_failed\n"; 1445 transition_failed = "transition_failed\n";
1451 if (domain->flags & 1446 if (domain->flags &
1452 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) 1447 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1453 ignore_global_allow_read 1448 ignore_global_allow_read
1454 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1449 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1455 if (!tomoyo_io_printf(head, 1450 if (!tomoyo_io_printf(head,
1456 "%s\n" TOMOYO_KEYWORD_USE_PROFILE "%u\n" 1451 "%s\n" TOMOYO_KEYWORD_USE_PROFILE "%u\n"
1457 "%s%s%s\n", domain->domainname->name, 1452 "%s%s%s\n", domain->domainname->name,
1458 domain->profile, quota_exceeded, 1453 domain->profile, quota_exceeded,
1459 transition_failed, 1454 transition_failed,
1460 ignore_global_allow_read)) { 1455 ignore_global_allow_read)) {
1461 done = false; 1456 done = false;
1462 break; 1457 break;
1463 } 1458 }
1464 head->read_step = 2; 1459 head->read_step = 2;
1465 acl_loop: 1460 acl_loop:
1466 if (head->read_step == 3) 1461 if (head->read_step == 3)
1467 goto tail_mark; 1462 goto tail_mark;
1468 /* Print ACL entries in the domain. */ 1463 /* Print ACL entries in the domain. */
1469 down_read(&tomoyo_domain_acl_info_list_lock); 1464 down_read(&tomoyo_domain_acl_info_list_lock);
1470 list_for_each_cookie(apos, head->read_var2, 1465 list_for_each_cookie(apos, head->read_var2,
1471 &domain->acl_info_list) { 1466 &domain->acl_info_list) {
1472 struct tomoyo_acl_info *ptr 1467 struct tomoyo_acl_info *ptr
1473 = list_entry(apos, struct tomoyo_acl_info, 1468 = list_entry(apos, struct tomoyo_acl_info,
1474 list); 1469 list);
1475 if (!tomoyo_print_entry(head, ptr)) { 1470 if (!tomoyo_print_entry(head, ptr)) {
1476 done = false; 1471 done = false;
1477 break; 1472 break;
1478 } 1473 }
1479 } 1474 }
1480 up_read(&tomoyo_domain_acl_info_list_lock); 1475 up_read(&tomoyo_domain_acl_info_list_lock);
1481 if (!done) 1476 if (!done)
1482 break; 1477 break;
1483 head->read_step = 3; 1478 head->read_step = 3;
1484 tail_mark: 1479 tail_mark:
1485 if (!tomoyo_io_printf(head, "\n")) { 1480 if (!tomoyo_io_printf(head, "\n")) {
1486 done = false; 1481 done = false;
1487 break; 1482 break;
1488 } 1483 }
1489 head->read_step = 1; 1484 head->read_step = 1;
1490 if (head->read_single_domain) 1485 if (head->read_single_domain)
1491 break; 1486 break;
1492 } 1487 }
1493 up_read(&tomoyo_domain_list_lock); 1488 up_read(&tomoyo_domain_list_lock);
1494 head->read_eof = done; 1489 head->read_eof = done;
1495 return 0; 1490 return 0;
1496 } 1491 }
1497 1492
1498 /** 1493 /**
1499 * tomoyo_write_domain_profile - Assign profile for specified domain. 1494 * tomoyo_write_domain_profile - Assign profile for specified domain.
1500 * 1495 *
1501 * @head: Pointer to "struct tomoyo_io_buffer". 1496 * @head: Pointer to "struct tomoyo_io_buffer".
1502 * 1497 *
1503 * Returns 0 on success, -EINVAL otherwise. 1498 * Returns 0 on success, -EINVAL otherwise.
1504 * 1499 *
1505 * This is equivalent to doing 1500 * This is equivalent to doing
1506 * 1501 *
1507 * ( echo "select " $domainname; echo "use_profile " $profile ) | 1502 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1508 * /usr/lib/ccs/loadpolicy -d 1503 * /usr/lib/ccs/loadpolicy -d
1509 */ 1504 */
1510 static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1505 static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1511 { 1506 {
1512 char *data = head->write_buf; 1507 char *data = head->write_buf;
1513 char *cp = strchr(data, ' '); 1508 char *cp = strchr(data, ' ');
1514 struct tomoyo_domain_info *domain; 1509 struct tomoyo_domain_info *domain;
1515 unsigned long profile; 1510 unsigned long profile;
1516 1511
1517 if (!cp) 1512 if (!cp)
1518 return -EINVAL; 1513 return -EINVAL;
1519 *cp = '\0'; 1514 *cp = '\0';
1520 down_read(&tomoyo_domain_list_lock); 1515 down_read(&tomoyo_domain_list_lock);
1521 domain = tomoyo_find_domain(cp + 1); 1516 domain = tomoyo_find_domain(cp + 1);
1522 up_read(&tomoyo_domain_list_lock); 1517 up_read(&tomoyo_domain_list_lock);
1523 if (strict_strtoul(data, 10, &profile)) 1518 if (strict_strtoul(data, 10, &profile))
1524 return -EINVAL; 1519 return -EINVAL;
1525 if (domain && profile < TOMOYO_MAX_PROFILES 1520 if (domain && profile < TOMOYO_MAX_PROFILES
1526 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)) 1521 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
1527 domain->profile = (u8) profile; 1522 domain->profile = (u8) profile;
1528 return 0; 1523 return 0;
1529 } 1524 }
1530 1525
1531 /** 1526 /**
1532 * tomoyo_read_domain_profile - Read only domainname and profile. 1527 * tomoyo_read_domain_profile - Read only domainname and profile.
1533 * 1528 *
1534 * @head: Pointer to "struct tomoyo_io_buffer". 1529 * @head: Pointer to "struct tomoyo_io_buffer".
1535 * 1530 *
1536 * Returns list of profile number and domainname pairs. 1531 * Returns list of profile number and domainname pairs.
1537 * 1532 *
1538 * This is equivalent to doing 1533 * This is equivalent to doing
1539 * 1534 *
1540 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy | 1535 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy |
1541 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) 1536 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1542 * domainname = $0; } else if ( $1 == "use_profile" ) { 1537 * domainname = $0; } else if ( $1 == "use_profile" ) {
1543 * print $2 " " domainname; domainname = ""; } } ; ' 1538 * print $2 " " domainname; domainname = ""; } } ; '
1544 */ 1539 */
1545 static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1540 static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1546 { 1541 {
1547 struct list_head *pos; 1542 struct list_head *pos;
1548 bool done = true; 1543 bool done = true;
1549 1544
1550 if (head->read_eof) 1545 if (head->read_eof)
1551 return 0; 1546 return 0;
1552 down_read(&tomoyo_domain_list_lock); 1547 down_read(&tomoyo_domain_list_lock);
1553 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { 1548 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
1554 struct tomoyo_domain_info *domain; 1549 struct tomoyo_domain_info *domain;
1555 domain = list_entry(pos, struct tomoyo_domain_info, list); 1550 domain = list_entry(pos, struct tomoyo_domain_info, list);
1556 if (domain->is_deleted) 1551 if (domain->is_deleted)
1557 continue; 1552 continue;
1558 if (!tomoyo_io_printf(head, "%u %s\n", domain->profile, 1553 if (!tomoyo_io_printf(head, "%u %s\n", domain->profile,
1559 domain->domainname->name)) { 1554 domain->domainname->name)) {
1560 done = false; 1555 done = false;
1561 break; 1556 break;
1562 } 1557 }
1563 } 1558 }
1564 up_read(&tomoyo_domain_list_lock); 1559 up_read(&tomoyo_domain_list_lock);
1565 head->read_eof = done; 1560 head->read_eof = done;
1566 return 0; 1561 return 0;
1567 } 1562 }
1568 1563
1569 /** 1564 /**
1570 * tomoyo_write_pid: Specify PID to obtain domainname. 1565 * tomoyo_write_pid: Specify PID to obtain domainname.
1571 * 1566 *
1572 * @head: Pointer to "struct tomoyo_io_buffer". 1567 * @head: Pointer to "struct tomoyo_io_buffer".
1573 * 1568 *
1574 * Returns 0. 1569 * Returns 0.
1575 */ 1570 */
1576 static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1571 static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1577 { 1572 {
1578 unsigned long pid; 1573 unsigned long pid;
1579 /* No error check. */ 1574 /* No error check. */
1580 strict_strtoul(head->write_buf, 10, &pid); 1575 strict_strtoul(head->write_buf, 10, &pid);
1581 head->read_step = (int) pid; 1576 head->read_step = (int) pid;
1582 head->read_eof = false; 1577 head->read_eof = false;
1583 return 0; 1578 return 0;
1584 } 1579 }
1585 1580
1586 /** 1581 /**
1587 * tomoyo_read_pid - Get domainname of the specified PID. 1582 * tomoyo_read_pid - Get domainname of the specified PID.
1588 * 1583 *
1589 * @head: Pointer to "struct tomoyo_io_buffer". 1584 * @head: Pointer to "struct tomoyo_io_buffer".
1590 * 1585 *
1591 * Returns the domainname which the specified PID is in on success, 1586 * Returns the domainname which the specified PID is in on success,
1592 * empty string otherwise. 1587 * empty string otherwise.
1593 * The PID is specified by tomoyo_write_pid() so that the user can obtain 1588 * The PID is specified by tomoyo_write_pid() so that the user can obtain
1594 * using read()/write() interface rather than sysctl() interface. 1589 * using read()/write() interface rather than sysctl() interface.
1595 */ 1590 */
1596 static int tomoyo_read_pid(struct tomoyo_io_buffer *head) 1591 static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1597 { 1592 {
1598 if (head->read_avail == 0 && !head->read_eof) { 1593 if (head->read_avail == 0 && !head->read_eof) {
1599 const int pid = head->read_step; 1594 const int pid = head->read_step;
1600 struct task_struct *p; 1595 struct task_struct *p;
1601 struct tomoyo_domain_info *domain = NULL; 1596 struct tomoyo_domain_info *domain = NULL;
1602 /***** CRITICAL SECTION START *****/ 1597 /***** CRITICAL SECTION START *****/
1603 read_lock(&tasklist_lock); 1598 read_lock(&tasklist_lock);
1604 p = find_task_by_vpid(pid); 1599 p = find_task_by_vpid(pid);
1605 if (p) 1600 if (p)
1606 domain = tomoyo_real_domain(p); 1601 domain = tomoyo_real_domain(p);
1607 read_unlock(&tasklist_lock); 1602 read_unlock(&tasklist_lock);
1608 /***** CRITICAL SECTION END *****/ 1603 /***** CRITICAL SECTION END *****/
1609 if (domain) 1604 if (domain)
1610 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1605 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1611 domain->domainname->name); 1606 domain->domainname->name);
1612 head->read_eof = true; 1607 head->read_eof = true;
1613 } 1608 }
1614 return 0; 1609 return 0;
1615 } 1610 }
1616 1611
1617 /** 1612 /**
1618 * tomoyo_write_exception_policy - Write exception policy. 1613 * tomoyo_write_exception_policy - Write exception policy.
1619 * 1614 *
1620 * @head: Pointer to "struct tomoyo_io_buffer". 1615 * @head: Pointer to "struct tomoyo_io_buffer".
1621 * 1616 *
1622 * Returns 0 on success, negative value otherwise. 1617 * Returns 0 on success, negative value otherwise.
1623 */ 1618 */
1624 static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1619 static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1625 { 1620 {
1626 char *data = head->write_buf; 1621 char *data = head->write_buf;
1627 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1622 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
1628 1623
1629 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN)) 1624 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN))
1630 return tomoyo_write_domain_keeper_policy(data, false, 1625 return tomoyo_write_domain_keeper_policy(data, false,
1631 is_delete); 1626 is_delete);
1632 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN)) 1627 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN))
1633 return tomoyo_write_domain_keeper_policy(data, true, is_delete); 1628 return tomoyo_write_domain_keeper_policy(data, true, is_delete);
1634 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN)) 1629 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN))
1635 return tomoyo_write_domain_initializer_policy(data, false, 1630 return tomoyo_write_domain_initializer_policy(data, false,
1636 is_delete); 1631 is_delete);
1637 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN)) 1632 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN))
1638 return tomoyo_write_domain_initializer_policy(data, true, 1633 return tomoyo_write_domain_initializer_policy(data, true,
1639 is_delete); 1634 is_delete);
1640 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS)) 1635 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS))
1641 return tomoyo_write_alias_policy(data, is_delete); 1636 return tomoyo_write_alias_policy(data, is_delete);
1642 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ)) 1637 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ))
1643 return tomoyo_write_globally_readable_policy(data, is_delete); 1638 return tomoyo_write_globally_readable_policy(data, is_delete);
1644 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN)) 1639 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN))
1645 return tomoyo_write_pattern_policy(data, is_delete); 1640 return tomoyo_write_pattern_policy(data, is_delete);
1646 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) 1641 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE))
1647 return tomoyo_write_no_rewrite_policy(data, is_delete); 1642 return tomoyo_write_no_rewrite_policy(data, is_delete);
1648 return -EINVAL; 1643 return -EINVAL;
1649 } 1644 }
1650 1645
1651 /** 1646 /**
1652 * tomoyo_read_exception_policy - Read exception policy. 1647 * tomoyo_read_exception_policy - Read exception policy.
1653 * 1648 *
1654 * @head: Pointer to "struct tomoyo_io_buffer". 1649 * @head: Pointer to "struct tomoyo_io_buffer".
1655 * 1650 *
1656 * Returns 0 on success, -EINVAL otherwise. 1651 * Returns 0 on success, -EINVAL otherwise.
1657 */ 1652 */
1658 static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1653 static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1659 { 1654 {
1660 if (!head->read_eof) { 1655 if (!head->read_eof) {
1661 switch (head->read_step) { 1656 switch (head->read_step) {
1662 case 0: 1657 case 0:
1663 head->read_var2 = NULL; 1658 head->read_var2 = NULL;
1664 head->read_step = 1; 1659 head->read_step = 1;
1665 case 1: 1660 case 1:
1666 if (!tomoyo_read_domain_keeper_policy(head)) 1661 if (!tomoyo_read_domain_keeper_policy(head))
1667 break; 1662 break;
1668 head->read_var2 = NULL; 1663 head->read_var2 = NULL;
1669 head->read_step = 2; 1664 head->read_step = 2;
1670 case 2: 1665 case 2:
1671 if (!tomoyo_read_globally_readable_policy(head)) 1666 if (!tomoyo_read_globally_readable_policy(head))
1672 break; 1667 break;
1673 head->read_var2 = NULL; 1668 head->read_var2 = NULL;
1674 head->read_step = 3; 1669 head->read_step = 3;
1675 case 3: 1670 case 3:
1676 head->read_var2 = NULL; 1671 head->read_var2 = NULL;
1677 head->read_step = 4; 1672 head->read_step = 4;
1678 case 4: 1673 case 4:
1679 if (!tomoyo_read_domain_initializer_policy(head)) 1674 if (!tomoyo_read_domain_initializer_policy(head))
1680 break; 1675 break;
1681 head->read_var2 = NULL; 1676 head->read_var2 = NULL;
1682 head->read_step = 5; 1677 head->read_step = 5;
1683 case 5: 1678 case 5:
1684 if (!tomoyo_read_alias_policy(head)) 1679 if (!tomoyo_read_alias_policy(head))
1685 break; 1680 break;
1686 head->read_var2 = NULL; 1681 head->read_var2 = NULL;
1687 head->read_step = 6; 1682 head->read_step = 6;
1688 case 6: 1683 case 6:
1689 head->read_var2 = NULL; 1684 head->read_var2 = NULL;
1690 head->read_step = 7; 1685 head->read_step = 7;
1691 case 7: 1686 case 7:
1692 if (!tomoyo_read_file_pattern(head)) 1687 if (!tomoyo_read_file_pattern(head))
1693 break; 1688 break;
1694 head->read_var2 = NULL; 1689 head->read_var2 = NULL;
1695 head->read_step = 8; 1690 head->read_step = 8;
1696 case 8: 1691 case 8:
1697 if (!tomoyo_read_no_rewrite_policy(head)) 1692 if (!tomoyo_read_no_rewrite_policy(head))
1698 break; 1693 break;
1699 head->read_var2 = NULL; 1694 head->read_var2 = NULL;
1700 head->read_step = 9; 1695 head->read_step = 9;
1701 case 9: 1696 case 9:
1702 head->read_eof = true; 1697 head->read_eof = true;
1703 break; 1698 break;
1704 default: 1699 default:
1705 return -EINVAL; 1700 return -EINVAL;
1706 } 1701 }
1707 } 1702 }
1708 return 0; 1703 return 0;
1709 } 1704 }
1710 1705
1711 /* path to policy loader */ 1706 /* path to policy loader */
1712 static const char *tomoyo_loader = "/sbin/tomoyo-init"; 1707 static const char *tomoyo_loader = "/sbin/tomoyo-init";
1713 1708
1714 /** 1709 /**
1715 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 1710 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
1716 * 1711 *
1717 * Returns true if /sbin/tomoyo-init exists, false otherwise. 1712 * Returns true if /sbin/tomoyo-init exists, false otherwise.
1718 */ 1713 */
1719 static bool tomoyo_policy_loader_exists(void) 1714 static bool tomoyo_policy_loader_exists(void)
1720 { 1715 {
1721 /* 1716 /*
1722 * Don't activate MAC if the policy loader doesn't exist. 1717 * Don't activate MAC if the policy loader doesn't exist.
1723 * If the initrd includes /sbin/init but real-root-dev has not 1718 * If the initrd includes /sbin/init but real-root-dev has not
1724 * mounted on / yet, activating MAC will block the system since 1719 * mounted on / yet, activating MAC will block the system since
1725 * policies are not loaded yet. 1720 * policies are not loaded yet.
1726 * Thus, let do_execve() call this function everytime. 1721 * Thus, let do_execve() call this function everytime.
1727 */ 1722 */
1728 struct nameidata nd; 1723 struct nameidata nd;
1729 1724
1730 if (path_lookup(tomoyo_loader, LOOKUP_FOLLOW, &nd)) { 1725 if (path_lookup(tomoyo_loader, LOOKUP_FOLLOW, &nd)) {
1731 printk(KERN_INFO "Not activating Mandatory Access Control now " 1726 printk(KERN_INFO "Not activating Mandatory Access Control now "
1732 "since %s doesn't exist.\n", tomoyo_loader); 1727 "since %s doesn't exist.\n", tomoyo_loader);
1733 return false; 1728 return false;
1734 } 1729 }
1735 path_put(&nd.path); 1730 path_put(&nd.path);
1736 return true; 1731 return true;
1737 } 1732 }
1738 1733
1739 /** 1734 /**
1740 * tomoyo_load_policy - Run external policy loader to load policy. 1735 * tomoyo_load_policy - Run external policy loader to load policy.
1741 * 1736 *
1742 * @filename: The program about to start. 1737 * @filename: The program about to start.
1743 * 1738 *
1744 * This function checks whether @filename is /sbin/init , and if so 1739 * This function checks whether @filename is /sbin/init , and if so
1745 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init 1740 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
1746 * and then continues invocation of /sbin/init. 1741 * and then continues invocation of /sbin/init.
1747 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and 1742 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
1748 * writes to /sys/kernel/security/tomoyo/ interfaces. 1743 * writes to /sys/kernel/security/tomoyo/ interfaces.
1749 * 1744 *
1750 * Returns nothing. 1745 * Returns nothing.
1751 */ 1746 */
1752 void tomoyo_load_policy(const char *filename) 1747 void tomoyo_load_policy(const char *filename)
1753 { 1748 {
1754 char *argv[2]; 1749 char *argv[2];
1755 char *envp[3]; 1750 char *envp[3];
1756 1751
1757 if (tomoyo_policy_loaded) 1752 if (tomoyo_policy_loaded)
1758 return; 1753 return;
1759 /* 1754 /*
1760 * Check filename is /sbin/init or /sbin/tomoyo-start. 1755 * Check filename is /sbin/init or /sbin/tomoyo-start.
1761 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't 1756 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't
1762 * be passed. 1757 * be passed.
1763 * You can create /sbin/tomoyo-start by 1758 * You can create /sbin/tomoyo-start by
1764 * "ln -s /bin/true /sbin/tomoyo-start". 1759 * "ln -s /bin/true /sbin/tomoyo-start".
1765 */ 1760 */
1766 if (strcmp(filename, "/sbin/init") && 1761 if (strcmp(filename, "/sbin/init") &&
1767 strcmp(filename, "/sbin/tomoyo-start")) 1762 strcmp(filename, "/sbin/tomoyo-start"))
1768 return; 1763 return;
1769 if (!tomoyo_policy_loader_exists()) 1764 if (!tomoyo_policy_loader_exists())
1770 return; 1765 return;
1771 1766
1772 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 1767 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
1773 tomoyo_loader); 1768 tomoyo_loader);
1774 argv[0] = (char *) tomoyo_loader; 1769 argv[0] = (char *) tomoyo_loader;
1775 argv[1] = NULL; 1770 argv[1] = NULL;
1776 envp[0] = "HOME=/"; 1771 envp[0] = "HOME=/";
1777 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 1772 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
1778 envp[2] = NULL; 1773 envp[2] = NULL;
1779 call_usermodehelper(argv[0], argv, envp, 1); 1774 call_usermodehelper(argv[0], argv, envp, 1);
1780 1775
1781 printk(KERN_INFO "TOMOYO: 2.2.0-pre 2009/02/01\n"); 1776 printk(KERN_INFO "TOMOYO: 2.2.0-pre 2009/02/01\n");
1782 printk(KERN_INFO "Mandatory Access Control activated.\n"); 1777 printk(KERN_INFO "Mandatory Access Control activated.\n");
1783 tomoyo_policy_loaded = true; 1778 tomoyo_policy_loaded = true;
1784 { /* Check all profiles currently assigned to domains are defined. */ 1779 { /* Check all profiles currently assigned to domains are defined. */
1785 struct tomoyo_domain_info *domain; 1780 struct tomoyo_domain_info *domain;
1786 down_read(&tomoyo_domain_list_lock); 1781 down_read(&tomoyo_domain_list_lock);
1787 list_for_each_entry(domain, &tomoyo_domain_list, list) { 1782 list_for_each_entry(domain, &tomoyo_domain_list, list) {
1788 const u8 profile = domain->profile; 1783 const u8 profile = domain->profile;
1789 if (tomoyo_profile_ptr[profile]) 1784 if (tomoyo_profile_ptr[profile])
1790 continue; 1785 continue;
1791 panic("Profile %u (used by '%s') not defined.\n", 1786 panic("Profile %u (used by '%s') not defined.\n",
1792 profile, domain->domainname->name); 1787 profile, domain->domainname->name);
1793 } 1788 }
1794 up_read(&tomoyo_domain_list_lock); 1789 up_read(&tomoyo_domain_list_lock);
1795 } 1790 }
1796 } 1791 }
1797 1792
1798 /** 1793 /**
1799 * tomoyo_read_version: Get version. 1794 * tomoyo_read_version: Get version.
1800 * 1795 *
1801 * @head: Pointer to "struct tomoyo_io_buffer". 1796 * @head: Pointer to "struct tomoyo_io_buffer".
1802 * 1797 *
1803 * Returns version information. 1798 * Returns version information.
1804 */ 1799 */
1805 static int tomoyo_read_version(struct tomoyo_io_buffer *head) 1800 static int tomoyo_read_version(struct tomoyo_io_buffer *head)
1806 { 1801 {
1807 if (!head->read_eof) { 1802 if (!head->read_eof) {
1808 tomoyo_io_printf(head, "2.2.0-pre"); 1803 tomoyo_io_printf(head, "2.2.0-pre");
1809 head->read_eof = true; 1804 head->read_eof = true;
1810 } 1805 }
1811 return 0; 1806 return 0;
1812 } 1807 }
1813 1808
1814 /** 1809 /**
1815 * tomoyo_read_self_domain - Get the current process's domainname. 1810 * tomoyo_read_self_domain - Get the current process's domainname.
1816 * 1811 *
1817 * @head: Pointer to "struct tomoyo_io_buffer". 1812 * @head: Pointer to "struct tomoyo_io_buffer".
1818 * 1813 *
1819 * Returns the current process's domainname. 1814 * Returns the current process's domainname.
1820 */ 1815 */
1821 static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head) 1816 static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1822 { 1817 {
1823 if (!head->read_eof) { 1818 if (!head->read_eof) {
1824 /* 1819 /*
1825 * tomoyo_domain()->domainname != NULL 1820 * tomoyo_domain()->domainname != NULL
1826 * because every process belongs to a domain and 1821 * because every process belongs to a domain and
1827 * the domain's name cannot be NULL. 1822 * the domain's name cannot be NULL.
1828 */ 1823 */
1829 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); 1824 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
1830 head->read_eof = true; 1825 head->read_eof = true;
1831 } 1826 }
1832 return 0; 1827 return 0;
1833 } 1828 }
1834 1829
1835 /** 1830 /**
1836 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 1831 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
1837 * 1832 *
1838 * @type: Type of interface. 1833 * @type: Type of interface.
1839 * @file: Pointer to "struct file". 1834 * @file: Pointer to "struct file".
1840 * 1835 *
1841 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 1836 * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
1842 */ 1837 */
1843 static int tomoyo_open_control(const u8 type, struct file *file) 1838 static int tomoyo_open_control(const u8 type, struct file *file)
1844 { 1839 {
1845 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head)); 1840 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head));
1846 1841
1847 if (!head) 1842 if (!head)
1848 return -ENOMEM; 1843 return -ENOMEM;
1849 mutex_init(&head->io_sem); 1844 mutex_init(&head->io_sem);
1850 switch (type) { 1845 switch (type) {
1851 case TOMOYO_DOMAINPOLICY: 1846 case TOMOYO_DOMAINPOLICY:
1852 /* /sys/kernel/security/tomoyo/domain_policy */ 1847 /* /sys/kernel/security/tomoyo/domain_policy */
1853 head->write = tomoyo_write_domain_policy; 1848 head->write = tomoyo_write_domain_policy;
1854 head->read = tomoyo_read_domain_policy; 1849 head->read = tomoyo_read_domain_policy;
1855 break; 1850 break;
1856 case TOMOYO_EXCEPTIONPOLICY: 1851 case TOMOYO_EXCEPTIONPOLICY:
1857 /* /sys/kernel/security/tomoyo/exception_policy */ 1852 /* /sys/kernel/security/tomoyo/exception_policy */
1858 head->write = tomoyo_write_exception_policy; 1853 head->write = tomoyo_write_exception_policy;
1859 head->read = tomoyo_read_exception_policy; 1854 head->read = tomoyo_read_exception_policy;
1860 break; 1855 break;
1861 case TOMOYO_SELFDOMAIN: 1856 case TOMOYO_SELFDOMAIN:
1862 /* /sys/kernel/security/tomoyo/self_domain */ 1857 /* /sys/kernel/security/tomoyo/self_domain */
1863 head->read = tomoyo_read_self_domain; 1858 head->read = tomoyo_read_self_domain;
1864 break; 1859 break;
1865 case TOMOYO_DOMAIN_STATUS: 1860 case TOMOYO_DOMAIN_STATUS:
1866 /* /sys/kernel/security/tomoyo/.domain_status */ 1861 /* /sys/kernel/security/tomoyo/.domain_status */
1867 head->write = tomoyo_write_domain_profile; 1862 head->write = tomoyo_write_domain_profile;
1868 head->read = tomoyo_read_domain_profile; 1863 head->read = tomoyo_read_domain_profile;
1869 break; 1864 break;
1870 case TOMOYO_PROCESS_STATUS: 1865 case TOMOYO_PROCESS_STATUS:
1871 /* /sys/kernel/security/tomoyo/.process_status */ 1866 /* /sys/kernel/security/tomoyo/.process_status */
1872 head->write = tomoyo_write_pid; 1867 head->write = tomoyo_write_pid;
1873 head->read = tomoyo_read_pid; 1868 head->read = tomoyo_read_pid;
1874 break; 1869 break;
1875 case TOMOYO_VERSION: 1870 case TOMOYO_VERSION:
1876 /* /sys/kernel/security/tomoyo/version */ 1871 /* /sys/kernel/security/tomoyo/version */
1877 head->read = tomoyo_read_version; 1872 head->read = tomoyo_read_version;
1878 head->readbuf_size = 128; 1873 head->readbuf_size = 128;
1879 break; 1874 break;
1880 case TOMOYO_MEMINFO: 1875 case TOMOYO_MEMINFO:
1881 /* /sys/kernel/security/tomoyo/meminfo */ 1876 /* /sys/kernel/security/tomoyo/meminfo */
1882 head->write = tomoyo_write_memory_quota; 1877 head->write = tomoyo_write_memory_quota;
1883 head->read = tomoyo_read_memory_counter; 1878 head->read = tomoyo_read_memory_counter;
1884 head->readbuf_size = 512; 1879 head->readbuf_size = 512;
1885 break; 1880 break;
1886 case TOMOYO_PROFILE: 1881 case TOMOYO_PROFILE:
1887 /* /sys/kernel/security/tomoyo/profile */ 1882 /* /sys/kernel/security/tomoyo/profile */
1888 head->write = tomoyo_write_profile; 1883 head->write = tomoyo_write_profile;
1889 head->read = tomoyo_read_profile; 1884 head->read = tomoyo_read_profile;
1890 break; 1885 break;
1891 case TOMOYO_MANAGER: 1886 case TOMOYO_MANAGER:
1892 /* /sys/kernel/security/tomoyo/manager */ 1887 /* /sys/kernel/security/tomoyo/manager */
1893 head->write = tomoyo_write_manager_policy; 1888 head->write = tomoyo_write_manager_policy;
1894 head->read = tomoyo_read_manager_policy; 1889 head->read = tomoyo_read_manager_policy;
1895 break; 1890 break;
1896 } 1891 }
1897 if (!(file->f_mode & FMODE_READ)) { 1892 if (!(file->f_mode & FMODE_READ)) {
1898 /* 1893 /*
1899 * No need to allocate read_buf since it is not opened 1894 * No need to allocate read_buf since it is not opened
1900 * for reading. 1895 * for reading.
1901 */ 1896 */
1902 head->read = NULL; 1897 head->read = NULL;
1903 } else { 1898 } else {
1904 if (!head->readbuf_size) 1899 if (!head->readbuf_size)
1905 head->readbuf_size = 4096 * 2; 1900 head->readbuf_size = 4096 * 2;
1906 head->read_buf = tomoyo_alloc(head->readbuf_size); 1901 head->read_buf = tomoyo_alloc(head->readbuf_size);
1907 if (!head->read_buf) { 1902 if (!head->read_buf) {
1908 tomoyo_free(head); 1903 tomoyo_free(head);
1909 return -ENOMEM; 1904 return -ENOMEM;
1910 } 1905 }
1911 } 1906 }
1912 if (!(file->f_mode & FMODE_WRITE)) { 1907 if (!(file->f_mode & FMODE_WRITE)) {
1913 /* 1908 /*
1914 * No need to allocate write_buf since it is not opened 1909 * No need to allocate write_buf since it is not opened
1915 * for writing. 1910 * for writing.
1916 */ 1911 */
1917 head->write = NULL; 1912 head->write = NULL;
1918 } else if (head->write) { 1913 } else if (head->write) {
1919 head->writebuf_size = 4096 * 2; 1914 head->writebuf_size = 4096 * 2;
1920 head->write_buf = tomoyo_alloc(head->writebuf_size); 1915 head->write_buf = tomoyo_alloc(head->writebuf_size);
1921 if (!head->write_buf) { 1916 if (!head->write_buf) {
1922 tomoyo_free(head->read_buf); 1917 tomoyo_free(head->read_buf);
1923 tomoyo_free(head); 1918 tomoyo_free(head);
1924 return -ENOMEM; 1919 return -ENOMEM;
1925 } 1920 }
1926 } 1921 }
1927 file->private_data = head; 1922 file->private_data = head;
1928 /* 1923 /*
1929 * Call the handler now if the file is 1924 * Call the handler now if the file is
1930 * /sys/kernel/security/tomoyo/self_domain 1925 * /sys/kernel/security/tomoyo/self_domain
1931 * so that the user can use 1926 * so that the user can use
1932 * cat < /sys/kernel/security/tomoyo/self_domain" 1927 * cat < /sys/kernel/security/tomoyo/self_domain"
1933 * to know the current process's domainname. 1928 * to know the current process's domainname.
1934 */ 1929 */
1935 if (type == TOMOYO_SELFDOMAIN) 1930 if (type == TOMOYO_SELFDOMAIN)
1936 tomoyo_read_control(file, NULL, 0); 1931 tomoyo_read_control(file, NULL, 0);
1937 return 0; 1932 return 0;
1938 } 1933 }
1939 1934
1940 /** 1935 /**
1941 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 1936 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
1942 * 1937 *
1943 * @file: Pointer to "struct file". 1938 * @file: Pointer to "struct file".
1944 * @buffer: Poiner to buffer to write to. 1939 * @buffer: Poiner to buffer to write to.
1945 * @buffer_len: Size of @buffer. 1940 * @buffer_len: Size of @buffer.
1946 * 1941 *
1947 * Returns bytes read on success, negative value otherwise. 1942 * Returns bytes read on success, negative value otherwise.
1948 */ 1943 */
1949 static int tomoyo_read_control(struct file *file, char __user *buffer, 1944 static int tomoyo_read_control(struct file *file, char __user *buffer,
1950 const int buffer_len) 1945 const int buffer_len)
1951 { 1946 {
1952 int len = 0; 1947 int len = 0;
1953 struct tomoyo_io_buffer *head = file->private_data; 1948 struct tomoyo_io_buffer *head = file->private_data;
1954 char *cp; 1949 char *cp;
1955 1950
1956 if (!head->read) 1951 if (!head->read)
1957 return -ENOSYS; 1952 return -ENOSYS;
1958 if (mutex_lock_interruptible(&head->io_sem)) 1953 if (mutex_lock_interruptible(&head->io_sem))
1959 return -EINTR; 1954 return -EINTR;
1960 /* Call the policy handler. */ 1955 /* Call the policy handler. */
1961 len = head->read(head); 1956 len = head->read(head);
1962 if (len < 0) 1957 if (len < 0)
1963 goto out; 1958 goto out;
1964 /* Write to buffer. */ 1959 /* Write to buffer. */
1965 len = head->read_avail; 1960 len = head->read_avail;
1966 if (len > buffer_len) 1961 if (len > buffer_len)
1967 len = buffer_len; 1962 len = buffer_len;
1968 if (!len) 1963 if (!len)
1969 goto out; 1964 goto out;
1970 /* head->read_buf changes by some functions. */ 1965 /* head->read_buf changes by some functions. */
1971 cp = head->read_buf; 1966 cp = head->read_buf;
1972 if (copy_to_user(buffer, cp, len)) { 1967 if (copy_to_user(buffer, cp, len)) {
1973 len = -EFAULT; 1968 len = -EFAULT;
1974 goto out; 1969 goto out;
1975 } 1970 }
1976 head->read_avail -= len; 1971 head->read_avail -= len;
1977 memmove(cp, cp + len, head->read_avail); 1972 memmove(cp, cp + len, head->read_avail);
1978 out: 1973 out:
1979 mutex_unlock(&head->io_sem); 1974 mutex_unlock(&head->io_sem);
1980 return len; 1975 return len;
1981 } 1976 }
1982 1977
1983 /** 1978 /**
1984 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 1979 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
1985 * 1980 *
1986 * @file: Pointer to "struct file". 1981 * @file: Pointer to "struct file".
1987 * @buffer: Pointer to buffer to read from. 1982 * @buffer: Pointer to buffer to read from.
1988 * @buffer_len: Size of @buffer. 1983 * @buffer_len: Size of @buffer.
1989 * 1984 *
1990 * Returns @buffer_len on success, negative value otherwise. 1985 * Returns @buffer_len on success, negative value otherwise.
1991 */ 1986 */
1992 static int tomoyo_write_control(struct file *file, const char __user *buffer, 1987 static int tomoyo_write_control(struct file *file, const char __user *buffer,
1993 const int buffer_len) 1988 const int buffer_len)
1994 { 1989 {
1995 struct tomoyo_io_buffer *head = file->private_data; 1990 struct tomoyo_io_buffer *head = file->private_data;
1996 int error = buffer_len; 1991 int error = buffer_len;
1997 int avail_len = buffer_len; 1992 int avail_len = buffer_len;
1998 char *cp0 = head->write_buf; 1993 char *cp0 = head->write_buf;
1999 1994
2000 if (!head->write) 1995 if (!head->write)
2001 return -ENOSYS; 1996 return -ENOSYS;
2002 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 1997 if (!access_ok(VERIFY_READ, buffer, buffer_len))
2003 return -EFAULT; 1998 return -EFAULT;
2004 /* Don't allow updating policies by non manager programs. */ 1999 /* Don't allow updating policies by non manager programs. */
2005 if (head->write != tomoyo_write_pid && 2000 if (head->write != tomoyo_write_pid &&
2006 head->write != tomoyo_write_domain_policy && 2001 head->write != tomoyo_write_domain_policy &&
2007 !tomoyo_is_policy_manager()) 2002 !tomoyo_is_policy_manager())
2008 return -EPERM; 2003 return -EPERM;
2009 if (mutex_lock_interruptible(&head->io_sem)) 2004 if (mutex_lock_interruptible(&head->io_sem))
2010 return -EINTR; 2005 return -EINTR;
2011 /* Read a line and dispatch it to the policy handler. */ 2006 /* Read a line and dispatch it to the policy handler. */
2012 while (avail_len > 0) { 2007 while (avail_len > 0) {
2013 char c; 2008 char c;
2014 if (head->write_avail >= head->writebuf_size - 1) { 2009 if (head->write_avail >= head->writebuf_size - 1) {
2015 error = -ENOMEM; 2010 error = -ENOMEM;
2016 break; 2011 break;
2017 } else if (get_user(c, buffer)) { 2012 } else if (get_user(c, buffer)) {
2018 error = -EFAULT; 2013 error = -EFAULT;
2019 break; 2014 break;
2020 } 2015 }
2021 buffer++; 2016 buffer++;
2022 avail_len--; 2017 avail_len--;
2023 cp0[head->write_avail++] = c; 2018 cp0[head->write_avail++] = c;
2024 if (c != '\n') 2019 if (c != '\n')
2025 continue; 2020 continue;
2026 cp0[head->write_avail - 1] = '\0'; 2021 cp0[head->write_avail - 1] = '\0';
2027 head->write_avail = 0; 2022 head->write_avail = 0;
2028 tomoyo_normalize_line(cp0); 2023 tomoyo_normalize_line(cp0);
2029 head->write(head); 2024 head->write(head);
2030 } 2025 }
2031 mutex_unlock(&head->io_sem); 2026 mutex_unlock(&head->io_sem);
2032 return error; 2027 return error;
2033 } 2028 }
2034 2029
2035 /** 2030 /**
2036 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2031 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2037 * 2032 *
2038 * @file: Pointer to "struct file". 2033 * @file: Pointer to "struct file".
2039 * 2034 *
2040 * Releases memory and returns 0. 2035 * Releases memory and returns 0.
2041 */ 2036 */
2042 static int tomoyo_close_control(struct file *file) 2037 static int tomoyo_close_control(struct file *file)
2043 { 2038 {
2044 struct tomoyo_io_buffer *head = file->private_data; 2039 struct tomoyo_io_buffer *head = file->private_data;
2045 2040
2046 /* Release memory used for policy I/O. */ 2041 /* Release memory used for policy I/O. */
2047 tomoyo_free(head->read_buf); 2042 tomoyo_free(head->read_buf);
2048 head->read_buf = NULL; 2043 head->read_buf = NULL;
2049 tomoyo_free(head->write_buf); 2044 tomoyo_free(head->write_buf);
2050 head->write_buf = NULL; 2045 head->write_buf = NULL;
2051 tomoyo_free(head); 2046 tomoyo_free(head);
2052 head = NULL; 2047 head = NULL;
2053 file->private_data = NULL; 2048 file->private_data = NULL;
2054 return 0; 2049 return 0;
2055 } 2050 }
2056 2051
2057 /** 2052 /**
2058 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry. 2053 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry.
2059 * 2054 *
2060 * @acl_type: Type of ACL entry. 2055 * @acl_type: Type of ACL entry.
2061 * 2056 *
2062 * Returns pointer to the ACL entry on success, NULL otherwise. 2057 * Returns pointer to the ACL entry on success, NULL otherwise.
2063 */ 2058 */
2064 void *tomoyo_alloc_acl_element(const u8 acl_type) 2059 void *tomoyo_alloc_acl_element(const u8 acl_type)
2065 { 2060 {
2066 int len; 2061 int len;
2067 struct tomoyo_acl_info *ptr; 2062 struct tomoyo_acl_info *ptr;
2068 2063
2069 switch (acl_type) { 2064 switch (acl_type) {
2070 case TOMOYO_TYPE_SINGLE_PATH_ACL: 2065 case TOMOYO_TYPE_SINGLE_PATH_ACL:
2071 len = sizeof(struct tomoyo_single_path_acl_record); 2066 len = sizeof(struct tomoyo_single_path_acl_record);
2072 break; 2067 break;
2073 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 2068 case TOMOYO_TYPE_DOUBLE_PATH_ACL:
2074 len = sizeof(struct tomoyo_double_path_acl_record); 2069 len = sizeof(struct tomoyo_double_path_acl_record);
2075 break; 2070 break;
2076 default: 2071 default:
2077 return NULL; 2072 return NULL;
2078 } 2073 }
2079 ptr = tomoyo_alloc_element(len); 2074 ptr = tomoyo_alloc_element(len);
2080 if (!ptr) 2075 if (!ptr)
2081 return NULL; 2076 return NULL;
2082 ptr->type = acl_type; 2077 ptr->type = acl_type;
2083 return ptr; 2078 return ptr;
2084 } 2079 }
2085 2080
2086 /** 2081 /**
2087 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2082 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
2088 * 2083 *
2089 * @inode: Pointer to "struct inode". 2084 * @inode: Pointer to "struct inode".
2090 * @file: Pointer to "struct file". 2085 * @file: Pointer to "struct file".
2091 * 2086 *
2092 * Returns 0 on success, negative value otherwise. 2087 * Returns 0 on success, negative value otherwise.
2093 */ 2088 */
2094 static int tomoyo_open(struct inode *inode, struct file *file) 2089 static int tomoyo_open(struct inode *inode, struct file *file)
2095 { 2090 {
2096 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private) 2091 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private)
2097 - ((u8 *) NULL); 2092 - ((u8 *) NULL);
2098 return tomoyo_open_control(key, file); 2093 return tomoyo_open_control(key, file);
2099 } 2094 }
2100 2095
2101 /** 2096 /**
2102 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface. 2097 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
2103 * 2098 *
2104 * @inode: Pointer to "struct inode". 2099 * @inode: Pointer to "struct inode".
2105 * @file: Pointer to "struct file". 2100 * @file: Pointer to "struct file".
2106 * 2101 *
2107 * Returns 0 on success, negative value otherwise. 2102 * Returns 0 on success, negative value otherwise.
2108 */ 2103 */
2109 static int tomoyo_release(struct inode *inode, struct file *file) 2104 static int tomoyo_release(struct inode *inode, struct file *file)
2110 { 2105 {
2111 return tomoyo_close_control(file); 2106 return tomoyo_close_control(file);
2112 } 2107 }
2113 2108
2114 /** 2109 /**
2115 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface. 2110 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface.
2116 * 2111 *
2117 * @file: Pointer to "struct file". 2112 * @file: Pointer to "struct file".
2118 * @buf: Pointer to buffer. 2113 * @buf: Pointer to buffer.
2119 * @count: Size of @buf. 2114 * @count: Size of @buf.
2120 * @ppos: Unused. 2115 * @ppos: Unused.
2121 * 2116 *
2122 * Returns bytes read on success, negative value otherwise. 2117 * Returns bytes read on success, negative value otherwise.
2123 */ 2118 */
2124 static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 2119 static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
2125 loff_t *ppos) 2120 loff_t *ppos)
2126 { 2121 {
2127 return tomoyo_read_control(file, buf, count); 2122 return tomoyo_read_control(file, buf, count);
2128 } 2123 }
2129 2124
2130 /** 2125 /**
2131 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface. 2126 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface.
2132 * 2127 *
2133 * @file: Pointer to "struct file". 2128 * @file: Pointer to "struct file".
2134 * @buf: Pointer to buffer. 2129 * @buf: Pointer to buffer.
2135 * @count: Size of @buf. 2130 * @count: Size of @buf.
2136 * @ppos: Unused. 2131 * @ppos: Unused.
2137 * 2132 *
2138 * Returns @count on success, negative value otherwise. 2133 * Returns @count on success, negative value otherwise.
2139 */ 2134 */
2140 static ssize_t tomoyo_write(struct file *file, const char __user *buf, 2135 static ssize_t tomoyo_write(struct file *file, const char __user *buf,
2141 size_t count, loff_t *ppos) 2136 size_t count, loff_t *ppos)
2142 { 2137 {
2143 return tomoyo_write_control(file, buf, count); 2138 return tomoyo_write_control(file, buf, count);
2144 } 2139 }
2145 2140
2146 /* Operations for /sys/kernel/security/tomoyo/ interface. */ 2141 /* Operations for /sys/kernel/security/tomoyo/ interface. */
2147 static const struct file_operations tomoyo_operations = { 2142 static const struct file_operations tomoyo_operations = {
2148 .open = tomoyo_open, 2143 .open = tomoyo_open,
2149 .release = tomoyo_release, 2144 .release = tomoyo_release,
2150 .read = tomoyo_read, 2145 .read = tomoyo_read,
2151 .write = tomoyo_write, 2146 .write = tomoyo_write,
2152 }; 2147 };
2153 2148
2154 /** 2149 /**
2155 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory. 2150 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory.
2156 * 2151 *
2157 * @name: The name of the interface file. 2152 * @name: The name of the interface file.
2158 * @mode: The permission of the interface file. 2153 * @mode: The permission of the interface file.
2159 * @parent: The parent directory. 2154 * @parent: The parent directory.
2160 * @key: Type of interface. 2155 * @key: Type of interface.
2161 * 2156 *
2162 * Returns nothing. 2157 * Returns nothing.
2163 */ 2158 */
2164 static void __init tomoyo_create_entry(const char *name, const mode_t mode, 2159 static void __init tomoyo_create_entry(const char *name, const mode_t mode,
2165 struct dentry *parent, const u8 key) 2160 struct dentry *parent, const u8 key)
2166 { 2161 {
2167 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key, 2162 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
2168 &tomoyo_operations); 2163 &tomoyo_operations);
2169 } 2164 }
2170 2165
2171 /** 2166 /**
2172 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface. 2167 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
2173 * 2168 *
2174 * Returns 0. 2169 * Returns 0.
2175 */ 2170 */
2176 static int __init tomoyo_initerface_init(void) 2171 static int __init tomoyo_initerface_init(void)
2177 { 2172 {
2178 struct dentry *tomoyo_dir; 2173 struct dentry *tomoyo_dir;
2179 2174
2180 /* Don't create securityfs entries unless registered. */ 2175 /* Don't create securityfs entries unless registered. */
2181 if (current_cred()->security != &tomoyo_kernel_domain) 2176 if (current_cred()->security != &tomoyo_kernel_domain)
2182 return 0; 2177 return 0;
2183 2178
2184 tomoyo_dir = securityfs_create_dir("tomoyo", NULL); 2179 tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
2185 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir, 2180 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir,
2186 TOMOYO_DOMAINPOLICY); 2181 TOMOYO_DOMAINPOLICY);
2187 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 2182 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
2188 TOMOYO_EXCEPTIONPOLICY); 2183 TOMOYO_EXCEPTIONPOLICY);
2189 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 2184 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
2190 TOMOYO_SELFDOMAIN); 2185 TOMOYO_SELFDOMAIN);
2191 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir, 2186 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir,
2192 TOMOYO_DOMAIN_STATUS); 2187 TOMOYO_DOMAIN_STATUS);
2193 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 2188 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
2194 TOMOYO_PROCESS_STATUS); 2189 TOMOYO_PROCESS_STATUS);
2195 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 2190 tomoyo_create_entry("meminfo", 0600, tomoyo_dir,
2196 TOMOYO_MEMINFO); 2191 TOMOYO_MEMINFO);
2197 tomoyo_create_entry("profile", 0600, tomoyo_dir, 2192 tomoyo_create_entry("profile", 0600, tomoyo_dir,
2198 TOMOYO_PROFILE); 2193 TOMOYO_PROFILE);
2199 tomoyo_create_entry("manager", 0600, tomoyo_dir, 2194 tomoyo_create_entry("manager", 0600, tomoyo_dir,
2200 TOMOYO_MANAGER); 2195 TOMOYO_MANAGER);
2201 tomoyo_create_entry("version", 0400, tomoyo_dir, 2196 tomoyo_create_entry("version", 0400, tomoyo_dir,
2202 TOMOYO_VERSION); 2197 TOMOYO_VERSION);
2203 return 0; 2198 return 0;
2204 } 2199 }
2205 2200
2206 fs_initcall(tomoyo_initerface_init); 2201 fs_initcall(tomoyo_initerface_init);
2207 2202
security/tomoyo/common.h
1 /* 1 /*
2 * security/tomoyo/common.h 2 * security/tomoyo/common.h
3 * 3 *
4 * Common functions for TOMOYO. 4 * Common functions for TOMOYO.
5 * 5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 * 7 *
8 * Version: 2.2.0-pre 2009/02/01 8 * Version: 2.2.0-pre 2009/02/01
9 * 9 *
10 */ 10 */
11 11
12 #ifndef _SECURITY_TOMOYO_COMMON_H 12 #ifndef _SECURITY_TOMOYO_COMMON_H
13 #define _SECURITY_TOMOYO_COMMON_H 13 #define _SECURITY_TOMOYO_COMMON_H
14 14
15 #include <linux/ctype.h> 15 #include <linux/ctype.h>
16 #include <linux/string.h> 16 #include <linux/string.h>
17 #include <linux/mm.h> 17 #include <linux/mm.h>
18 #include <linux/file.h> 18 #include <linux/file.h>
19 #include <linux/kmod.h> 19 #include <linux/kmod.h>
20 #include <linux/fs.h> 20 #include <linux/fs.h>
21 #include <linux/sched.h> 21 #include <linux/sched.h>
22 #include <linux/namei.h> 22 #include <linux/namei.h>
23 #include <linux/mount.h> 23 #include <linux/mount.h>
24 #include <linux/list.h> 24 #include <linux/list.h>
25 25
26 struct dentry; 26 struct dentry;
27 struct vfsmount; 27 struct vfsmount;
28 28
29 /* Temporary buffer for holding pathnames. */ 29 /* Temporary buffer for holding pathnames. */
30 struct tomoyo_page_buffer { 30 struct tomoyo_page_buffer {
31 char buffer[4096]; 31 char buffer[4096];
32 }; 32 };
33 33
34 /* Structure for holding a token. */ 34 /* Structure for holding a token. */
35 struct tomoyo_path_info { 35 struct tomoyo_path_info {
36 const char *name; 36 const char *name;
37 u32 hash; /* = full_name_hash(name, strlen(name)) */ 37 u32 hash; /* = full_name_hash(name, strlen(name)) */
38 u16 total_len; /* = strlen(name) */ 38 u16 total_len; /* = strlen(name) */
39 u16 const_len; /* = tomoyo_const_part_length(name) */ 39 u16 const_len; /* = tomoyo_const_part_length(name) */
40 bool is_dir; /* = tomoyo_strendswith(name, "/") */ 40 bool is_dir; /* = tomoyo_strendswith(name, "/") */
41 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 41 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
42 u16 depth; /* = tomoyo_path_depth(name) */ 42 u16 depth; /* = tomoyo_path_depth(name) */
43 }; 43 };
44 44
45 /* 45 /*
46 * This is the max length of a token. 46 * This is the max length of a token.
47 * 47 *
48 * A token consists of only ASCII printable characters. 48 * A token consists of only ASCII printable characters.
49 * Non printable characters in a token is represented in \ooo style 49 * Non printable characters in a token is represented in \ooo style
50 * octal string. Thus, \ itself is represented as \\. 50 * octal string. Thus, \ itself is represented as \\.
51 */ 51 */
52 #define TOMOYO_MAX_PATHNAME_LEN 4000 52 #define TOMOYO_MAX_PATHNAME_LEN 4000
53 53
54 /* Structure for holding requested pathname. */ 54 /* Structure for holding requested pathname. */
55 struct tomoyo_path_info_with_data { 55 struct tomoyo_path_info_with_data {
56 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 56 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */
57 struct tomoyo_path_info head; 57 struct tomoyo_path_info head;
58 char barrier1[16]; /* Safeguard for overrun. */ 58 char barrier1[16]; /* Safeguard for overrun. */
59 char body[TOMOYO_MAX_PATHNAME_LEN]; 59 char body[TOMOYO_MAX_PATHNAME_LEN];
60 char barrier2[16]; /* Safeguard for overrun. */ 60 char barrier2[16]; /* Safeguard for overrun. */
61 }; 61 };
62 62
63 /* 63 /*
64 * Common header for holding ACL entries. 64 * Common header for holding ACL entries.
65 * 65 *
66 * Packing "struct tomoyo_acl_info" allows 66 * Packing "struct tomoyo_acl_info" allows
67 * "struct tomoyo_single_path_acl_record" to embed "u16" and 67 * "struct tomoyo_single_path_acl_record" to embed "u16" and
68 * "struct tomoyo_double_path_acl_record" to embed "u8" 68 * "struct tomoyo_double_path_acl_record" to embed "u8"
69 * without enlarging their structure size. 69 * without enlarging their structure size.
70 */ 70 */
71 struct tomoyo_acl_info { 71 struct tomoyo_acl_info {
72 struct list_head list; 72 struct list_head list;
73 /* 73 /*
74 * Type of this ACL entry. 74 * Type of this ACL entry.
75 * 75 *
76 * MSB is is_deleted flag. 76 * MSB is is_deleted flag.
77 */ 77 */
78 u8 type; 78 u8 type;
79 } __packed; 79 } __packed;
80 80
81 /* This ACL entry is deleted. */ 81 /* This ACL entry is deleted. */
82 #define TOMOYO_ACL_DELETED 0x80 82 #define TOMOYO_ACL_DELETED 0x80
83 83
84 /* Structure for domain information. */ 84 /* Structure for domain information. */
85 struct tomoyo_domain_info { 85 struct tomoyo_domain_info {
86 struct list_head list; 86 struct list_head list;
87 struct list_head acl_info_list; 87 struct list_head acl_info_list;
88 /* Name of this domain. Never NULL. */ 88 /* Name of this domain. Never NULL. */
89 const struct tomoyo_path_info *domainname; 89 const struct tomoyo_path_info *domainname;
90 u8 profile; /* Profile number to use. */ 90 u8 profile; /* Profile number to use. */
91 u8 is_deleted; /* Delete flag. 91 bool 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. */ 92 bool quota_warned; /* Quota warnning flag. */
96 /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ 93 /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */
97 u8 flags; 94 u8 flags;
98 }; 95 };
99 96
100 /* Profile number is an integer between 0 and 255. */ 97 /* Profile number is an integer between 0 and 255. */
101 #define TOMOYO_MAX_PROFILES 256 98 #define TOMOYO_MAX_PROFILES 256
102 99
103 /* Ignore "allow_read" directive in exception policy. */ 100 /* Ignore "allow_read" directive in exception policy. */
104 #define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1 101 #define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1
105 /* 102 /*
106 * This domain was unable to create a new domain at tomoyo_find_next_domain() 103 * 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 104 * because the name of the domain to be created was too long or
108 * it could not allocate memory. 105 * it could not allocate memory.
109 * More than one process continued execve() without domain transition. 106 * More than one process continued execve() without domain transition.
110 */ 107 */
111 #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2 108 #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
112 109
113 /* 110 /*
114 * Structure for "allow_read/write", "allow_execute", "allow_read", 111 * Structure for "allow_read/write", "allow_execute", "allow_read",
115 * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 112 * "allow_write", "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
116 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 113 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
117 * "allow_truncate", "allow_symlink" and "allow_rewrite" directive. 114 * "allow_truncate", "allow_symlink" and "allow_rewrite" directive.
118 */ 115 */
119 struct tomoyo_single_path_acl_record { 116 struct tomoyo_single_path_acl_record {
120 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ 117 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
121 u16 perm; 118 u16 perm;
122 /* Pointer to single pathname. */ 119 /* Pointer to single pathname. */
123 const struct tomoyo_path_info *filename; 120 const struct tomoyo_path_info *filename;
124 }; 121 };
125 122
126 /* Structure for "allow_rename" and "allow_link" directive. */ 123 /* Structure for "allow_rename" and "allow_link" directive. */
127 struct tomoyo_double_path_acl_record { 124 struct tomoyo_double_path_acl_record {
128 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 125 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
129 u8 perm; 126 u8 perm;
130 /* Pointer to single pathname. */ 127 /* Pointer to single pathname. */
131 const struct tomoyo_path_info *filename1; 128 const struct tomoyo_path_info *filename1;
132 /* Pointer to single pathname. */ 129 /* Pointer to single pathname. */
133 const struct tomoyo_path_info *filename2; 130 const struct tomoyo_path_info *filename2;
134 }; 131 };
135 132
136 /* Keywords for ACLs. */ 133 /* Keywords for ACLs. */
137 #define TOMOYO_KEYWORD_ALIAS "alias " 134 #define TOMOYO_KEYWORD_ALIAS "alias "
138 #define TOMOYO_KEYWORD_ALLOW_READ "allow_read " 135 #define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
139 #define TOMOYO_KEYWORD_DELETE "delete " 136 #define TOMOYO_KEYWORD_DELETE "delete "
140 #define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite " 137 #define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
141 #define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern " 138 #define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
142 #define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain " 139 #define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
143 #define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain " 140 #define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
144 #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " 141 #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
145 #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain " 142 #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
146 #define TOMOYO_KEYWORD_SELECT "select " 143 #define TOMOYO_KEYWORD_SELECT "select "
147 #define TOMOYO_KEYWORD_UNDELETE "undelete "
148 #define TOMOYO_KEYWORD_USE_PROFILE "use_profile " 144 #define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
149 #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read" 145 #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
150 /* A domain definition starts with <kernel>. */ 146 /* A domain definition starts with <kernel>. */
151 #define TOMOYO_ROOT_NAME "<kernel>" 147 #define TOMOYO_ROOT_NAME "<kernel>"
152 #define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1) 148 #define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
153 149
154 /* Index numbers for Access Controls. */ 150 /* Index numbers for Access Controls. */
155 #define TOMOYO_MAC_FOR_FILE 0 /* domain_policy.conf */ 151 #define TOMOYO_MAC_FOR_FILE 0 /* domain_policy.conf */
156 #define TOMOYO_MAX_ACCEPT_ENTRY 1 152 #define TOMOYO_MAX_ACCEPT_ENTRY 1
157 #define TOMOYO_VERBOSE 2 153 #define TOMOYO_VERBOSE 2
158 #define TOMOYO_MAX_CONTROL_INDEX 3 154 #define TOMOYO_MAX_CONTROL_INDEX 3
159 155
160 /* Structure for reading/writing policy via securityfs interfaces. */ 156 /* Structure for reading/writing policy via securityfs interfaces. */
161 struct tomoyo_io_buffer { 157 struct tomoyo_io_buffer {
162 int (*read) (struct tomoyo_io_buffer *); 158 int (*read) (struct tomoyo_io_buffer *);
163 int (*write) (struct tomoyo_io_buffer *); 159 int (*write) (struct tomoyo_io_buffer *);
164 /* Exclusive lock for this structure. */ 160 /* Exclusive lock for this structure. */
165 struct mutex io_sem; 161 struct mutex io_sem;
166 /* The position currently reading from. */ 162 /* The position currently reading from. */
167 struct list_head *read_var1; 163 struct list_head *read_var1;
168 /* Extra variables for reading. */ 164 /* Extra variables for reading. */
169 struct list_head *read_var2; 165 struct list_head *read_var2;
170 /* The position currently writing to. */ 166 /* The position currently writing to. */
171 struct tomoyo_domain_info *write_var1; 167 struct tomoyo_domain_info *write_var1;
172 /* The step for reading. */ 168 /* The step for reading. */
173 int read_step; 169 int read_step;
174 /* Buffer for reading. */ 170 /* Buffer for reading. */
175 char *read_buf; 171 char *read_buf;
176 /* EOF flag for reading. */ 172 /* EOF flag for reading. */
177 bool read_eof; 173 bool read_eof;
178 /* Read domain ACL of specified PID? */ 174 /* Read domain ACL of specified PID? */
179 bool read_single_domain; 175 bool read_single_domain;
180 /* Extra variable for reading. */ 176 /* Extra variable for reading. */
181 u8 read_bit; 177 u8 read_bit;
182 /* Bytes available for reading. */ 178 /* Bytes available for reading. */
183 int read_avail; 179 int read_avail;
184 /* Size of read buffer. */ 180 /* Size of read buffer. */
185 int readbuf_size; 181 int readbuf_size;
186 /* Buffer for writing. */ 182 /* Buffer for writing. */
187 char *write_buf; 183 char *write_buf;
188 /* Bytes available for writing. */ 184 /* Bytes available for writing. */
189 int write_avail; 185 int write_avail;
190 /* Size of write buffer. */ 186 /* Size of write buffer. */
191 int writebuf_size; 187 int writebuf_size;
192 }; 188 };
193 189
194 /* Check whether the domain has too many ACL entries to hold. */ 190 /* Check whether the domain has too many ACL entries to hold. */
195 bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain); 191 bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain);
196 /* Transactional sprintf() for policy dump. */ 192 /* Transactional sprintf() for policy dump. */
197 bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 193 bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
198 __attribute__ ((format(printf, 2, 3))); 194 __attribute__ ((format(printf, 2, 3)));
199 /* Check whether the domainname is correct. */ 195 /* Check whether the domainname is correct. */
200 bool tomoyo_is_correct_domain(const unsigned char *domainname, 196 bool tomoyo_is_correct_domain(const unsigned char *domainname,
201 const char *function); 197 const char *function);
202 /* Check whether the token is correct. */ 198 /* Check whether the token is correct. */
203 bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 199 bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
204 const s8 pattern_type, const s8 end_type, 200 const s8 pattern_type, const s8 end_type,
205 const char *function); 201 const char *function);
206 /* Check whether the token can be a domainname. */ 202 /* Check whether the token can be a domainname. */
207 bool tomoyo_is_domain_def(const unsigned char *buffer); 203 bool tomoyo_is_domain_def(const unsigned char *buffer);
208 /* Check whether the given filename matches the given pattern. */ 204 /* Check whether the given filename matches the given pattern. */
209 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 205 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
210 const struct tomoyo_path_info *pattern); 206 const struct tomoyo_path_info *pattern);
211 /* Read "alias" entry in exception policy. */ 207 /* Read "alias" entry in exception policy. */
212 bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head); 208 bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head);
213 /* 209 /*
214 * Read "initialize_domain" and "no_initialize_domain" entry 210 * Read "initialize_domain" and "no_initialize_domain" entry
215 * in exception policy. 211 * in exception policy.
216 */ 212 */
217 bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head); 213 bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head);
218 /* Read "keep_domain" and "no_keep_domain" entry in exception policy. */ 214 /* Read "keep_domain" and "no_keep_domain" entry in exception policy. */
219 bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head); 215 bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head);
220 /* Read "file_pattern" entry in exception policy. */ 216 /* Read "file_pattern" entry in exception policy. */
221 bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head); 217 bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head);
222 /* Read "allow_read" entry in exception policy. */ 218 /* Read "allow_read" entry in exception policy. */
223 bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head); 219 bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head);
224 /* Read "deny_rewrite" entry in exception policy. */ 220 /* Read "deny_rewrite" entry in exception policy. */
225 bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head); 221 bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head);
226 /* Write domain policy violation warning message to console? */ 222 /* Write domain policy violation warning message to console? */
227 bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain); 223 bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
228 /* Convert double path operation to operation name. */ 224 /* Convert double path operation to operation name. */
229 const char *tomoyo_dp2keyword(const u8 operation); 225 const char *tomoyo_dp2keyword(const u8 operation);
230 /* Get the last component of the given domainname. */ 226 /* Get the last component of the given domainname. */
231 const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); 227 const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
232 /* Get warning message. */ 228 /* Get warning message. */
233 const char *tomoyo_get_msg(const bool is_enforce); 229 const char *tomoyo_get_msg(const bool is_enforce);
234 /* Convert single path operation to operation name. */ 230 /* Convert single path operation to operation name. */
235 const char *tomoyo_sp2keyword(const u8 operation); 231 const char *tomoyo_sp2keyword(const u8 operation);
236 /* Delete a domain. */ 232 /* Delete a domain. */
237 int tomoyo_delete_domain(char *data); 233 int tomoyo_delete_domain(char *data);
238 /* Create "alias" entry in exception policy. */ 234 /* Create "alias" entry in exception policy. */
239 int tomoyo_write_alias_policy(char *data, const bool is_delete); 235 int tomoyo_write_alias_policy(char *data, const bool is_delete);
240 /* 236 /*
241 * Create "initialize_domain" and "no_initialize_domain" entry 237 * Create "initialize_domain" and "no_initialize_domain" entry
242 * in exception policy. 238 * in exception policy.
243 */ 239 */
244 int tomoyo_write_domain_initializer_policy(char *data, const bool is_not, 240 int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
245 const bool is_delete); 241 const bool is_delete);
246 /* Create "keep_domain" and "no_keep_domain" entry in exception policy. */ 242 /* Create "keep_domain" and "no_keep_domain" entry in exception policy. */
247 int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, 243 int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
248 const bool is_delete); 244 const bool is_delete);
249 /* 245 /*
250 * Create "allow_read/write", "allow_execute", "allow_read", "allow_write", 246 * Create "allow_read/write", "allow_execute", "allow_read", "allow_write",
251 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 247 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
252 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 248 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
253 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and 249 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and
254 * "allow_link" entry in domain policy. 250 * "allow_link" entry in domain policy.
255 */ 251 */
256 int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 252 int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
257 const bool is_delete); 253 const bool is_delete);
258 /* Create "allow_read" entry in exception policy. */ 254 /* Create "allow_read" entry in exception policy. */
259 int tomoyo_write_globally_readable_policy(char *data, const bool is_delete); 255 int tomoyo_write_globally_readable_policy(char *data, const bool is_delete);
260 /* Create "deny_rewrite" entry in exception policy. */ 256 /* Create "deny_rewrite" entry in exception policy. */
261 int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete); 257 int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete);
262 /* Create "file_pattern" entry in exception policy. */ 258 /* Create "file_pattern" entry in exception policy. */
263 int tomoyo_write_pattern_policy(char *data, const bool is_delete); 259 int tomoyo_write_pattern_policy(char *data, const bool is_delete);
264 /* Find a domain by the given name. */ 260 /* Find a domain by the given name. */
265 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname); 261 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
266 /* Find or create a domain by the given name. */ 262 /* Find or create a domain by the given name. */
267 struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 263 struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
268 domainname, 264 domainname,
269 const u8 profile); 265 const u8 profile);
270 /* Undelete a domain. */
271 struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname);
272 /* Check mode for specified functionality. */ 266 /* Check mode for specified functionality. */
273 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 267 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
274 const u8 index); 268 const u8 index);
275 /* Allocate memory for structures. */ 269 /* Allocate memory for structures. */
276 void *tomoyo_alloc_acl_element(const u8 acl_type); 270 void *tomoyo_alloc_acl_element(const u8 acl_type);
277 /* Fill in "struct tomoyo_path_info" members. */ 271 /* Fill in "struct tomoyo_path_info" members. */
278 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 272 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
279 /* Run policy loader when /sbin/init starts. */ 273 /* Run policy loader when /sbin/init starts. */
280 void tomoyo_load_policy(const char *filename); 274 void tomoyo_load_policy(const char *filename);
281 /* Change "struct tomoyo_domain_info"->flags. */ 275 /* Change "struct tomoyo_domain_info"->flags. */
282 void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain, 276 void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
283 const bool is_delete, const u8 flags); 277 const bool is_delete, const u8 flags);
284 278
285 /* strcmp() for "struct tomoyo_path_info" structure. */ 279 /* strcmp() for "struct tomoyo_path_info" structure. */
286 static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, 280 static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
287 const struct tomoyo_path_info *b) 281 const struct tomoyo_path_info *b)
288 { 282 {
289 return a->hash != b->hash || strcmp(a->name, b->name); 283 return a->hash != b->hash || strcmp(a->name, b->name);
290 } 284 }
291 285
292 /* Get type of an ACL entry. */ 286 /* Get type of an ACL entry. */
293 static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr) 287 static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr)
294 { 288 {
295 return ptr->type & ~TOMOYO_ACL_DELETED; 289 return ptr->type & ~TOMOYO_ACL_DELETED;
296 } 290 }
297 291
298 /* Get type of an ACL entry. */ 292 /* Get type of an ACL entry. */
299 static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr) 293 static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr)
300 { 294 {
301 return ptr->type; 295 return ptr->type;
302 } 296 }
303 297
304 /** 298 /**
305 * tomoyo_is_valid - Check whether the character is a valid char. 299 * tomoyo_is_valid - Check whether the character is a valid char.
306 * 300 *
307 * @c: The character to check. 301 * @c: The character to check.
308 * 302 *
309 * Returns true if @c is a valid character, false otherwise. 303 * Returns true if @c is a valid character, false otherwise.
310 */ 304 */
311 static inline bool tomoyo_is_valid(const unsigned char c) 305 static inline bool tomoyo_is_valid(const unsigned char c)
312 { 306 {
313 return c > ' ' && c < 127; 307 return c > ' ' && c < 127;
314 } 308 }
315 309
316 /** 310 /**
317 * tomoyo_is_invalid - Check whether the character is an invalid char. 311 * tomoyo_is_invalid - Check whether the character is an invalid char.
318 * 312 *
319 * @c: The character to check. 313 * @c: The character to check.
320 * 314 *
321 * Returns true if @c is an invalid character, false otherwise. 315 * Returns true if @c is an invalid character, false otherwise.
322 */ 316 */
323 static inline bool tomoyo_is_invalid(const unsigned char c) 317 static inline bool tomoyo_is_invalid(const unsigned char c)
324 { 318 {
325 return c && (c <= ' ' || c >= 127); 319 return c && (c <= ' ' || c >= 127);
326 } 320 }
327 321
328 /* The list for "struct tomoyo_domain_info". */ 322 /* The list for "struct tomoyo_domain_info". */
329 extern struct list_head tomoyo_domain_list; 323 extern struct list_head tomoyo_domain_list;
330 extern struct rw_semaphore tomoyo_domain_list_lock; 324 extern struct rw_semaphore tomoyo_domain_list_lock;
331 325
332 /* Lock for domain->acl_info_list. */ 326 /* Lock for domain->acl_info_list. */
333 extern struct rw_semaphore tomoyo_domain_acl_info_list_lock; 327 extern struct rw_semaphore tomoyo_domain_acl_info_list_lock;
334 328
335 /* Has /sbin/init started? */ 329 /* Has /sbin/init started? */
336 extern bool tomoyo_policy_loaded; 330 extern bool tomoyo_policy_loaded;
337 331
338 /* The kernel's domain. */ 332 /* The kernel's domain. */
339 extern struct tomoyo_domain_info tomoyo_kernel_domain; 333 extern struct tomoyo_domain_info tomoyo_kernel_domain;
340 334
341 /** 335 /**
342 * list_for_each_cookie - iterate over a list with cookie. 336 * list_for_each_cookie - iterate over a list with cookie.
343 * @pos: the &struct list_head to use as a loop cursor. 337 * @pos: the &struct list_head to use as a loop cursor.
344 * @cookie: the &struct list_head to use as a cookie. 338 * @cookie: the &struct list_head to use as a cookie.
345 * @head: the head for your list. 339 * @head: the head for your list.
346 * 340 *
347 * Same with list_for_each() except that this primitive uses @cookie 341 * Same with list_for_each() except that this primitive uses @cookie
348 * so that we can continue iteration. 342 * so that we can continue iteration.
349 * @cookie must be NULL when iteration starts, and @cookie will become 343 * @cookie must be NULL when iteration starts, and @cookie will become
350 * NULL when iteration finishes. 344 * NULL when iteration finishes.
351 */ 345 */
352 #define list_for_each_cookie(pos, cookie, head) \ 346 #define list_for_each_cookie(pos, cookie, head) \
353 for (({ if (!cookie) \ 347 for (({ if (!cookie) \
354 cookie = head; }), \ 348 cookie = head; }), \
355 pos = (cookie)->next; \ 349 pos = (cookie)->next; \
356 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \ 350 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
357 (cookie) = pos, pos = pos->next) 351 (cookie) = pos, pos = pos->next)
358 352
359 #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ 353 #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
360 354
security/tomoyo/domain.c
1 /* 1 /*
2 * security/tomoyo/domain.c 2 * security/tomoyo/domain.c
3 * 3 *
4 * Implementation of the Domain-Based Mandatory Access Control. 4 * Implementation of the Domain-Based Mandatory Access Control.
5 * 5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 * 7 *
8 * Version: 2.2.0-pre 2009/02/01 8 * Version: 2.2.0-pre 2009/02/01
9 * 9 *
10 */ 10 */
11 11
12 #include "common.h" 12 #include "common.h"
13 #include "tomoyo.h" 13 #include "tomoyo.h"
14 #include "realpath.h" 14 #include "realpath.h"
15 #include <linux/binfmts.h> 15 #include <linux/binfmts.h>
16 16
17 /* Variables definitions.*/ 17 /* Variables definitions.*/
18 18
19 /* The initial domain. */ 19 /* The initial domain. */
20 struct tomoyo_domain_info tomoyo_kernel_domain; 20 struct tomoyo_domain_info tomoyo_kernel_domain;
21 21
22 /* The list for "struct tomoyo_domain_info". */ 22 /* The list for "struct tomoyo_domain_info". */
23 LIST_HEAD(tomoyo_domain_list); 23 LIST_HEAD(tomoyo_domain_list);
24 DECLARE_RWSEM(tomoyo_domain_list_lock); 24 DECLARE_RWSEM(tomoyo_domain_list_lock);
25 25
26 /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */ 26 /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */
27 struct tomoyo_domain_initializer_entry { 27 struct tomoyo_domain_initializer_entry {
28 struct list_head list; 28 struct list_head list;
29 const struct tomoyo_path_info *domainname; /* This may be NULL */ 29 const struct tomoyo_path_info *domainname; /* This may be NULL */
30 const struct tomoyo_path_info *program; 30 const struct tomoyo_path_info *program;
31 bool is_deleted; 31 bool is_deleted;
32 bool is_not; /* True if this entry is "no_initialize_domain". */ 32 bool is_not; /* True if this entry is "no_initialize_domain". */
33 /* True if the domainname is tomoyo_get_last_name(). */ 33 /* True if the domainname is tomoyo_get_last_name(). */
34 bool is_last_name; 34 bool is_last_name;
35 }; 35 };
36 36
37 /* Structure for "keep_domain" and "no_keep_domain" keyword. */ 37 /* Structure for "keep_domain" and "no_keep_domain" keyword. */
38 struct tomoyo_domain_keeper_entry { 38 struct tomoyo_domain_keeper_entry {
39 struct list_head list; 39 struct list_head list;
40 const struct tomoyo_path_info *domainname; 40 const struct tomoyo_path_info *domainname;
41 const struct tomoyo_path_info *program; /* This may be NULL */ 41 const struct tomoyo_path_info *program; /* This may be NULL */
42 bool is_deleted; 42 bool is_deleted;
43 bool is_not; /* True if this entry is "no_keep_domain". */ 43 bool is_not; /* True if this entry is "no_keep_domain". */
44 /* True if the domainname is tomoyo_get_last_name(). */ 44 /* True if the domainname is tomoyo_get_last_name(). */
45 bool is_last_name; 45 bool is_last_name;
46 }; 46 };
47 47
48 /* Structure for "alias" keyword. */ 48 /* Structure for "alias" keyword. */
49 struct tomoyo_alias_entry { 49 struct tomoyo_alias_entry {
50 struct list_head list; 50 struct list_head list;
51 const struct tomoyo_path_info *original_name; 51 const struct tomoyo_path_info *original_name;
52 const struct tomoyo_path_info *aliased_name; 52 const struct tomoyo_path_info *aliased_name;
53 bool is_deleted; 53 bool is_deleted;
54 }; 54 };
55 55
56 /** 56 /**
57 * tomoyo_set_domain_flag - Set or clear domain's attribute flags. 57 * tomoyo_set_domain_flag - Set or clear domain's attribute flags.
58 * 58 *
59 * @domain: Pointer to "struct tomoyo_domain_info". 59 * @domain: Pointer to "struct tomoyo_domain_info".
60 * @is_delete: True if it is a delete request. 60 * @is_delete: True if it is a delete request.
61 * @flags: Flags to set or clear. 61 * @flags: Flags to set or clear.
62 * 62 *
63 * Returns nothing. 63 * Returns nothing.
64 */ 64 */
65 void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain, 65 void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
66 const bool is_delete, const u8 flags) 66 const bool is_delete, const u8 flags)
67 { 67 {
68 /* We need to serialize because this is bitfield operation. */ 68 /* We need to serialize because this is bitfield operation. */
69 static DEFINE_SPINLOCK(lock); 69 static DEFINE_SPINLOCK(lock);
70 /***** CRITICAL SECTION START *****/ 70 /***** CRITICAL SECTION START *****/
71 spin_lock(&lock); 71 spin_lock(&lock);
72 if (!is_delete) 72 if (!is_delete)
73 domain->flags |= flags; 73 domain->flags |= flags;
74 else 74 else
75 domain->flags &= ~flags; 75 domain->flags &= ~flags;
76 spin_unlock(&lock); 76 spin_unlock(&lock);
77 /***** CRITICAL SECTION END *****/ 77 /***** CRITICAL SECTION END *****/
78 } 78 }
79 79
80 /** 80 /**
81 * tomoyo_get_last_name - Get last component of a domainname. 81 * tomoyo_get_last_name - Get last component of a domainname.
82 * 82 *
83 * @domain: Pointer to "struct tomoyo_domain_info". 83 * @domain: Pointer to "struct tomoyo_domain_info".
84 * 84 *
85 * Returns the last component of the domainname. 85 * Returns the last component of the domainname.
86 */ 86 */
87 const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain) 87 const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
88 { 88 {
89 const char *cp0 = domain->domainname->name; 89 const char *cp0 = domain->domainname->name;
90 const char *cp1 = strrchr(cp0, ' '); 90 const char *cp1 = strrchr(cp0, ' ');
91 91
92 if (cp1) 92 if (cp1)
93 return cp1 + 1; 93 return cp1 + 1;
94 return cp0; 94 return cp0;
95 } 95 }
96 96
97 /* The list for "struct tomoyo_domain_initializer_entry". */ 97 /* The list for "struct tomoyo_domain_initializer_entry". */
98 static LIST_HEAD(tomoyo_domain_initializer_list); 98 static LIST_HEAD(tomoyo_domain_initializer_list);
99 static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock); 99 static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
100 100
101 /** 101 /**
102 * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list. 102 * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
103 * 103 *
104 * @domainname: The name of domain. May be NULL. 104 * @domainname: The name of domain. May be NULL.
105 * @program: The name of program. 105 * @program: The name of program.
106 * @is_not: True if it is "no_initialize_domain" entry. 106 * @is_not: True if it is "no_initialize_domain" entry.
107 * @is_delete: True if it is a delete request. 107 * @is_delete: True if it is a delete request.
108 * 108 *
109 * Returns 0 on success, negative value otherwise. 109 * Returns 0 on success, negative value otherwise.
110 */ 110 */
111 static int tomoyo_update_domain_initializer_entry(const char *domainname, 111 static int tomoyo_update_domain_initializer_entry(const char *domainname,
112 const char *program, 112 const char *program,
113 const bool is_not, 113 const bool is_not,
114 const bool is_delete) 114 const bool is_delete)
115 { 115 {
116 struct tomoyo_domain_initializer_entry *new_entry; 116 struct tomoyo_domain_initializer_entry *new_entry;
117 struct tomoyo_domain_initializer_entry *ptr; 117 struct tomoyo_domain_initializer_entry *ptr;
118 const struct tomoyo_path_info *saved_program; 118 const struct tomoyo_path_info *saved_program;
119 const struct tomoyo_path_info *saved_domainname = NULL; 119 const struct tomoyo_path_info *saved_domainname = NULL;
120 int error = -ENOMEM; 120 int error = -ENOMEM;
121 bool is_last_name = false; 121 bool is_last_name = false;
122 122
123 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 123 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
124 return -EINVAL; /* No patterns allowed. */ 124 return -EINVAL; /* No patterns allowed. */
125 if (domainname) { 125 if (domainname) {
126 if (!tomoyo_is_domain_def(domainname) && 126 if (!tomoyo_is_domain_def(domainname) &&
127 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__)) 127 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
128 is_last_name = true; 128 is_last_name = true;
129 else if (!tomoyo_is_correct_domain(domainname, __func__)) 129 else if (!tomoyo_is_correct_domain(domainname, __func__))
130 return -EINVAL; 130 return -EINVAL;
131 saved_domainname = tomoyo_save_name(domainname); 131 saved_domainname = tomoyo_save_name(domainname);
132 if (!saved_domainname) 132 if (!saved_domainname)
133 return -ENOMEM; 133 return -ENOMEM;
134 } 134 }
135 saved_program = tomoyo_save_name(program); 135 saved_program = tomoyo_save_name(program);
136 if (!saved_program) 136 if (!saved_program)
137 return -ENOMEM; 137 return -ENOMEM;
138 /***** EXCLUSIVE SECTION START *****/ 138 /***** EXCLUSIVE SECTION START *****/
139 down_write(&tomoyo_domain_initializer_list_lock); 139 down_write(&tomoyo_domain_initializer_list_lock);
140 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 140 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
141 if (ptr->is_not != is_not || 141 if (ptr->is_not != is_not ||
142 ptr->domainname != saved_domainname || 142 ptr->domainname != saved_domainname ||
143 ptr->program != saved_program) 143 ptr->program != saved_program)
144 continue; 144 continue;
145 ptr->is_deleted = is_delete; 145 ptr->is_deleted = is_delete;
146 error = 0; 146 error = 0;
147 goto out; 147 goto out;
148 } 148 }
149 if (is_delete) { 149 if (is_delete) {
150 error = -ENOENT; 150 error = -ENOENT;
151 goto out; 151 goto out;
152 } 152 }
153 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 153 new_entry = tomoyo_alloc_element(sizeof(*new_entry));
154 if (!new_entry) 154 if (!new_entry)
155 goto out; 155 goto out;
156 new_entry->domainname = saved_domainname; 156 new_entry->domainname = saved_domainname;
157 new_entry->program = saved_program; 157 new_entry->program = saved_program;
158 new_entry->is_not = is_not; 158 new_entry->is_not = is_not;
159 new_entry->is_last_name = is_last_name; 159 new_entry->is_last_name = is_last_name;
160 list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list); 160 list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list);
161 error = 0; 161 error = 0;
162 out: 162 out:
163 up_write(&tomoyo_domain_initializer_list_lock); 163 up_write(&tomoyo_domain_initializer_list_lock);
164 /***** EXCLUSIVE SECTION END *****/ 164 /***** EXCLUSIVE SECTION END *****/
165 return error; 165 return error;
166 } 166 }
167 167
168 /** 168 /**
169 * tomoyo_read_domain_initializer_policy - Read "struct tomoyo_domain_initializer_entry" list. 169 * tomoyo_read_domain_initializer_policy - Read "struct tomoyo_domain_initializer_entry" list.
170 * 170 *
171 * @head: Pointer to "struct tomoyo_io_buffer". 171 * @head: Pointer to "struct tomoyo_io_buffer".
172 * 172 *
173 * Returns true on success, false otherwise. 173 * Returns true on success, false otherwise.
174 */ 174 */
175 bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head) 175 bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
176 { 176 {
177 struct list_head *pos; 177 struct list_head *pos;
178 bool done = true; 178 bool done = true;
179 179
180 down_read(&tomoyo_domain_initializer_list_lock); 180 down_read(&tomoyo_domain_initializer_list_lock);
181 list_for_each_cookie(pos, head->read_var2, 181 list_for_each_cookie(pos, head->read_var2,
182 &tomoyo_domain_initializer_list) { 182 &tomoyo_domain_initializer_list) {
183 const char *no; 183 const char *no;
184 const char *from = ""; 184 const char *from = "";
185 const char *domain = ""; 185 const char *domain = "";
186 struct tomoyo_domain_initializer_entry *ptr; 186 struct tomoyo_domain_initializer_entry *ptr;
187 ptr = list_entry(pos, struct tomoyo_domain_initializer_entry, 187 ptr = list_entry(pos, struct tomoyo_domain_initializer_entry,
188 list); 188 list);
189 if (ptr->is_deleted) 189 if (ptr->is_deleted)
190 continue; 190 continue;
191 no = ptr->is_not ? "no_" : ""; 191 no = ptr->is_not ? "no_" : "";
192 if (ptr->domainname) { 192 if (ptr->domainname) {
193 from = " from "; 193 from = " from ";
194 domain = ptr->domainname->name; 194 domain = ptr->domainname->name;
195 } 195 }
196 if (!tomoyo_io_printf(head, 196 if (!tomoyo_io_printf(head,
197 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN 197 "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN
198 "%s%s%s\n", no, ptr->program->name, from, 198 "%s%s%s\n", no, ptr->program->name, from,
199 domain)) { 199 domain)) {
200 done = false; 200 done = false;
201 break; 201 break;
202 } 202 }
203 } 203 }
204 up_read(&tomoyo_domain_initializer_list_lock); 204 up_read(&tomoyo_domain_initializer_list_lock);
205 return done; 205 return done;
206 } 206 }
207 207
208 /** 208 /**
209 * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list. 209 * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list.
210 * 210 *
211 * @data: String to parse. 211 * @data: String to parse.
212 * @is_not: True if it is "no_initialize_domain" entry. 212 * @is_not: True if it is "no_initialize_domain" entry.
213 * @is_delete: True if it is a delete request. 213 * @is_delete: True if it is a delete request.
214 * 214 *
215 * Returns 0 on success, negative value otherwise. 215 * Returns 0 on success, negative value otherwise.
216 */ 216 */
217 int tomoyo_write_domain_initializer_policy(char *data, const bool is_not, 217 int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
218 const bool is_delete) 218 const bool is_delete)
219 { 219 {
220 char *cp = strstr(data, " from "); 220 char *cp = strstr(data, " from ");
221 221
222 if (cp) { 222 if (cp) {
223 *cp = '\0'; 223 *cp = '\0';
224 return tomoyo_update_domain_initializer_entry(cp + 6, data, 224 return tomoyo_update_domain_initializer_entry(cp + 6, data,
225 is_not, 225 is_not,
226 is_delete); 226 is_delete);
227 } 227 }
228 return tomoyo_update_domain_initializer_entry(NULL, data, is_not, 228 return tomoyo_update_domain_initializer_entry(NULL, data, is_not,
229 is_delete); 229 is_delete);
230 } 230 }
231 231
232 /** 232 /**
233 * tomoyo_is_domain_initializer - Check whether the given program causes domainname reinitialization. 233 * tomoyo_is_domain_initializer - Check whether the given program causes domainname reinitialization.
234 * 234 *
235 * @domainname: The name of domain. 235 * @domainname: The name of domain.
236 * @program: The name of program. 236 * @program: The name of program.
237 * @last_name: The last component of @domainname. 237 * @last_name: The last component of @domainname.
238 * 238 *
239 * Returns true if executing @program reinitializes domain transition, 239 * Returns true if executing @program reinitializes domain transition,
240 * false otherwise. 240 * false otherwise.
241 */ 241 */
242 static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info * 242 static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
243 domainname, 243 domainname,
244 const struct tomoyo_path_info *program, 244 const struct tomoyo_path_info *program,
245 const struct tomoyo_path_info * 245 const struct tomoyo_path_info *
246 last_name) 246 last_name)
247 { 247 {
248 struct tomoyo_domain_initializer_entry *ptr; 248 struct tomoyo_domain_initializer_entry *ptr;
249 bool flag = false; 249 bool flag = false;
250 250
251 down_read(&tomoyo_domain_initializer_list_lock); 251 down_read(&tomoyo_domain_initializer_list_lock);
252 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 252 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
253 if (ptr->is_deleted) 253 if (ptr->is_deleted)
254 continue; 254 continue;
255 if (ptr->domainname) { 255 if (ptr->domainname) {
256 if (!ptr->is_last_name) { 256 if (!ptr->is_last_name) {
257 if (ptr->domainname != domainname) 257 if (ptr->domainname != domainname)
258 continue; 258 continue;
259 } else { 259 } else {
260 if (tomoyo_pathcmp(ptr->domainname, last_name)) 260 if (tomoyo_pathcmp(ptr->domainname, last_name))
261 continue; 261 continue;
262 } 262 }
263 } 263 }
264 if (tomoyo_pathcmp(ptr->program, program)) 264 if (tomoyo_pathcmp(ptr->program, program))
265 continue; 265 continue;
266 if (ptr->is_not) { 266 if (ptr->is_not) {
267 flag = false; 267 flag = false;
268 break; 268 break;
269 } 269 }
270 flag = true; 270 flag = true;
271 } 271 }
272 up_read(&tomoyo_domain_initializer_list_lock); 272 up_read(&tomoyo_domain_initializer_list_lock);
273 return flag; 273 return flag;
274 } 274 }
275 275
276 /* The list for "struct tomoyo_domain_keeper_entry". */ 276 /* The list for "struct tomoyo_domain_keeper_entry". */
277 static LIST_HEAD(tomoyo_domain_keeper_list); 277 static LIST_HEAD(tomoyo_domain_keeper_list);
278 static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock); 278 static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
279 279
280 /** 280 /**
281 * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list. 281 * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
282 * 282 *
283 * @domainname: The name of domain. 283 * @domainname: The name of domain.
284 * @program: The name of program. May be NULL. 284 * @program: The name of program. May be NULL.
285 * @is_not: True if it is "no_keep_domain" entry. 285 * @is_not: True if it is "no_keep_domain" entry.
286 * @is_delete: True if it is a delete request. 286 * @is_delete: True if it is a delete request.
287 * 287 *
288 * Returns 0 on success, negative value otherwise. 288 * Returns 0 on success, negative value otherwise.
289 */ 289 */
290 static int tomoyo_update_domain_keeper_entry(const char *domainname, 290 static int tomoyo_update_domain_keeper_entry(const char *domainname,
291 const char *program, 291 const char *program,
292 const bool is_not, 292 const bool is_not,
293 const bool is_delete) 293 const bool is_delete)
294 { 294 {
295 struct tomoyo_domain_keeper_entry *new_entry; 295 struct tomoyo_domain_keeper_entry *new_entry;
296 struct tomoyo_domain_keeper_entry *ptr; 296 struct tomoyo_domain_keeper_entry *ptr;
297 const struct tomoyo_path_info *saved_domainname; 297 const struct tomoyo_path_info *saved_domainname;
298 const struct tomoyo_path_info *saved_program = NULL; 298 const struct tomoyo_path_info *saved_program = NULL;
299 static DEFINE_MUTEX(lock); 299 static DEFINE_MUTEX(lock);
300 int error = -ENOMEM; 300 int error = -ENOMEM;
301 bool is_last_name = false; 301 bool is_last_name = false;
302 302
303 if (!tomoyo_is_domain_def(domainname) && 303 if (!tomoyo_is_domain_def(domainname) &&
304 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__)) 304 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
305 is_last_name = true; 305 is_last_name = true;
306 else if (!tomoyo_is_correct_domain(domainname, __func__)) 306 else if (!tomoyo_is_correct_domain(domainname, __func__))
307 return -EINVAL; 307 return -EINVAL;
308 if (program) { 308 if (program) {
309 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 309 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
310 return -EINVAL; 310 return -EINVAL;
311 saved_program = tomoyo_save_name(program); 311 saved_program = tomoyo_save_name(program);
312 if (!saved_program) 312 if (!saved_program)
313 return -ENOMEM; 313 return -ENOMEM;
314 } 314 }
315 saved_domainname = tomoyo_save_name(domainname); 315 saved_domainname = tomoyo_save_name(domainname);
316 if (!saved_domainname) 316 if (!saved_domainname)
317 return -ENOMEM; 317 return -ENOMEM;
318 /***** EXCLUSIVE SECTION START *****/ 318 /***** EXCLUSIVE SECTION START *****/
319 down_write(&tomoyo_domain_keeper_list_lock); 319 down_write(&tomoyo_domain_keeper_list_lock);
320 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 320 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
321 if (ptr->is_not != is_not || 321 if (ptr->is_not != is_not ||
322 ptr->domainname != saved_domainname || 322 ptr->domainname != saved_domainname ||
323 ptr->program != saved_program) 323 ptr->program != saved_program)
324 continue; 324 continue;
325 ptr->is_deleted = is_delete; 325 ptr->is_deleted = is_delete;
326 error = 0; 326 error = 0;
327 goto out; 327 goto out;
328 } 328 }
329 if (is_delete) { 329 if (is_delete) {
330 error = -ENOENT; 330 error = -ENOENT;
331 goto out; 331 goto out;
332 } 332 }
333 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 333 new_entry = tomoyo_alloc_element(sizeof(*new_entry));
334 if (!new_entry) 334 if (!new_entry)
335 goto out; 335 goto out;
336 new_entry->domainname = saved_domainname; 336 new_entry->domainname = saved_domainname;
337 new_entry->program = saved_program; 337 new_entry->program = saved_program;
338 new_entry->is_not = is_not; 338 new_entry->is_not = is_not;
339 new_entry->is_last_name = is_last_name; 339 new_entry->is_last_name = is_last_name;
340 list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list); 340 list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list);
341 error = 0; 341 error = 0;
342 out: 342 out:
343 up_write(&tomoyo_domain_keeper_list_lock); 343 up_write(&tomoyo_domain_keeper_list_lock);
344 /***** EXCLUSIVE SECTION END *****/ 344 /***** EXCLUSIVE SECTION END *****/
345 return error; 345 return error;
346 } 346 }
347 347
348 /** 348 /**
349 * tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list. 349 * tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list.
350 * 350 *
351 * @data: String to parse. 351 * @data: String to parse.
352 * @is_not: True if it is "no_keep_domain" entry. 352 * @is_not: True if it is "no_keep_domain" entry.
353 * @is_delete: True if it is a delete request. 353 * @is_delete: True if it is a delete request.
354 * 354 *
355 */ 355 */
356 int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, 356 int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
357 const bool is_delete) 357 const bool is_delete)
358 { 358 {
359 char *cp = strstr(data, " from "); 359 char *cp = strstr(data, " from ");
360 360
361 if (cp) { 361 if (cp) {
362 *cp = '\0'; 362 *cp = '\0';
363 return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not, 363 return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not,
364 is_delete); 364 is_delete);
365 } 365 }
366 return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete); 366 return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete);
367 } 367 }
368 368
369 /** 369 /**
370 * tomoyo_read_domain_keeper_policy - Read "struct tomoyo_domain_keeper_entry" list. 370 * tomoyo_read_domain_keeper_policy - Read "struct tomoyo_domain_keeper_entry" list.
371 * 371 *
372 * @head: Pointer to "struct tomoyo_io_buffer". 372 * @head: Pointer to "struct tomoyo_io_buffer".
373 * 373 *
374 * Returns true on success, false otherwise. 374 * Returns true on success, false otherwise.
375 */ 375 */
376 bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head) 376 bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
377 { 377 {
378 struct list_head *pos; 378 struct list_head *pos;
379 bool done = true; 379 bool done = true;
380 380
381 down_read(&tomoyo_domain_keeper_list_lock); 381 down_read(&tomoyo_domain_keeper_list_lock);
382 list_for_each_cookie(pos, head->read_var2, 382 list_for_each_cookie(pos, head->read_var2,
383 &tomoyo_domain_keeper_list) { 383 &tomoyo_domain_keeper_list) {
384 struct tomoyo_domain_keeper_entry *ptr; 384 struct tomoyo_domain_keeper_entry *ptr;
385 const char *no; 385 const char *no;
386 const char *from = ""; 386 const char *from = "";
387 const char *program = ""; 387 const char *program = "";
388 388
389 ptr = list_entry(pos, struct tomoyo_domain_keeper_entry, list); 389 ptr = list_entry(pos, struct tomoyo_domain_keeper_entry, list);
390 if (ptr->is_deleted) 390 if (ptr->is_deleted)
391 continue; 391 continue;
392 no = ptr->is_not ? "no_" : ""; 392 no = ptr->is_not ? "no_" : "";
393 if (ptr->program) { 393 if (ptr->program) {
394 from = " from "; 394 from = " from ";
395 program = ptr->program->name; 395 program = ptr->program->name;
396 } 396 }
397 if (!tomoyo_io_printf(head, 397 if (!tomoyo_io_printf(head,
398 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN 398 "%s" TOMOYO_KEYWORD_KEEP_DOMAIN
399 "%s%s%s\n", no, program, from, 399 "%s%s%s\n", no, program, from,
400 ptr->domainname->name)) { 400 ptr->domainname->name)) {
401 done = false; 401 done = false;
402 break; 402 break;
403 } 403 }
404 } 404 }
405 up_read(&tomoyo_domain_keeper_list_lock); 405 up_read(&tomoyo_domain_keeper_list_lock);
406 return done; 406 return done;
407 } 407 }
408 408
409 /** 409 /**
410 * tomoyo_is_domain_keeper - Check whether the given program causes domain transition suppression. 410 * tomoyo_is_domain_keeper - Check whether the given program causes domain transition suppression.
411 * 411 *
412 * @domainname: The name of domain. 412 * @domainname: The name of domain.
413 * @program: The name of program. 413 * @program: The name of program.
414 * @last_name: The last component of @domainname. 414 * @last_name: The last component of @domainname.
415 * 415 *
416 * Returns true if executing @program supresses domain transition, 416 * Returns true if executing @program supresses domain transition,
417 * false otherwise. 417 * false otherwise.
418 */ 418 */
419 static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname, 419 static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
420 const struct tomoyo_path_info *program, 420 const struct tomoyo_path_info *program,
421 const struct tomoyo_path_info *last_name) 421 const struct tomoyo_path_info *last_name)
422 { 422 {
423 struct tomoyo_domain_keeper_entry *ptr; 423 struct tomoyo_domain_keeper_entry *ptr;
424 bool flag = false; 424 bool flag = false;
425 425
426 down_read(&tomoyo_domain_keeper_list_lock); 426 down_read(&tomoyo_domain_keeper_list_lock);
427 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 427 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
428 if (ptr->is_deleted) 428 if (ptr->is_deleted)
429 continue; 429 continue;
430 if (!ptr->is_last_name) { 430 if (!ptr->is_last_name) {
431 if (ptr->domainname != domainname) 431 if (ptr->domainname != domainname)
432 continue; 432 continue;
433 } else { 433 } else {
434 if (tomoyo_pathcmp(ptr->domainname, last_name)) 434 if (tomoyo_pathcmp(ptr->domainname, last_name))
435 continue; 435 continue;
436 } 436 }
437 if (ptr->program && tomoyo_pathcmp(ptr->program, program)) 437 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
438 continue; 438 continue;
439 if (ptr->is_not) { 439 if (ptr->is_not) {
440 flag = false; 440 flag = false;
441 break; 441 break;
442 } 442 }
443 flag = true; 443 flag = true;
444 } 444 }
445 up_read(&tomoyo_domain_keeper_list_lock); 445 up_read(&tomoyo_domain_keeper_list_lock);
446 return flag; 446 return flag;
447 } 447 }
448 448
449 /* The list for "struct tomoyo_alias_entry". */ 449 /* The list for "struct tomoyo_alias_entry". */
450 static LIST_HEAD(tomoyo_alias_list); 450 static LIST_HEAD(tomoyo_alias_list);
451 static DECLARE_RWSEM(tomoyo_alias_list_lock); 451 static DECLARE_RWSEM(tomoyo_alias_list_lock);
452 452
453 /** 453 /**
454 * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list. 454 * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list.
455 * 455 *
456 * @original_name: The original program's real name. 456 * @original_name: The original program's real name.
457 * @aliased_name: The symbolic program's symbolic link's name. 457 * @aliased_name: The symbolic program's symbolic link's name.
458 * @is_delete: True if it is a delete request. 458 * @is_delete: True if it is a delete request.
459 * 459 *
460 * Returns 0 on success, negative value otherwise. 460 * Returns 0 on success, negative value otherwise.
461 */ 461 */
462 static int tomoyo_update_alias_entry(const char *original_name, 462 static int tomoyo_update_alias_entry(const char *original_name,
463 const char *aliased_name, 463 const char *aliased_name,
464 const bool is_delete) 464 const bool is_delete)
465 { 465 {
466 struct tomoyo_alias_entry *new_entry; 466 struct tomoyo_alias_entry *new_entry;
467 struct tomoyo_alias_entry *ptr; 467 struct tomoyo_alias_entry *ptr;
468 const struct tomoyo_path_info *saved_original_name; 468 const struct tomoyo_path_info *saved_original_name;
469 const struct tomoyo_path_info *saved_aliased_name; 469 const struct tomoyo_path_info *saved_aliased_name;
470 int error = -ENOMEM; 470 int error = -ENOMEM;
471 471
472 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || 472 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
473 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) 473 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
474 return -EINVAL; /* No patterns allowed. */ 474 return -EINVAL; /* No patterns allowed. */
475 saved_original_name = tomoyo_save_name(original_name); 475 saved_original_name = tomoyo_save_name(original_name);
476 saved_aliased_name = tomoyo_save_name(aliased_name); 476 saved_aliased_name = tomoyo_save_name(aliased_name);
477 if (!saved_original_name || !saved_aliased_name) 477 if (!saved_original_name || !saved_aliased_name)
478 return -ENOMEM; 478 return -ENOMEM;
479 /***** EXCLUSIVE SECTION START *****/ 479 /***** EXCLUSIVE SECTION START *****/
480 down_write(&tomoyo_alias_list_lock); 480 down_write(&tomoyo_alias_list_lock);
481 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 481 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
482 if (ptr->original_name != saved_original_name || 482 if (ptr->original_name != saved_original_name ||
483 ptr->aliased_name != saved_aliased_name) 483 ptr->aliased_name != saved_aliased_name)
484 continue; 484 continue;
485 ptr->is_deleted = is_delete; 485 ptr->is_deleted = is_delete;
486 error = 0; 486 error = 0;
487 goto out; 487 goto out;
488 } 488 }
489 if (is_delete) { 489 if (is_delete) {
490 error = -ENOENT; 490 error = -ENOENT;
491 goto out; 491 goto out;
492 } 492 }
493 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 493 new_entry = tomoyo_alloc_element(sizeof(*new_entry));
494 if (!new_entry) 494 if (!new_entry)
495 goto out; 495 goto out;
496 new_entry->original_name = saved_original_name; 496 new_entry->original_name = saved_original_name;
497 new_entry->aliased_name = saved_aliased_name; 497 new_entry->aliased_name = saved_aliased_name;
498 list_add_tail(&new_entry->list, &tomoyo_alias_list); 498 list_add_tail(&new_entry->list, &tomoyo_alias_list);
499 error = 0; 499 error = 0;
500 out: 500 out:
501 up_write(&tomoyo_alias_list_lock); 501 up_write(&tomoyo_alias_list_lock);
502 /***** EXCLUSIVE SECTION END *****/ 502 /***** EXCLUSIVE SECTION END *****/
503 return error; 503 return error;
504 } 504 }
505 505
506 /** 506 /**
507 * tomoyo_read_alias_policy - Read "struct tomoyo_alias_entry" list. 507 * tomoyo_read_alias_policy - Read "struct tomoyo_alias_entry" list.
508 * 508 *
509 * @head: Pointer to "struct tomoyo_io_buffer". 509 * @head: Pointer to "struct tomoyo_io_buffer".
510 * 510 *
511 * Returns true on success, false otherwise. 511 * Returns true on success, false otherwise.
512 */ 512 */
513 bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head) 513 bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
514 { 514 {
515 struct list_head *pos; 515 struct list_head *pos;
516 bool done = true; 516 bool done = true;
517 517
518 down_read(&tomoyo_alias_list_lock); 518 down_read(&tomoyo_alias_list_lock);
519 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) { 519 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
520 struct tomoyo_alias_entry *ptr; 520 struct tomoyo_alias_entry *ptr;
521 521
522 ptr = list_entry(pos, struct tomoyo_alias_entry, list); 522 ptr = list_entry(pos, struct tomoyo_alias_entry, list);
523 if (ptr->is_deleted) 523 if (ptr->is_deleted)
524 continue; 524 continue;
525 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n", 525 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n",
526 ptr->original_name->name, 526 ptr->original_name->name,
527 ptr->aliased_name->name)) { 527 ptr->aliased_name->name)) {
528 done = false; 528 done = false;
529 break; 529 break;
530 } 530 }
531 } 531 }
532 up_read(&tomoyo_alias_list_lock); 532 up_read(&tomoyo_alias_list_lock);
533 return done; 533 return done;
534 } 534 }
535 535
536 /** 536 /**
537 * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list. 537 * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list.
538 * 538 *
539 * @data: String to parse. 539 * @data: String to parse.
540 * @is_delete: True if it is a delete request. 540 * @is_delete: True if it is a delete request.
541 * 541 *
542 * Returns 0 on success, negative value otherwise. 542 * Returns 0 on success, negative value otherwise.
543 */ 543 */
544 int tomoyo_write_alias_policy(char *data, const bool is_delete) 544 int tomoyo_write_alias_policy(char *data, const bool is_delete)
545 { 545 {
546 char *cp = strchr(data, ' '); 546 char *cp = strchr(data, ' ');
547 547
548 if (!cp) 548 if (!cp)
549 return -EINVAL; 549 return -EINVAL;
550 *cp++ = '\0'; 550 *cp++ = '\0';
551 return tomoyo_update_alias_entry(data, cp, is_delete); 551 return tomoyo_update_alias_entry(data, cp, is_delete);
552 } 552 }
553 553
554 /* Domain create/delete/undelete handler. */ 554 /* Domain create/delete handler. */
555 555
556 /* #define TOMOYO_DEBUG_DOMAIN_UNDELETE */
557
558 /** 556 /**
559 * tomoyo_delete_domain - Delete a domain. 557 * tomoyo_delete_domain - Delete a domain.
560 * 558 *
561 * @domainname: The name of domain. 559 * @domainname: The name of domain.
562 * 560 *
563 * Returns 0. 561 * Returns 0.
564 */ 562 */
565 int tomoyo_delete_domain(char *domainname) 563 int tomoyo_delete_domain(char *domainname)
566 { 564 {
567 struct tomoyo_domain_info *domain; 565 struct tomoyo_domain_info *domain;
568 struct tomoyo_path_info name; 566 struct tomoyo_path_info name;
569 567
570 name.name = domainname; 568 name.name = domainname;
571 tomoyo_fill_path_info(&name); 569 tomoyo_fill_path_info(&name);
572 /***** EXCLUSIVE SECTION START *****/ 570 /***** EXCLUSIVE SECTION START *****/
573 down_write(&tomoyo_domain_list_lock); 571 down_write(&tomoyo_domain_list_lock);
574 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
575 printk(KERN_DEBUG "tomoyo_delete_domain %s\n", domainname);
576 list_for_each_entry(domain, &tomoyo_domain_list, list) {
577 if (tomoyo_pathcmp(domain->domainname, &name))
578 continue;
579 printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
580 }
581 #endif
582 /* Is there an active domain? */ 572 /* Is there an active domain? */
583 list_for_each_entry(domain, &tomoyo_domain_list, list) { 573 list_for_each_entry(domain, &tomoyo_domain_list, list) {
584 struct tomoyo_domain_info *domain2;
585 /* Never delete tomoyo_kernel_domain */ 574 /* Never delete tomoyo_kernel_domain */
586 if (domain == &tomoyo_kernel_domain) 575 if (domain == &tomoyo_kernel_domain)
587 continue; 576 continue;
588 if (domain->is_deleted || 577 if (domain->is_deleted ||
589 tomoyo_pathcmp(domain->domainname, &name)) 578 tomoyo_pathcmp(domain->domainname, &name))
590 continue; 579 continue;
591 /* Mark already deleted domains as non undeletable. */ 580 domain->is_deleted = true;
592 list_for_each_entry(domain2, &tomoyo_domain_list, list) {
593 if (!domain2->is_deleted ||
594 tomoyo_pathcmp(domain2->domainname, &name))
595 continue;
596 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
597 if (domain2->is_deleted != 255)
598 printk(KERN_DEBUG
599 "Marked %p as non undeletable\n",
600 domain2);
601 #endif
602 domain2->is_deleted = 255;
603 }
604 /* Delete and mark active domain as undeletable. */
605 domain->is_deleted = 1;
606 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
607 printk(KERN_DEBUG "Marked %p as undeletable\n", domain);
608 #endif
609 break; 581 break;
610 } 582 }
611 up_write(&tomoyo_domain_list_lock); 583 up_write(&tomoyo_domain_list_lock);
612 /***** EXCLUSIVE SECTION END *****/ 584 /***** EXCLUSIVE SECTION END *****/
613 return 0; 585 return 0;
614 } 586 }
615 587
616 /** 588 /**
617 * tomoyo_undelete_domain - Undelete a domain.
618 *
619 * @domainname: The name of domain.
620 *
621 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
622 */
623 struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname)
624 {
625 struct tomoyo_domain_info *domain;
626 struct tomoyo_domain_info *candidate_domain = NULL;
627 struct tomoyo_path_info name;
628
629 name.name = domainname;
630 tomoyo_fill_path_info(&name);
631 /***** EXCLUSIVE SECTION START *****/
632 down_write(&tomoyo_domain_list_lock);
633 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
634 printk(KERN_DEBUG "tomoyo_undelete_domain %s\n", domainname);
635 list_for_each_entry(domain, &tomoyo_domain_list, list) {
636 if (tomoyo_pathcmp(domain->domainname, &name))
637 continue;
638 printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
639 }
640 #endif
641 list_for_each_entry(domain, &tomoyo_domain_list, list) {
642 if (tomoyo_pathcmp(&name, domain->domainname))
643 continue;
644 if (!domain->is_deleted) {
645 /* This domain is active. I can't undelete. */
646 candidate_domain = NULL;
647 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
648 printk(KERN_DEBUG "%p is active. I can't undelete.\n",
649 domain);
650 #endif
651 break;
652 }
653 /* Is this domain undeletable? */
654 if (domain->is_deleted == 1)
655 candidate_domain = domain;
656 }
657 if (candidate_domain) {
658 candidate_domain->is_deleted = 0;
659 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
660 printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain);
661 #endif
662 }
663 up_write(&tomoyo_domain_list_lock);
664 /***** EXCLUSIVE SECTION END *****/
665 return candidate_domain;
666 }
667
668 /**
669 * tomoyo_find_or_assign_new_domain - Create a domain. 589 * tomoyo_find_or_assign_new_domain - Create a domain.
670 * 590 *
671 * @domainname: The name of domain. 591 * @domainname: The name of domain.
672 * @profile: Profile number to assign if the domain was newly created. 592 * @profile: Profile number to assign if the domain was newly created.
673 * 593 *
674 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 594 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
675 */ 595 */
676 struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 596 struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
677 domainname, 597 domainname,
678 const u8 profile) 598 const u8 profile)
679 { 599 {
680 struct tomoyo_domain_info *domain = NULL; 600 struct tomoyo_domain_info *domain = NULL;
681 const struct tomoyo_path_info *saved_domainname; 601 const struct tomoyo_path_info *saved_domainname;
682 602
683 /***** EXCLUSIVE SECTION START *****/ 603 /***** EXCLUSIVE SECTION START *****/
684 down_write(&tomoyo_domain_list_lock); 604 down_write(&tomoyo_domain_list_lock);
685 domain = tomoyo_find_domain(domainname); 605 domain = tomoyo_find_domain(domainname);
686 if (domain) 606 if (domain)
687 goto out; 607 goto out;
688 if (!tomoyo_is_correct_domain(domainname, __func__)) 608 if (!tomoyo_is_correct_domain(domainname, __func__))
689 goto out; 609 goto out;
690 saved_domainname = tomoyo_save_name(domainname); 610 saved_domainname = tomoyo_save_name(domainname);
691 if (!saved_domainname) 611 if (!saved_domainname)
692 goto out; 612 goto out;
693 /* Can I reuse memory of deleted domain? */ 613 /* Can I reuse memory of deleted domain? */
694 list_for_each_entry(domain, &tomoyo_domain_list, list) { 614 list_for_each_entry(domain, &tomoyo_domain_list, list) {
695 struct task_struct *p; 615 struct task_struct *p;
696 struct tomoyo_acl_info *ptr; 616 struct tomoyo_acl_info *ptr;
697 bool flag; 617 bool flag;
698 if (!domain->is_deleted || 618 if (!domain->is_deleted ||
699 domain->domainname != saved_domainname) 619 domain->domainname != saved_domainname)
700 continue; 620 continue;
701 flag = false; 621 flag = false;
702 /***** CRITICAL SECTION START *****/ 622 /***** CRITICAL SECTION START *****/
703 read_lock(&tasklist_lock); 623 read_lock(&tasklist_lock);
704 for_each_process(p) { 624 for_each_process(p) {
705 if (tomoyo_real_domain(p) != domain) 625 if (tomoyo_real_domain(p) != domain)
706 continue; 626 continue;
707 flag = true; 627 flag = true;
708 break; 628 break;
709 } 629 }
710 read_unlock(&tasklist_lock); 630 read_unlock(&tasklist_lock);
711 /***** CRITICAL SECTION END *****/ 631 /***** CRITICAL SECTION END *****/
712 if (flag) 632 if (flag)
713 continue; 633 continue;
714 #ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE
715 printk(KERN_DEBUG "Reusing %p %s\n", domain,
716 domain->domainname->name);
717 #endif
718 list_for_each_entry(ptr, &domain->acl_info_list, list) { 634 list_for_each_entry(ptr, &domain->acl_info_list, list) {
719 ptr->type |= TOMOYO_ACL_DELETED; 635 ptr->type |= TOMOYO_ACL_DELETED;
720 } 636 }
721 tomoyo_set_domain_flag(domain, true, domain->flags); 637 tomoyo_set_domain_flag(domain, true, domain->flags);
722 domain->profile = profile; 638 domain->profile = profile;
723 domain->quota_warned = false; 639 domain->quota_warned = false;
724 mb(); /* Avoid out-of-order execution. */ 640 mb(); /* Avoid out-of-order execution. */
725 domain->is_deleted = 0; 641 domain->is_deleted = false;
726 goto out; 642 goto out;
727 } 643 }
728 /* No memory reusable. Create using new memory. */ 644 /* No memory reusable. Create using new memory. */
729 domain = tomoyo_alloc_element(sizeof(*domain)); 645 domain = tomoyo_alloc_element(sizeof(*domain));
730 if (domain) { 646 if (domain) {
731 INIT_LIST_HEAD(&domain->acl_info_list); 647 INIT_LIST_HEAD(&domain->acl_info_list);
732 domain->domainname = saved_domainname; 648 domain->domainname = saved_domainname;
733 domain->profile = profile; 649 domain->profile = profile;
734 list_add_tail(&domain->list, &tomoyo_domain_list); 650 list_add_tail(&domain->list, &tomoyo_domain_list);
735 } 651 }
736 out: 652 out:
737 up_write(&tomoyo_domain_list_lock); 653 up_write(&tomoyo_domain_list_lock);
738 /***** EXCLUSIVE SECTION END *****/ 654 /***** EXCLUSIVE SECTION END *****/
739 return domain; 655 return domain;
740 } 656 }
741 657
742 /** 658 /**
743 * tomoyo_find_next_domain - Find a domain. 659 * tomoyo_find_next_domain - Find a domain.
744 * 660 *
745 * @bprm: Pointer to "struct linux_binprm". 661 * @bprm: Pointer to "struct linux_binprm".
746 * @next_domain: Pointer to pointer to "struct tomoyo_domain_info". 662 * @next_domain: Pointer to pointer to "struct tomoyo_domain_info".
747 * 663 *
748 * Returns 0 on success, negative value otherwise. 664 * Returns 0 on success, negative value otherwise.
749 */ 665 */
750 int tomoyo_find_next_domain(struct linux_binprm *bprm, 666 int tomoyo_find_next_domain(struct linux_binprm *bprm,
751 struct tomoyo_domain_info **next_domain) 667 struct tomoyo_domain_info **next_domain)
752 { 668 {
753 /* 669 /*
754 * This function assumes that the size of buffer returned by 670 * This function assumes that the size of buffer returned by
755 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN. 671 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
756 */ 672 */
757 struct tomoyo_page_buffer *tmp = tomoyo_alloc(sizeof(*tmp)); 673 struct tomoyo_page_buffer *tmp = tomoyo_alloc(sizeof(*tmp));
758 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 674 struct tomoyo_domain_info *old_domain = tomoyo_domain();
759 struct tomoyo_domain_info *domain = NULL; 675 struct tomoyo_domain_info *domain = NULL;
760 const char *old_domain_name = old_domain->domainname->name; 676 const char *old_domain_name = old_domain->domainname->name;
761 const char *original_name = bprm->filename; 677 const char *original_name = bprm->filename;
762 char *new_domain_name = NULL; 678 char *new_domain_name = NULL;
763 char *real_program_name = NULL; 679 char *real_program_name = NULL;
764 char *symlink_program_name = NULL; 680 char *symlink_program_name = NULL;
765 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 681 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
766 const bool is_enforce = (mode == 3); 682 const bool is_enforce = (mode == 3);
767 int retval = -ENOMEM; 683 int retval = -ENOMEM;
768 struct tomoyo_path_info r; /* real name */ 684 struct tomoyo_path_info r; /* real name */
769 struct tomoyo_path_info s; /* symlink name */ 685 struct tomoyo_path_info s; /* symlink name */
770 struct tomoyo_path_info l; /* last name */ 686 struct tomoyo_path_info l; /* last name */
771 static bool initialized; 687 static bool initialized;
772 688
773 if (!tmp) 689 if (!tmp)
774 goto out; 690 goto out;
775 691
776 if (!initialized) { 692 if (!initialized) {
777 /* 693 /*
778 * Built-in initializers. This is needed because policies are 694 * Built-in initializers. This is needed because policies are
779 * not loaded until starting /sbin/init. 695 * not loaded until starting /sbin/init.
780 */ 696 */
781 tomoyo_update_domain_initializer_entry(NULL, "/sbin/hotplug", 697 tomoyo_update_domain_initializer_entry(NULL, "/sbin/hotplug",
782 false, false); 698 false, false);
783 tomoyo_update_domain_initializer_entry(NULL, "/sbin/modprobe", 699 tomoyo_update_domain_initializer_entry(NULL, "/sbin/modprobe",
784 false, false); 700 false, false);
785 initialized = true; 701 initialized = true;
786 } 702 }
787 703
788 /* Get tomoyo_realpath of program. */ 704 /* Get tomoyo_realpath of program. */
789 retval = -ENOENT; 705 retval = -ENOENT;
790 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */ 706 /* I hope tomoyo_realpath() won't fail with -ENOMEM. */
791 real_program_name = tomoyo_realpath(original_name); 707 real_program_name = tomoyo_realpath(original_name);
792 if (!real_program_name) 708 if (!real_program_name)
793 goto out; 709 goto out;
794 /* Get tomoyo_realpath of symbolic link. */ 710 /* Get tomoyo_realpath of symbolic link. */
795 symlink_program_name = tomoyo_realpath_nofollow(original_name); 711 symlink_program_name = tomoyo_realpath_nofollow(original_name);
796 if (!symlink_program_name) 712 if (!symlink_program_name)
797 goto out; 713 goto out;
798 714
799 r.name = real_program_name; 715 r.name = real_program_name;
800 tomoyo_fill_path_info(&r); 716 tomoyo_fill_path_info(&r);
801 s.name = symlink_program_name; 717 s.name = symlink_program_name;
802 tomoyo_fill_path_info(&s); 718 tomoyo_fill_path_info(&s);
803 l.name = tomoyo_get_last_name(old_domain); 719 l.name = tomoyo_get_last_name(old_domain);
804 tomoyo_fill_path_info(&l); 720 tomoyo_fill_path_info(&l);
805 721
806 /* Check 'alias' directive. */ 722 /* Check 'alias' directive. */
807 if (tomoyo_pathcmp(&r, &s)) { 723 if (tomoyo_pathcmp(&r, &s)) {
808 struct tomoyo_alias_entry *ptr; 724 struct tomoyo_alias_entry *ptr;
809 /* Is this program allowed to be called via symbolic links? */ 725 /* Is this program allowed to be called via symbolic links? */
810 down_read(&tomoyo_alias_list_lock); 726 down_read(&tomoyo_alias_list_lock);
811 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 727 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
812 if (ptr->is_deleted || 728 if (ptr->is_deleted ||
813 tomoyo_pathcmp(&r, ptr->original_name) || 729 tomoyo_pathcmp(&r, ptr->original_name) ||
814 tomoyo_pathcmp(&s, ptr->aliased_name)) 730 tomoyo_pathcmp(&s, ptr->aliased_name))
815 continue; 731 continue;
816 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN); 732 memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN);
817 strncpy(real_program_name, ptr->aliased_name->name, 733 strncpy(real_program_name, ptr->aliased_name->name,
818 TOMOYO_MAX_PATHNAME_LEN - 1); 734 TOMOYO_MAX_PATHNAME_LEN - 1);
819 tomoyo_fill_path_info(&r); 735 tomoyo_fill_path_info(&r);
820 break; 736 break;
821 } 737 }
822 up_read(&tomoyo_alias_list_lock); 738 up_read(&tomoyo_alias_list_lock);
823 } 739 }
824 740
825 /* Check execute permission. */ 741 /* Check execute permission. */
826 retval = tomoyo_check_exec_perm(old_domain, &r, tmp); 742 retval = tomoyo_check_exec_perm(old_domain, &r, tmp);
827 if (retval < 0) 743 if (retval < 0)
828 goto out; 744 goto out;
829 745
830 new_domain_name = tmp->buffer; 746 new_domain_name = tmp->buffer;
831 if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) { 747 if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) {
832 /* Transit to the child of tomoyo_kernel_domain domain. */ 748 /* Transit to the child of tomoyo_kernel_domain domain. */
833 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 749 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
834 TOMOYO_ROOT_NAME " " "%s", real_program_name); 750 TOMOYO_ROOT_NAME " " "%s", real_program_name);
835 } else if (old_domain == &tomoyo_kernel_domain && 751 } else if (old_domain == &tomoyo_kernel_domain &&
836 !tomoyo_policy_loaded) { 752 !tomoyo_policy_loaded) {
837 /* 753 /*
838 * Needn't to transit from kernel domain before starting 754 * Needn't to transit from kernel domain before starting
839 * /sbin/init. But transit from kernel domain if executing 755 * /sbin/init. But transit from kernel domain if executing
840 * initializers because they might start before /sbin/init. 756 * initializers because they might start before /sbin/init.
841 */ 757 */
842 domain = old_domain; 758 domain = old_domain;
843 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) { 759 } else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) {
844 /* Keep current domain. */ 760 /* Keep current domain. */
845 domain = old_domain; 761 domain = old_domain;
846 } else { 762 } else {
847 /* Normal domain transition. */ 763 /* Normal domain transition. */
848 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1, 764 snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
849 "%s %s", old_domain_name, real_program_name); 765 "%s %s", old_domain_name, real_program_name);
850 } 766 }
851 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN) 767 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN)
852 goto done; 768 goto done;
853 down_read(&tomoyo_domain_list_lock); 769 down_read(&tomoyo_domain_list_lock);
854 domain = tomoyo_find_domain(new_domain_name); 770 domain = tomoyo_find_domain(new_domain_name);
855 up_read(&tomoyo_domain_list_lock); 771 up_read(&tomoyo_domain_list_lock);
856 if (domain) 772 if (domain)
857 goto done; 773 goto done;
858 if (is_enforce) 774 if (is_enforce)
859 goto done; 775 goto done;
860 domain = tomoyo_find_or_assign_new_domain(new_domain_name, 776 domain = tomoyo_find_or_assign_new_domain(new_domain_name,
861 old_domain->profile); 777 old_domain->profile);
862 done: 778 done:
863 if (domain) 779 if (domain)
864 goto out; 780 goto out;
865 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", 781 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
866 new_domain_name); 782 new_domain_name);
867 if (is_enforce) 783 if (is_enforce)
868 retval = -EPERM; 784 retval = -EPERM;
869 else 785 else
870 tomoyo_set_domain_flag(old_domain, false, 786 tomoyo_set_domain_flag(old_domain, false,
871 TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED); 787 TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED);
872 out: 788 out:
873 tomoyo_free(real_program_name); 789 tomoyo_free(real_program_name);
874 tomoyo_free(symlink_program_name); 790 tomoyo_free(symlink_program_name);
875 *next_domain = domain ? domain : old_domain; 791 *next_domain = domain ? domain : old_domain;
876 tomoyo_free(tmp); 792 tomoyo_free(tmp);
877 return retval; 793 return retval;
878 } 794 }
879 795