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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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