オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /trunk/1.7.x/ccs-patch/security/ccsecurity/util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2544 - (hide annotations) (download) (as text)
Thu May 14 06:55:46 2009 UTC (15 years ago) by kumaneko
Original Path: branches/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 91356 byte(s)


1 kumaneko 111 /*
2     * fs/ccs_common.c
3     *
4     * Common functions for SAKURA and TOMOYO.
5     *
6 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 2519 * Version: 1.6.8-pre 2009/05/08
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14    
15 kumaneko 1255 #include <linux/version.h>
16     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
17     #define __KERNEL_SYSCALLS__
18     #endif
19 kumaneko 111 #include <linux/string.h>
20     #include <linux/mm.h>
21     #include <linux/utime.h>
22     #include <linux/file.h>
23     #include <linux/module.h>
24     #include <linux/slab.h>
25     #include <asm/uaccess.h>
26     #include <stdarg.h>
27 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
28 kumaneko 111 #include <linux/namei.h>
29     #include <linux/mount.h>
30 kumaneko 2002 static const int ccs_lookup_flags = LOOKUP_FOLLOW;
31 kumaneko 111 #else
32 kumaneko 2002 static const int ccs_lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;
33 kumaneko 111 #endif
34 kumaneko 2540 #include <linux/ccs_common.h>
35 kumaneko 111 #include <linux/realpath.h>
36     #include <linux/ccs_proc.h>
37     #include <linux/tomoyo.h>
38 kumaneko 1255 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
39     #include <linux/unistd.h>
40     #endif
41 kumaneko 1052
42     /* To support PID namespace. */
43     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
44 kumaneko 964 #define find_task_by_pid find_task_by_vpid
45     #endif
46 kumaneko 111
47 kumaneko 1052 /* Set default specified by the kernel config. */
48 kumaneko 1260 #ifdef CONFIG_TOMOYO
49 kumaneko 120 #define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)
50 kumaneko 1052 #define MAX_GRANT_LOG (CONFIG_TOMOYO_MAX_GRANT_LOG)
51     #define MAX_REJECT_LOG (CONFIG_TOMOYO_MAX_REJECT_LOG)
52 kumaneko 1260 #else
53     #define MAX_ACCEPT_ENTRY 0
54     #define MAX_GRANT_LOG 0
55     #define MAX_REJECT_LOG 0
56     #endif
57 kumaneko 111
58 kumaneko 2540 DECLARE_RWSEM(ccs_policy_lock);
59    
60 kumaneko 1052 /* Has /sbin/init started? */
61 kumaneko 2040 bool ccs_policy_loaded;
62 kumaneko 111
63 kumaneko 1052 /* Log level for SAKURA's printk(). */
64 kumaneko 111 const char *ccs_log_level = KERN_DEBUG;
65    
66 kumaneko 1052 /* String table for functionality that takes 4 modes. */
67 kumaneko 2002 static const char *ccs_mode_4[4] = {
68 kumaneko 1052 "disabled", "learning", "permissive", "enforcing"
69     };
70     /* String table for functionality that takes 2 modes. */
71 kumaneko 2002 static const char *ccs_mode_2[4] = {
72 kumaneko 1052 "disabled", "enabled", "enabled", "enabled"
73     };
74 kumaneko 1014
75 kumaneko 1052 /* Table for profile. */
76 kumaneko 111 static struct {
77     const char *keyword;
78     unsigned int current_value;
79     const unsigned int max_value;
80     } ccs_control_array[CCS_MAX_CONTROL_INDEX] = {
81 kumaneko 2282 [CCS_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
82     [CCS_MAC_FOR_IOCTL] = { "MAC_FOR_IOCTL", 0, 3 },
83     [CCS_MAC_FOR_ARGV0] = { "MAC_FOR_ARGV0", 0, 3 },
84     [CCS_MAC_FOR_ENV] = { "MAC_FOR_ENV", 0, 3 },
85     [CCS_MAC_FOR_NETWORK] = { "MAC_FOR_NETWORK", 0, 3 },
86     [CCS_MAC_FOR_SIGNAL] = { "MAC_FOR_SIGNAL", 0, 3 },
87     [CCS_DENY_CONCEAL_MOUNT] = { "DENY_CONCEAL_MOUNT", 0, 3 },
88     [CCS_RESTRICT_CHROOT] = { "RESTRICT_CHROOT", 0, 3 },
89     [CCS_RESTRICT_MOUNT] = { "RESTRICT_MOUNT", 0, 3 },
90     [CCS_RESTRICT_UNMOUNT] = { "RESTRICT_UNMOUNT", 0, 3 },
91     [CCS_RESTRICT_PIVOT_ROOT] = { "RESTRICT_PIVOT_ROOT", 0, 3 },
92     [CCS_RESTRICT_AUTOBIND] = { "RESTRICT_AUTOBIND", 0, 1 },
93     [CCS_MAX_ACCEPT_ENTRY]
94 kumaneko 1052 = { "MAX_ACCEPT_ENTRY", MAX_ACCEPT_ENTRY, INT_MAX },
95 kumaneko 2213 #ifdef CONFIG_TOMOYO_AUDIT
96 kumaneko 2282 [CCS_MAX_GRANT_LOG]
97 kumaneko 1052 = { "MAX_GRANT_LOG", MAX_GRANT_LOG, INT_MAX },
98 kumaneko 2282 [CCS_MAX_REJECT_LOG]
99 kumaneko 1052 = { "MAX_REJECT_LOG", MAX_REJECT_LOG, INT_MAX },
100 kumaneko 2213 #endif
101 kumaneko 2282 [CCS_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
102 kumaneko 1052 [CCS_SLEEP_PERIOD]
103     = { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */
104 kumaneko 111 };
105    
106 kumaneko 1015 #ifdef CONFIG_TOMOYO
107 kumaneko 1052 /* Capability name used by domain policy. */
108 kumaneko 2282 static const char *ccs_capability_control_keyword[CCS_MAX_CAPABILITY_INDEX]
109 kumaneko 2002 = {
110 kumaneko 2282 [CCS_INET_STREAM_SOCKET_CREATE] = "inet_tcp_create",
111     [CCS_INET_STREAM_SOCKET_LISTEN] = "inet_tcp_listen",
112     [CCS_INET_STREAM_SOCKET_CONNECT] = "inet_tcp_connect",
113     [CCS_USE_INET_DGRAM_SOCKET] = "use_inet_udp",
114     [CCS_USE_INET_RAW_SOCKET] = "use_inet_ip",
115     [CCS_USE_ROUTE_SOCKET] = "use_route",
116     [CCS_USE_PACKET_SOCKET] = "use_packet",
117     [CCS_SYS_MOUNT] = "SYS_MOUNT",
118     [CCS_SYS_UMOUNT] = "SYS_UMOUNT",
119     [CCS_SYS_REBOOT] = "SYS_REBOOT",
120     [CCS_SYS_CHROOT] = "SYS_CHROOT",
121     [CCS_SYS_KILL] = "SYS_KILL",
122     [CCS_SYS_VHANGUP] = "SYS_VHANGUP",
123     [CCS_SYS_SETTIME] = "SYS_TIME",
124     [CCS_SYS_NICE] = "SYS_NICE",
125     [CCS_SYS_SETHOSTNAME] = "SYS_SETHOSTNAME",
126     [CCS_USE_KERNEL_MODULE] = "use_kernel_module",
127     [CCS_CREATE_FIFO] = "create_fifo",
128     [CCS_CREATE_BLOCK_DEV] = "create_block_dev",
129     [CCS_CREATE_CHAR_DEV] = "create_char_dev",
130     [CCS_CREATE_UNIX_SOCKET] = "create_unix_socket",
131     [CCS_SYS_LINK] = "SYS_LINK",
132     [CCS_SYS_SYMLINK] = "SYS_SYMLINK",
133     [CCS_SYS_RENAME] = "SYS_RENAME",
134     [CCS_SYS_UNLINK] = "SYS_UNLINK",
135     [CCS_SYS_CHMOD] = "SYS_CHMOD",
136     [CCS_SYS_CHOWN] = "SYS_CHOWN",
137     [CCS_SYS_IOCTL] = "SYS_IOCTL",
138     [CCS_SYS_KEXEC_LOAD] = "SYS_KEXEC_LOAD",
139     [CCS_SYS_PIVOT_ROOT] = "SYS_PIVOT_ROOT",
140     [CCS_SYS_PTRACE] = "SYS_PTRACE",
141 kumaneko 1015 };
142     #endif
143    
144 kumaneko 2254 #ifdef CONFIG_TOMOYO
145     static bool ccs_profile_entry_used[CCS_MAX_CONTROL_INDEX +
146 kumaneko 2282 CCS_MAX_CAPABILITY_INDEX + 1];
147 kumaneko 2254 #else
148     static bool ccs_profile_entry_used[CCS_MAX_CONTROL_INDEX + 1];
149     #endif
150    
151 kumaneko 1052 /* Profile table. Memory is allocated as needed. */
152 kumaneko 2002 static struct ccs_profile {
153 kumaneko 111 unsigned int value[CCS_MAX_CONTROL_INDEX];
154 kumaneko 2002 const struct ccs_path_info *comment;
155 kumaneko 1015 #ifdef CONFIG_TOMOYO
156 kumaneko 2282 unsigned char capability_value[CCS_MAX_CAPABILITY_INDEX];
157 kumaneko 1015 #endif
158 kumaneko 2002 } *ccs_profile_ptr[MAX_PROFILES];
159 kumaneko 111
160 kumaneko 1052 /* Permit policy management by non-root user? */
161 kumaneko 2002 static bool ccs_manage_by_non_root;
162 kumaneko 111
163 kumaneko 1052 /* Utility functions. */
164 kumaneko 111
165     #ifdef CONFIG_TOMOYO
166 kumaneko 1052 /**
167 kumaneko 2282 * ccs_quiet_setup - Set CCS_VERBOSE=0 by default.
168 kumaneko 1052 *
169     * @str: Unused.
170     *
171     * Returns 0.
172     */
173 kumaneko 2002 static int __init ccs_quiet_setup(char *str)
174 kumaneko 111 {
175 kumaneko 2282 ccs_control_array[CCS_VERBOSE].current_value = 0;
176 kumaneko 111 return 0;
177     }
178    
179 kumaneko 2282 __setup("CCS_QUIET", ccs_quiet_setup);
180 kumaneko 111 #endif
181    
182 kumaneko 1052 /**
183 kumaneko 2002 * ccs_is_byte_range - Check whether the string isa \ooo style octal value.
184 kumaneko 1052 *
185     * @str: Pointer to the string.
186     *
187     * Returns true if @str is a \ooo style octal value, false otherwise.
188     */
189 kumaneko 2002 static inline bool ccs_is_byte_range(const char *str)
190 kumaneko 1052 {
191     return *str >= '0' && *str++ <= '3' &&
192     *str >= '0' && *str++ <= '7' &&
193     *str >= '0' && *str <= '7';
194     }
195    
196     /**
197 kumaneko 2002 * ccs_is_decimal - Check whether the character is a decimal character.
198 kumaneko 1052 *
199     * @c: The character to check.
200     *
201     * Returns true if @c is a decimal character, false otherwise.
202     */
203 kumaneko 2002 static inline bool ccs_is_decimal(const char c)
204 kumaneko 1052 {
205 kumaneko 1468 return c >= '0' && c <= '9';
206 kumaneko 1052 }
207    
208     /**
209 kumaneko 2002 * ccs_is_hexadecimal - Check whether the character is a hexadecimal character.
210 kumaneko 1052 *
211     * @c: The character to check.
212     *
213     * Returns true if @c is a hexadecimal character, false otherwise.
214     */
215 kumaneko 2002 static inline bool ccs_is_hexadecimal(const char c)
216 kumaneko 1052 {
217 kumaneko 1468 return (c >= '0' && c <= '9') ||
218 kumaneko 1052 (c >= 'A' && c <= 'F') ||
219 kumaneko 1468 (c >= 'a' && c <= 'f');
220 kumaneko 1052 }
221    
222     /**
223 kumaneko 2002 * ccs_is_alphabet_char - Check whether the character is an alphabet.
224 kumaneko 1052 *
225     * @c: The character to check.
226     *
227     * Returns true if @c is an alphabet character, false otherwise.
228     */
229 kumaneko 2002 static inline bool ccs_is_alphabet_char(const char c)
230 kumaneko 1052 {
231 kumaneko 1794 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
232 kumaneko 1052 }
233    
234     /**
235 kumaneko 2002 * ccs_make_byte - Make byte value from three octal characters.
236 kumaneko 1064 *
237     * @c1: The first character.
238     * @c2: The second character.
239     * @c3: The third character.
240     *
241     * Returns byte value.
242     */
243 kumaneko 2002 static inline u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
244 kumaneko 1064 {
245     return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
246     }
247    
248     /**
249 kumaneko 2002 * ccs_str_starts - Check whether the given string starts with the given keyword.
250 kumaneko 1052 *
251     * @src: Pointer to pointer to the string.
252     * @find: Pointer to the keyword.
253     *
254     * Returns true if @src starts with @find, false otherwise.
255     *
256     * The @src is updated to point the first character after the @find
257 kumaneko 1064 * if @src starts with @find.
258 kumaneko 1052 */
259 kumaneko 2002 static bool ccs_str_starts(char **src, const char *find)
260 kumaneko 1052 {
261     const int len = strlen(find);
262     char *tmp = *src;
263     if (strncmp(tmp, find, len))
264     return false;
265     tmp += len;
266     *src = tmp;
267     return true;
268     }
269    
270     /**
271 kumaneko 2002 * ccs_normalize_line - Format string.
272 kumaneko 1052 *
273     * @buffer: The line to normalize.
274     *
275 kumaneko 111 * Leading and trailing whitespaces are removed.
276     * Multiple whitespaces are packed into single space.
277 kumaneko 1052 *
278     * Returns nothing.
279 kumaneko 111 */
280 kumaneko 2308 void ccs_normalize_line(unsigned char *buffer)
281 kumaneko 111 {
282 kumaneko 1064 unsigned char *sp = buffer;
283     unsigned char *dp = buffer;
284 kumaneko 1006 bool first = true;
285 kumaneko 1052 while (*sp && (*sp <= ' ' || *sp >= 127))
286     sp++;
287 kumaneko 111 while (*sp) {
288 kumaneko 1052 if (!first)
289     *dp++ = ' ';
290 kumaneko 1006 first = false;
291 kumaneko 1052 while (*sp > ' ' && *sp < 127)
292     *dp++ = *sp++;
293     while (*sp && (*sp <= ' ' || *sp >= 127))
294     sp++;
295 kumaneko 111 }
296     *dp = '\0';
297     }
298    
299 kumaneko 1052 /**
300 kumaneko 1054 * ccs_is_correct_path - Validate a pathname.
301     * @filename: The pathname to check.
302     * @start_type: Should the pathname start with '/'?
303     * 1 = must / -1 = must not / 0 = don't care
304     * @pattern_type: Can the pathname contain a wildcard?
305     * 1 = must / -1 = must not / 0 = don't care
306     * @end_type: Should the pathname end with '/'?
307     * 1 = must / -1 = must not / 0 = don't care
308     * @function: The name of function calling me.
309 kumaneko 1052 *
310 kumaneko 1054 * Check whether the given filename follows the naming rules.
311 kumaneko 1052 * Returns true if @filename follows the naming rules, false otherwise.
312 kumaneko 111 */
313 kumaneko 1052 bool ccs_is_correct_path(const char *filename, const s8 start_type,
314     const s8 pattern_type, const s8 end_type,
315     const char *function)
316 kumaneko 111 {
317 kumaneko 1006 bool contains_pattern = false;
318 kumaneko 1064 unsigned char c;
319     unsigned char d;
320     unsigned char e;
321 kumaneko 111 const char *original_filename = filename;
322 kumaneko 1052 if (!filename)
323     goto out;
324 kumaneko 111 c = *filename;
325     if (start_type == 1) { /* Must start with '/' */
326 kumaneko 1052 if (c != '/')
327     goto out;
328 kumaneko 111 } else if (start_type == -1) { /* Must not start with '/' */
329 kumaneko 1052 if (c == '/')
330     goto out;
331 kumaneko 111 }
332 kumaneko 1052 if (c)
333 kumaneko 1795 c = *(filename + strlen(filename) - 1);
334 kumaneko 111 if (end_type == 1) { /* Must end with '/' */
335 kumaneko 1052 if (c != '/')
336     goto out;
337 kumaneko 111 } else if (end_type == -1) { /* Must not end with '/' */
338 kumaneko 1052 if (c == '/')
339     goto out;
340 kumaneko 111 }
341 kumaneko 1747 while (1) {
342     c = *filename++;
343     if (!c)
344     break;
345 kumaneko 111 if (c == '\\') {
346 kumaneko 1747 c = *filename++;
347     switch (c) {
348 kumaneko 111 case '\\': /* "\\" */
349     continue;
350     case '$': /* "\$" */
351     case '+': /* "\+" */
352     case '?': /* "\?" */
353     case '*': /* "\*" */
354     case '@': /* "\@" */
355     case 'x': /* "\x" */
356     case 'X': /* "\X" */
357     case 'a': /* "\a" */
358     case 'A': /* "\A" */
359 kumaneko 206 case '-': /* "\-" */
360 kumaneko 1052 if (pattern_type == -1)
361     break; /* Must not contain pattern */
362 kumaneko 1006 contains_pattern = true;
363 kumaneko 111 continue;
364     case '0': /* "\ooo" */
365     case '1':
366     case '2':
367     case '3':
368 kumaneko 1052 d = *filename++;
369     if (d < '0' || d > '7')
370     break;
371     e = *filename++;
372     if (e < '0' || e > '7')
373     break;
374 kumaneko 2002 c = ccs_make_byte(c, d, e);
375 kumaneko 1052 if (c && (c <= ' ' || c >= 127))
376     continue; /* pattern is not \000 */
377 kumaneko 111 }
378     goto out;
379     } else if (c <= ' ' || c >= 127) {
380     goto out;
381     }
382     }
383     if (pattern_type == 1) { /* Must contain pattern */
384 kumaneko 1052 if (!contains_pattern)
385     goto out;
386 kumaneko 111 }
387 kumaneko 1006 return true;
388 kumaneko 111 out:
389 kumaneko 1052 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
390     original_filename);
391 kumaneko 1006 return false;
392 kumaneko 111 }
393    
394 kumaneko 1052 /**
395 kumaneko 1054 * ccs_is_correct_domain - Check whether the given domainname follows the naming rules.
396     * @domainname: The domainname to check.
397     * @function: The name of function calling me.
398 kumaneko 1052 *
399     * Returns true if @domainname follows the naming rules, false otherwise.
400 kumaneko 111 */
401 kumaneko 1052 bool ccs_is_correct_domain(const unsigned char *domainname,
402     const char *function)
403 kumaneko 111 {
404 kumaneko 1064 unsigned char c;
405     unsigned char d;
406     unsigned char e;
407 kumaneko 111 const char *org_domainname = domainname;
408 kumaneko 1052 if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN))
409     goto out;
410 kumaneko 111 domainname += ROOT_NAME_LEN;
411 kumaneko 1052 if (!*domainname)
412     return true;
413 kumaneko 111 do {
414 kumaneko 1052 if (*domainname++ != ' ')
415     goto out;
416     if (*domainname++ != '/')
417     goto out;
418 kumaneko 1747 while (1) {
419     c = *domainname;
420     if (!c || c == ' ')
421     break;
422 kumaneko 111 domainname++;
423     if (c == '\\') {
424 kumaneko 1052 c = *domainname++;
425     switch ((c)) {
426 kumaneko 111 case '\\': /* "\\" */
427     continue;
428     case '0': /* "\ooo" */
429     case '1':
430     case '2':
431     case '3':
432 kumaneko 1052 d = *domainname++;
433     if (d < '0' || d > '7')
434     break;
435     e = *domainname++;
436     if (e < '0' || e > '7')
437     break;
438 kumaneko 2002 c = ccs_make_byte(c, d, e);
439 kumaneko 1052 if (c && (c <= ' ' || c >= 127))
440     /* pattern is not \000 */
441     continue;
442 kumaneko 111 }
443     goto out;
444     } else if (c < ' ' || c >= 127) {
445     goto out;
446     }
447     }
448     } while (*domainname);
449 kumaneko 1006 return true;
450 kumaneko 111 out:
451 kumaneko 1052 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function,
452     org_domainname);
453 kumaneko 1006 return false;
454 kumaneko 111 }
455    
456 kumaneko 1052 /**
457     * ccs_is_domain_def - Check whether the given token can be a domainname.
458     *
459     * @buffer: The token to check.
460     *
461     * Returns true if @buffer possibly be a domainname, false otherwise.
462     */
463     bool ccs_is_domain_def(const unsigned char *buffer)
464 kumaneko 461 {
465 kumaneko 1052 return !strncmp(buffer, ROOT_NAME, ROOT_NAME_LEN);
466 kumaneko 461 }
467    
468 kumaneko 1052 /**
469     * ccs_find_domain - Find a domain by the given name.
470     *
471 kumaneko 1054 * @domainname: The domainname to find.
472 kumaneko 2540 * @cookie: Pointer to "struct ccs_cookie".
473 kumaneko 1052 *
474 kumaneko 2540 * Returns true if found, false otherwise.
475 kumaneko 1052 */
476 kumaneko 2540 bool ccs_find_domain(const char *domainname, struct ccs_cookie *cookie)
477 kumaneko 461 {
478 kumaneko 2282 struct ccs_domain_info *domain;
479 kumaneko 2002 struct ccs_path_info name;
480 kumaneko 1052 name.name = domainname;
481     ccs_fill_path_info(&name);
482 kumaneko 2544 cookie->u.domain = NULL;
483     /***** READER SECTION START *****/
484     down_read(&ccs_policy_lock);
485 kumaneko 2540 list_for_each_entry(domain, &ccs_domain_list, list) {
486     if (domain->is_deleted ||
487     ccs_pathcmp(&name, domain->domainname))
488     continue;
489 kumaneko 2544 cookie->u.domain = domain;
490     break;
491 kumaneko 461 }
492 kumaneko 2544 up_read(&ccs_policy_lock);
493 kumaneko 2540 /***** READER SECTION END *****/
494 kumaneko 2544 return cookie->u.domain != NULL;
495 kumaneko 461 }
496    
497 kumaneko 1052 /**
498 kumaneko 2002 * ccs_path_depth - Evaluate the number of '/' in a string.
499 kumaneko 1052 *
500     * @pathname: The string to evaluate.
501     *
502     * Returns path depth of the string.
503     *
504     * I score 2 for each of the '/' in the @pathname
505     * and score 1 if the @pathname ends with '/'.
506     */
507 kumaneko 2002 static int ccs_path_depth(const char *pathname)
508 kumaneko 111 {
509     int i = 0;
510     if (pathname) {
511 kumaneko 1795 const char *ep = pathname + strlen(pathname);
512 kumaneko 111 if (pathname < ep--) {
513 kumaneko 1052 if (*ep != '/')
514     i++;
515     while (pathname <= ep)
516     if (*ep-- == '/')
517     i += 2;
518 kumaneko 111 }
519     }
520     return i;
521     }
522    
523 kumaneko 1052 /**
524 kumaneko 2002 * ccs_const_part_length - Evaluate the initial length without a pattern in a token.
525 kumaneko 1052 *
526     * @filename: The string to evaluate.
527     *
528 kumaneko 1064 * Returns the initial length without a pattern in @filename.
529 kumaneko 1052 */
530 kumaneko 2002 static int ccs_const_part_length(const char *filename)
531 kumaneko 111 {
532 kumaneko 1052 char c;
533 kumaneko 111 int len = 0;
534 kumaneko 1052 if (!filename)
535     return 0;
536 kumaneko 1747 while (1) {
537     c = *filename++;
538     if (!c)
539     break;
540 kumaneko 1052 if (c != '\\') {
541     len++;
542     continue;
543 kumaneko 111 }
544 kumaneko 1052 c = *filename++;
545     switch (c) {
546     case '\\': /* "\\" */
547     len += 2;
548     continue;
549     case '0': /* "\ooo" */
550     case '1':
551     case '2':
552     case '3':
553     c = *filename++;
554     if (c < '0' || c > '7')
555     break;
556     c = *filename++;
557     if (c < '0' || c > '7')
558     break;
559     len += 4;
560     continue;
561     }
562     break;
563 kumaneko 111 }
564     return len;
565     }
566    
567 kumaneko 1052 /**
568 kumaneko 2002 * ccs_fill_path_info - Fill in "struct ccs_path_info" members.
569 kumaneko 1052 *
570 kumaneko 2002 * @ptr: Pointer to "struct ccs_path_info" to fill in.
571 kumaneko 1052 *
572 kumaneko 2002 * The caller sets "struct ccs_path_info"->name.
573 kumaneko 1052 */
574 kumaneko 2002 void ccs_fill_path_info(struct ccs_path_info *ptr)
575 kumaneko 111 {
576     const char *name = ptr->name;
577     const int len = strlen(name);
578     ptr->total_len = len;
579 kumaneko 2002 ptr->const_len = ccs_const_part_length(name);
580 kumaneko 111 ptr->is_dir = len && (name[len - 1] == '/');
581     ptr->is_patterned = (ptr->const_len < len);
582     ptr->hash = full_name_hash(name, len);
583 kumaneko 2002 ptr->depth = ccs_path_depth(name);
584 kumaneko 111 }
585    
586 kumaneko 1052 /**
587 kumaneko 2039 * ccs_file_matches_pattern2 - Pattern matching without '/' character
588 kumaneko 1052 * and "\-" pattern.
589     *
590     * @filename: The start of string to check.
591     * @filename_end: The end of string to check.
592     * @pattern: The start of pattern to compare.
593     * @pattern_end: The end of pattern to compare.
594     *
595     * Returns true if @filename matches @pattern, false otherwise.
596     */
597 kumaneko 2039 static bool ccs_file_matches_pattern2(const char *filename,
598     const char *filename_end,
599     const char *pattern,
600     const char *pattern_end)
601 kumaneko 111 {
602     while (filename < filename_end && pattern < pattern_end) {
603 kumaneko 1052 char c;
604 kumaneko 111 if (*pattern != '\\') {
605 kumaneko 1052 if (*filename++ != *pattern++)
606     return false;
607     continue;
608     }
609     c = *filename;
610     pattern++;
611     switch (*pattern) {
612 kumaneko 1064 int i;
613     int j;
614 kumaneko 1052 case '?':
615     if (c == '/') {
616     return false;
617     } else if (c == '\\') {
618     if (filename[1] == '\\')
619     filename++;
620 kumaneko 2002 else if (ccs_is_byte_range(filename + 1))
621 kumaneko 1052 filename += 3;
622     else
623 kumaneko 1006 return false;
624 kumaneko 1052 }
625     break;
626     case '\\':
627     if (c != '\\')
628     return false;
629     if (*++filename != '\\')
630     return false;
631     break;
632     case '+':
633 kumaneko 2002 if (!ccs_is_decimal(c))
634 kumaneko 1052 return false;
635     break;
636     case 'x':
637 kumaneko 2002 if (!ccs_is_hexadecimal(c))
638 kumaneko 1052 return false;
639     break;
640     case 'a':
641 kumaneko 2002 if (!ccs_is_alphabet_char(c))
642 kumaneko 1052 return false;
643     break;
644     case '0':
645     case '1':
646     case '2':
647     case '3':
648 kumaneko 2002 if (c == '\\' && ccs_is_byte_range(filename + 1)
649 kumaneko 1052 && strncmp(filename + 1, pattern, 3) == 0) {
650     filename += 3;
651     pattern += 2;
652 kumaneko 111 break;
653 kumaneko 1052 }
654     return false; /* Not matched. */
655     case '*':
656     case '@':
657     for (i = 0; i <= filename_end - filename; i++) {
658 kumaneko 2039 if (ccs_file_matches_pattern2(filename + i,
659     filename_end,
660     pattern + 1,
661     pattern_end))
662 kumaneko 1052 return true;
663     c = filename[i];
664     if (c == '.' && *pattern == '@')
665 kumaneko 111 break;
666 kumaneko 1052 if (c != '\\')
667     continue;
668     if (filename[i + 1] == '\\')
669     i++;
670 kumaneko 2002 else if (ccs_is_byte_range(filename + i + 1))
671 kumaneko 1052 i += 3;
672     else
673     break; /* Bad pattern. */
674 kumaneko 111 }
675 kumaneko 1052 return false; /* Not matched. */
676     default:
677     j = 0;
678     c = *pattern;
679     if (c == '$') {
680 kumaneko 2002 while (ccs_is_decimal(filename[j]))
681 kumaneko 1052 j++;
682     } else if (c == 'X') {
683 kumaneko 2002 while (ccs_is_hexadecimal(filename[j]))
684 kumaneko 1052 j++;
685     } else if (c == 'A') {
686 kumaneko 2002 while (ccs_is_alphabet_char(filename[j]))
687 kumaneko 1052 j++;
688     }
689     for (i = 1; i <= j; i++) {
690 kumaneko 2039 if (ccs_file_matches_pattern2(filename + i,
691     filename_end,
692     pattern + 1,
693     pattern_end))
694 kumaneko 1052 return true;
695     }
696     return false; /* Not matched or bad pattern. */
697 kumaneko 111 }
698 kumaneko 1052 filename++;
699     pattern++;
700 kumaneko 111 }
701 kumaneko 1052 while (*pattern == '\\' &&
702     (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
703     pattern += 2;
704 kumaneko 1468 return filename == filename_end && pattern == pattern_end;
705 kumaneko 111 }
706    
707 kumaneko 1052 /**
708 kumaneko 2039 * ccs_file_matches_pattern - Pattern matching without without '/' character.
709 kumaneko 1052 *
710     * @filename: The start of string to check.
711     * @filename_end: The end of string to check.
712     * @pattern: The start of pattern to compare.
713     * @pattern_end: The end of pattern to compare.
714     *
715     * Returns true if @filename matches @pattern, false otherwise.
716     */
717 kumaneko 2039 static bool ccs_file_matches_pattern(const char *filename,
718     const char *filename_end,
719     const char *pattern,
720     const char *pattern_end)
721 kumaneko 206 {
722     const char *pattern_start = pattern;
723 kumaneko 1006 bool first = true;
724     bool result;
725 kumaneko 206 while (pattern < pattern_end - 1) {
726 kumaneko 1052 /* Split at "\-" pattern. */
727     if (*pattern++ != '\\' || *pattern++ != '-')
728     continue;
729 kumaneko 2039 result = ccs_file_matches_pattern2(filename, filename_end,
730 kumaneko 2040 pattern_start, pattern - 2);
731 kumaneko 1052 if (first)
732     result = !result;
733     if (result)
734     return false;
735 kumaneko 1006 first = false;
736 kumaneko 206 pattern_start = pattern;
737     }
738 kumaneko 2039 result = ccs_file_matches_pattern2(filename, filename_end,
739     pattern_start, pattern_end);
740 kumaneko 206 return first ? result : !result;
741     }
742    
743 kumaneko 1052 /**
744 kumaneko 1054 * ccs_path_matches_pattern - Check whether the given filename matches the given pattern.
745 kumaneko 1052 * @filename: The filename to check.
746     * @pattern: The pattern to compare.
747 kumaneko 111 *
748 kumaneko 1052 * Returns true if matches, false otherwise.
749     *
750     * The following patterns are available.
751     * \\ \ itself.
752     * \ooo Octal representation of a byte.
753     * \* More than or equals to 0 character other than '/'.
754     * \@ More than or equals to 0 character other than '/' or '.'.
755     * \? 1 byte character other than '/'.
756     * \$ More than or equals to 1 decimal digit.
757     * \+ 1 decimal digit.
758     * \X More than or equals to 1 hexadecimal digit.
759     * \x 1 hexadecimal digit.
760     * \A More than or equals to 1 alphabet character.
761     * \a 1 alphabet character.
762     * \- Subtraction operator.
763 kumaneko 111 */
764 kumaneko 2002 bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
765     const struct ccs_path_info *pattern)
766 kumaneko 111 {
767 kumaneko 1052 /*
768     if (!filename || !pattern)
769     return false;
770     */
771     const char *f = filename->name;
772     const char *p = pattern->name;
773     const int len = pattern->const_len;
774     /* If @pattern doesn't contain pattern, I can use strcmp(). */
775     if (!pattern->is_patterned)
776     return !ccs_pathcmp(filename, pattern);
777     /* Dont compare if the number of '/' differs. */
778     if (filename->depth != pattern->depth)
779     return false;
780     /* Compare the initial length without patterns. */
781     if (strncmp(f, p, len))
782     return false;
783     f += len;
784     p += len;
785     /* Main loop. Compare each directory component. */
786     while (*f && *p) {
787     const char *f_delimiter = strchr(f, '/');
788     const char *p_delimiter = strchr(p, '/');
789     if (!f_delimiter)
790 kumaneko 1795 f_delimiter = f + strlen(f);
791 kumaneko 1052 if (!p_delimiter)
792 kumaneko 1795 p_delimiter = p + strlen(p);
793 kumaneko 2040 if (!ccs_file_matches_pattern(f, f_delimiter, p, p_delimiter))
794 kumaneko 1052 return false;
795     f = f_delimiter;
796     if (*f)
797     f++;
798     p = p_delimiter;
799     if (*p)
800     p++;
801 kumaneko 111 }
802 kumaneko 1052 /* Ignore trailing "\*" and "\@" in @pattern. */
803     while (*p == '\\' &&
804     (*(p + 1) == '*' || *(p + 1) == '@'))
805     p += 2;
806 kumaneko 1468 return !*f && !*p;
807 kumaneko 111 }
808    
809 kumaneko 1052 /**
810     * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.
811     *
812     * @head: Pointer to "struct ccs_io_buffer".
813     * @fmt: The printf()'s format string, followed by parameters.
814     *
815     * Returns true on success, false otherwise.
816     *
817     * The snprintf() will truncate, but ccs_io_printf() won't.
818 kumaneko 111 */
819 kumaneko 1052 bool ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
820 kumaneko 111 {
821     va_list args;
822 kumaneko 1064 int len;
823     int pos = head->read_avail;
824     int size = head->readbuf_size - pos;
825 kumaneko 1052 if (size <= 0)
826     return false;
827 kumaneko 111 va_start(args, fmt);
828     len = vsnprintf(head->read_buf + pos, size, fmt, args);
829     va_end(args);
830 kumaneko 1052 if (pos + len >= head->readbuf_size)
831     return false;
832 kumaneko 111 head->read_avail += len;
833 kumaneko 1052 return true;
834 kumaneko 111 }
835    
836 kumaneko 1052 /**
837     * ccs_get_exe - Get ccs_realpath() of current process.
838     *
839     * Returns the ccs_realpath() of current process on success, NULL otherwise.
840     *
841     * This function uses ccs_alloc(), so the caller must ccs_free()
842     * if this function didn't return NULL.
843 kumaneko 111 */
844 kumaneko 1052 const char *ccs_get_exe(void)
845 kumaneko 111 {
846 kumaneko 737 struct mm_struct *mm = current->mm;
847     struct vm_area_struct *vma;
848     const char *cp = NULL;
849 kumaneko 1052 if (!mm)
850     return NULL;
851 kumaneko 737 down_read(&mm->mmap_sem);
852     for (vma = mm->mmap; vma; vma = vma->vm_next) {
853     if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
854 kumaneko 1052 cp = ccs_realpath_from_dentry(vma->vm_file->f_dentry,
855     vma->vm_file->f_vfsmnt);
856 kumaneko 737 break;
857 kumaneko 111 }
858     }
859 kumaneko 737 up_read(&mm->mmap_sem);
860     return cp;
861 kumaneko 111 }
862    
863 kumaneko 1052 /**
864     * ccs_get_msg - Get warning message.
865     *
866     * @is_enforce: Is it enforcing mode?
867     *
868     * Returns "ERROR" or "WARNING".
869     */
870     const char *ccs_get_msg(const bool is_enforce)
871 kumaneko 111 {
872 kumaneko 1052 if (is_enforce)
873     return "ERROR";
874     else
875     return "WARNING";
876 kumaneko 111 }
877    
878 kumaneko 1052 /**
879 kumaneko 1657 * ccs_can_sleep - Check whether it is permitted to do operations that may sleep.
880 kumaneko 1052 *
881     * Returns true if it is permitted to do operations that may sleep,
882     * false otherwise.
883     *
884     * TOMOYO Linux supports interactive enforcement that lets processes
885     * wait for the administrator's decision.
886     * All hooks but the one for ccs_may_autobind() are inserted where
887     * it is permitted to do operations that may sleep.
888     * Thus, this warning should not happen.
889     */
890 kumaneko 1657 bool ccs_can_sleep(void)
891 kumaneko 899 {
892 kumaneko 1052 static u8 count = 20;
893     if (likely(!in_interrupt()))
894     return true;
895     if (count) {
896     count--;
897     printk(KERN_ERR "BUG: sleeping function called "
898     "from invalid context.\n");
899     dump_stack();
900 kumaneko 899 }
901 kumaneko 1052 return false;
902 kumaneko 899 }
903    
904 kumaneko 1052 /**
905     * ccs_check_flags - Check mode for specified functionality.
906     *
907 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
908 kumaneko 1657 * @index: The functionality to check mode.
909 kumaneko 1052 *
910     * Returns the mode of specified functionality.
911     */
912 kumaneko 2282 unsigned int ccs_check_flags(const struct ccs_domain_info *domain,
913     const u8 index)
914 kumaneko 1015 {
915 kumaneko 1657 u8 profile;
916     if (!domain)
917 kumaneko 2282 domain = ccs_current_domain();
918 kumaneko 1657 profile = domain->profile;
919 kumaneko 2040 return ccs_policy_loaded && index < CCS_MAX_CONTROL_INDEX
920 kumaneko 1657 #if MAX_PROFILES != 256
921     && profile < MAX_PROFILES
922     #endif
923 kumaneko 2002 && ccs_profile_ptr[profile] ?
924     ccs_profile_ptr[profile]->value[index] : 0;
925 kumaneko 1015 }
926    
927     #ifdef CONFIG_TOMOYO
928 kumaneko 1052 /**
929     * ccs_check_capability_flags - Check mode for specified capability.
930     *
931 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
932 kumaneko 1657 * @index: The capability to check mode.
933 kumaneko 1052 *
934     * Returns the mode of specified capability.
935     */
936 kumaneko 2282 static u8 ccs_check_capability_flags(const struct ccs_domain_info *domain,
937 kumaneko 1657 const u8 index)
938 kumaneko 1015 {
939 kumaneko 1657 const u8 profile = domain ? domain->profile :
940 kumaneko 2282 ccs_current_domain()->profile;
941     return ccs_policy_loaded && index < CCS_MAX_CAPABILITY_INDEX
942 kumaneko 1015 #if MAX_PROFILES != 256
943     && profile < MAX_PROFILES
944     #endif
945 kumaneko 2002 && ccs_profile_ptr[profile] ?
946     ccs_profile_ptr[profile]->capability_value[index] : 0;
947 kumaneko 1015 }
948    
949 kumaneko 1052 /**
950     * ccs_cap2keyword - Convert capability operation to capability name.
951     *
952     * @operation: The capability index.
953     *
954     * Returns the name of the specified capability's name.
955     */
956     const char *ccs_cap2keyword(const u8 operation)
957 kumaneko 1015 {
958 kumaneko 2282 return operation < CCS_MAX_CAPABILITY_INDEX
959 kumaneko 2002 ? ccs_capability_control_keyword[operation] : NULL;
960 kumaneko 1015 }
961    
962     #endif
963    
964 kumaneko 1052 /**
965 kumaneko 1657 * ccs_init_request_info - Initialize "struct ccs_request_info" members.
966     *
967     * @r: Pointer to "struct ccs_request_info" to initialize.
968 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
969 kumaneko 1657 * @index: Index number of functionality.
970     */
971     void ccs_init_request_info(struct ccs_request_info *r,
972 kumaneko 2282 struct ccs_domain_info *domain, const u8 index)
973 kumaneko 1657 {
974     memset(r, 0, sizeof(*r));
975 kumaneko 2544 ccs_add_cookie(&r->cookie, NULL);
976     ccs_add_cookie(&r->condition_cookie, NULL);
977 kumaneko 1657 if (!domain)
978 kumaneko 2282 domain = ccs_current_domain();
979 kumaneko 2540 r->cookie.u.domain = domain;
980 kumaneko 1657 r->profile = domain->profile;
981     if (index < CCS_MAX_CONTROL_INDEX)
982     r->mode = ccs_check_flags(domain, index);
983     #ifdef CONFIG_TOMOYO
984     else
985     r->mode = ccs_check_capability_flags(domain, index
986     - CCS_MAX_CONTROL_INDEX);
987     #endif
988     }
989    
990     /**
991 kumaneko 2544 * ccs_exit_request_info - Cleanup "struct ccs_request_info" members.
992     *
993     * @r: Pointer to "struct ccs_request_info".
994     */
995     void ccs_exit_request_info(struct ccs_request_info *r)
996     {
997     ccs_del_cookie(&r->condition_cookie);
998     ccs_del_cookie(&r->cookie);
999     }
1000    
1001     /**
1002 kumaneko 1052 * ccs_verbose_mode - Check whether TOMOYO is verbose mode.
1003     *
1004 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
1005 kumaneko 1657 *
1006 kumaneko 1052 * Returns true if domain policy violation warning should be printed to
1007     * console.
1008     */
1009 kumaneko 2282 bool ccs_verbose_mode(const struct ccs_domain_info *domain)
1010 kumaneko 111 {
1011 kumaneko 2282 return ccs_check_flags(domain, CCS_VERBOSE) != 0;
1012 kumaneko 111 }
1013    
1014 kumaneko 1052 /**
1015 kumaneko 2209 * ccs_domain_quota_ok - Check for domain's quota.
1016 kumaneko 1052 *
1017 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
1018 kumaneko 1052 *
1019     * Returns true if the domain is not exceeded quota, false otherwise.
1020     */
1021 kumaneko 2282 bool ccs_domain_quota_ok(struct ccs_domain_info * const domain)
1022 kumaneko 512 {
1023     unsigned int count = 0;
1024 kumaneko 2002 struct ccs_acl_info *ptr;
1025 kumaneko 2540 bool quota_ok = false;
1026 kumaneko 1052 if (!domain)
1027     return true;
1028 kumaneko 2540 /***** READER SECTION START *****/
1029     down_read(&ccs_policy_lock);
1030     list_for_each_entry(ptr, &domain->acl_info_list, list) {
1031 kumaneko 1064 if (ptr->type & ACL_DELETED)
1032     continue;
1033 kumaneko 2540 switch (ptr->type) {
1034 kumaneko 2002 struct ccs_single_path_acl_record *acl1;
1035     struct ccs_double_path_acl_record *acl2;
1036 kumaneko 1064 u16 perm;
1037     case TYPE_SINGLE_PATH_ACL:
1038 kumaneko 2002 acl1 = container_of(ptr,
1039     struct ccs_single_path_acl_record,
1040 kumaneko 1064 head);
1041     perm = acl1->perm;
1042     if (perm & (1 << TYPE_EXECUTE_ACL))
1043     count++;
1044     if (perm &
1045     ((1 << TYPE_READ_ACL) | (1 << TYPE_WRITE_ACL)))
1046     count++;
1047     if (perm & (1 << TYPE_CREATE_ACL))
1048     count++;
1049     if (perm & (1 << TYPE_UNLINK_ACL))
1050     count++;
1051     if (perm & (1 << TYPE_MKDIR_ACL))
1052     count++;
1053     if (perm & (1 << TYPE_RMDIR_ACL))
1054     count++;
1055     if (perm & (1 << TYPE_MKFIFO_ACL))
1056     count++;
1057     if (perm & (1 << TYPE_MKSOCK_ACL))
1058     count++;
1059     if (perm & (1 << TYPE_MKBLOCK_ACL))
1060     count++;
1061     if (perm & (1 << TYPE_MKCHAR_ACL))
1062     count++;
1063     if (perm & (1 << TYPE_TRUNCATE_ACL))
1064     count++;
1065     if (perm & (1 << TYPE_SYMLINK_ACL))
1066     count++;
1067     if (perm & (1 << TYPE_REWRITE_ACL))
1068     count++;
1069     break;
1070     case TYPE_DOUBLE_PATH_ACL:
1071 kumaneko 2002 acl2 = container_of(ptr,
1072     struct ccs_double_path_acl_record,
1073 kumaneko 1064 head);
1074     perm = acl2->perm;
1075     if (perm & (1 << TYPE_LINK_ACL))
1076     count++;
1077     if (perm & (1 << TYPE_RENAME_ACL))
1078     count++;
1079     break;
1080     case TYPE_EXECUTE_HANDLER:
1081     case TYPE_DENIED_EXECUTE_HANDLER:
1082     break;
1083     default:
1084 kumaneko 1052 count++;
1085 kumaneko 1064 }
1086 kumaneko 512 }
1087 kumaneko 2282 if (count < ccs_check_flags(domain, CCS_MAX_ACCEPT_ENTRY))
1088 kumaneko 2540 quota_ok = true;
1089     else if (!domain->quota_warned) {
1090 kumaneko 1006 domain->quota_warned = true;
1091 kumaneko 1052 printk(KERN_WARNING "TOMOYO-WARNING: "
1092     "Domain '%s' has so many ACLs to hold. "
1093     "Stopped learning mode.\n", domain->domainname->name);
1094 kumaneko 512 }
1095 kumaneko 2540 up_read(&ccs_policy_lock);
1096     /***** READER SECTION END *****/
1097     return quota_ok;
1098 kumaneko 512 }
1099    
1100 kumaneko 1052 /**
1101     * ccs_find_or_assign_new_profile - Create a new profile.
1102     *
1103     * @profile: Profile number to create.
1104     *
1105 kumaneko 2002 * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
1106 kumaneko 1052 */
1107 kumaneko 2002 static struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int
1108     profile)
1109 kumaneko 111 {
1110 kumaneko 2540 struct ccs_profile *ptr;
1111     struct ccs_profile *entry;
1112     int i;
1113     if (profile >= MAX_PROFILES)
1114     return NULL;
1115     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
1116     /***** WRITER SECTION START *****/
1117     down_write(&ccs_policy_lock);
1118     ptr = ccs_profile_ptr[profile];
1119     if (!ptr && ccs_memory_ok(entry)) {
1120     ptr = entry;
1121     for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++)
1122     ptr->value[i] = ccs_control_array[i].current_value;
1123     /*
1124     * Needn't to initialize "ptr->capability_value"
1125     * because they are always 0.
1126     */
1127     mb(); /* Avoid out-of-order execution. */
1128     ccs_profile_ptr[profile] = ptr;
1129     entry = NULL;
1130 kumaneko 111 }
1131 kumaneko 2540 up_write(&ccs_policy_lock);
1132     /***** WRITER SECTION END *****/
1133     kfree(entry);
1134 kumaneko 111 return ptr;
1135     }
1136    
1137 kumaneko 1052 /**
1138 kumaneko 2002 * ccs_write_profile - Write profile table.
1139 kumaneko 1052 *
1140 kumaneko 1657 * @head: Pointer to "struct ccs_io_buffer".
1141 kumaneko 1052 *
1142     * Returns 0 on success, negative value otherwise.
1143     */
1144 kumaneko 2002 static int ccs_write_profile(struct ccs_io_buffer *head)
1145 kumaneko 111 {
1146     char *data = head->write_buf;
1147 kumaneko 1064 unsigned int i;
1148     unsigned int value;
1149 kumaneko 111 char *cp;
1150 kumaneko 2002 struct ccs_profile *ccs_profile;
1151 kumaneko 111 i = simple_strtoul(data, &cp, 10);
1152     if (data != cp) {
1153 kumaneko 1052 if (*cp != '-')
1154     return -EINVAL;
1155     data = cp + 1;
1156 kumaneko 111 }
1157 kumaneko 2002 ccs_profile = ccs_find_or_assign_new_profile(i);
1158     if (!ccs_profile)
1159 kumaneko 1052 return -EINVAL;
1160 kumaneko 111 cp = strchr(data, '=');
1161 kumaneko 1052 if (!cp)
1162     return -EINVAL;
1163 kumaneko 111 *cp = '\0';
1164 kumaneko 1052 ccs_update_counter(CCS_UPDATES_COUNTER_PROFILE);
1165     if (!strcmp(data, "COMMENT")) {
1166 kumaneko 2540 ccs_profile->comment = ccs_get_name(cp + 1);
1167 kumaneko 2254 ccs_profile_entry_used[0] = true;
1168 kumaneko 111 return 0;
1169     }
1170 kumaneko 708 #ifdef CONFIG_TOMOYO
1171 kumaneko 2002 if (ccs_str_starts(&data, KEYWORD_MAC_FOR_CAPABILITY)) {
1172 kumaneko 1014 if (sscanf(cp + 1, "%u", &value) != 1) {
1173 kumaneko 1015 for (i = 0; i < 4; i++) {
1174 kumaneko 2002 if (strcmp(cp + 1, ccs_mode_4[i]))
1175 kumaneko 1052 continue;
1176 kumaneko 1015 value = i;
1177 kumaneko 1014 break;
1178     }
1179 kumaneko 1052 if (i == 4)
1180     return -EINVAL;
1181 kumaneko 1014 }
1182 kumaneko 1052 if (value > 3)
1183     value = 3;
1184 kumaneko 2282 for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) {
1185 kumaneko 2002 if (strcmp(data, ccs_capability_control_keyword[i]))
1186 kumaneko 1052 continue;
1187 kumaneko 2002 ccs_profile->capability_value[i] = value;
1188 kumaneko 2254 ccs_profile_entry_used[i + 1 + CCS_MAX_CONTROL_INDEX]
1189     = true;
1190 kumaneko 1015 return 0;
1191     }
1192     return -EINVAL;
1193 kumaneko 111 }
1194 kumaneko 461 #endif
1195 kumaneko 111 for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {
1196 kumaneko 1052 if (strcmp(data, ccs_control_array[i].keyword))
1197     continue;
1198 kumaneko 1014 if (sscanf(cp + 1, "%u", &value) != 1) {
1199     int j;
1200     const char **modes;
1201     switch (i) {
1202 kumaneko 2282 case CCS_RESTRICT_AUTOBIND:
1203     case CCS_VERBOSE:
1204 kumaneko 2002 modes = ccs_mode_2;
1205 kumaneko 1014 break;
1206     default:
1207 kumaneko 2002 modes = ccs_mode_4;
1208 kumaneko 1014 break;
1209     }
1210     for (j = 0; j < 4; j++) {
1211 kumaneko 1052 if (strcmp(cp + 1, modes[j]))
1212     continue;
1213 kumaneko 1014 value = j;
1214     break;
1215     }
1216 kumaneko 1052 if (j == 4)
1217     return -EINVAL;
1218 kumaneko 1014 } else if (value > ccs_control_array[i].max_value) {
1219     value = ccs_control_array[i].max_value;
1220     }
1221     switch (i) {
1222 kumaneko 2282 case CCS_DENY_CONCEAL_MOUNT:
1223     case CCS_RESTRICT_UNMOUNT:
1224 kumaneko 1052 if (value == 1)
1225     value = 2; /* learning mode is not supported. */
1226 kumaneko 1014 }
1227 kumaneko 2002 ccs_profile->value[i] = value;
1228 kumaneko 2254 ccs_profile_entry_used[i + 1] = true;
1229 kumaneko 111 return 0;
1230     }
1231     return -EINVAL;
1232     }
1233    
1234 kumaneko 1052 /**
1235 kumaneko 2002 * ccs_read_profile - Read profile table.
1236 kumaneko 1052 *
1237 kumaneko 1657 * @head: Pointer to "struct ccs_io_buffer".
1238 kumaneko 1052 *
1239     * Returns 0.
1240     */
1241 kumaneko 2002 static int ccs_read_profile(struct ccs_io_buffer *head)
1242 kumaneko 111 {
1243 kumaneko 2002 static const int ccs_total
1244 kumaneko 2282 = CCS_MAX_CONTROL_INDEX + CCS_MAX_CAPABILITY_INDEX + 1;
1245 kumaneko 1006 int step;
1246 kumaneko 1052 if (head->read_eof)
1247     return 0;
1248 kumaneko 2002 for (step = head->read_step; step < MAX_PROFILES * ccs_total; step++) {
1249     const u8 index = step / ccs_total;
1250     u8 type = step % ccs_total;
1251     const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];
1252 kumaneko 1006 head->read_step = step;
1253 kumaneko 2002 if (!ccs_profile)
1254 kumaneko 1052 continue;
1255     #if !defined(CONFIG_SAKURA) || !defined(CONFIG_TOMOYO)
1256 kumaneko 2201 switch (type - 1) {
1257 kumaneko 461 #ifndef CONFIG_SAKURA
1258 kumaneko 2282 case CCS_DENY_CONCEAL_MOUNT:
1259     case CCS_RESTRICT_CHROOT:
1260     case CCS_RESTRICT_MOUNT:
1261     case CCS_RESTRICT_UNMOUNT:
1262     case CCS_RESTRICT_PIVOT_ROOT:
1263     case CCS_RESTRICT_AUTOBIND:
1264 kumaneko 461 #endif
1265 kumaneko 111 #ifndef CONFIG_TOMOYO
1266 kumaneko 2282 case CCS_MAC_FOR_FILE:
1267 kumaneko 2303 case CCS_MAC_FOR_IOCTL:
1268 kumaneko 2282 case CCS_MAC_FOR_ARGV0:
1269     case CCS_MAC_FOR_ENV:
1270     case CCS_MAC_FOR_NETWORK:
1271     case CCS_MAC_FOR_SIGNAL:
1272     case CCS_MAX_ACCEPT_ENTRY:
1273     case CCS_VERBOSE:
1274 kumaneko 111 #endif
1275 kumaneko 1006 continue;
1276 kumaneko 111 }
1277 kumaneko 1052 #endif
1278 kumaneko 2254 if (!ccs_profile_entry_used[type])
1279     continue;
1280 kumaneko 1052 if (!type) { /* Print profile' comment tag. */
1281     if (!ccs_io_printf(head, "%u-COMMENT=%s\n",
1282 kumaneko 2002 index, ccs_profile->comment ?
1283     ccs_profile->comment->name : ""))
1284 kumaneko 1052 break;
1285     continue;
1286     }
1287     type--;
1288     if (type >= CCS_MAX_CONTROL_INDEX) {
1289 kumaneko 1015 #ifdef CONFIG_TOMOYO
1290 kumaneko 1052 const int i = type - CCS_MAX_CONTROL_INDEX;
1291 kumaneko 2002 const u8 value = ccs_profile->capability_value[i];
1292 kumaneko 1052 if (!ccs_io_printf(head,
1293     "%u-" KEYWORD_MAC_FOR_CAPABILITY
1294     "%s=%s\n", index,
1295 kumaneko 2002 ccs_capability_control_keyword[i],
1296     ccs_mode_4[value]))
1297 kumaneko 1052 break;
1298 kumaneko 1015 #endif
1299 kumaneko 1006 } else {
1300 kumaneko 2002 const unsigned int value = ccs_profile->value[type];
1301 kumaneko 1014 const char **modes = NULL;
1302 kumaneko 1052 const char *keyword = ccs_control_array[type].keyword;
1303     switch (ccs_control_array[type].max_value) {
1304 kumaneko 1014 case 3:
1305 kumaneko 2002 modes = ccs_mode_4;
1306 kumaneko 1014 break;
1307     case 1:
1308 kumaneko 2002 modes = ccs_mode_2;
1309 kumaneko 1014 break;
1310     }
1311     if (modes) {
1312 kumaneko 1052 if (!ccs_io_printf(head, "%u-%s=%s\n", index,
1313     keyword, modes[value]))
1314     break;
1315 kumaneko 1014 } else {
1316 kumaneko 1052 if (!ccs_io_printf(head, "%u-%s=%u\n", index,
1317     keyword, value))
1318     break;
1319 kumaneko 1014 }
1320 kumaneko 1006 }
1321     }
1322 kumaneko 2002 if (step == MAX_PROFILES * ccs_total)
1323 kumaneko 1052 head->read_eof = true;
1324 kumaneko 111 return 0;
1325     }
1326    
1327 kumaneko 2002 /* The list for "struct ccs_policy_manager_entry". */
1328 kumaneko 2540 LIST_HEAD(ccs_policy_manager_list);
1329 kumaneko 111
1330 kumaneko 1052 /**
1331 kumaneko 2002 * ccs_update_manager_entry - Add a manager entry.
1332 kumaneko 1052 *
1333     * @manager: The path to manager or the domainnamme.
1334     * @is_delete: True if it is a delete request.
1335     *
1336     * Returns 0 on success, negative value otherwise.
1337     */
1338 kumaneko 2002 static int ccs_update_manager_entry(const char *manager, const bool is_delete)
1339 kumaneko 111 {
1340 kumaneko 2540 struct ccs_policy_manager_entry *entry = NULL;
1341 kumaneko 2002 struct ccs_policy_manager_entry *ptr;
1342     const struct ccs_path_info *saved_manager;
1343 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
1344 kumaneko 1006 bool is_domain = false;
1345 kumaneko 1052 if (ccs_is_domain_def(manager)) {
1346     if (!ccs_is_correct_domain(manager, __func__))
1347     return -EINVAL;
1348 kumaneko 1006 is_domain = true;
1349 kumaneko 111 } else {
1350 kumaneko 1052 if (!ccs_is_correct_path(manager, 1, -1, -1, __func__))
1351     return -EINVAL;
1352 kumaneko 111 }
1353 kumaneko 2540 saved_manager = ccs_get_name(manager);
1354 kumaneko 1052 if (!saved_manager)
1355     return -ENOMEM;
1356 kumaneko 2540 if (!is_delete)
1357     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
1358     /***** WRITER SECTION START *****/
1359     down_write(&ccs_policy_lock);
1360     list_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1361 kumaneko 1064 if (ptr->manager != saved_manager)
1362     continue;
1363     ptr->is_deleted = is_delete;
1364     error = 0;
1365 kumaneko 2540 break;
1366 kumaneko 111 }
1367 kumaneko 2540 if (!is_delete && error && ccs_memory_ok(entry)) {
1368     entry->manager = saved_manager;
1369     saved_manager = NULL;
1370     entry->is_domain = is_domain;
1371     list_add_tail(&entry->list, &ccs_policy_manager_list);
1372     entry = NULL;
1373     error = 0;
1374 kumaneko 111 }
1375 kumaneko 2540 up_write(&ccs_policy_lock);
1376     /***** WRITER SECTION END *****/
1377     ccs_put_name(saved_manager);
1378     kfree(entry);
1379 kumaneko 1052 if (!error)
1380     ccs_update_counter(CCS_UPDATES_COUNTER_MANAGER);
1381 kumaneko 111 return error;
1382     }
1383    
1384 kumaneko 1052 /**
1385 kumaneko 2002 * ccs_write_manager_policy - Write manager policy.
1386 kumaneko 1052 *
1387 kumaneko 1657 * @head: Pointer to "struct ccs_io_buffer".
1388 kumaneko 1052 *
1389     * Returns 0 on success, negative value otherwise.
1390     */
1391 kumaneko 2002 static int ccs_write_manager_policy(struct ccs_io_buffer *head)
1392 kumaneko 111 {
1393 kumaneko 1052 char *data = head->write_buf;
1394 kumaneko 2002 bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
1395 kumaneko 1064 if (!strcmp(data, "manage_by_non_root")) {
1396 kumaneko 2002 ccs_manage_by_non_root = !is_delete;
1397 kumaneko 1006 return 0;
1398     }
1399 kumaneko 2002 return ccs_update_manager_entry(data, is_delete);
1400 kumaneko 111 }
1401    
1402 kumaneko 1052 /**
1403 kumaneko 2002 * ccs_read_manager_policy - Read manager policy.
1404 kumaneko 1052 *
1405 kumaneko 1657 * @head: Pointer to "struct ccs_io_buffer".
1406 kumaneko 1052 *
1407     * Returns 0.
1408     */
1409 kumaneko 2002 static int ccs_read_manager_policy(struct ccs_io_buffer *head)
1410 kumaneko 111 {
1411 kumaneko 2540 struct list_head *pos;
1412     bool done = true;
1413 kumaneko 1052 if (head->read_eof)
1414     return 0;
1415 kumaneko 2540 /***** READER SECTION START *****/
1416     down_read(&ccs_policy_lock);
1417     list_for_each_cookie(pos, head->read_var2.u.list,
1418     &ccs_policy_manager_list) {
1419 kumaneko 2002 struct ccs_policy_manager_entry *ptr;
1420 kumaneko 2540 ptr = list_entry(pos, struct ccs_policy_manager_entry, list);
1421 kumaneko 1052 if (ptr->is_deleted)
1422     continue;
1423 kumaneko 2540 done = ccs_io_printf(head, "%s\n", ptr->manager->name);
1424     if (!done)
1425     break;
1426 kumaneko 111 }
1427 kumaneko 2540 up_read(&ccs_policy_lock);
1428     /***** READER SECTION END *****/
1429     head->read_eof = done;
1430 kumaneko 111 return 0;
1431     }
1432    
1433 kumaneko 1052 /**
1434 kumaneko 2002 * ccs_is_policy_manager - Check whether the current process is a policy manager.
1435 kumaneko 1052 *
1436     * Returns true if the current process is permitted to modify policy
1437     * via /proc/ccs/ interface.
1438     */
1439 kumaneko 2002 static bool ccs_is_policy_manager(void)
1440 kumaneko 111 {
1441 kumaneko 2002 struct ccs_policy_manager_entry *ptr;
1442 kumaneko 111 const char *exe;
1443 kumaneko 1578 struct task_struct *task = current;
1444 kumaneko 2282 const struct ccs_path_info *domainname
1445     = ccs_current_domain()->domainname;
1446 kumaneko 1006 bool found = false;
1447 kumaneko 2040 if (!ccs_policy_loaded)
1448 kumaneko 1052 return true;
1449 kumaneko 2282 if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)
1450 kumaneko 1578 return true;
1451 kumaneko 2016 if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
1452 kumaneko 1052 return false;
1453 kumaneko 2540 list_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1454 kumaneko 1052 if (!ptr->is_deleted && ptr->is_domain
1455 kumaneko 1578 && !ccs_pathcmp(domainname, ptr->manager)) {
1456     /* Set manager flag. */
1457 kumaneko 2282 task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
1458 kumaneko 1052 return true;
1459 kumaneko 1578 }
1460 kumaneko 111 }
1461 kumaneko 1052 exe = ccs_get_exe();
1462     if (!exe)
1463     return false;
1464 kumaneko 2540 list_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1465 kumaneko 1052 if (!ptr->is_deleted && !ptr->is_domain
1466     && !strcmp(exe, ptr->manager->name)) {
1467 kumaneko 1006 found = true;
1468 kumaneko 1578 /* Set manager flag. */
1469 kumaneko 2282 task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
1470 kumaneko 708 break;
1471     }
1472 kumaneko 111 }
1473 kumaneko 708 if (!found) { /* Reduce error messages. */
1474 kumaneko 2002 static pid_t ccs_last_pid;
1475 kumaneko 111 const pid_t pid = current->pid;
1476 kumaneko 2002 if (ccs_last_pid != pid) {
1477 kumaneko 1052 printk(KERN_WARNING "%s ( %s ) is not permitted to "
1478     "update policies.\n", domainname->name, exe);
1479 kumaneko 2002 ccs_last_pid = pid;
1480 kumaneko 111 }
1481     }
1482     ccs_free(exe);
1483 kumaneko 708 return found;
1484 kumaneko 111 }
1485    
1486     #ifdef CONFIG_TOMOYO
1487    
1488 kumaneko 1052 /**
1489     * ccs_find_condition_part - Find condition part from the statement.
1490     *
1491     * @data: String to parse.
1492     *
1493     * Returns pointer to the condition part if it was found in the statement,
1494     * NULL otherwise.
1495     */
1496     static char *ccs_find_condition_part(char *data)
1497 kumaneko 581 {
1498 kumaneko 1064 char *cp = strstr(data, " if ");
1499 kumaneko 581 if (cp) {
1500 kumaneko 1747 while (1) {
1501     char *cp2 = strstr(cp + 3, " if ");
1502     if (!cp2)
1503     break;
1504 kumaneko 1064 cp = cp2;
1505 kumaneko 1747 }
1506 kumaneko 581 *cp++ = '\0';
1507 kumaneko 1052 } else {
1508     cp = strstr(data, " ; set ");
1509     if (cp)
1510     *cp++ = '\0';
1511 kumaneko 581 }
1512     return cp;
1513     }
1514    
1515 kumaneko 1052 /**
1516 kumaneko 2002 * ccs_is_select_one - Parse select command.
1517 kumaneko 1609 *
1518     * @head: Pointer to "struct ccs_io_buffer".
1519     * @data: String to parse.
1520     *
1521     * Returns true on success, false otherwise.
1522     */
1523 kumaneko 2002 static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)
1524 kumaneko 1609 {
1525     unsigned int pid;
1526 kumaneko 2540 struct ccs_cookie *cookie = &head->write_var1;
1527 kumaneko 1926 if (!strcmp(data, "allow_execute")) {
1528     head->read_execute_only = true;
1529     return true;
1530     }
1531 kumaneko 1609 if (sscanf(data, "pid=%u", &pid) == 1) {
1532     struct task_struct *p;
1533 kumaneko 2544 cookie->u.domain = NULL;
1534 kumaneko 2540 /***** READER SECTION START *****/
1535     down_read(&ccs_policy_lock);
1536 kumaneko 1609 /***** CRITICAL SECTION START *****/
1537     read_lock(&tasklist_lock);
1538     p = find_task_by_pid(pid);
1539     if (p)
1540 kumaneko 2544 cookie->u.domain = ccs_task_domain(p);
1541 kumaneko 1609 read_unlock(&tasklist_lock);
1542     /***** CRITICAL SECTION END *****/
1543 kumaneko 2540 up_read(&ccs_policy_lock);
1544     /***** READER SECTION END *****/
1545 kumaneko 1609 } else if (!strncmp(data, "domain=", 7)) {
1546 kumaneko 2544 cookie->u.domain = NULL;
1547     if (ccs_is_domain_def(data + 7))
1548     ccs_find_domain(data + 7, cookie);
1549 kumaneko 1609 } else
1550     return false;
1551 kumaneko 1810 /* Accessing read_buf is safe because head->io_sem is held. */
1552 kumaneko 1809 if (!head->read_buf)
1553     return true; /* Do nothing if open(O_WRONLY). */
1554 kumaneko 2544 /***** READER SECTION START *****/
1555     down_read(&ccs_policy_lock);
1556     if (cookie->u.domain)
1557     head->read_var1.u.list = cookie->u.domain->list.prev;
1558     up_read(&ccs_policy_lock);
1559     /***** READER SECTION END *****/
1560 kumaneko 1609 head->read_avail = 0;
1561     ccs_io_printf(head, "# select %s\n", data);
1562     head->read_single_domain = true;
1563 kumaneko 2544 head->read_eof = !cookie->u.domain;
1564     head->read_var2.u.list = NULL;
1565     head->read_bit = 0;
1566     head->read_step = 0;
1567     if (cookie->u.domain && cookie->u.domain->is_deleted)
1568     ccs_io_printf(head, "# This is a deleted domain.\n");
1569 kumaneko 1609 return true;
1570     }
1571    
1572     /**
1573 kumaneko 2002 * ccs_write_domain_policy - Write domain policy.
1574 kumaneko 1052 *
1575     * @head: Pointer to "struct ccs_io_buffer".
1576     *
1577     * Returns 0 on success, negative value otherwise.
1578     */
1579 kumaneko 2002 static int ccs_write_domain_policy(struct ccs_io_buffer *head)
1580 kumaneko 111 {
1581     char *data = head->write_buf;
1582 kumaneko 2544 struct ccs_cookie *cookie = &head->write_var1;
1583 kumaneko 1064 bool is_delete = false;
1584     bool is_select = false;
1585 kumaneko 111 unsigned int profile;
1586 kumaneko 2002 const struct ccs_condition_list *cond = NULL;
1587 kumaneko 906 char *cp;
1588 kumaneko 2002 if (ccs_str_starts(&data, KEYWORD_DELETE))
1589 kumaneko 1006 is_delete = true;
1590 kumaneko 2002 else if (ccs_str_starts(&data, KEYWORD_SELECT))
1591 kumaneko 1006 is_select = true;
1592 kumaneko 2002 if (is_select && ccs_is_select_one(head, data))
1593 kumaneko 1609 return 0;
1594 kumaneko 1606 /* Don't allow updating policies by non manager programs. */
1595 kumaneko 2002 if (!ccs_is_policy_manager())
1596 kumaneko 1606 return -EPERM;
1597 kumaneko 1052 if (ccs_is_domain_def(data)) {
1598 kumaneko 2544 cookie->u.domain = NULL;
1599 kumaneko 2540 if (is_delete) {
1600 kumaneko 1052 ccs_delete_domain(data);
1601 kumaneko 2544 } else if (is_select)
1602 kumaneko 2540 ccs_find_domain(data, cookie);
1603 kumaneko 2544 else
1604 kumaneko 2540 ccs_find_or_assign_new_domain(data, 0, cookie);
1605 kumaneko 1052 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
1606 kumaneko 111 return 0;
1607     }
1608 kumaneko 2544 if (!cookie->u.domain)
1609 kumaneko 1052 return -EINVAL;
1610 kumaneko 581
1611 kumaneko 1052 if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1
1612     && profile < MAX_PROFILES) {
1613 kumaneko 2040 if (ccs_profile_ptr[profile] || !ccs_policy_loaded)
1614 kumaneko 2544 cookie->u.domain->profile = (u8) profile;
1615 kumaneko 581 return 0;
1616     }
1617 kumaneko 1052 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1618 kumaneko 2544 cookie->u.domain->ignore_global_allow_read = !is_delete;
1619 kumaneko 1007 return 0;
1620     }
1621 kumaneko 1052 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_ENV)) {
1622 kumaneko 2544 cookie->u.domain->ignore_global_allow_env = !is_delete;
1623 kumaneko 1007 return 0;
1624     }
1625 kumaneko 1052 cp = ccs_find_condition_part(data);
1626     if (cp) {
1627     cond = ccs_find_or_assign_new_condition(cp);
1628     if (!cond)
1629     return -EINVAL;
1630 kumaneko 111 }
1631 kumaneko 2002 if (ccs_str_starts(&data, KEYWORD_ALLOW_CAPABILITY))
1632 kumaneko 2544 return ccs_write_capability_policy(data, cookie->u.domain,
1633     cond, is_delete);
1634 kumaneko 2002 else if (ccs_str_starts(&data, KEYWORD_ALLOW_NETWORK))
1635 kumaneko 2544 return ccs_write_network_policy(data, cookie->u.domain, cond,
1636     is_delete);
1637 kumaneko 2002 else if (ccs_str_starts(&data, KEYWORD_ALLOW_SIGNAL))
1638 kumaneko 2544 return ccs_write_signal_policy(data, cookie->u.domain, cond,
1639     is_delete);
1640 kumaneko 2002 else if (ccs_str_starts(&data, KEYWORD_ALLOW_ARGV0))
1641 kumaneko 2544 return ccs_write_argv0_policy(data, cookie->u.domain, cond,
1642     is_delete);
1643 kumaneko 2002 else if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
1644 kumaneko 2544 return ccs_write_env_policy(data, cookie->u.domain, cond,
1645     is_delete);
1646 kumaneko 2271 else if (ccs_str_starts(&data, KEYWORD_ALLOW_IOCTL))
1647 kumaneko 2544 return ccs_write_ioctl_policy(data, cookie->u.domain, cond,
1648     is_delete);
1649 kumaneko 1052 else
1650 kumaneko 2544 return ccs_write_file_policy(data, cookie->u.domain, cond,
1651     is_delete);
1652 kumaneko 111 }
1653    
1654 kumaneko 1052 /**
1655 kumaneko 2002 * ccs_print_single_path_acl - Print a single path ACL entry.
1656 kumaneko 1052 *
1657     * @head: Pointer to "struct ccs_io_buffer".
1658 kumaneko 2002 * @ptr: Pointer to "struct ccs_single_path_acl_record".
1659     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1660 kumaneko 1052 *
1661     * Returns true on success, false otherwise.
1662     */
1663 kumaneko 2002 static bool ccs_print_single_path_acl(struct ccs_io_buffer *head,
1664     struct ccs_single_path_acl_record *ptr,
1665     const struct ccs_condition_list *cond)
1666 kumaneko 856 {
1667     int pos;
1668     u8 bit;
1669 kumaneko 1052 const char *atmark = "";
1670     const char *filename;
1671 kumaneko 856 const u16 perm = ptr->perm;
1672 kumaneko 1052 if (ptr->u_is_group) {
1673     atmark = "@";
1674     filename = ptr->u.group->group_name->name;
1675     } else {
1676     filename = ptr->u.filename->name;
1677     }
1678 kumaneko 856 for (bit = head->read_bit; bit < MAX_SINGLE_PATH_OPERATION; bit++) {
1679     const char *msg;
1680 kumaneko 1052 if (!(perm & (1 << bit)))
1681     continue;
1682 kumaneko 1926 if (head->read_execute_only && bit != TYPE_EXECUTE_ACL)
1683     continue;
1684 kumaneko 856 /* Print "read/write" instead of "read" and "write". */
1685 kumaneko 1052 if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)
1686     && (perm & (1 << TYPE_READ_WRITE_ACL)))
1687     continue;
1688     msg = ccs_sp2keyword(bit);
1689 kumaneko 856 pos = head->read_avail;
1690 kumaneko 1052 if (!ccs_io_printf(head, "allow_%s %s%s", msg,
1691     atmark, filename) ||
1692 kumaneko 1054 !ccs_print_condition(head, cond))
1693 kumaneko 1052 goto out;
1694 kumaneko 856 }
1695     head->read_bit = 0;
1696 kumaneko 1006 return true;
1697 kumaneko 856 out:
1698     head->read_bit = bit;
1699     head->read_avail = pos;
1700 kumaneko 1006 return false;
1701 kumaneko 856 }
1702    
1703 kumaneko 1052 /**
1704 kumaneko 2002 * ccs_print_double_path_acl - Print a double path ACL entry.
1705 kumaneko 1052 *
1706     * @head: Pointer to "struct ccs_io_buffer".
1707 kumaneko 2002 * @ptr: Pointer to "struct ccs_double_path_acl_record".
1708     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1709 kumaneko 1052 *
1710     * Returns true on success, false otherwise.
1711     */
1712 kumaneko 2002 static bool ccs_print_double_path_acl(struct ccs_io_buffer *head,
1713     struct ccs_double_path_acl_record *ptr,
1714     const struct ccs_condition_list *cond)
1715 kumaneko 856 {
1716     int pos;
1717 kumaneko 1052 const char *atmark1 = "";
1718     const char *atmark2 = "";
1719     const char *filename1;
1720     const char *filename2;
1721 kumaneko 856 const u8 perm = ptr->perm;
1722     u8 bit;
1723 kumaneko 1052 if (ptr->u1_is_group) {
1724     atmark1 = "@";
1725     filename1 = ptr->u1.group1->group_name->name;
1726     } else {
1727     filename1 = ptr->u1.filename1->name;
1728     }
1729     if (ptr->u2_is_group) {
1730     atmark2 = "@";
1731     filename2 = ptr->u2.group2->group_name->name;
1732     } else {
1733     filename2 = ptr->u2.filename2->name;
1734     }
1735 kumaneko 856 for (bit = head->read_bit; bit < MAX_DOUBLE_PATH_OPERATION; bit++) {
1736     const char *msg;
1737 kumaneko 1052 if (!(perm & (1 << bit)))
1738     continue;
1739     msg = ccs_dp2keyword(bit);
1740 kumaneko 856 pos = head->read_avail;
1741 kumaneko 1052 if (!ccs_io_printf(head, "allow_%s %s%s %s%s", msg,
1742 kumaneko 1064 atmark1, filename1, atmark2, filename2) ||
1743 kumaneko 1054 !ccs_print_condition(head, cond))
1744 kumaneko 1052 goto out;
1745 kumaneko 856 }
1746 kumaneko 1032 head->read_bit = 0;
1747 kumaneko 1006 return true;
1748 kumaneko 856 out:
1749     head->read_bit = bit;
1750     head->read_avail = pos;
1751 kumaneko 1006 return false;
1752 kumaneko 856 }
1753    
1754 kumaneko 1052 /**
1755 kumaneko 2271 * ccs_print_ioctl_acl - Print an ioctl ACL entry.
1756     *
1757     * @head: Pointer to "struct ccs_io_buffer".
1758     * @ptr: Pointer to "struct ccs_ioctl_acl_record".
1759     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1760     *
1761     * Returns true on success, false otherwise.
1762     */
1763     static bool ccs_print_ioctl_acl(struct ccs_io_buffer *head,
1764     struct ccs_ioctl_acl_record *ptr,
1765     const struct ccs_condition_list *cond)
1766     {
1767     int pos = head->read_avail;
1768     const char *atmark = "";
1769     const char *filename;
1770     const unsigned int cmd_min = ptr->cmd_min;
1771     const unsigned int cmd_max = ptr->cmd_max;
1772     if (ptr->u_is_group) {
1773     atmark = "@";
1774     filename = ptr->u.group->group_name->name;
1775     } else {
1776     filename = ptr->u.filename->name;
1777     }
1778     if (!ccs_io_printf(head, KEYWORD_ALLOW_IOCTL "%s%s ", atmark, filename))
1779     goto out;
1780     if (!ccs_io_printf(head, "%u", cmd_min))
1781     goto out;
1782     if (cmd_min != cmd_max && !ccs_io_printf(head, "-%u", cmd_max))
1783     goto out;
1784     if (!ccs_print_condition(head, cond))
1785     goto out;
1786     return true;
1787     out:
1788     head->read_avail = pos;
1789     return false;
1790     }
1791    
1792     /**
1793 kumaneko 2002 * ccs_print_argv0_acl - Print an argv[0] ACL entry.
1794 kumaneko 1052 *
1795     * @head: Pointer to "struct ccs_io_buffer".
1796 kumaneko 2002 * @ptr: Pointer to "struct ccs_argv0_acl_record".
1797     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1798 kumaneko 1052 *
1799     * Returns true on success, false otherwise.
1800     */
1801 kumaneko 2002 static bool ccs_print_argv0_acl(struct ccs_io_buffer *head,
1802     struct ccs_argv0_acl_record *ptr,
1803     const struct ccs_condition_list *cond)
1804 kumaneko 856 {
1805     int pos = head->read_avail;
1806 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
1807     ptr->filename->name, ptr->argv0->name))
1808     goto out;
1809 kumaneko 1054 if (!ccs_print_condition(head, cond))
1810 kumaneko 1052 goto out;
1811 kumaneko 1006 return true;
1812 kumaneko 856 out:
1813     head->read_avail = pos;
1814 kumaneko 1006 return false;
1815 kumaneko 856 }
1816    
1817 kumaneko 1052 /**
1818 kumaneko 2002 * ccs_print_env_acl - Print an evironment variable name's ACL entry.
1819 kumaneko 1052 *
1820     * @head: Pointer to "struct ccs_io_buffer".
1821 kumaneko 2002 * @ptr: Pointer to "struct ccs_env_acl_record".
1822     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1823 kumaneko 1052 *
1824     * Returns true on success, false otherwise.
1825     */
1826 kumaneko 2002 static bool ccs_print_env_acl(struct ccs_io_buffer *head,
1827     struct ccs_env_acl_record *ptr,
1828     const struct ccs_condition_list *cond)
1829 kumaneko 856 {
1830     int pos = head->read_avail;
1831 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))
1832     goto out;
1833 kumaneko 1054 if (!ccs_print_condition(head, cond))
1834 kumaneko 1052 goto out;
1835 kumaneko 1006 return true;
1836 kumaneko 856 out:
1837     head->read_avail = pos;
1838 kumaneko 1006 return false;
1839 kumaneko 856 }
1840    
1841 kumaneko 1052 /**
1842 kumaneko 2002 * ccs_print_capability_acl - Print a capability ACL entry.
1843 kumaneko 1052 *
1844     * @head: Pointer to "struct ccs_io_buffer".
1845 kumaneko 2002 * @ptr: Pointer to "struct ccs_capability_acl_record".
1846     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1847 kumaneko 1052 *
1848     * Returns true on success, false otherwise.
1849     */
1850 kumaneko 2002 static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
1851     struct ccs_capability_acl_record *ptr,
1852     const struct ccs_condition_list *cond)
1853 kumaneko 856 {
1854 kumaneko 860 int pos = head->read_avail;
1855 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",
1856     ccs_cap2keyword(ptr->operation)))
1857     goto out;
1858 kumaneko 1054 if (!ccs_print_condition(head, cond))
1859 kumaneko 1052 goto out;
1860 kumaneko 1006 return true;
1861 kumaneko 856 out:
1862     head->read_avail = pos;
1863 kumaneko 1006 return false;
1864 kumaneko 856 }
1865    
1866 kumaneko 1052 /**
1867 kumaneko 2002 * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
1868 kumaneko 1052 *
1869     * @head: Pointer to "struct ccs_io_buffer".
1870 kumaneko 2002 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1871 kumaneko 1052 *
1872     * Returns true on success, false otherwise.
1873     */
1874 kumaneko 2002 static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
1875     struct ccs_ip_network_acl_record *ptr)
1876 kumaneko 856 {
1877 kumaneko 1052 const u32 min_address = ptr->u.ipv4.min;
1878     const u32 max_address = ptr->u.ipv4.max;
1879     if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
1880     return false;
1881     if (min_address != max_address
1882     && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
1883     return false;
1884     return true;
1885     }
1886    
1887     /**
1888 kumaneko 2002 * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
1889 kumaneko 1052 *
1890     * @head: Pointer to "struct ccs_io_buffer".
1891 kumaneko 2002 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1892 kumaneko 1052 *
1893     * Returns true on success, false otherwise.
1894     */
1895 kumaneko 2002 static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
1896     struct ccs_ip_network_acl_record *ptr)
1897 kumaneko 1052 {
1898     char buf[64];
1899     const struct in6_addr *min_address = ptr->u.ipv6.min;
1900     const struct in6_addr *max_address = ptr->u.ipv6.max;
1901     ccs_print_ipv6(buf, sizeof(buf), min_address);
1902     if (!ccs_io_printf(head, "%s", buf))
1903     return false;
1904     if (min_address != max_address) {
1905     ccs_print_ipv6(buf, sizeof(buf), max_address);
1906     if (!ccs_io_printf(head, "-%s", buf))
1907     return false;
1908     }
1909     return true;
1910     }
1911    
1912     /**
1913 kumaneko 2002 * ccs_print_port_entry - Print port number of a network ACL entry.
1914 kumaneko 1052 *
1915     * @head: Pointer to "struct ccs_io_buffer".
1916 kumaneko 2002 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1917 kumaneko 1052 *
1918     * Returns true on success, false otherwise.
1919     */
1920 kumaneko 2002 static bool ccs_print_port_entry(struct ccs_io_buffer *head,
1921     struct ccs_ip_network_acl_record *ptr)
1922 kumaneko 1052 {
1923 kumaneko 2046 const u16 min_port = ptr->min_port;
1924     const u16 max_port = ptr->max_port;
1925 kumaneko 1052 if (!ccs_io_printf(head, " %u", min_port))
1926     return false;
1927     if (min_port != max_port && !ccs_io_printf(head, "-%u", max_port))
1928     return false;
1929     return true;
1930     }
1931    
1932     /**
1933 kumaneko 2002 * ccs_print_network_acl - Print a network ACL entry.
1934 kumaneko 1052 *
1935     * @head: Pointer to "struct ccs_io_buffer".
1936 kumaneko 2002 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1937     * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1938 kumaneko 1052 *
1939     * Returns true on success, false otherwise.
1940     */
1941 kumaneko 2002 static bool ccs_print_network_acl(struct ccs_io_buffer *head,
1942     struct ccs_ip_network_acl_record *ptr,
1943     const struct ccs_condition_list *cond)
1944 kumaneko 1052 {
1945 kumaneko 856 int pos = head->read_avail;
1946 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",
1947     ccs_net2keyword(ptr->operation_type)))
1948     goto out;
1949 kumaneko 856 switch (ptr->record_type) {
1950     case IP_RECORD_TYPE_ADDRESS_GROUP:
1951 kumaneko 1052 if (!ccs_io_printf(head, "@%s", ptr->u.group->group_name->name))
1952     goto out;
1953 kumaneko 856 break;
1954     case IP_RECORD_TYPE_IPv4:
1955 kumaneko 2002 if (!ccs_print_ipv4_entry(head, ptr))
1956 kumaneko 1052 goto out;
1957 kumaneko 856 break;
1958     case IP_RECORD_TYPE_IPv6:
1959 kumaneko 2002 if (!ccs_print_ipv6_entry(head, ptr))
1960 kumaneko 1052 goto out;
1961 kumaneko 856 break;
1962     }
1963 kumaneko 2002 if (!ccs_print_port_entry(head, ptr))
1964 kumaneko 1052 goto out;
1965 kumaneko 1054 if (!ccs_print_condition(head, cond))
1966 kumaneko 1052 goto out;
1967 kumaneko 1006 return true;
1968 kumaneko 856 out:
1969     head->read_avail = pos;
1970 kumaneko 1006 return false;
1971 kumaneko 856 }
1972    
1973 kumaneko 1052 /**
1974 kumaneko 2002 * ccs_print_signal_acl - Print a signal ACL entry.
1975 kumaneko 1052 *
1976     * @head: Pointer to "struct ccs_io_buffer".
1977     * @ptr: Pointer to "struct signale_acl_record".
1978 kumaneko 2002 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1979 kumaneko 1052 *
1980     * Returns true on success, false otherwise.
1981     */
1982 kumaneko 2002 static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
1983     struct ccs_signal_acl_record *ptr,
1984     const struct ccs_condition_list *cond)
1985 kumaneko 856 {
1986     int pos = head->read_avail;
1987 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",
1988     ptr->sig, ptr->domainname->name))
1989     goto out;
1990 kumaneko 1054 if (!ccs_print_condition(head, cond))
1991 kumaneko 1052 goto out;
1992 kumaneko 1006 return true;
1993 kumaneko 856 out:
1994     head->read_avail = pos;
1995 kumaneko 1006 return false;
1996 kumaneko 856 }
1997    
1998 kumaneko 1052 /**
1999 kumaneko 2002 * ccs_print_execute_handler_record - Print an execute handler ACL entry.
2000 kumaneko 1052 *
2001     * @head: Pointer to "struct ccs_io_buffer".
2002     * @keyword: Name of the keyword.
2003 kumaneko 2002 * @ptr: Pointer to "struct ccs_execute_handler_record".
2004 kumaneko 1052 *
2005     * Returns true on success, false otherwise.
2006     */
2007 kumaneko 2002 static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
2008     const char *keyword,
2009     struct ccs_execute_handler_record *
2010     ptr)
2011 kumaneko 1029 {
2012 kumaneko 1052 return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
2013 kumaneko 1029 }
2014    
2015 kumaneko 1052 /**
2016 kumaneko 2002 * ccs_print_entry - Print an ACL entry.
2017 kumaneko 1052 *
2018     * @head: Pointer to "struct ccs_io_buffer".
2019     * @ptr: Pointer to an ACL entry.
2020     *
2021     * Returns true on success, false otherwise.
2022     */
2023 kumaneko 2002 static bool ccs_print_entry(struct ccs_io_buffer *head,
2024     struct ccs_acl_info *ptr)
2025 kumaneko 111 {
2026 kumaneko 2544 const struct ccs_condition_list *cond = ptr->cond;
2027 kumaneko 2540 const u8 acl_type = ptr->type;
2028 kumaneko 1052 if (acl_type & ACL_DELETED)
2029     return true;
2030     if (acl_type == TYPE_SINGLE_PATH_ACL) {
2031 kumaneko 2002 struct ccs_single_path_acl_record *acl
2032     = container_of(ptr, struct ccs_single_path_acl_record,
2033 kumaneko 1052 head);
2034 kumaneko 2002 return ccs_print_single_path_acl(head, acl, cond);
2035 kumaneko 1052 }
2036 kumaneko 1926 if (acl_type == TYPE_EXECUTE_HANDLER) {
2037 kumaneko 2002 struct ccs_execute_handler_record *acl
2038     = container_of(ptr, struct ccs_execute_handler_record,
2039 kumaneko 1926 head);
2040     const char *keyword = KEYWORD_EXECUTE_HANDLER;
2041 kumaneko 2002 return ccs_print_execute_handler_record(head, keyword, acl);
2042 kumaneko 1926 }
2043     if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {
2044 kumaneko 2002 struct ccs_execute_handler_record *acl
2045     = container_of(ptr, struct ccs_execute_handler_record,
2046 kumaneko 1926 head);
2047     const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;
2048 kumaneko 2002 return ccs_print_execute_handler_record(head, keyword, acl);
2049 kumaneko 1926 }
2050     if (head->read_execute_only)
2051     return true;
2052 kumaneko 1052 if (acl_type == TYPE_DOUBLE_PATH_ACL) {
2053 kumaneko 2002 struct ccs_double_path_acl_record *acl
2054     = container_of(ptr, struct ccs_double_path_acl_record,
2055 kumaneko 1052 head);
2056 kumaneko 2002 return ccs_print_double_path_acl(head, acl, cond);
2057 kumaneko 1052 }
2058 kumaneko 2271 if (acl_type == TYPE_IOCTL_ACL) {
2059     struct ccs_ioctl_acl_record *acl
2060     = container_of(ptr, struct ccs_ioctl_acl_record, head);
2061     return ccs_print_ioctl_acl(head, acl, cond);
2062     }
2063 kumaneko 1052 if (acl_type == TYPE_ARGV0_ACL) {
2064 kumaneko 2002 struct ccs_argv0_acl_record *acl
2065     = container_of(ptr, struct ccs_argv0_acl_record, head);
2066     return ccs_print_argv0_acl(head, acl, cond);
2067 kumaneko 1052 }
2068     if (acl_type == TYPE_ENV_ACL) {
2069 kumaneko 2002 struct ccs_env_acl_record *acl
2070     = container_of(ptr, struct ccs_env_acl_record, head);
2071     return ccs_print_env_acl(head, acl, cond);
2072 kumaneko 1052 }
2073     if (acl_type == TYPE_CAPABILITY_ACL) {
2074 kumaneko 2002 struct ccs_capability_acl_record *acl
2075     = container_of(ptr, struct ccs_capability_acl_record,
2076     head);
2077     return ccs_print_capability_acl(head, acl, cond);
2078 kumaneko 1052 }
2079     if (acl_type == TYPE_IP_NETWORK_ACL) {
2080 kumaneko 2002 struct ccs_ip_network_acl_record *acl
2081     = container_of(ptr, struct ccs_ip_network_acl_record,
2082     head);
2083     return ccs_print_network_acl(head, acl, cond);
2084 kumaneko 1052 }
2085     if (acl_type == TYPE_SIGNAL_ACL) {
2086 kumaneko 2002 struct ccs_signal_acl_record *acl
2087     = container_of(ptr, struct ccs_signal_acl_record, head);
2088     return ccs_print_signal_acl(head, acl, cond);
2089 kumaneko 1052 }
2090 kumaneko 1120 /* Workaround for gcc 3.2.2's inline bug. */
2091     if (acl_type & ACL_DELETED)
2092     return true;
2093 kumaneko 1052 BUG(); /* This must not happen. */
2094     return false;
2095     }
2096    
2097     /**
2098 kumaneko 2002 * ccs_read_domain_policy - Read domain policy.
2099 kumaneko 1052 *
2100     * @head: Pointer to "struct ccs_io_buffer".
2101     *
2102     * Returns 0.
2103     */
2104 kumaneko 2002 static int ccs_read_domain_policy(struct ccs_io_buffer *head)
2105 kumaneko 1052 {
2106 kumaneko 2540 struct list_head *dpos;
2107     struct list_head *apos;
2108 kumaneko 1052 if (head->read_eof)
2109     return 0;
2110     if (head->read_step == 0)
2111     head->read_step = 1;
2112 kumaneko 2540 list_for_each_cookie(dpos, head->read_var1.u.list, &ccs_domain_list) {
2113 kumaneko 2282 struct ccs_domain_info *domain;
2114 kumaneko 1052 const char *quota_exceeded = "";
2115 kumaneko 1180 const char *transition_failed = "";
2116 kumaneko 1052 const char *ignore_global_allow_read = "";
2117     const char *ignore_global_allow_env = "";
2118 kumaneko 2540 domain = list_entry(dpos, struct ccs_domain_info, list);
2119 kumaneko 1052 if (head->read_step != 1)
2120     goto acl_loop;
2121 kumaneko 1609 if (domain->is_deleted && !head->read_single_domain)
2122     continue;
2123 kumaneko 1054 /* Print domainname and flags. */
2124 kumaneko 1052 if (domain->quota_warned)
2125     quota_exceeded = "quota_exceeded\n";
2126 kumaneko 2540 if (domain->domain_transition_failed)
2127 kumaneko 1180 transition_failed = "transition_failed\n";
2128 kumaneko 2540 if (domain->ignore_global_allow_read)
2129 kumaneko 1052 ignore_global_allow_read
2130     = KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
2131 kumaneko 2540 if (domain->ignore_global_allow_env)
2132 kumaneko 1052 ignore_global_allow_env
2133     = KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
2134 kumaneko 1609 if (!ccs_io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n"
2135     "%s%s%s%s\n", domain->domainname->name,
2136     domain->profile, quota_exceeded,
2137     transition_failed,
2138 kumaneko 1052 ignore_global_allow_read,
2139     ignore_global_allow_env))
2140     return 0;
2141 kumaneko 708 head->read_step = 2;
2142 kumaneko 2041 acl_loop:
2143 kumaneko 1052 if (head->read_step == 3)
2144     goto tail_mark;
2145 kumaneko 1054 /* Print ACL entries in the domain. */
2146 kumaneko 2540 list_for_each_cookie(apos, head->read_var2.u.list,
2147 kumaneko 1052 &domain->acl_info_list) {
2148 kumaneko 2002 struct ccs_acl_info *ptr
2149 kumaneko 2540 = list_entry(apos, struct ccs_acl_info, list);
2150 kumaneko 2002 if (!ccs_print_entry(head, ptr))
2151 kumaneko 1052 return 0;
2152 kumaneko 111 }
2153 kumaneko 708 head->read_step = 3;
2154 kumaneko 2041 tail_mark:
2155 kumaneko 1052 if (!ccs_io_printf(head, "\n"))
2156     return 0;
2157 kumaneko 708 head->read_step = 1;
2158 kumaneko 1606 if (head->read_single_domain)
2159     break;
2160 kumaneko 111 }
2161 kumaneko 1006 head->read_eof = true;
2162 kumaneko 111 return 0;
2163     }
2164    
2165 kumaneko 461 #endif
2166    
2167 kumaneko 1052 /**
2168 kumaneko 2002 * ccs_write_domain_profile - Assign profile for specified domain.
2169 kumaneko 1052 *
2170     * @head: Pointer to "struct ccs_io_buffer".
2171     *
2172     * Returns 0 on success, -EINVAL otherwise.
2173     */
2174 kumaneko 2002 static int ccs_write_domain_profile(struct ccs_io_buffer *head)
2175 kumaneko 461 {
2176     char *data = head->write_buf;
2177     char *cp = strchr(data, ' ');
2178 kumaneko 2540 struct ccs_cookie cookie;
2179 kumaneko 461 unsigned int profile;
2180 kumaneko 1052 if (!cp)
2181     return -EINVAL;
2182 kumaneko 461 *cp = '\0';
2183     profile = simple_strtoul(data, NULL, 10);
2184 kumaneko 2540 if (profile >= MAX_PROFILES)
2185     return -EINVAL;
2186 kumaneko 2544 ccs_add_cookie(&cookie, NULL);
2187 kumaneko 2540 if (ccs_find_domain(cp + 1, &cookie) &&
2188     (ccs_profile_ptr[profile] || !ccs_policy_loaded))
2189     cookie.u.domain->profile = (u8) profile;
2190 kumaneko 2544 ccs_del_cookie(&cookie);
2191 kumaneko 1052 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
2192 kumaneko 461 return 0;
2193     }
2194    
2195 kumaneko 1052 /**
2196 kumaneko 2002 * ccs_read_domain_profile - Read only domainname and profile.
2197 kumaneko 1052 *
2198     * @head: Pointer to "struct ccs_io_buffer".
2199     *
2200     * Returns list of profile number and domainname pairs.
2201     */
2202 kumaneko 2002 static int ccs_read_domain_profile(struct ccs_io_buffer *head)
2203 kumaneko 111 {
2204 kumaneko 2540 struct list_head *pos;
2205 kumaneko 1052 if (head->read_eof)
2206     return 0;
2207 kumaneko 2540 list_for_each_cookie(pos, head->read_var1.u.list, &ccs_domain_list) {
2208 kumaneko 2282 struct ccs_domain_info *domain;
2209 kumaneko 2540 domain = list_entry(pos, struct ccs_domain_info, list);
2210 kumaneko 1052 if (domain->is_deleted)
2211     continue;
2212     if (!ccs_io_printf(head, "%u %s\n", domain->profile,
2213     domain->domainname->name))
2214     return 0;
2215 kumaneko 111 }
2216 kumaneko 1006 head->read_eof = true;
2217 kumaneko 111 return 0;
2218     }
2219    
2220 kumaneko 1052 /**
2221 kumaneko 2002 * ccs_write_pid: Specify PID to obtain domainname.
2222 kumaneko 1052 *
2223     * @head: Pointer to "struct ccs_io_buffer".
2224     *
2225     * Returns 0.
2226     */
2227 kumaneko 2002 static int ccs_write_pid(struct ccs_io_buffer *head)
2228 kumaneko 111 {
2229 kumaneko 1006 head->read_eof = false;
2230 kumaneko 111 return 0;
2231     }
2232    
2233 kumaneko 1052 /**
2234 kumaneko 2002 * ccs_read_pid - Read information of a process.
2235 kumaneko 1052 *
2236     * @head: Pointer to "struct ccs_io_buffer".
2237     *
2238 kumaneko 1705 * Returns the domainname which the specified PID is in or
2239     * process information of the specified PID on success,
2240 kumaneko 1052 * empty string otherwise.
2241     */
2242 kumaneko 2002 static int ccs_read_pid(struct ccs_io_buffer *head)
2243 kumaneko 111 {
2244 kumaneko 1705 char *buf = head->write_buf;
2245     bool task_info = false;
2246     unsigned int pid;
2247     struct task_struct *p;
2248 kumaneko 2282 struct ccs_domain_info *domain = NULL;
2249     u32 ccs_flags = 0;
2250 kumaneko 1810 /* Accessing write_buf is safe because head->io_sem is held. */
2251 kumaneko 1809 if (!buf)
2252     goto done; /* Do nothing if open(O_RDONLY). */
2253 kumaneko 1705 if (head->read_avail || head->read_eof)
2254     goto done;
2255     head->read_eof = true;
2256 kumaneko 2002 if (ccs_str_starts(&buf, "info "))
2257 kumaneko 1705 task_info = true;
2258     pid = (unsigned int) simple_strtoul(buf, NULL, 10);
2259 kumaneko 2540 /***** READER SECTION START *****/
2260     down_read(&ccs_policy_lock);
2261 kumaneko 1705