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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1377 - (hide annotations) (download) (as text)
Tue Jul 8 09:55:46 2008 UTC (15 years, 10 months ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 82841 byte(s)
Don't check permissions if vfsmount is NULL.
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 1377 * Version: 1.6.3-pre 2008/07/08
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14    
15 kumaneko 1255 #include <linux/version.h>
16     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
17     #define __KERNEL_SYSCALLS__
18     #endif
19 kumaneko 111 #include <linux/string.h>
20     #include <linux/mm.h>
21     #include <linux/utime.h>
22     #include <linux/file.h>
23     #include <linux/module.h>
24     #include <linux/slab.h>
25     #include <asm/uaccess.h>
26     #include <stdarg.h>
27 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
28 kumaneko 111 #include <linux/namei.h>
29     #include <linux/mount.h>
30     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     return (c >= '0' && c <= '9');
193     }
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     return ((c >= '0' && c <= '9') ||
205     (c >= 'A' && c <= 'F') ||
206     (c >= 'a' && c <= 'f'));
207     }
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     return ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
219     }
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 111 return (filename == filename_end && pattern == pattern_end);
674     }
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     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 1006 const struct task_struct *task = current;
1367     const struct path_info *domainname = task->domain_info->domainname;
1368     bool found = false;
1369 kumaneko 1052 if (!sbin_init_started)
1370     return true;
1371     if (!manage_by_non_root && (task->uid || task->euid))
1372     return false;
1373 kumaneko 722 list1_for_each_entry(ptr, &policy_manager_list, list) {
1374 kumaneko 1052 if (!ptr->is_deleted && ptr->is_domain
1375     && !ccs_pathcmp(domainname, ptr->manager))
1376     return true;
1377 kumaneko 111 }
1378 kumaneko 1052 exe = ccs_get_exe();
1379     if (!exe)
1380     return false;
1381 kumaneko 722 list1_for_each_entry(ptr, &policy_manager_list, list) {
1382 kumaneko 1052 if (!ptr->is_deleted && !ptr->is_domain
1383     && !strcmp(exe, ptr->manager->name)) {
1384 kumaneko 1006 found = true;
1385 kumaneko 708 break;
1386     }
1387 kumaneko 111 }
1388 kumaneko 708 if (!found) { /* Reduce error messages. */
1389 kumaneko 1052 static pid_t last_pid;
1390 kumaneko 111 const pid_t pid = current->pid;
1391     if (last_pid != pid) {
1392 kumaneko 1052 printk(KERN_WARNING "%s ( %s ) is not permitted to "
1393     "update policies.\n", domainname->name, exe);
1394 kumaneko 111 last_pid = pid;
1395     }
1396     }
1397     ccs_free(exe);
1398 kumaneko 708 return found;
1399 kumaneko 111 }
1400    
1401     #ifdef CONFIG_TOMOYO
1402    
1403 kumaneko 1052 /**
1404     * ccs_find_condition_part - Find condition part from the statement.
1405     *
1406     * @data: String to parse.
1407     *
1408     * Returns pointer to the condition part if it was found in the statement,
1409     * NULL otherwise.
1410     */
1411     static char *ccs_find_condition_part(char *data)
1412 kumaneko 581 {
1413 kumaneko 1064 char *cp = strstr(data, " if ");
1414 kumaneko 581 if (cp) {
1415 kumaneko 1064 char *cp2;
1416     while ((cp2 = strstr(cp + 3, " if ")) != NULL)
1417     cp = cp2;
1418 kumaneko 581 *cp++ = '\0';
1419 kumaneko 1052 } else {
1420     cp = strstr(data, " ; set ");
1421     if (cp)
1422     *cp++ = '\0';
1423 kumaneko 581 }
1424     return cp;
1425     }
1426    
1427 kumaneko 1052 /**
1428     * write_domain_policy - Write domain policy.
1429     *
1430     * @head: Pointer to "struct ccs_io_buffer".
1431     *
1432     * Returns 0 on success, negative value otherwise.
1433     */
1434     static int write_domain_policy(struct ccs_io_buffer *head)
1435 kumaneko 111 {
1436     char *data = head->write_buf;
1437     struct domain_info *domain = head->write_var1;
1438 kumaneko 1064 bool is_delete = false;
1439     bool is_select = false;
1440     bool is_undelete = false;
1441 kumaneko 111 unsigned int profile;
1442 kumaneko 581 const struct condition_list *cond = NULL;
1443 kumaneko 906 char *cp;
1444 kumaneko 1052 if (str_starts(&data, KEYWORD_DELETE))
1445 kumaneko 1006 is_delete = true;
1446 kumaneko 1052 else if (str_starts(&data, KEYWORD_SELECT))
1447 kumaneko 1006 is_select = true;
1448 kumaneko 1052 else if (str_starts(&data, KEYWORD_UNDELETE))
1449 kumaneko 1006 is_undelete = true;
1450 kumaneko 1052 if (ccs_is_domain_def(data)) {
1451 kumaneko 1064 domain = NULL;
1452     if (is_delete)
1453 kumaneko 1052 ccs_delete_domain(data);
1454 kumaneko 1064 else if (is_select)
1455 kumaneko 1052 domain = ccs_find_domain(data);
1456 kumaneko 1064 else if (is_undelete)
1457 kumaneko 1052 domain = ccs_undelete_domain(data);
1458 kumaneko 1064 else
1459 kumaneko 1052 domain = ccs_find_or_assign_new_domain(data, 0);
1460 kumaneko 111 head->write_var1 = domain;
1461 kumaneko 1052 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
1462 kumaneko 111 return 0;
1463     }
1464 kumaneko 1052 if (!domain)
1465     return -EINVAL;
1466 kumaneko 581
1467 kumaneko 1052 if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1
1468     && profile < MAX_PROFILES) {
1469     if (profile_ptr[profile] || !sbin_init_started)
1470     domain->profile = (u8) profile;
1471 kumaneko 581 return 0;
1472     }
1473 kumaneko 1052 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1474     ccs_set_domain_flag(domain, is_delete,
1475     DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
1476 kumaneko 1007 return 0;
1477     }
1478 kumaneko 1052 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_ENV)) {
1479     ccs_set_domain_flag(domain, is_delete,
1480     DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV);
1481 kumaneko 1007 return 0;
1482     }
1483 kumaneko 1052 cp = ccs_find_condition_part(data);
1484     if (cp) {
1485     cond = ccs_find_or_assign_new_condition(cp);
1486     if (!cond)
1487     return -EINVAL;
1488 kumaneko 111 }
1489 kumaneko 1052 if (str_starts(&data, KEYWORD_ALLOW_CAPABILITY))
1490     return ccs_write_capability_policy(data, domain, cond,
1491     is_delete);
1492     else if (str_starts(&data, KEYWORD_ALLOW_NETWORK))
1493     return ccs_write_network_policy(data, domain, cond, is_delete);
1494     else if (str_starts(&data, KEYWORD_ALLOW_SIGNAL))
1495     return ccs_write_signal_policy(data, domain, cond, is_delete);
1496     else if (str_starts(&data, KEYWORD_ALLOW_ARGV0))
1497     return ccs_write_argv0_policy(data, domain, cond, is_delete);
1498     else if (str_starts(&data, KEYWORD_ALLOW_ENV))
1499     return ccs_write_env_policy(data, domain, cond, is_delete);
1500     else
1501     return ccs_write_file_policy(data, domain, cond, is_delete);
1502 kumaneko 111 }
1503    
1504 kumaneko 1052 /**
1505 kumaneko 1054 * print_single_path_acl - Print a single path ACL entry.
1506 kumaneko 1052 *
1507     * @head: Pointer to "struct ccs_io_buffer".
1508     * @ptr: Pointer to "struct single_path_acl_record".
1509 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1510 kumaneko 1052 *
1511     * Returns true on success, false otherwise.
1512     */
1513     static bool print_single_path_acl(struct ccs_io_buffer *head,
1514     struct single_path_acl_record *ptr,
1515     const struct condition_list *cond)
1516 kumaneko 856 {
1517     int pos;
1518     u8 bit;
1519 kumaneko 1052 const char *atmark = "";
1520     const char *filename;
1521 kumaneko 856 const u16 perm = ptr->perm;
1522 kumaneko 1052 if (ptr->u_is_group) {
1523     atmark = "@";
1524     filename = ptr->u.group->group_name->name;
1525     } else {
1526     filename = ptr->u.filename->name;
1527     }
1528 kumaneko 856 for (bit = head->read_bit; bit < MAX_SINGLE_PATH_OPERATION; bit++) {
1529     const char *msg;
1530 kumaneko 1052 if (!(perm & (1 << bit)))
1531     continue;
1532 kumaneko 856 /* Print "read/write" instead of "read" and "write". */
1533 kumaneko 1052 if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)
1534     && (perm & (1 << TYPE_READ_WRITE_ACL)))
1535     continue;
1536     msg = ccs_sp2keyword(bit);
1537 kumaneko 856 pos = head->read_avail;
1538 kumaneko 1052 if (!ccs_io_printf(head, "allow_%s %s%s", msg,
1539     atmark, filename) ||
1540 kumaneko 1054 !ccs_print_condition(head, cond))
1541 kumaneko 1052 goto out;
1542 kumaneko 856 }
1543     head->read_bit = 0;
1544 kumaneko 1006 return true;
1545 kumaneko 856 out:
1546     head->read_bit = bit;
1547     head->read_avail = pos;
1548 kumaneko 1006 return false;
1549 kumaneko 856 }
1550    
1551 kumaneko 1052 /**
1552 kumaneko 1054 * print_double_path_acl - Print a double path ACL entry.
1553 kumaneko 1052 *
1554     * @head: Pointer to "struct ccs_io_buffer".
1555     * @ptr: Pointer to "struct double_path_acl_record".
1556 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1557 kumaneko 1052 *
1558     * Returns true on success, false otherwise.
1559     */
1560     static bool print_double_path_acl(struct ccs_io_buffer *head,
1561     struct double_path_acl_record *ptr,
1562     const struct condition_list *cond)
1563 kumaneko 856 {
1564     int pos;
1565 kumaneko 1052 const char *atmark1 = "";
1566     const char *atmark2 = "";
1567     const char *filename1;
1568     const char *filename2;
1569 kumaneko 856 const u8 perm = ptr->perm;
1570     u8 bit;
1571 kumaneko 1052 if (ptr->u1_is_group) {
1572     atmark1 = "@";
1573     filename1 = ptr->u1.group1->group_name->name;
1574     } else {
1575     filename1 = ptr->u1.filename1->name;
1576     }
1577     if (ptr->u2_is_group) {
1578     atmark2 = "@";
1579     filename2 = ptr->u2.group2->group_name->name;
1580     } else {
1581     filename2 = ptr->u2.filename2->name;
1582     }
1583 kumaneko 856 for (bit = head->read_bit; bit < MAX_DOUBLE_PATH_OPERATION; bit++) {
1584     const char *msg;
1585 kumaneko 1052 if (!(perm & (1 << bit)))
1586     continue;
1587     msg = ccs_dp2keyword(bit);
1588 kumaneko 856 pos = head->read_avail;
1589 kumaneko 1052 if (!ccs_io_printf(head, "allow_%s %s%s %s%s", msg,
1590 kumaneko 1064 atmark1, filename1, atmark2, filename2) ||
1591 kumaneko 1054 !ccs_print_condition(head, cond))
1592 kumaneko 1052 goto out;
1593 kumaneko 856 }
1594 kumaneko 1032 head->read_bit = 0;
1595 kumaneko 1006 return true;
1596 kumaneko 856 out:
1597     head->read_bit = bit;
1598     head->read_avail = pos;
1599 kumaneko 1006 return false;
1600 kumaneko 856 }
1601    
1602 kumaneko 1052 /**
1603 kumaneko 1054 * print_argv0_acl - Print an argv[0] ACL entry.
1604 kumaneko 1052 *
1605     * @head: Pointer to "struct ccs_io_buffer".
1606     * @ptr: Pointer to "struct argv0_acl_record".
1607 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1608 kumaneko 1052 *
1609     * Returns true on success, false otherwise.
1610     */
1611     static bool print_argv0_acl(struct ccs_io_buffer *head,
1612     struct argv0_acl_record *ptr,
1613     const struct condition_list *cond)
1614 kumaneko 856 {
1615     int pos = head->read_avail;
1616 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
1617     ptr->filename->name, ptr->argv0->name))
1618     goto out;
1619 kumaneko 1054 if (!ccs_print_condition(head, cond))
1620 kumaneko 1052 goto out;
1621 kumaneko 1006 return true;
1622 kumaneko 856 out:
1623     head->read_avail = pos;
1624 kumaneko 1006 return false;
1625 kumaneko 856 }
1626    
1627 kumaneko 1052 /**
1628 kumaneko 1054 * print_env_acl - Print an evironment variable name's ACL entry.
1629 kumaneko 1052 *
1630     * @head: Pointer to "struct ccs_io_buffer".
1631     * @ptr: Pointer to "struct env_acl_record".
1632 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1633 kumaneko 1052 *
1634     * Returns true on success, false otherwise.
1635     */
1636     static bool print_env_acl(struct ccs_io_buffer *head,
1637     struct env_acl_record *ptr,
1638     const struct condition_list *cond)
1639 kumaneko 856 {
1640     int pos = head->read_avail;
1641 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))
1642     goto out;
1643 kumaneko 1054 if (!ccs_print_condition(head, cond))
1644 kumaneko 1052 goto out;
1645 kumaneko 1006 return true;
1646 kumaneko 856 out:
1647     head->read_avail = pos;
1648 kumaneko 1006 return false;
1649 kumaneko 856 }
1650    
1651 kumaneko 1052 /**
1652 kumaneko 1054 * print_capability_acl - Print a capability ACL entry.
1653 kumaneko 1052 *
1654     * @head: Pointer to "struct ccs_io_buffer".
1655     * @ptr: Pointer to "struct capability_acl_record".
1656 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1657 kumaneko 1052 *
1658     * Returns true on success, false otherwise.
1659     */
1660     static bool print_capability_acl(struct ccs_io_buffer *head,
1661     struct capability_acl_record *ptr,
1662     const struct condition_list *cond)
1663 kumaneko 856 {
1664 kumaneko 860 int pos = head->read_avail;
1665 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",
1666     ccs_cap2keyword(ptr->operation)))
1667     goto out;
1668 kumaneko 1054 if (!ccs_print_condition(head, cond))
1669 kumaneko 1052 goto out;
1670 kumaneko 1006 return true;
1671 kumaneko 856 out:
1672     head->read_avail = pos;
1673 kumaneko 1006 return false;
1674 kumaneko 856 }
1675    
1676 kumaneko 1052 /**
1677 kumaneko 1054 * print_ipv4_entry - Print IPv4 address of a network ACL entry.
1678 kumaneko 1052 *
1679     * @head: Pointer to "struct ccs_io_buffer".
1680     * @ptr: Pointer to "struct ip_network_acl_record".
1681     *
1682     * Returns true on success, false otherwise.
1683     */
1684     static bool print_ipv4_entry(struct ccs_io_buffer *head,
1685     struct ip_network_acl_record *ptr)
1686 kumaneko 856 {
1687 kumaneko 1052 const u32 min_address = ptr->u.ipv4.min;
1688     const u32 max_address = ptr->u.ipv4.max;
1689     if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
1690     return false;
1691     if (min_address != max_address
1692     && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
1693     return false;
1694     return true;
1695     }
1696    
1697     /**
1698 kumaneko 1054 * print_ipv6_entry - Print IPv6 address of a network ACL entry.
1699 kumaneko 1052 *
1700     * @head: Pointer to "struct ccs_io_buffer".
1701     * @ptr: Pointer to "struct ip_network_acl_record".
1702     *
1703     * Returns true on success, false otherwise.
1704     */
1705     static bool print_ipv6_entry(struct ccs_io_buffer *head,
1706     struct ip_network_acl_record *ptr)
1707     {
1708     char buf[64];
1709     const struct in6_addr *min_address = ptr->u.ipv6.min;
1710     const struct in6_addr *max_address = ptr->u.ipv6.max;
1711     ccs_print_ipv6(buf, sizeof(buf), min_address);
1712     if (!ccs_io_printf(head, "%s", buf))
1713     return false;
1714     if (min_address != max_address) {
1715     ccs_print_ipv6(buf, sizeof(buf), max_address);
1716     if (!ccs_io_printf(head, "-%s", buf))
1717     return false;
1718     }
1719     return true;
1720     }
1721    
1722     /**
1723 kumaneko 1054 * print_port_entry - Print port number of a network ACL entry.
1724 kumaneko 1052 *
1725     * @head: Pointer to "struct ccs_io_buffer".
1726     * @ptr: Pointer to "struct ip_network_acl_record".
1727     *
1728     * Returns true on success, false otherwise.
1729     */
1730     static bool print_port_entry(struct ccs_io_buffer *head,
1731     struct ip_network_acl_record *ptr)
1732     {
1733     const u16 min_port = ptr->min_port, max_port = ptr->max_port;
1734     if (!ccs_io_printf(head, " %u", min_port))
1735     return false;
1736     if (min_port != max_port && !ccs_io_printf(head, "-%u", max_port))
1737     return false;
1738     return true;
1739     }
1740    
1741     /**
1742 kumaneko 1054 * print_network_acl - Print a network ACL entry.
1743 kumaneko 1052 *
1744     * @head: Pointer to "struct ccs_io_buffer".
1745     * @ptr: Pointer to "struct ip_network_acl_record".
1746 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1747 kumaneko 1052 *
1748     * Returns true on success, false otherwise.
1749     */
1750     static bool print_network_acl(struct ccs_io_buffer *head,
1751     struct ip_network_acl_record *ptr,
1752     const struct condition_list *cond)
1753     {
1754 kumaneko 856 int pos = head->read_avail;
1755 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",
1756     ccs_net2keyword(ptr->operation_type)))
1757     goto out;
1758 kumaneko 856 switch (ptr->record_type) {
1759     case IP_RECORD_TYPE_ADDRESS_GROUP:
1760 kumaneko 1052 if (!ccs_io_printf(head, "@%s", ptr->u.group->group_name->name))
1761     goto out;
1762 kumaneko 856 break;
1763     case IP_RECORD_TYPE_IPv4:
1764 kumaneko 1052 if (!print_ipv4_entry(head, ptr))
1765     goto out;
1766 kumaneko 856 break;
1767     case IP_RECORD_TYPE_IPv6:
1768 kumaneko 1052 if (!print_ipv6_entry(head, ptr))
1769     goto out;
1770 kumaneko 856 break;
1771     }
1772 kumaneko 1052 if (!print_port_entry(head, ptr))
1773     goto out;
1774 kumaneko 1054 if (!ccs_print_condition(head, cond))
1775 kumaneko 1052 goto out;
1776 kumaneko 1006 return true;
1777 kumaneko 856 out:
1778     head->read_avail = pos;
1779 kumaneko 1006 return false;
1780 kumaneko 856 }
1781    
1782 kumaneko 1052 /**
1783 kumaneko 1054 * print_signal_acl - Print a signal ACL entry.
1784 kumaneko 1052 *
1785     * @head: Pointer to "struct ccs_io_buffer".
1786     * @ptr: Pointer to "struct signale_acl_record".
1787 kumaneko 1064 * @cond: Pointer to "struct condition_list". May be NULL.
1788 kumaneko 1052 *
1789     * Returns true on success, false otherwise.
1790     */
1791     static bool print_signal_acl(struct ccs_io_buffer *head,
1792     struct signal_acl_record *ptr,
1793     const struct condition_list *cond)
1794 kumaneko 856 {
1795     int pos = head->read_avail;
1796 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",
1797     ptr->sig, ptr->domainname->name))
1798     goto out;
1799 kumaneko 1054 if (!ccs_print_condition(head, cond))
1800 kumaneko 1052 goto out;
1801 kumaneko 1006 return true;
1802 kumaneko 856 out:
1803     head->read_avail = pos;
1804 kumaneko 1006 return false;
1805 kumaneko 856 }
1806    
1807 kumaneko 1052 /**
1808 kumaneko 1054 * print_execute_handler_record - Print an execute handler ACL entry.
1809 kumaneko 1052 *
1810     * @head: Pointer to "struct ccs_io_buffer".
1811     * @keyword: Name of the keyword.
1812     * @ptr: Pointer to "struct execute_handler_record".
1813     *
1814     * Returns true on success, false otherwise.
1815     */
1816     static bool print_execute_handler_record(struct ccs_io_buffer *head,
1817     const char *keyword,
1818     struct execute_handler_record *ptr)
1819 kumaneko 1029 {
1820 kumaneko 1052 return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1821 kumaneko 1029 }
1822    
1823 kumaneko 1052 /**
1824 kumaneko 1054 * print_entry - Print an ACL entry.
1825 kumaneko 1052 *
1826     * @head: Pointer to "struct ccs_io_buffer".
1827     * @ptr: Pointer to an ACL entry.
1828     *
1829     * Returns true on success, false otherwise.
1830     */
1831     static bool print_entry(struct ccs_io_buffer *head, struct acl_info *ptr)
1832 kumaneko 111 {
1833 kumaneko 1052 const struct condition_list *cond = ccs_get_condition_part(ptr);
1834 kumaneko 1064 const u8 acl_type = ccs_acl_type2(ptr);
1835 kumaneko 1052 if (acl_type & ACL_DELETED)
1836     return true;
1837     if (acl_type == TYPE_SINGLE_PATH_ACL) {
1838     struct single_path_acl_record *acl
1839     = container_of(ptr, struct single_path_acl_record,
1840     head);
1841     return print_single_path_acl(head, acl, cond);
1842     }
1843     if (acl_type == TYPE_DOUBLE_PATH_ACL) {
1844     struct double_path_acl_record *acl
1845     = container_of(ptr, struct double_path_acl_record,
1846     head);
1847     return print_double_path_acl(head, acl, cond);
1848     }
1849     if (acl_type == TYPE_ARGV0_ACL) {
1850     struct argv0_acl_record *acl
1851     = container_of(ptr, struct argv0_acl_record, head);
1852     return print_argv0_acl(head, acl, cond);
1853     }
1854     if (acl_type == TYPE_ENV_ACL) {
1855     struct env_acl_record *acl
1856     = container_of(ptr, struct env_acl_record, head);
1857     return print_env_acl(head, acl, cond);
1858     }
1859     if (acl_type == TYPE_CAPABILITY_ACL) {
1860     struct capability_acl_record *acl
1861     = container_of(ptr, struct capability_acl_record, head);
1862     return print_capability_acl(head, acl, cond);
1863     }
1864     if (acl_type == TYPE_IP_NETWORK_ACL) {
1865     struct ip_network_acl_record *acl
1866     = container_of(ptr, struct ip_network_acl_record, head);
1867     return print_network_acl(head, acl, cond);
1868     }
1869     if (acl_type == TYPE_SIGNAL_ACL) {
1870     struct signal_acl_record *acl
1871     = container_of(ptr, struct signal_acl_record, head);
1872     return print_signal_acl(head, acl, cond);
1873     }
1874 kumaneko 1064 if (acl_type == TYPE_EXECUTE_HANDLER) {
1875 kumaneko 1052 struct execute_handler_record *acl
1876     = container_of(ptr, struct execute_handler_record,
1877     head);
1878 kumaneko 1064 const char *keyword = KEYWORD_EXECUTE_HANDLER;
1879 kumaneko 1052 return print_execute_handler_record(head, keyword, acl);
1880     }
1881 kumaneko 1064 if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {
1882 kumaneko 1052 struct execute_handler_record *acl
1883     = container_of(ptr, struct execute_handler_record,
1884     head);
1885 kumaneko 1064 const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;
1886 kumaneko 1052 return print_execute_handler_record(head, keyword, acl);
1887     }
1888 kumaneko 1120 /* Workaround for gcc 3.2.2's inline bug. */
1889     if (acl_type & ACL_DELETED)
1890     return true;
1891 kumaneko 1052 BUG(); /* This must not happen. */
1892     return false;
1893     }
1894    
1895     /**
1896     * read_domain_policy - Read domain policy.
1897     *
1898     * @head: Pointer to "struct ccs_io_buffer".
1899     *
1900     * Returns 0.
1901     */
1902     static int read_domain_policy(struct ccs_io_buffer *head)
1903     {
1904 kumaneko 722 struct list1_head *dpos;
1905     struct list1_head *apos;
1906 kumaneko 1052 if (head->read_eof)
1907     return 0;
1908     if (head->read_step == 0)
1909     head->read_step = 1;
1910 kumaneko 722 list1_for_each_cookie(dpos, head->read_var1, &domain_list) {
1911 kumaneko 708 struct domain_info *domain;
1912 kumaneko 1052 const char *quota_exceeded = "";
1913 kumaneko 1180 const char *transition_failed = "";
1914 kumaneko 1052 const char *ignore_global_allow_read = "";
1915     const char *ignore_global_allow_env = "";
1916 kumaneko 722 domain = list1_entry(dpos, struct domain_info, list);
1917 kumaneko 1052 if (head->read_step != 1)
1918     goto acl_loop;
1919     if (domain->is_deleted)
1920     continue;
1921 kumaneko 1054 /* Print domainname and flags. */
1922 kumaneko 1052 if (domain->quota_warned)
1923     quota_exceeded = "quota_exceeded\n";
1924 kumaneko 1180 if (domain->flags & DOMAIN_FLAGS_TRANSITION_FAILED)
1925     transition_failed = "transition_failed\n";
1926 kumaneko 1052 if (domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1927     ignore_global_allow_read
1928     = KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1929     if (domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV)
1930     ignore_global_allow_env
1931     = KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
1932     if (!ccs_io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n"
1933 kumaneko 1180 "%s%s%s%s\n", domain->domainname->name,
1934 kumaneko 1052 domain->profile, quota_exceeded,
1935 kumaneko 1180 transition_failed,
1936 kumaneko 1052 ignore_global_allow_read,
1937     ignore_global_allow_env))
1938     return 0;
1939 kumaneko 708 head->read_step = 2;
1940 kumaneko 1052 acl_loop:
1941     if (head->read_step == 3)
1942     goto tail_mark;
1943 kumaneko 1054 /* Print ACL entries in the domain. */
1944 kumaneko 1052 list1_for_each_cookie(apos, head->read_var2,
1945     &domain->acl_info_list) {
1946     struct acl_info *ptr
1947     = list1_entry(apos, struct acl_info, list);
1948     if (!print_entry(head, ptr))
1949     return 0;
1950 kumaneko 111 }
1951 kumaneko 708 head->read_step = 3;
1952 kumaneko 1052 tail_mark:
1953     if (!ccs_io_printf(head, "\n"))
1954     return 0;
1955 kumaneko 708 head->read_step = 1;
1956 kumaneko 111 }
1957 kumaneko 1006 head->read_eof = true;
1958 kumaneko 111 return 0;
1959     }
1960    
1961 kumaneko 461 #endif
1962    
1963 kumaneko 1052 /**
1964     * write_domain_profile - Assign profile for specified domain.
1965     *
1966     * @head: Pointer to "struct ccs_io_buffer".
1967     *
1968     * Returns 0 on success, -EINVAL otherwise.
1969     *
1970     * This is equivalent to doing
1971 kumaneko 1054 *
1972     * ( echo "select " $domainname; echo "use_profile " $profile ) |
1973 kumaneko 1057 * /usr/lib/ccs/loadpolicy -d
1974 kumaneko 1052 */
1975     static int write_domain_profile(struct ccs_io_buffer *head)
1976 kumaneko 461 {
1977     char *data = head->write_buf;
1978     char *cp = strchr(data, ' ');
1979     struct domain_info *domain;
1980     unsigned int profile;
1981 kumaneko 1052 if (!cp)
1982     return -EINVAL;
1983 kumaneko 461 *cp = '\0';
1984 kumaneko 1052 domain = ccs_find_domain(cp + 1);
1985 kumaneko 461 profile = simple_strtoul(data, NULL, 10);
1986 kumaneko 1052 if (domain && profile < MAX_PROFILES
1987     && (profile_ptr[profile] || !sbin_init_started))
1988     domain->profile = (u8) profile;
1989     ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
1990 kumaneko 461 return 0;
1991     }
1992    
1993 kumaneko 1052 /**
1994     * read_domain_profile - Read only domainname and profile.
1995     *
1996     * @head: Pointer to "struct ccs_io_buffer".
1997     *
1998     * Returns list of profile number and domainname pairs.
1999     *
2000     * This is equivalent to doing
2001 kumaneko 1054 *
2002     * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
2003 kumaneko 1057 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
2004     * domainname = $0; } else if ( $1 == "use_profile" ) {
2005     * print $2 " " domainname; domainname = ""; } } ; '
2006 kumaneko 1052 */
2007     static int read_domain_profile(struct ccs_io_buffer *head)
2008 kumaneko 111 {
2009 kumaneko 722 struct list1_head *pos;
2010 kumaneko 1052 if (head->read_eof)
2011     return 0;
2012 kumaneko 722 list1_for_each_cookie(pos, head->read_var1, &domain_list) {
2013 kumaneko 111 struct domain_info *domain;
2014 kumaneko 722 domain = list1_entry(pos, struct domain_info, list);
2015 kumaneko 1052 if (domain->is_deleted)
2016     continue;
2017     if (!ccs_io_printf(head, "%u %s\n", domain->profile,
2018     domain->domainname->name))
2019     return 0;
2020 kumaneko 111 }
2021 kumaneko 1006 head->read_eof = true;
2022 kumaneko 111 return 0;
2023     }
2024    
2025 kumaneko 1052 /**
2026     * write_pid: Specify PID to obtain domainname.
2027     *
2028     * @head: Pointer to "struct ccs_io_buffer".
2029     *
2030     * Returns 0.
2031     */
2032     static int write_pid(struct ccs_io_buffer *head)
2033 kumaneko 111 {
2034     head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);
2035 kumaneko 1006 head->read_eof = false;
2036 kumaneko 111 return 0;
2037     }
2038    
2039 kumaneko 1052 /**
2040     * read_pid - Get domainname of the specified PID.
2041     *
2042     * @head: Pointer to "struct ccs_io_buffer".
2043     *
2044     * Returns the domainname which the specified PID is in on success,
2045     * empty string otherwise.
2046     * The PID is specified by write_pid() so that the user can obtain
2047     * using read()/write() interface rather than sysctl() interface.
2048     */
2049     static int read_pid(struct ccs_io_buffer *head)
2050 kumaneko 111 {
2051     if (head->read_avail == 0 && !head->read_eof) {
2052     const int pid = head->read_step;
2053     struct task_struct *p;
2054     struct domain_info *domain = NULL;
2055     /***** CRITICAL SECTION START *****/
2056     read_lock(&tasklist_lock);
2057     p = find_task_by_pid(pid);
2058 kumaneko 1052 if (p)
2059     domain = p->domain_info;
2060 kumaneko 111 read_unlock(&tasklist_lock);
2061     /***** CRITICAL SECTION END *****/
2062 kumaneko 1052 if (domain)
2063     ccs_io_printf(head, "%d %u %s", pid, domain->profile,
2064     domain->domainname->name);
2065 kumaneko 1006 head->read_eof = true;
2066 kumaneko 111 }
2067     return 0;
2068     }
2069    
2070     #ifdef CONFIG_TOMOYO
2071    
2072 kumaneko 1052 /**
2073     * write_exception_policy - Write exception policy.
2074     *
2075     * @head: Pointer to "struct ccs_io_buffer".
2076     *
2077     * Returns 0 on success, negative value otherwise.
2078     */
2079     static int write_exception_policy(struct ccs_io_buffer *head)
2080 kumaneko 111 {
2081     char *data = head->write_buf;
2082 kumaneko 1052 bool is_delete = str_starts(&data, KEYWORD_DELETE);
2083     if (str_starts(&data, KEYWORD_KEEP_DOMAIN))
2084     return ccs_write_domain_keeper_policy(data, false, is_delete);
2085     if (str_starts(&data, KEYWORD_NO_KEEP_DOMAIN))
2086     return ccs_write_domain_keeper_policy(data, true, is_delete);
2087     if (str_starts(&data, KEYWORD_INITIALIZE_DOMAIN))
2088     return ccs_write_domain_initializer_policy(data, false,
2089     is_delete);
2090     if (str_starts(&data, KEYWORD_NO_INITIALIZE_DOMAIN))
2091     return ccs_write_domain_initializer_policy(data, true,
2092     is_delete);
2093     if (str_starts(&data, KEYWORD_ALIAS))
2094     return ccs_write_alias_policy(data, is_delete);
2095     if (str_starts(&data, KEYWORD_AGGREGATOR))
2096     return ccs_write_aggregator_policy(data, is_delete);
2097     if (str_starts(&data, KEYWORD_ALLOW_READ))
2098     return ccs_write_globally_readable_policy(data, is_delete);
2099     if (str_starts(&data, KEYWORD_ALLOW_ENV))
2100     return ccs_write_globally_usable_env_policy(data, is_delete);
2101     if (str_starts(&data, KEYWORD_FILE_PATTERN))
2102     return ccs_write_pattern_policy(data, is_delete);
2103     if (str_starts(&data, KEYWORD_PATH_GROUP))
2104     return ccs_write_path_group_policy(data, is_delete);
2105     if (str_starts(&data, KEYWORD_DENY_REWRITE))
2106     return ccs_write_no_rewrite_policy(data, is_delete);
2107     if (str_starts(&data, KEYWORD_ADDRESS_GROUP))
2108     return ccs_write_address_group_policy(data, is_delete);
2109 kumaneko 111 return -EINVAL;
2110     }
2111    
2112 kumaneko 1052 /**
2113     * read_exception_policy - Read exception policy.
2114     *
2115     * @head: Pointer to "struct ccs_io_buffer".
2116     *
2117     * Returns 0 on success, -EINVAL otherwise.
2118     */
2119     static int read_exception_policy(struct ccs_io_buffer *head)
2120 kumaneko 111 {
2121     if (!head->read_eof) {
2122     switch (head->read_step) {
2123     case 0:
2124 kumaneko 1052 head->read_var2 = NULL;
2125     head->read_step = 1;
2126 kumaneko 111 case 1:
2127 kumaneko 1052 if (!ccs_read_domain_keeper_policy(head))
2128     break;
2129     head->read_var2 = NULL;
2130     head->read_step = 2;
2131 kumaneko 111 case 2:
2132 kumaneko 1052 if (!ccs_read_globally_readable_policy(head))
2133     break;
2134     head->read_var2 = NULL;
2135     head->read_step = 3;
2136 kumaneko 111 case 3:
2137 kumaneko 1052 if (!ccs_read_globally_usable_env_policy(head))
2138     break;
2139     head->read_var2 = NULL;
2140     head->read_step = 4;
2141 kumaneko 111 case 4:
2142 kumaneko 1052 if (!ccs_read_domain_initializer_policy(head))
2143     break;
2144     head->read_var2 = NULL;
2145     head->read_step = 5;
2146 kumaneko 111 case 5:
2147 kumaneko 1052 if (!ccs_read_alias_policy(head))
2148     break;
2149     head->read_var2 = NULL;
2150     head->read_step = 6;
2151 kumaneko 111 case 6:
2152 kumaneko 1052 if (!ccs_read_aggregator_policy(head))
2153     break;
2154     head->read_var2 = NULL;
2155     head->read_step = 7;
2156 kumaneko 111 case 7:
2157 kumaneko 1052 if (!ccs_read_file_pattern(head))
2158     break;
2159     head->read_var2 = NULL;
2160     head->read_step = 8;
2161 kumaneko 111 case 8:
2162 kumaneko 1052 if (!ccs_read_no_rewrite_policy(head))
2163     break;
2164     head->read_var2 = NULL;
2165     head->read_step = 9;
2166 kumaneko 581 case 9:
2167 kumaneko 1052 if (!ccs_read_path_group_policy(head))
2168     break;
2169     head->read_var1 = NULL;
2170     head->read_var2 = NULL;
2171     head->read_step = 10;
2172 kumaneko 581 case 10:
2173 kumaneko 1052 if (!ccs_read_address_group_policy(head))
2174     break;
2175 kumaneko 1006 head->read_eof = true;
2176 kumaneko 111 break;
2177     default:
2178     return -EINVAL;
2179     }
2180     }
2181     return 0;
2182     }
2183    
2184     #endif
2185    
2186     #ifdef CONFIG_SAKURA
2187    
2188 kumaneko 1052 /**
2189     * write_system_policy - Write system policy.
2190     *
2191     * @head: Pointer to "struct ccs_io_buffer".
2192     *
2193     * Returns 0 on success, negative value otherwise.
2194     */
2195     static int write_system_policy(struct ccs_io_buffer *head)
2196 kumaneko 111 {
2197     char *data = head->write_buf;
2198 kumaneko 1006 bool is_delete = false;
2199 kumaneko 1052 if (str_starts(&data, KEYWORD_DELETE))
2200 kumaneko 1006 is_delete = true;
2201 kumaneko 1052 if (str_starts(&data, KEYWORD_ALLOW_MOUNT))
2202     return ccs_write_mount_policy(data, is_delete);
2203     if (str_starts(&data, KEYWORD_DENY_UNMOUNT))
2204     return ccs_write_no_umount_policy(data, is_delete);
2205     if (str_starts(&data, KEYWORD_ALLOW_CHROOT))
2206     return ccs_write_chroot_policy(data, is_delete);
2207     if (str_starts(&data, KEYWORD_ALLOW_PIVOT_ROOT))
2208     return ccs_write_pivot_root_policy(data, is_delete);
2209     if (str_starts(&data, KEYWORD_DENY_AUTOBIND))
2210     return ccs_write_reserved_port_policy(data, is_delete);
2211 kumaneko 111 return -EINVAL;
2212     }
2213    
2214 kumaneko 1052 /**
2215     * read_system_policy - Read system policy.
2216     *
2217     * @head: Pointer to "struct ccs_io_buffer".
2218     *
2219     * Returns 0 on success, -EINVAL otherwise.
2220     */
2221     static int read_system_policy(struct ccs_io_buffer *head)
2222 kumaneko 111 {
2223     if (!head->read_eof) {
2224     switch (head->read_step) {
2225     case 0:
2226 kumaneko 1052 head->read_var2 = NULL;
2227     head->read_step = 1;
2228 kumaneko 111 case 1:
2229 kumaneko 1052 if (!ccs_read_mount_policy(head))
2230     break;
2231     head->read_var2 = NULL;
2232     head->read_step = 2;
2233 kumaneko 111 case 2:
2234 kumaneko 1052 if (!ccs_read_no_umount_policy(head))
2235     break;
2236     head->read_var2 = NULL;
2237     head->read_step = 3;
2238 kumaneko 111 case 3:
2239 kumaneko 1052 if (!ccs_read_chroot_policy(head))
2240     break;
2241     head->read_var2 = NULL;
2242     head->read_step = 4;
2243 kumaneko 111 case 4:
2244 kumaneko 1052 if (!ccs_read_pivot_root_policy(head))
2245     break;
2246     head->read_var2 = NULL;
2247     head->read_step = 5;
2248 kumaneko 141 case 5:
2249 kumaneko 1052 if (!ccs_read_reserved_port_policy(head))
2250     break;
2251 kumaneko 1006 head->read_eof = true;
2252 kumaneko 111 break;
2253     default:
2254     return -EINVAL;
2255     }
2256     }
2257     return 0;
2258     }
2259    
2260     #endif
2261    
2262 kumaneko 1064 /* Path to the policy loader. The default is /sbin/ccs-init. */
2263 kumaneko 1052 static const char *ccs_loader;
2264 kumaneko 111
2265 kumaneko 1052 /**
2266     * loader_setup - Specify the policy loader to use.
2267     *
2268     * @str: Path to the policy loader.
2269     *
2270     * Returns 0.
2271     */
2272     static int __init loader_setup(char *str)
2273 kumaneko 111 {
2274     ccs_loader = str;
2275     return 0;
2276     }
2277    
2278 kumaneko 1052 __setup("CCS_loader=", loader_setup);
2279 kumaneko 111
2280 kumaneko 1052 /**
2281     * policy_loader_exists - Check whether /sbin/ccs-init exists.
2282     *
2283     * Returns true if /sbin/ccs-init exists, false otherwise.
2284     */
2285     static bool policy_loader_exists(void)
2286 kumaneko 111 {
2287     /*
2288 kumaneko 1052 * Don't activate MAC if the path given by 'CCS_loader=' option doesn't
2289     * exist. If the initrd includes /sbin/init but real-root-dev has not
2290     * mounted on / yet, activating MAC will block the system since
2291     * policies are not loaded yet.
2292     * Thus, let do_execve() call this function everytime.
2293 kumaneko 111 */
2294 kumaneko 1052 struct nameidata nd;
2295     if (!ccs_loader)
2296     ccs_loader = "/sbin/ccs-init";
2297     if (path_lookup(ccs_loader, lookup_flags, &nd)) {
2298     printk(KERN_INFO "Not activating Mandatory Access Control now "
2299     "since %s doesn't exist.\n", ccs_loader);
2300     return false;
2301     }
2302     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
2303     path_put(&nd.path);
2304     #else
2305     path_release(&nd);
2306     #endif
2307     return true;
2308     }
2309    
2310 kumaneko 1255 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2311 kumaneko 1052 /**
2312 kumaneko 1255 * run_ccs_loader - Start /sbin/ccs-init .
2313     *
2314     * @unused: Not used.
2315     *
2316     * Returns PID of /sbin/ccs-init on success, negative value otherwise.
2317     */
2318     static int run_ccs_loader(void *unused)
2319     {
2320     char *argv[2];
2321     char *envp[3];
2322     printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
2323     ccs_loader);
2324     argv[0] = (char *) ccs_loader;
2325     argv[1] = NULL;
2326     envp[0] = "HOME=/";
2327     envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
2328     envp[2] = NULL;
2329     return exec_usermodehelper(argv[0], argv, envp);
2330     }
2331     #endif
2332    
2333     /**
2334 kumaneko 1052 * ccs_load_policy - Run external policy loader to load policy.
2335     *
2336     * @filename: The program about to start.
2337     *
2338     * This function checks whether @filename is /sbin/init , and if so
2339     * invoke /sbin/ccs-init and wait for the termination of /sbin/ccs-init
2340 kumaneko 1064 * and then continues invocation of /sbin/init.
2341 kumaneko 1052 * /sbin/ccs-init reads policy files in /etc/ccs/ directory and
2342     * writes to /proc/ccs/ interfaces.
2343     *
2344     * Returns nothing.
2345     */
2346     void ccs_load_policy(const char *filename)
2347     {
2348     if (sbin_init_started)
2349     return;
2350 kumaneko 111 /*
2351 kumaneko 1064 * Check filename is /sbin/init or /sbin/ccs-start.
2352 kumaneko 1052 * /sbin/ccs-start is a dummy filename in case where /sbin/init can't
2353     * be passed.
2354     * You can create /sbin/ccs-start by "ln -s /bin/true /sbin/ccs-start".
2355 kumaneko 111 */
2356 kumaneko 1052 if (strcmp(filename, "/sbin/init") &&
2357     strcmp(filename, "/sbin/ccs-start"))
2358     return;
2359     if (!policy_loader_exists())
2360     return;
2361 kumaneko 1255 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
2362     {
2363 kumaneko 1064 char *argv[2];
2364     char *envp[3];
2365 kumaneko 1052 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
2366     ccs_loader);
2367 kumaneko 325 argv[0] = (char *) ccs_loader;
2368     argv[1] = NULL;
2369     envp[0] = "HOME=/";
2370     envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
2371     envp[2] = NULL;
2372     call_usermodehelper(argv[0], argv, envp, 1);
2373 kumaneko 1255 }
2374 kumaneko 1366 #elif defined(TASK_DEAD)
2375     {
2376     /* Copied from kernel/kmod.c */
2377     struct task_struct *task = current;
2378     pid_t pid = kernel_thread(run_ccs_loader, NULL, 0);
2379     sigset_t tmpsig;
2380     spin_lock_irq(&task->sighand->siglock);
2381     tmpsig = task->blocked;
2382     siginitsetinv(&task->blocked,
2383     sigmask(SIGKILL) | sigmask(SIGSTOP));
2384     recalc_sigpending();
2385     spin_unlock_irq(&current->sighand->siglock);
2386     if (pid >= 0)
2387     waitpid(pid, NULL, __WCLONE);
2388     spin_lock_irq(&task->sighand->siglock);
2389     task->blocked = tmpsig;
2390     recalc_sigpending();
2391     spin_unlock_irq(&task->sighand->siglock);
2392     }
2393 kumaneko 325 #else
2394 kumaneko 1255 {
2395     /* Copied from kernel/kmod.c */
2396     struct task_struct *task = current;
2397     pid_t pid = kernel_thread(run_ccs_loader, NULL, 0);
2398     sigset_t tmpsig;
2399     spin_lock_irq(&task->sigmask_lock);
2400     tmpsig = task->blocked;
2401     siginitsetinv(&task->blocked,
2402   &n