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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1645 - (hide annotations) (download) (as text)
Thu Oct 2 05:35:20 2008 UTC (15 years, 7 months ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 84921 byte(s)


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