Commit c3fa109a5894077d1eaf8731ea741a15dd117b3c

Authored by Tetsuo Handa
Committed by James Morris
1 parent 5bf1692f65

TOMOYO: Add description of lists and structures.

This patch adds some descriptions of lists and structures.
This patch contains no code changes.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>

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