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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2393 - (show annotations) (download) (as text)
Mon Apr 6 05:24:05 2009 UTC (15 years, 1 month ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 91926 byte(s)
Drop "undelete domain" command. Escape invalid characters in ccs_check_mount_permission2().
1 /*
2 * fs/ccs_common.c
3 *
4 * Common functions for SAKURA and TOMOYO.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 1.6.7 2009/04/01
9 *
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 #include <linux/version.h>
16 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
17 #define __KERNEL_SYSCALLS__
18 #endif
19 #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 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
28 #include <linux/namei.h>
29 #include <linux/mount.h>
30 static const int ccs_lookup_flags = LOOKUP_FOLLOW;
31 #else
32 static const int ccs_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 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
39 #include <linux/unistd.h>
40 #endif
41
42 /* To support PID namespace. */
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
44 #define find_task_by_pid find_task_by_vpid
45 #endif
46
47 /* Set default specified by the kernel config. */
48 #ifdef CONFIG_TOMOYO
49 #define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)
50 #define MAX_GRANT_LOG (CONFIG_TOMOYO_MAX_GRANT_LOG)
51 #define MAX_REJECT_LOG (CONFIG_TOMOYO_MAX_REJECT_LOG)
52 #else
53 #define MAX_ACCEPT_ENTRY 0
54 #define MAX_GRANT_LOG 0
55 #define MAX_REJECT_LOG 0
56 #endif
57
58 /* Has /sbin/init started? */
59 bool ccs_policy_loaded;
60
61 /* Log level for SAKURA's printk(). */
62 const char *ccs_log_level = KERN_DEBUG;
63
64 /* String table for functionality that takes 4 modes. */
65 static const char *ccs_mode_4[4] = {
66 "disabled", "learning", "permissive", "enforcing"
67 };
68 /* String table for functionality that takes 2 modes. */
69 static const char *ccs_mode_2[4] = {
70 "disabled", "enabled", "enabled", "enabled"
71 };
72
73 /* Table for profile. */
74 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_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
80 [CCS_MAC_FOR_IOCTL] = { "MAC_FOR_IOCTL", 0, 3 },
81 [CCS_MAC_FOR_ARGV0] = { "MAC_FOR_ARGV0", 0, 3 },
82 [CCS_MAC_FOR_ENV] = { "MAC_FOR_ENV", 0, 3 },
83 [CCS_MAC_FOR_NETWORK] = { "MAC_FOR_NETWORK", 0, 3 },
84 [CCS_MAC_FOR_SIGNAL] = { "MAC_FOR_SIGNAL", 0, 3 },
85 [CCS_DENY_CONCEAL_MOUNT] = { "DENY_CONCEAL_MOUNT", 0, 3 },
86 [CCS_RESTRICT_CHROOT] = { "RESTRICT_CHROOT", 0, 3 },
87 [CCS_RESTRICT_MOUNT] = { "RESTRICT_MOUNT", 0, 3 },
88 [CCS_RESTRICT_UNMOUNT] = { "RESTRICT_UNMOUNT", 0, 3 },
89 [CCS_RESTRICT_PIVOT_ROOT] = { "RESTRICT_PIVOT_ROOT", 0, 3 },
90 [CCS_RESTRICT_AUTOBIND] = { "RESTRICT_AUTOBIND", 0, 1 },
91 [CCS_MAX_ACCEPT_ENTRY]
92 = { "MAX_ACCEPT_ENTRY", MAX_ACCEPT_ENTRY, INT_MAX },
93 #ifdef CONFIG_TOMOYO_AUDIT
94 [CCS_MAX_GRANT_LOG]
95 = { "MAX_GRANT_LOG", MAX_GRANT_LOG, INT_MAX },
96 [CCS_MAX_REJECT_LOG]
97 = { "MAX_REJECT_LOG", MAX_REJECT_LOG, INT_MAX },
98 #endif
99 [CCS_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
100 [CCS_SLEEP_PERIOD]
101 = { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */
102 };
103
104 #ifdef CONFIG_TOMOYO
105 /* Capability name used by domain policy. */
106 static const char *ccs_capability_control_keyword[CCS_MAX_CAPABILITY_INDEX]
107 = {
108 [CCS_INET_STREAM_SOCKET_CREATE] = "inet_tcp_create",
109 [CCS_INET_STREAM_SOCKET_LISTEN] = "inet_tcp_listen",
110 [CCS_INET_STREAM_SOCKET_CONNECT] = "inet_tcp_connect",
111 [CCS_USE_INET_DGRAM_SOCKET] = "use_inet_udp",
112 [CCS_USE_INET_RAW_SOCKET] = "use_inet_ip",
113 [CCS_USE_ROUTE_SOCKET] = "use_route",
114 [CCS_USE_PACKET_SOCKET] = "use_packet",
115 [CCS_SYS_MOUNT] = "SYS_MOUNT",
116 [CCS_SYS_UMOUNT] = "SYS_UMOUNT",
117 [CCS_SYS_REBOOT] = "SYS_REBOOT",
118 [CCS_SYS_CHROOT] = "SYS_CHROOT",
119 [CCS_SYS_KILL] = "SYS_KILL",
120 [CCS_SYS_VHANGUP] = "SYS_VHANGUP",
121 [CCS_SYS_SETTIME] = "SYS_TIME",
122 [CCS_SYS_NICE] = "SYS_NICE",
123 [CCS_SYS_SETHOSTNAME] = "SYS_SETHOSTNAME",
124 [CCS_USE_KERNEL_MODULE] = "use_kernel_module",
125 [CCS_CREATE_FIFO] = "create_fifo",
126 [CCS_CREATE_BLOCK_DEV] = "create_block_dev",
127 [CCS_CREATE_CHAR_DEV] = "create_char_dev",
128 [CCS_CREATE_UNIX_SOCKET] = "create_unix_socket",
129 [CCS_SYS_LINK] = "SYS_LINK",
130 [CCS_SYS_SYMLINK] = "SYS_SYMLINK",
131 [CCS_SYS_RENAME] = "SYS_RENAME",
132 [CCS_SYS_UNLINK] = "SYS_UNLINK",
133 [CCS_SYS_CHMOD] = "SYS_CHMOD",
134 [CCS_SYS_CHOWN] = "SYS_CHOWN",
135 [CCS_SYS_IOCTL] = "SYS_IOCTL",
136 [CCS_SYS_KEXEC_LOAD] = "SYS_KEXEC_LOAD",
137 [CCS_SYS_PIVOT_ROOT] = "SYS_PIVOT_ROOT",
138 [CCS_SYS_PTRACE] = "SYS_PTRACE",
139 };
140 #endif
141
142 #ifdef CONFIG_TOMOYO
143 static bool ccs_profile_entry_used[CCS_MAX_CONTROL_INDEX +
144 CCS_MAX_CAPABILITY_INDEX + 1];
145 #else
146 static bool ccs_profile_entry_used[CCS_MAX_CONTROL_INDEX + 1];
147 #endif
148
149 /* Profile table. Memory is allocated as needed. */
150 static struct ccs_profile {
151 unsigned int value[CCS_MAX_CONTROL_INDEX];
152 const struct ccs_path_info *comment;
153 #ifdef CONFIG_TOMOYO
154 unsigned char capability_value[CCS_MAX_CAPABILITY_INDEX];
155 #endif
156 } *ccs_profile_ptr[MAX_PROFILES];
157
158 /* Permit policy management by non-root user? */
159 static bool ccs_manage_by_non_root;
160
161 /* Utility functions. */
162
163 #ifdef CONFIG_TOMOYO
164 /**
165 * ccs_quiet_setup - Set CCS_VERBOSE=0 by default.
166 *
167 * @str: Unused.
168 *
169 * Returns 0.
170 */
171 static int __init ccs_quiet_setup(char *str)
172 {
173 ccs_control_array[CCS_VERBOSE].current_value = 0;
174 return 0;
175 }
176
177 __setup("CCS_QUIET", ccs_quiet_setup);
178 #endif
179
180 /**
181 * ccs_is_byte_range - Check whether the string isa \ooo style octal value.
182 *
183 * @str: Pointer to the string.
184 *
185 * Returns true if @str is a \ooo style octal value, false otherwise.
186 */
187 static inline bool ccs_is_byte_range(const char *str)
188 {
189 return *str >= '0' && *str++ <= '3' &&
190 *str >= '0' && *str++ <= '7' &&
191 *str >= '0' && *str <= '7';
192 }
193
194 /**
195 * ccs_is_decimal - Check whether the character is a decimal character.
196 *
197 * @c: The character to check.
198 *
199 * Returns true if @c is a decimal character, false otherwise.
200 */
201 static inline bool ccs_is_decimal(const char c)
202 {
203 return c >= '0' && c <= '9';
204 }
205
206 /**
207 * ccs_is_hexadecimal - Check whether the character is a hexadecimal character.
208 *
209 * @c: The character to check.
210 *
211 * Returns true if @c is a hexadecimal character, false otherwise.
212 */
213 static inline bool ccs_is_hexadecimal(const char c)
214 {
215 return (c >= '0' && c <= '9') ||
216 (c >= 'A' && c <= 'F') ||
217 (c >= 'a' && c <= 'f');
218 }
219
220 /**
221 * ccs_is_alphabet_char - Check whether the character is an alphabet.
222 *
223 * @c: The character to check.
224 *
225 * Returns true if @c is an alphabet character, false otherwise.
226 */
227 static inline bool ccs_is_alphabet_char(const char c)
228 {
229 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
230 }
231
232 /**
233 * ccs_make_byte - Make byte value from three octal characters.
234 *
235 * @c1: The first character.
236 * @c2: The second character.
237 * @c3: The third character.
238 *
239 * Returns byte value.
240 */
241 static inline u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
242 {
243 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
244 }
245
246 /**
247 * ccs_str_starts - Check whether the given string starts with the given keyword.
248 *
249 * @src: Pointer to pointer to the string.
250 * @find: Pointer to the keyword.
251 *
252 * Returns true if @src starts with @find, false otherwise.
253 *
254 * The @src is updated to point the first character after the @find
255 * if @src starts with @find.
256 */
257 static bool ccs_str_starts(char **src, const char *find)
258 {
259 const int len = strlen(find);
260 char *tmp = *src;
261 if (strncmp(tmp, find, len))
262 return false;
263 tmp += len;
264 *src = tmp;
265 return true;
266 }
267
268 /**
269 * ccs_normalize_line - Format string.
270 *
271 * @buffer: The line to normalize.
272 *
273 * Leading and trailing whitespaces are removed.
274 * Multiple whitespaces are packed into single space.
275 *
276 * Returns nothing.
277 */
278 void ccs_normalize_line(unsigned char *buffer)
279 {
280 unsigned char *sp = buffer;
281 unsigned char *dp = buffer;
282 bool first = true;
283 while (*sp && (*sp <= ' ' || *sp >= 127))
284 sp++;
285 while (*sp) {
286 if (!first)
287 *dp++ = ' ';
288 first = false;
289 while (*sp > ' ' && *sp < 127)
290 *dp++ = *sp++;
291 while (*sp && (*sp <= ' ' || *sp >= 127))
292 sp++;
293 }
294 *dp = '\0';
295 }
296
297 /**
298 * ccs_is_correct_path - Validate a pathname.
299 * @filename: The pathname to check.
300 * @start_type: Should the pathname start with '/'?
301 * 1 = must / -1 = must not / 0 = don't care
302 * @pattern_type: Can the pathname contain a wildcard?
303 * 1 = must / -1 = must not / 0 = don't care
304 * @end_type: Should the pathname end with '/'?
305 * 1 = must / -1 = must not / 0 = don't care
306 * @function: The name of function calling me.
307 *
308 * Check whether the given filename follows the naming rules.
309 * Returns true if @filename follows the naming rules, false otherwise.
310 */
311 bool ccs_is_correct_path(const char *filename, const s8 start_type,
312 const s8 pattern_type, const s8 end_type,
313 const char *function)
314 {
315 bool contains_pattern = false;
316 unsigned char c;
317 unsigned char d;
318 unsigned char e;
319 const char *original_filename = filename;
320 if (!filename)
321 goto out;
322 c = *filename;
323 if (start_type == 1) { /* Must start with '/' */
324 if (c != '/')
325 goto out;
326 } else if (start_type == -1) { /* Must not start with '/' */
327 if (c == '/')
328 goto out;
329 }
330 if (c)
331 c = *(filename + strlen(filename) - 1);
332 if (end_type == 1) { /* Must end with '/' */
333 if (c != '/')
334 goto out;
335 } else if (end_type == -1) { /* Must not end with '/' */
336 if (c == '/')
337 goto out;
338 }
339 while (1) {
340 c = *filename++;
341 if (!c)
342 break;
343 if (c == '\\') {
344 c = *filename++;
345 switch (c) {
346 case '\\': /* "\\" */
347 continue;
348 case '$': /* "\$" */
349 case '+': /* "\+" */
350 case '?': /* "\?" */
351 case '*': /* "\*" */
352 case '@': /* "\@" */
353 case 'x': /* "\x" */
354 case 'X': /* "\X" */
355 case 'a': /* "\a" */
356 case 'A': /* "\A" */
357 case '-': /* "\-" */
358 if (pattern_type == -1)
359 break; /* Must not contain pattern */
360 contains_pattern = true;
361 continue;
362 case '0': /* "\ooo" */
363 case '1':
364 case '2':
365 case '3':
366 d = *filename++;
367 if (d < '0' || d > '7')
368 break;
369 e = *filename++;
370 if (e < '0' || e > '7')
371 break;
372 c = ccs_make_byte(c, d, e);
373 if (c && (c <= ' ' || c >= 127))
374 continue; /* pattern is not \000 */
375 }
376 goto out;
377 } else if (c <= ' ' || c >= 127) {
378 goto out;
379 }
380 }
381 if (pattern_type == 1) { /* Must contain pattern */
382 if (!contains_pattern)
383 goto out;
384 }
385 return true;
386 out:
387 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
388 original_filename);
389 return false;
390 }
391
392 /**
393 * ccs_is_correct_domain - Check whether the given domainname follows the naming rules.
394 * @domainname: The domainname to check.
395 * @function: The name of function calling me.
396 *
397 * Returns true if @domainname follows the naming rules, false otherwise.
398 */
399 bool ccs_is_correct_domain(const unsigned char *domainname,
400 const char *function)
401 {
402 unsigned char c;
403 unsigned char d;
404 unsigned char e;
405 const char *org_domainname = domainname;
406 if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN))
407 goto out;
408 domainname += ROOT_NAME_LEN;
409 if (!*domainname)
410 return true;
411 do {
412 if (*domainname++ != ' ')
413 goto out;
414 if (*domainname++ != '/')
415 goto out;
416 while (1) {
417 c = *domainname;
418 if (!c || c == ' ')
419 break;
420 domainname++;
421 if (c == '\\') {
422 c = *domainname++;
423 switch ((c)) {
424 case '\\': /* "\\" */
425 continue;
426 case '0': /* "\ooo" */
427 case '1':
428 case '2':
429 case '3':
430 d = *domainname++;
431 if (d < '0' || d > '7')
432 break;
433 e = *domainname++;
434 if (e < '0' || e > '7')
435 break;
436 c = ccs_make_byte(c, d, e);
437 if (c && (c <= ' ' || c >= 127))
438 /* pattern is not \000 */
439 continue;
440 }
441 goto out;
442 } else if (c < ' ' || c >= 127) {
443 goto out;
444 }
445 }
446 } while (*domainname);
447 return true;
448 out:
449 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function,
450 org_domainname);
451 return false;
452 }
453
454 /**
455 * ccs_is_domain_def - Check whether the given token can be a domainname.
456 *
457 * @buffer: The token to check.
458 *
459 * Returns true if @buffer possibly be a domainname, false otherwise.
460 */
461 bool ccs_is_domain_def(const unsigned char *buffer)
462 {
463 return !strncmp(buffer, ROOT_NAME, ROOT_NAME_LEN);
464 }
465
466 /**
467 * ccs_find_domain - Find a domain by the given name.
468 *
469 * @domainname: The domainname to find.
470 *
471 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
472 */
473 struct ccs_domain_info *ccs_find_domain(const char *domainname)
474 {
475 struct ccs_domain_info *domain;
476 struct ccs_path_info name;
477 name.name = domainname;
478 ccs_fill_path_info(&name);
479 list1_for_each_entry(domain, &ccs_domain_list, list) {
480 if (!domain->is_deleted &&
481 !ccs_pathcmp(&name, domain->domainname))
482 return domain;
483 }
484 return NULL;
485 }
486
487 /**
488 * ccs_path_depth - Evaluate the number of '/' in a string.
489 *
490 * @pathname: The string to evaluate.
491 *
492 * Returns path depth of the string.
493 *
494 * I score 2 for each of the '/' in the @pathname
495 * and score 1 if the @pathname ends with '/'.
496 */
497 static int ccs_path_depth(const char *pathname)
498 {
499 int i = 0;
500 if (pathname) {
501 const char *ep = pathname + strlen(pathname);
502 if (pathname < ep--) {
503 if (*ep != '/')
504 i++;
505 while (pathname <= ep)
506 if (*ep-- == '/')
507 i += 2;
508 }
509 }
510 return i;
511 }
512
513 /**
514 * ccs_const_part_length - Evaluate the initial length without a pattern in a token.
515 *
516 * @filename: The string to evaluate.
517 *
518 * Returns the initial length without a pattern in @filename.
519 */
520 static int ccs_const_part_length(const char *filename)
521 {
522 char c;
523 int len = 0;
524 if (!filename)
525 return 0;
526 while (1) {
527 c = *filename++;
528 if (!c)
529 break;
530 if (c != '\\') {
531 len++;
532 continue;
533 }
534 c = *filename++;
535 switch (c) {
536 case '\\': /* "\\" */
537 len += 2;
538 continue;
539 case '0': /* "\ooo" */
540 case '1':
541 case '2':
542 case '3':
543 c = *filename++;
544 if (c < '0' || c > '7')
545 break;
546 c = *filename++;
547 if (c < '0' || c > '7')
548 break;
549 len += 4;
550 continue;
551 }
552 break;
553 }
554 return len;
555 }
556
557 /**
558 * ccs_fill_path_info - Fill in "struct ccs_path_info" members.
559 *
560 * @ptr: Pointer to "struct ccs_path_info" to fill in.
561 *
562 * The caller sets "struct ccs_path_info"->name.
563 */
564 void ccs_fill_path_info(struct ccs_path_info *ptr)
565 {
566 const char *name = ptr->name;
567 const int len = strlen(name);
568 ptr->total_len = len;
569 ptr->const_len = ccs_const_part_length(name);
570 ptr->is_dir = len && (name[len - 1] == '/');
571 ptr->is_patterned = (ptr->const_len < len);
572 ptr->hash = full_name_hash(name, len);
573 ptr->depth = ccs_path_depth(name);
574 }
575
576 /**
577 * ccs_file_matches_pattern2 - Pattern matching without '/' character
578 * and "\-" pattern.
579 *
580 * @filename: The start of string to check.
581 * @filename_end: The end of string to check.
582 * @pattern: The start of pattern to compare.
583 * @pattern_end: The end of pattern to compare.
584 *
585 * Returns true if @filename matches @pattern, false otherwise.
586 */
587 static bool ccs_file_matches_pattern2(const char *filename,
588 const char *filename_end,
589 const char *pattern,
590 const char *pattern_end)
591 {
592 while (filename < filename_end && pattern < pattern_end) {
593 char c;
594 if (*pattern != '\\') {
595 if (*filename++ != *pattern++)
596 return false;
597 continue;
598 }
599 c = *filename;
600 pattern++;
601 switch (*pattern) {
602 int i;
603 int j;
604 case '?':
605 if (c == '/') {
606 return false;
607 } else if (c == '\\') {
608 if (filename[1] == '\\')
609 filename++;
610 else if (ccs_is_byte_range(filename + 1))
611 filename += 3;
612 else
613 return false;
614 }
615 break;
616 case '\\':
617 if (c != '\\')
618 return false;
619 if (*++filename != '\\')
620 return false;
621 break;
622 case '+':
623 if (!ccs_is_decimal(c))
624 return false;
625 break;
626 case 'x':
627 if (!ccs_is_hexadecimal(c))
628 return false;
629 break;
630 case 'a':
631 if (!ccs_is_alphabet_char(c))
632 return false;
633 break;
634 case '0':
635 case '1':
636 case '2':
637 case '3':
638 if (c == '\\' && ccs_is_byte_range(filename + 1)
639 && strncmp(filename + 1, pattern, 3) == 0) {
640 filename += 3;
641 pattern += 2;
642 break;
643 }
644 return false; /* Not matched. */
645 case '*':
646 case '@':
647 for (i = 0; i <= filename_end - filename; i++) {
648 if (ccs_file_matches_pattern2(filename + i,
649 filename_end,
650 pattern + 1,
651 pattern_end))
652 return true;
653 c = filename[i];
654 if (c == '.' && *pattern == '@')
655 break;
656 if (c != '\\')
657 continue;
658 if (filename[i + 1] == '\\')
659 i++;
660 else if (ccs_is_byte_range(filename + i + 1))
661 i += 3;
662 else
663 break; /* Bad pattern. */
664 }
665 return false; /* Not matched. */
666 default:
667 j = 0;
668 c = *pattern;
669 if (c == '$') {
670 while (ccs_is_decimal(filename[j]))
671 j++;
672 } else if (c == 'X') {
673 while (ccs_is_hexadecimal(filename[j]))
674 j++;
675 } else if (c == 'A') {
676 while (ccs_is_alphabet_char(filename[j]))
677 j++;
678 }
679 for (i = 1; i <= j; i++) {
680 if (ccs_file_matches_pattern2(filename + i,
681 filename_end,
682 pattern + 1,
683 pattern_end))
684 return true;
685 }
686 return false; /* Not matched or bad pattern. */
687 }
688 filename++;
689 pattern++;
690 }
691 while (*pattern == '\\' &&
692 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
693 pattern += 2;
694 return filename == filename_end && pattern == pattern_end;
695 }
696
697 /**
698 * ccs_file_matches_pattern - Pattern matching without without '/' character.
699 *
700 * @filename: The start of string to check.
701 * @filename_end: The end of string to check.
702 * @pattern: The start of pattern to compare.
703 * @pattern_end: The end of pattern to compare.
704 *
705 * Returns true if @filename matches @pattern, false otherwise.
706 */
707 static bool ccs_file_matches_pattern(const char *filename,
708 const char *filename_end,
709 const char *pattern,
710 const char *pattern_end)
711 {
712 const char *pattern_start = pattern;
713 bool first = true;
714 bool result;
715 while (pattern < pattern_end - 1) {
716 /* Split at "\-" pattern. */
717 if (*pattern++ != '\\' || *pattern++ != '-')
718 continue;
719 result = ccs_file_matches_pattern2(filename, filename_end,
720 pattern_start, pattern - 2);
721 if (first)
722 result = !result;
723 if (result)
724 return false;
725 first = false;
726 pattern_start = pattern;
727 }
728 result = ccs_file_matches_pattern2(filename, filename_end,
729 pattern_start, pattern_end);
730 return first ? result : !result;
731 }
732
733 /**
734 * ccs_path_matches_pattern - Check whether the given filename matches the given pattern.
735 * @filename: The filename to check.
736 * @pattern: The pattern to compare.
737 *
738 * Returns true if matches, false otherwise.
739 *
740 * The following patterns are available.
741 * \\ \ itself.
742 * \ooo Octal representation of a byte.
743 * \* More than or equals to 0 character other than '/'.
744 * \@ More than or equals to 0 character other than '/' or '.'.
745 * \? 1 byte character other than '/'.
746 * \$ More than or equals to 1 decimal digit.
747 * \+ 1 decimal digit.
748 * \X More than or equals to 1 hexadecimal digit.
749 * \x 1 hexadecimal digit.
750 * \A More than or equals to 1 alphabet character.
751 * \a 1 alphabet character.
752 * \- Subtraction operator.
753 */
754 bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
755 const struct ccs_path_info *pattern)
756 {
757 /*
758 if (!filename || !pattern)
759 return false;
760 */
761 const char *f = filename->name;
762 const char *p = pattern->name;
763 const int len = pattern->const_len;
764 /* If @pattern doesn't contain pattern, I can use strcmp(). */
765 if (!pattern->is_patterned)
766 return !ccs_pathcmp(filename, pattern);
767 /* Dont compare if the number of '/' differs. */
768 if (filename->depth != pattern->depth)
769 return false;
770 /* Compare the initial length without patterns. */
771 if (strncmp(f, p, len))
772 return false;
773 f += len;
774 p += len;
775 /* Main loop. Compare each directory component. */
776 while (*f && *p) {
777 const char *f_delimiter = strchr(f, '/');
778 const char *p_delimiter = strchr(p, '/');
779 if (!f_delimiter)
780 f_delimiter = f + strlen(f);
781 if (!p_delimiter)
782 p_delimiter = p + strlen(p);
783 if (!ccs_file_matches_pattern(f, f_delimiter, p, p_delimiter))
784 return false;
785 f = f_delimiter;
786 if (*f)
787 f++;
788 p = p_delimiter;
789 if (*p)
790 p++;
791 }
792 /* Ignore trailing "\*" and "\@" in @pattern. */
793 while (*p == '\\' &&
794 (*(p + 1) == '*' || *(p + 1) == '@'))
795 p += 2;
796 return !*f && !*p;
797 }
798
799 /**
800 * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.
801 *
802 * @head: Pointer to "struct ccs_io_buffer".
803 * @fmt: The printf()'s format string, followed by parameters.
804 *
805 * Returns true on success, false otherwise.
806 *
807 * The snprintf() will truncate, but ccs_io_printf() won't.
808 */
809 bool ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
810 {
811 va_list args;
812 int len;
813 int pos = head->read_avail;
814 int size = head->readbuf_size - pos;
815 if (size <= 0)
816 return false;
817 va_start(args, fmt);
818 len = vsnprintf(head->read_buf + pos, size, fmt, args);
819 va_end(args);
820 if (pos + len >= head->readbuf_size)
821 return false;
822 head->read_avail += len;
823 return true;
824 }
825
826 /**
827 * ccs_get_exe - Get ccs_realpath() of current process.
828 *
829 * Returns the ccs_realpath() of current process on success, NULL otherwise.
830 *
831 * This function uses ccs_alloc(), so the caller must ccs_free()
832 * if this function didn't return NULL.
833 */
834 const char *ccs_get_exe(void)
835 {
836 struct mm_struct *mm = current->mm;
837 struct vm_area_struct *vma;
838 const char *cp = NULL;
839 if (!mm)
840 return NULL;
841 down_read(&mm->mmap_sem);
842 for (vma = mm->mmap; vma; vma = vma->vm_next) {
843 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
844 cp = ccs_realpath_from_dentry(vma->vm_file->f_dentry,
845 vma->vm_file->f_vfsmnt);
846 break;
847 }
848 }
849 up_read(&mm->mmap_sem);
850 return cp;
851 }
852
853 /**
854 * ccs_get_msg - Get warning message.
855 *
856 * @is_enforce: Is it enforcing mode?
857 *
858 * Returns "ERROR" or "WARNING".
859 */
860 const char *ccs_get_msg(const bool is_enforce)
861 {
862 if (is_enforce)
863 return "ERROR";
864 else
865 return "WARNING";
866 }
867
868 /**
869 * ccs_can_sleep - Check whether it is permitted to do operations that may sleep.
870 *
871 * Returns true if it is permitted to do operations that may sleep,
872 * false otherwise.
873 *
874 * TOMOYO Linux supports interactive enforcement that lets processes
875 * wait for the administrator's decision.
876 * All hooks but the one for ccs_may_autobind() are inserted where
877 * it is permitted to do operations that may sleep.
878 * Thus, this warning should not happen.
879 */
880 bool ccs_can_sleep(void)
881 {
882 static u8 count = 20;
883 if (likely(!in_interrupt()))
884 return true;
885 if (count) {
886 count--;
887 printk(KERN_ERR "BUG: sleeping function called "
888 "from invalid context.\n");
889 dump_stack();
890 }
891 return false;
892 }
893
894 /**
895 * ccs_check_flags - Check mode for specified functionality.
896 *
897 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
898 * @index: The functionality to check mode.
899 *
900 * Returns the mode of specified functionality.
901 */
902 unsigned int ccs_check_flags(const struct ccs_domain_info *domain,
903 const u8 index)
904 {
905 u8 profile;
906 if (!domain)
907 domain = ccs_current_domain();
908 profile = domain->profile;
909 return ccs_policy_loaded && index < CCS_MAX_CONTROL_INDEX
910 #if MAX_PROFILES != 256
911 && profile < MAX_PROFILES
912 #endif
913 && ccs_profile_ptr[profile] ?
914 ccs_profile_ptr[profile]->value[index] : 0;
915 }
916
917 #ifdef CONFIG_TOMOYO
918 /**
919 * ccs_check_capability_flags - Check mode for specified capability.
920 *
921 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
922 * @index: The capability to check mode.
923 *
924 * Returns the mode of specified capability.
925 */
926 static u8 ccs_check_capability_flags(const struct ccs_domain_info *domain,
927 const u8 index)
928 {
929 const u8 profile = domain ? domain->profile :
930 ccs_current_domain()->profile;
931 return ccs_policy_loaded && index < CCS_MAX_CAPABILITY_INDEX
932 #if MAX_PROFILES != 256
933 && profile < MAX_PROFILES
934 #endif
935 && ccs_profile_ptr[profile] ?
936 ccs_profile_ptr[profile]->capability_value[index] : 0;
937 }
938
939 /**
940 * ccs_cap2keyword - Convert capability operation to capability name.
941 *
942 * @operation: The capability index.
943 *
944 * Returns the name of the specified capability's name.
945 */
946 const char *ccs_cap2keyword(const u8 operation)
947 {
948 return operation < CCS_MAX_CAPABILITY_INDEX
949 ? ccs_capability_control_keyword[operation] : NULL;
950 }
951
952 #endif
953
954 /**
955 * ccs_init_request_info - Initialize "struct ccs_request_info" members.
956 *
957 * @r: Pointer to "struct ccs_request_info" to initialize.
958 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
959 * @index: Index number of functionality.
960 */
961 void ccs_init_request_info(struct ccs_request_info *r,
962 struct ccs_domain_info *domain, const u8 index)
963 {
964 memset(r, 0, sizeof(*r));
965 if (!domain)
966 domain = ccs_current_domain();
967 r->domain = domain;
968 r->profile = domain->profile;
969 if (index < CCS_MAX_CONTROL_INDEX)
970 r->mode = ccs_check_flags(domain, index);
971 #ifdef CONFIG_TOMOYO
972 else
973 r->mode = ccs_check_capability_flags(domain, index
974 - CCS_MAX_CONTROL_INDEX);
975 #endif
976 }
977
978 /**
979 * ccs_verbose_mode - Check whether TOMOYO is verbose mode.
980 *
981 * @domain: Pointer to "struct ccs_domain_info". NULL for ccs_current_domain().
982 *
983 * Returns true if domain policy violation warning should be printed to
984 * console.
985 */
986 bool ccs_verbose_mode(const struct ccs_domain_info *domain)
987 {
988 return ccs_check_flags(domain, CCS_VERBOSE) != 0;
989 }
990
991 /**
992 * ccs_domain_quota_ok - Check for domain's quota.
993 *
994 * @domain: Pointer to "struct ccs_domain_info".
995 *
996 * Returns true if the domain is not exceeded quota, false otherwise.
997 */
998 bool ccs_domain_quota_ok(struct ccs_domain_info * const domain)
999 {
1000 unsigned int count = 0;
1001 struct ccs_acl_info *ptr;
1002 if (!domain)
1003 return true;
1004 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
1005 if (ptr->type & ACL_DELETED)
1006 continue;
1007 switch (ccs_acl_type2(ptr)) {
1008 struct ccs_single_path_acl_record *acl1;
1009 struct ccs_double_path_acl_record *acl2;
1010 u16 perm;
1011 case TYPE_SINGLE_PATH_ACL:
1012 acl1 = container_of(ptr,
1013 struct ccs_single_path_acl_record,
1014 head);
1015 perm = acl1->perm;
1016 if (perm & (1 << TYPE_EXECUTE_ACL))
1017 count++;
1018 if (perm &
1019 ((1 << TYPE_READ_ACL) | (1 << TYPE_WRITE_ACL)))
1020 count++;
1021 if (perm & (1 << TYPE_CREATE_ACL))
1022 count++;
1023 if (perm & (1 << TYPE_UNLINK_ACL))
1024 count++;
1025 if (perm & (1 << TYPE_MKDIR_ACL))
1026 count++;
1027 if (perm & (1 << TYPE_RMDIR_ACL))
1028 count++;
1029 if (perm & (1 << TYPE_MKFIFO_ACL))
1030 count++;
1031 if (perm & (1 << TYPE_MKSOCK_ACL))
1032 count++;
1033 if (perm & (1 << TYPE_MKBLOCK_ACL))
1034 count++;
1035 if (perm & (1 << TYPE_MKCHAR_ACL))
1036 count++;
1037 if (perm & (1 << TYPE_TRUNCATE_ACL))
1038 count++;
1039 if (perm & (1 << TYPE_SYMLINK_ACL))
1040 count++;
1041 if (perm & (1 << TYPE_REWRITE_ACL))
1042 count++;
1043 break;
1044 case TYPE_DOUBLE_PATH_ACL:
1045 acl2 = container_of(ptr,
1046 struct ccs_double_path_acl_record,
1047 head);
1048 perm = acl2->perm;
1049 if (perm & (1 << TYPE_LINK_ACL))
1050 count++;
1051 if (perm & (1 << TYPE_RENAME_ACL))
1052 count++;
1053 break;
1054 case TYPE_EXECUTE_HANDLER:
1055 case TYPE_DENIED_EXECUTE_HANDLER:
1056 break;
1057 default:
1058 count++;
1059 }
1060 }
1061 if (count < ccs_check_flags(domain, CCS_MAX_ACCEPT_ENTRY))
1062 return true;
1063 if (!domain->quota_warned) {
1064 domain->quota_warned = true;
1065 printk(KERN_WARNING "TOMOYO-WARNING: "
1066 "Domain '%s' has so many ACLs to hold. "
1067 "Stopped learning mode.\n", domain->domainname->name);
1068 }
1069 return false;
1070 }
1071
1072 /**
1073 * ccs_find_or_assign_new_profile - Create a new profile.
1074 *
1075 * @profile: Profile number to create.
1076 *
1077 * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
1078 */
1079 static struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int
1080 profile)
1081 {
1082 static DEFINE_MUTEX(lock);
1083 struct ccs_profile *ptr = NULL;
1084 mutex_lock(&lock);
1085 if (profile < MAX_PROFILES) {
1086 ptr = ccs_profile_ptr[profile];
1087 if (ptr)
1088 goto ok;
1089 ptr = ccs_alloc_element(sizeof(*ptr));
1090 if (ptr) {
1091 int i;
1092 for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++)
1093 ptr->value[i]
1094 = ccs_control_array[i].current_value;
1095 /*
1096 * Needn't to initialize "ptr->capability_value"
1097 * because they are always 0.
1098 */
1099 mb(); /* Avoid out-of-order execution. */
1100 ccs_profile_ptr[profile] = ptr;
1101 }
1102 }
1103 ok:
1104 mutex_unlock(&lock);
1105 return ptr;
1106 }
1107
1108 /**
1109 * ccs_write_profile - Write profile table.
1110 *
1111 * @head: Pointer to "struct ccs_io_buffer".
1112 *
1113 * Returns 0 on success, negative value otherwise.
1114 */
1115 static int ccs_write_profile(struct ccs_io_buffer *head)
1116 {
1117 char *data = head->write_buf;
1118 unsigned int i;
1119 unsigned int value;
1120 char *cp;
1121 struct ccs_profile *ccs_profile;
1122 i = simple_strtoul(data, &cp, 10);
1123 if (data != cp) {
1124 if (*cp != '-')
1125 return -EINVAL;
1126 data = cp + 1;
1127 }
1128 ccs_profile = ccs_find_or_assign_new_profile(i);
1129 if (!ccs_profile)
1130 return -EINVAL;
1131 cp = strchr(data, '=');
1132 if (!cp)
1133 return -EINVAL;
1134 *cp = '\0';
1135 ccs_update_counter(CCS_UPDATES_COUNTER_PROFILE);
1136 if (!strcmp(data, "COMMENT")) {
1137 ccs_profile->comment = ccs_save_name(cp + 1);
1138 ccs_profile_entry_used[0] = true;
1139 return 0;
1140 }
1141 #ifdef CONFIG_TOMOYO
1142 if (ccs_str_starts(&data, KEYWORD_MAC_FOR_CAPABILITY)) {
1143 if (sscanf(cp + 1, "%u", &value) != 1) {
1144 for (i = 0; i < 4; i++) {
1145 if (strcmp(cp + 1, ccs_mode_4[i]))
1146 continue;
1147 value = i;
1148 break;
1149 }
1150 if (i == 4)
1151 return -EINVAL;
1152 }
1153 if (value > 3)
1154 value = 3;
1155 for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) {
1156 if (strcmp(data, ccs_capability_control_keyword[i]))
1157 continue;
1158 ccs_profile->capability_value[i] = value;
1159 ccs_profile_entry_used[i + 1 + CCS_MAX_CONTROL_INDEX]
1160 = true;
1161 return 0;
1162 }
1163 return -EINVAL;
1164 }
1165 #endif
1166 for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {
1167 if (strcmp(data, ccs_control_array[i].keyword))
1168 continue;
1169 if (sscanf(cp + 1, "%u", &value) != 1) {
1170 int j;
1171 const char **modes;
1172 switch (i) {
1173 case CCS_RESTRICT_AUTOBIND:
1174 case CCS_VERBOSE:
1175 modes = ccs_mode_2;
1176 break;
1177 default:
1178 modes = ccs_mode_4;
1179 break;
1180 }
1181 for (j = 0; j < 4; j++) {
1182 if (strcmp(cp + 1, modes[j]))
1183 continue;
1184 value = j;
1185 break;
1186 }
1187 if (j == 4)
1188 return -EINVAL;
1189 } else if (value > ccs_control_array[i].max_value) {
1190 value = ccs_control_array[i].max_value;
1191 }
1192 switch (i) {
1193 case CCS_DENY_CONCEAL_MOUNT:
1194 case CCS_RESTRICT_UNMOUNT:
1195 if (value == 1)
1196 value = 2; /* learning mode is not supported. */
1197 }
1198 ccs_profile->value[i] = value;
1199 ccs_profile_entry_used[i + 1] = true;
1200 return 0;
1201 }
1202 return -EINVAL;
1203 }
1204
1205 /**
1206 * ccs_read_profile - Read profile table.
1207 *
1208 * @head: Pointer to "struct ccs_io_buffer".
1209 *
1210 * Returns 0.
1211 */
1212 static int ccs_read_profile(struct ccs_io_buffer *head)
1213 {
1214 static const int ccs_total
1215 = CCS_MAX_CONTROL_INDEX + CCS_MAX_CAPABILITY_INDEX + 1;
1216 int step;
1217 if (head->read_eof)
1218 return 0;
1219 for (step = head->read_step; step < MAX_PROFILES * ccs_total; step++) {
1220 const u8 index = step / ccs_total;
1221 u8 type = step % ccs_total;
1222 const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];
1223 head->read_step = step;
1224 if (!ccs_profile)
1225 continue;
1226 #if !defined(CONFIG_SAKURA) || !defined(CONFIG_TOMOYO)
1227 switch (type - 1) {
1228 #ifndef CONFIG_SAKURA
1229 case CCS_DENY_CONCEAL_MOUNT:
1230 case CCS_RESTRICT_CHROOT:
1231 case CCS_RESTRICT_MOUNT:
1232 case CCS_RESTRICT_UNMOUNT:
1233 case CCS_RESTRICT_PIVOT_ROOT:
1234 case CCS_RESTRICT_AUTOBIND:
1235 #endif
1236 #ifndef CONFIG_TOMOYO
1237 case CCS_MAC_FOR_FILE:
1238 case CCS_MAC_FOR_IOCTL:
1239 case CCS_MAC_FOR_ARGV0:
1240 case CCS_MAC_FOR_ENV:
1241 case CCS_MAC_FOR_NETWORK:
1242 case CCS_MAC_FOR_SIGNAL:
1243 case CCS_MAX_ACCEPT_ENTRY:
1244 case CCS_VERBOSE:
1245 #endif
1246 continue;
1247 }
1248 #endif
1249 if (!ccs_profile_entry_used[type])
1250 continue;
1251 if (!type) { /* Print profile' comment tag. */
1252 if (!ccs_io_printf(head, "%u-COMMENT=%s\n",
1253 index, ccs_profile->comment ?
1254 ccs_profile->comment->name : ""))
1255 break;
1256 continue;
1257 }
1258 type--;
1259 if (type >= CCS_MAX_CONTROL_INDEX) {
1260 #ifdef CONFIG_TOMOYO
1261 const int i = type - CCS_MAX_CONTROL_INDEX;
1262 const u8 value = ccs_profile->capability_value[i];
1263 if (!ccs_io_printf(head,
1264 "%u-" KEYWORD_MAC_FOR_CAPABILITY
1265 "%s=%s\n", index,
1266 ccs_capability_control_keyword[i],
1267 ccs_mode_4[value]))
1268 break;
1269 #endif
1270 } else {
1271 const unsigned int value = ccs_profile->value[type];
1272 const char **modes = NULL;
1273 const char *keyword = ccs_control_array[type].keyword;
1274 switch (ccs_control_array[type].max_value) {
1275 case 3:
1276 modes = ccs_mode_4;
1277 break;
1278 case 1:
1279 modes = ccs_mode_2;
1280 break;
1281 }
1282 if (modes) {
1283 if (!ccs_io_printf(head, "%u-%s=%s\n", index,
1284 keyword, modes[value]))
1285 break;
1286 } else {
1287 if (!ccs_io_printf(head, "%u-%s=%u\n", index,
1288 keyword, value))
1289 break;
1290 }
1291 }
1292 }
1293 if (step == MAX_PROFILES * ccs_total)
1294 head->read_eof = true;
1295 return 0;
1296 }
1297
1298 /* Structure for policy manager. */
1299 struct ccs_policy_manager_entry {
1300 struct list1_head list;
1301 /* A path to program or a domainname. */
1302 const struct ccs_path_info *manager;
1303 bool is_domain; /* True if manager is a domainname. */
1304 bool is_deleted; /* True if this entry is deleted. */
1305 };
1306
1307 /* The list for "struct ccs_policy_manager_entry". */
1308 static LIST1_HEAD(ccs_policy_manager_list);
1309
1310 /**
1311 * ccs_update_manager_entry - Add a manager entry.
1312 *
1313 * @manager: The path to manager or the domainnamme.
1314 * @is_delete: True if it is a delete request.
1315 *
1316 * Returns 0 on success, negative value otherwise.
1317 */
1318 static int ccs_update_manager_entry(const char *manager, const bool is_delete)
1319 {
1320 struct ccs_policy_manager_entry *new_entry;
1321 struct ccs_policy_manager_entry *ptr;
1322 static DEFINE_MUTEX(lock);
1323 const struct ccs_path_info *saved_manager;
1324 int error = -ENOMEM;
1325 bool is_domain = false;
1326 if (ccs_is_domain_def(manager)) {
1327 if (!ccs_is_correct_domain(manager, __func__))
1328 return -EINVAL;
1329 is_domain = true;
1330 } else {
1331 if (!ccs_is_correct_path(manager, 1, -1, -1, __func__))
1332 return -EINVAL;
1333 }
1334 saved_manager = ccs_save_name(manager);
1335 if (!saved_manager)
1336 return -ENOMEM;
1337 mutex_lock(&lock);
1338 list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1339 if (ptr->manager != saved_manager)
1340 continue;
1341 ptr->is_deleted = is_delete;
1342 error = 0;
1343 goto out;
1344 }
1345 if (is_delete) {
1346 error = -ENOENT;
1347 goto out;
1348 }
1349 new_entry = ccs_alloc_element(sizeof(*new_entry));
1350 if (!new_entry)
1351 goto out;
1352 new_entry->manager = saved_manager;
1353 new_entry->is_domain = is_domain;
1354 list1_add_tail_mb(&new_entry->list, &ccs_policy_manager_list);
1355 error = 0;
1356 out:
1357 mutex_unlock(&lock);
1358 if (!error)
1359 ccs_update_counter(CCS_UPDATES_COUNTER_MANAGER);
1360 return error;
1361 }
1362
1363 /**
1364 * ccs_write_manager_policy - Write manager policy.
1365 *
1366 * @head: Pointer to "struct ccs_io_buffer".
1367 *
1368 * Returns 0 on success, negative value otherwise.
1369 */
1370 static int ccs_write_manager_policy(struct ccs_io_buffer *head)
1371 {
1372 char *data = head->write_buf;
1373 bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
1374 if (!strcmp(data, "manage_by_non_root")) {
1375 ccs_manage_by_non_root = !is_delete;
1376 return 0;
1377 }
1378 return ccs_update_manager_entry(data, is_delete);
1379 }
1380
1381 /**
1382 * ccs_read_manager_policy - Read manager policy.
1383 *
1384 * @head: Pointer to "struct ccs_io_buffer".
1385 *
1386 * Returns 0.
1387 */
1388 static int ccs_read_manager_policy(struct ccs_io_buffer *head)
1389 {
1390 struct list1_head *pos;
1391 if (head->read_eof)
1392 return 0;
1393 list1_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {
1394 struct ccs_policy_manager_entry *ptr;
1395 ptr = list1_entry(pos, struct ccs_policy_manager_entry, list);
1396 if (ptr->is_deleted)
1397 continue;
1398 if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
1399 return 0;
1400 }
1401 head->read_eof = true;
1402 return 0;
1403 }
1404
1405 /**
1406 * ccs_is_policy_manager - Check whether the current process is a policy manager.
1407 *
1408 * Returns true if the current process is permitted to modify policy
1409 * via /proc/ccs/ interface.
1410 */
1411 static bool ccs_is_policy_manager(void)
1412 {
1413 struct ccs_policy_manager_entry *ptr;
1414 const char *exe;
1415 struct task_struct *task = current;
1416 const struct ccs_path_info *domainname
1417 = ccs_current_domain()->domainname;
1418 bool found = false;
1419 if (!ccs_policy_loaded)
1420 return true;
1421 if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)
1422 return true;
1423 if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
1424 return false;
1425 list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1426 if (!ptr->is_deleted && ptr->is_domain
1427 && !ccs_pathcmp(domainname, ptr->manager)) {
1428 /* Set manager flag. */
1429 task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
1430 return true;
1431 }
1432 }
1433 exe = ccs_get_exe();
1434 if (!exe)
1435 return false;
1436 list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1437 if (!ptr->is_deleted && !ptr->is_domain
1438 && !strcmp(exe, ptr->manager->name)) {
1439 found = true;
1440 /* Set manager flag. */
1441 task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
1442 break;
1443 }
1444 }
1445 if (!found) { /* Reduce error messages. */
1446 static pid_t ccs_last_pid;
1447 const pid_t pid = current->pid;
1448 if (ccs_last_pid != pid) {
1449 printk(KERN_WARNING "%s ( %s ) is not permitted to "
1450 "update policies.\n", domainname->name, exe);
1451 ccs_last_pid = pid;
1452 }
1453 }
1454 ccs_free(exe);
1455 return found;
1456 }
1457
1458 #ifdef CONFIG_TOMOYO
1459
1460 /**
1461 * ccs_find_condition_part - Find condition part from the statement.
1462 *
1463 * @data: String to parse.
1464 *
1465 * Returns pointer to the condition part if it was found in the statement,
1466 * NULL otherwise.
1467 */
1468 static char *ccs_find_condition_part(char *data)
1469 {
1470 char *cp = strstr(data, " if ");
1471 if (cp) {
1472 while (1) {
1473 char *cp2 = strstr(cp + 3, " if ");
1474 if (!cp2)
1475 break;
1476 cp = cp2;
1477 }
1478 *cp++ = '\0';
1479 } else {
1480 cp = strstr(data, " ; set ");
1481 if (cp)
1482 *cp++ = '\0';
1483 }
1484 return cp;
1485 }
1486
1487 /**
1488 * ccs_is_select_one - Parse select command.
1489 *
1490 * @head: Pointer to "struct ccs_io_buffer".
1491 * @data: String to parse.
1492 *
1493 * Returns true on success, false otherwise.
1494 */
1495 static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)
1496 {
1497 unsigned int pid;
1498 struct ccs_domain_info *domain = NULL;
1499 if (!strcmp(data, "allow_execute")) {
1500 head->read_execute_only = true;
1501 return true;
1502 }
1503 if (sscanf(data, "pid=%u", &pid) == 1) {
1504 struct task_struct *p;
1505 /***** CRITICAL SECTION START *****/
1506 read_lock(&tasklist_lock);
1507 p = find_task_by_pid(pid);
1508 if (p)
1509 domain = ccs_task_domain(p);
1510 read_unlock(&tasklist_lock);
1511 /***** CRITICAL SECTION END *****/
1512 } else if (!strncmp(data, "domain=", 7)) {
1513 if (ccs_is_domain_def(data + 7))
1514 domain = ccs_find_domain(data + 7);
1515 } else
1516 return false;
1517 head->write_var1 = domain;
1518 /* Accessing read_buf is safe because head->io_sem is held. */
1519 if (!head->read_buf)
1520 return true; /* Do nothing if open(O_WRONLY). */
1521 head->read_avail = 0;
1522 ccs_io_printf(head, "# select %s\n", data);
1523 head->read_single_domain = true;
1524 head->read_eof = !domain;
1525 if (domain) {
1526 struct ccs_domain_info *d;
1527 head->read_var1 = NULL;
1528 list1_for_each_entry(d, &ccs_domain_list, list) {
1529 if (d == domain)
1530 break;
1531 head->read_var1 = &d->list;
1532 }
1533 head->read_var2 = NULL;
1534 head->read_bit = 0;
1535 head->read_step = 0;
1536 if (domain->is_deleted)
1537 ccs_io_printf(head, "# This is a deleted domain.\n");
1538 }
1539 return true;
1540 }
1541
1542 /**
1543 * ccs_write_domain_policy - Write domain policy.
1544 *
1545 * @head: Pointer to "struct ccs_io_buffer".
1546 *
1547 * Returns 0 on success, negative value otherwise.
1548 */
1549 static int ccs_write_domain_policy(struct ccs_io_buffer *head)
1550 {
1551 char *data = head->write_buf;
1552 struct ccs_domain_info *domain = head->write_var1;
1553 bool is_delete = false;
1554 bool is_select = false;
1555 unsigned int profile;
1556 const struct ccs_condition_list *cond = NULL;
1557 char *cp;
1558 if (ccs_str_starts(&data, KEYWORD_DELETE))
1559 is_delete = true;
1560 else if (ccs_str_starts(&data, KEYWORD_SELECT))
1561 is_select = true;
1562 if (is_select && ccs_is_select_one(head, data))
1563 return 0;
1564 /* Don't allow updating policies by non manager programs. */
1565 if (!ccs_is_policy_manager())
1566 return -EPERM;
1567 if (ccs_is_domain_def(data)) {
1568 domain = NULL;
1569 if (is_delete)
1570 ccs_delete_domain(data);
1571 else if (is_select)
1572 domain = ccs_find_domain(data);
1573 else
1574 domain = ccs_find_or_assign_new_domain(data, 0);
1575 head->write_var1 = domain;
1576 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
1577 return 0;
1578 }
1579 if (!domain)
1580 return -EINVAL;
1581
1582 if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1
1583 && profile < MAX_PROFILES) {
1584 if (ccs_profile_ptr[profile] || !ccs_policy_loaded)
1585 domain->profile = (u8) profile;
1586 return 0;
1587 }
1588 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1589 ccs_set_domain_flag(domain, is_delete,
1590 DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
1591 return 0;
1592 }
1593 if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_ENV)) {
1594 ccs_set_domain_flag(domain, is_delete,
1595 DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV);
1596 return 0;
1597 }
1598 cp = ccs_find_condition_part(data);
1599 if (cp) {
1600 cond = ccs_find_or_assign_new_condition(cp);
1601 if (!cond)
1602 return -EINVAL;
1603 }
1604 if (ccs_str_starts(&data, KEYWORD_ALLOW_CAPABILITY))
1605 return ccs_write_capability_policy(data, domain, cond,
1606 is_delete);
1607 else if (ccs_str_starts(&data, KEYWORD_ALLOW_NETWORK))
1608 return ccs_write_network_policy(data, domain, cond, is_delete);
1609 else if (ccs_str_starts(&data, KEYWORD_ALLOW_SIGNAL))
1610 return ccs_write_signal_policy(data, domain, cond, is_delete);
1611 else if (ccs_str_starts(&data, KEYWORD_ALLOW_ARGV0))
1612 return ccs_write_argv0_policy(data, domain, cond, is_delete);
1613 else if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
1614 return ccs_write_env_policy(data, domain, cond, is_delete);
1615 else if (ccs_str_starts(&data, KEYWORD_ALLOW_IOCTL))
1616 return ccs_write_ioctl_policy(data, domain, cond, is_delete);
1617 else
1618 return ccs_write_file_policy(data, domain, cond, is_delete);
1619 }
1620
1621 /**
1622 * ccs_print_single_path_acl - Print a single path ACL entry.
1623 *
1624 * @head: Pointer to "struct ccs_io_buffer".
1625 * @ptr: Pointer to "struct ccs_single_path_acl_record".
1626 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1627 *
1628 * Returns true on success, false otherwise.
1629 */
1630 static bool ccs_print_single_path_acl(struct ccs_io_buffer *head,
1631 struct ccs_single_path_acl_record *ptr,
1632 const struct ccs_condition_list *cond)
1633 {
1634 int pos;
1635 u8 bit;
1636 const char *atmark = "";
1637 const char *filename;
1638 const u16 perm = ptr->perm;
1639 if (ptr->u_is_group) {
1640 atmark = "@";
1641 filename = ptr->u.group->group_name->name;
1642 } else {
1643 filename = ptr->u.filename->name;
1644 }
1645 for (bit = head->read_bit; bit < MAX_SINGLE_PATH_OPERATION; bit++) {
1646 const char *msg;
1647 if (!(perm & (1 << bit)))
1648 continue;
1649 if (head->read_execute_only && bit != TYPE_EXECUTE_ACL)
1650 continue;
1651 /* Print "read/write" instead of "read" and "write". */
1652 if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)
1653 && (perm & (1 << TYPE_READ_WRITE_ACL)))
1654 continue;
1655 msg = ccs_sp2keyword(bit);
1656 pos = head->read_avail;
1657 if (!ccs_io_printf(head, "allow_%s %s%s", msg,
1658 atmark, filename) ||
1659 !ccs_print_condition(head, cond))
1660 goto out;
1661 }
1662 head->read_bit = 0;
1663 return true;
1664 out:
1665 head->read_bit = bit;
1666 head->read_avail = pos;
1667 return false;
1668 }
1669
1670 /**
1671 * ccs_print_double_path_acl - Print a double path ACL entry.
1672 *
1673 * @head: Pointer to "struct ccs_io_buffer".
1674 * @ptr: Pointer to "struct ccs_double_path_acl_record".
1675 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1676 *
1677 * Returns true on success, false otherwise.
1678 */
1679 static bool ccs_print_double_path_acl(struct ccs_io_buffer *head,
1680 struct ccs_double_path_acl_record *ptr,
1681 const struct ccs_condition_list *cond)
1682 {
1683 int pos;
1684 const char *atmark1 = "";
1685 const char *atmark2 = "";
1686 const char *filename1;
1687 const char *filename2;
1688 const u8 perm = ptr->perm;
1689 u8 bit;
1690 if (ptr->u1_is_group) {
1691 atmark1 = "@";
1692 filename1 = ptr->u1.group1->group_name->name;
1693 } else {
1694 filename1 = ptr->u1.filename1->name;
1695 }
1696 if (ptr->u2_is_group) {
1697 atmark2 = "@";
1698 filename2 = ptr->u2.group2->group_name->name;
1699 } else {
1700 filename2 = ptr->u2.filename2->name;
1701 }
1702 for (bit = head->read_bit; bit < MAX_DOUBLE_PATH_OPERATION; bit++) {
1703 const char *msg;
1704 if (!(perm & (1 << bit)))
1705 continue;
1706 msg = ccs_dp2keyword(bit);
1707 pos = head->read_avail;
1708 if (!ccs_io_printf(head, "allow_%s %s%s %s%s", msg,
1709 atmark1, filename1, atmark2, filename2) ||
1710 !ccs_print_condition(head, cond))
1711 goto out;
1712 }
1713 head->read_bit = 0;
1714 return true;
1715 out:
1716 head->read_bit = bit;
1717 head->read_avail = pos;
1718 return false;
1719 }
1720
1721 /**
1722 * ccs_print_ioctl_acl - Print an ioctl ACL entry.
1723 *
1724 * @head: Pointer to "struct ccs_io_buffer".
1725 * @ptr: Pointer to "struct ccs_ioctl_acl_record".
1726 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1727 *
1728 * Returns true on success, false otherwise.
1729 */
1730 static bool ccs_print_ioctl_acl(struct ccs_io_buffer *head,
1731 struct ccs_ioctl_acl_record *ptr,
1732 const struct ccs_condition_list *cond)
1733 {
1734 int pos = head->read_avail;
1735 const char *atmark = "";
1736 const char *filename;
1737 const unsigned int cmd_min = ptr->cmd_min;
1738 const unsigned int cmd_max = ptr->cmd_max;
1739 if (ptr->u_is_group) {
1740 atmark = "@";
1741 filename = ptr->u.group->group_name->name;
1742 } else {
1743 filename = ptr->u.filename->name;
1744 }
1745 if (!ccs_io_printf(head, KEYWORD_ALLOW_IOCTL "%s%s ", atmark, filename))
1746 goto out;
1747 if (!ccs_io_printf(head, "%u", cmd_min))
1748 goto out;
1749 if (cmd_min != cmd_max && !ccs_io_printf(head, "-%u", cmd_max))
1750 goto out;
1751 if (!ccs_print_condition(head, cond))
1752 goto out;
1753 return true;
1754 out:
1755 head->read_avail = pos;
1756 return false;
1757 }
1758
1759 /**
1760 * ccs_print_argv0_acl - Print an argv[0] ACL entry.
1761 *
1762 * @head: Pointer to "struct ccs_io_buffer".
1763 * @ptr: Pointer to "struct ccs_argv0_acl_record".
1764 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1765 *
1766 * Returns true on success, false otherwise.
1767 */
1768 static bool ccs_print_argv0_acl(struct ccs_io_buffer *head,
1769 struct ccs_argv0_acl_record *ptr,
1770 const struct ccs_condition_list *cond)
1771 {
1772 int pos = head->read_avail;
1773 if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
1774 ptr->filename->name, ptr->argv0->name))
1775 goto out;
1776 if (!ccs_print_condition(head, cond))
1777 goto out;
1778 return true;
1779 out:
1780 head->read_avail = pos;
1781 return false;
1782 }
1783
1784 /**
1785 * ccs_print_env_acl - Print an evironment variable name's ACL entry.
1786 *
1787 * @head: Pointer to "struct ccs_io_buffer".
1788 * @ptr: Pointer to "struct ccs_env_acl_record".
1789 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1790 *
1791 * Returns true on success, false otherwise.
1792 */
1793 static bool ccs_print_env_acl(struct ccs_io_buffer *head,
1794 struct ccs_env_acl_record *ptr,
1795 const struct ccs_condition_list *cond)
1796 {
1797 int pos = head->read_avail;
1798 if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))
1799 goto out;
1800 if (!ccs_print_condition(head, cond))
1801 goto out;
1802 return true;
1803 out:
1804 head->read_avail = pos;
1805 return false;
1806 }
1807
1808 /**
1809 * ccs_print_capability_acl - Print a capability ACL entry.
1810 *
1811 * @head: Pointer to "struct ccs_io_buffer".
1812 * @ptr: Pointer to "struct ccs_capability_acl_record".
1813 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1814 *
1815 * Returns true on success, false otherwise.
1816 */
1817 static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
1818 struct ccs_capability_acl_record *ptr,
1819 const struct ccs_condition_list *cond)
1820 {
1821 int pos = head->read_avail;
1822 if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",
1823 ccs_cap2keyword(ptr->operation)))
1824 goto out;
1825 if (!ccs_print_condition(head, cond))
1826 goto out;
1827 return true;
1828 out:
1829 head->read_avail = pos;
1830 return false;
1831 }
1832
1833 /**
1834 * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
1835 *
1836 * @head: Pointer to "struct ccs_io_buffer".
1837 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1838 *
1839 * Returns true on success, false otherwise.
1840 */
1841 static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
1842 struct ccs_ip_network_acl_record *ptr)
1843 {
1844 const u32 min_address = ptr->u.ipv4.min;
1845 const u32 max_address = ptr->u.ipv4.max;
1846 if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
1847 return false;
1848 if (min_address != max_address
1849 && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
1850 return false;
1851 return true;
1852 }
1853
1854 /**
1855 * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
1856 *
1857 * @head: Pointer to "struct ccs_io_buffer".
1858 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1859 *
1860 * Returns true on success, false otherwise.
1861 */
1862 static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
1863 struct ccs_ip_network_acl_record *ptr)
1864 {
1865 char buf[64];
1866 const struct in6_addr *min_address = ptr->u.ipv6.min;
1867 const struct in6_addr *max_address = ptr->u.ipv6.max;
1868 ccs_print_ipv6(buf, sizeof(buf), min_address);
1869 if (!ccs_io_printf(head, "%s", buf))
1870 return false;
1871 if (min_address != max_address) {
1872 ccs_print_ipv6(buf, sizeof(buf), max_address);
1873 if (!ccs_io_printf(head, "-%s", buf))
1874 return false;
1875 }
1876 return true;
1877 }
1878
1879 /**
1880 * ccs_print_port_entry - Print port number of a network ACL entry.
1881 *
1882 * @head: Pointer to "struct ccs_io_buffer".
1883 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1884 *
1885 * Returns true on success, false otherwise.
1886 */
1887 static bool ccs_print_port_entry(struct ccs_io_buffer *head,
1888 struct ccs_ip_network_acl_record *ptr)
1889 {
1890 const u16 min_port = ptr->min_port;
1891 const u16 max_port = ptr->max_port;
1892 if (!ccs_io_printf(head, " %u", min_port))
1893 return false;
1894 if (min_port != max_port && !ccs_io_printf(head, "-%u", max_port))
1895 return false;
1896 return true;
1897 }
1898
1899 /**
1900 * ccs_print_network_acl - Print a network ACL entry.
1901 *
1902 * @head: Pointer to "struct ccs_io_buffer".
1903 * @ptr: Pointer to "struct ccs_ip_network_acl_record".
1904 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1905 *
1906 * Returns true on success, false otherwise.
1907 */
1908 static bool ccs_print_network_acl(struct ccs_io_buffer *head,
1909 struct ccs_ip_network_acl_record *ptr,
1910 const struct ccs_condition_list *cond)
1911 {
1912 int pos = head->read_avail;
1913 if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",
1914 ccs_net2keyword(ptr->operation_type)))
1915 goto out;
1916 switch (ptr->record_type) {
1917 case IP_RECORD_TYPE_ADDRESS_GROUP:
1918 if (!ccs_io_printf(head, "@%s", ptr->u.group->group_name->name))
1919 goto out;
1920 break;
1921 case IP_RECORD_TYPE_IPv4:
1922 if (!ccs_print_ipv4_entry(head, ptr))
1923 goto out;
1924 break;
1925 case IP_RECORD_TYPE_IPv6:
1926 if (!ccs_print_ipv6_entry(head, ptr))
1927 goto out;
1928 break;
1929 }
1930 if (!ccs_print_port_entry(head, ptr))
1931 goto out;
1932 if (!ccs_print_condition(head, cond))
1933 goto out;
1934 return true;
1935 out:
1936 head->read_avail = pos;
1937 return false;
1938 }
1939
1940 /**
1941 * ccs_print_signal_acl - Print a signal ACL entry.
1942 *
1943 * @head: Pointer to "struct ccs_io_buffer".
1944 * @ptr: Pointer to "struct signale_acl_record".
1945 * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1946 *
1947 * Returns true on success, false otherwise.
1948 */
1949 static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
1950 struct ccs_signal_acl_record *ptr,
1951 const struct ccs_condition_list *cond)
1952 {
1953 int pos = head->read_avail;
1954 if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",
1955 ptr->sig, ptr->domainname->name))
1956 goto out;
1957 if (!ccs_print_condition(head, cond))
1958 goto out;
1959 return true;
1960 out:
1961 head->read_avail = pos;
1962 return false;
1963 }
1964
1965 /**
1966 * ccs_print_execute_handler_record - Print an execute handler ACL entry.
1967 *
1968 * @head: Pointer to "struct ccs_io_buffer".
1969 * @keyword: Name of the keyword.
1970 * @ptr: Pointer to "struct ccs_execute_handler_record".
1971 *
1972 * Returns true on success, false otherwise.
1973 */
1974 static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1975 const char *keyword,
1976 struct ccs_execute_handler_record *
1977 ptr)
1978 {
1979 return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1980 }
1981
1982 /**
1983 * ccs_print_entry - Print an ACL entry.
1984 *
1985 * @head: Pointer to "struct ccs_io_buffer".
1986 * @ptr: Pointer to an ACL entry.
1987 *
1988 * Returns true on success, false otherwise.
1989 */
1990 static bool ccs_print_entry(struct ccs_io_buffer *head,
1991 struct ccs_acl_info *ptr)
1992 {
1993 const struct ccs_condition_list *cond = ccs_get_condition_part(ptr);
1994 const u8 acl_type = ccs_acl_type2(ptr);
1995 if (acl_type & ACL_DELETED)
1996 return true;
1997 if (acl_type == TYPE_SINGLE_PATH_ACL) {
1998 struct ccs_single_path_acl_record *acl
1999 = container_of(ptr, struct ccs_single_path_acl_record,
2000 head);
2001 return ccs_print_single_path_acl(head, acl, cond);
2002 }
2003 if (acl_type == TYPE_EXECUTE_HANDLER) {
2004 struct ccs_execute_handler_record *acl
2005 = container_of(ptr, struct ccs_execute_handler_record,
2006 head);
2007 const char *keyword = KEYWORD_EXECUTE_HANDLER;
2008 return ccs_print_execute_handler_record(head, keyword, acl);
2009 }
2010 if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {
2011 struct ccs_execute_handler_record *acl
2012 = container_of(ptr, struct ccs_execute_handler_record,
2013 head);
2014 const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;
2015 return ccs_print_execute_handler_record(head, keyword, acl);
2016 }
2017 if (head->read_execute_only)
2018 return true;
2019 if (acl_type == TYPE_DOUBLE_PATH_ACL) {
2020 struct ccs_double_path_acl_record *acl
2021 = container_of(ptr, struct ccs_double_path_acl_record,
2022 head);
2023 return ccs_print_double_path_acl(head, acl, cond);
2024 }
2025 if (acl_type == TYPE_IOCTL_ACL) {
2026 struct ccs_ioctl_acl_record *acl
2027 = container_of(ptr, struct ccs_ioctl_acl_record, head);
2028 return ccs_print_ioctl_acl(head, acl, cond);
2029 }
2030 if (acl_type == TYPE_ARGV0_ACL) {
2031 struct ccs_argv0_acl_record *acl
2032 = container_of(ptr, struct ccs_argv0_acl_record, head);
2033 return ccs_print_argv0_acl(head, acl, cond);
2034 }
2035 if (acl_type == TYPE_ENV_ACL) {
2036 struct ccs_env_acl_record *acl
2037 = container_of(ptr, struct ccs_env_acl_record, head);
2038 return ccs_print_env_acl(head, acl, cond);
2039 }
2040 if (acl_type == TYPE_CAPABILITY_ACL) {
2041 struct ccs_capability_acl_record *acl
2042 = container_of(ptr, struct ccs_capability_acl_record,
2043 head);
2044 return ccs_print_capability_acl(head, acl, cond);
2045 }
2046 if (acl_type == TYPE_IP_NETWORK_ACL) {
2047 struct ccs_ip_network_acl_record *acl
2048 = container_of(ptr, struct ccs_ip_network_acl_record,
2049 head);
2050 return ccs_print_network_acl(head, acl, cond);
2051 }
2052 if (acl_type == TYPE_SIGNAL_ACL) {
2053 struct ccs_signal_acl_record *acl
2054 = container_of(ptr, struct ccs_signal_acl_record, head);
2055 return ccs_print_signal_acl(head, acl, cond);
2056 }
2057 /* Workaround for gcc 3.2.2's inline bug. */
2058 if (acl_type & ACL_DELETED)
2059 return true;
2060 BUG(); /* This must not happen. */
2061 return false;
2062 }
2063
2064 /**
2065 * ccs_read_domain_policy - Read domain policy.
2066 *
2067 * @head: Pointer to "struct ccs_io_buffer".
2068 *
2069 * Returns 0.
2070 */
2071 static int ccs_read_domain_policy(struct ccs_io_buffer *head)
2072 {
2073 struct list1_head *dpos;
2074 struct list1_head *apos;
2075 if (head->read_eof)
2076 return 0;
2077 if (head->read_step == 0)
2078 head->read_step = 1;
2079 list1_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
2080 struct ccs_domain_info *domain;
2081 const char *quota_exceeded = "";
2082 const char *transition_failed = "";
2083 const char *ignore_global_allow_read = "";
2084 const char *ignore_global_allow_env = "";
2085 domain = list1_entry(dpos, struct ccs_domain_info, list);
2086 if (head->read_step != 1)
2087 goto acl_loop;
2088 if (domain->is_deleted && !head->read_single_domain)
2089 continue;
2090 /* Print domainname and flags. */
2091 if (domain->quota_warned)
2092 quota_exceeded = "quota_exceeded\n";
2093 if (domain->flags & DOMAIN_FLAGS_TRANSITION_FAILED)
2094 transition_failed = "transition_failed\n";
2095 if (domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
2096 ignore_global_allow_read
2097 = KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
2098 if (domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV)
2099 ignore_global_allow_env
2100 = KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
2101 if (!ccs_io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n"
2102 "%s%s%s%s\n", domain->domainname->name,
2103 domain->profile, quota_exceeded,
2104 transition_failed,
2105 ignore_global_allow_read,
2106 ignore_global_allow_env))
2107 return 0;
2108 head->read_step = 2;
2109 acl_loop:
2110 if (head->read_step == 3)
2111 goto tail_mark;
2112 /* Print ACL entries in the domain. */
2113 list1_for_each_cookie(apos, head->read_var2,
2114 &domain->acl_info_list) {
2115 struct ccs_acl_info *ptr
2116 = list1_entry(apos, struct ccs_acl_info, list);
2117 if (!ccs_print_entry(head, ptr))
2118 return 0;
2119 }
2120 head->read_step = 3;
2121 tail_mark:
2122 if (!ccs_io_printf(head, "\n"))
2123 return 0;
2124 head->read_step = 1;
2125 if (head->read_single_domain)
2126 break;
2127 }
2128 head->read_eof = true;
2129 return 0;
2130 }
2131
2132 #endif
2133
2134 /**
2135 * ccs_write_domain_profile - Assign profile for specified domain.
2136 *
2137 * @head: Pointer to "struct ccs_io_buffer".
2138 *
2139 * Returns 0 on success, -EINVAL otherwise.
2140 *
2141 * This is equivalent to doing
2142 *
2143 * ( echo "select " $domainname; echo "use_profile " $profile ) |
2144 * /usr/lib/ccs/loadpolicy -d
2145 */
2146 static int ccs_write_domain_profile(struct ccs_io_buffer *head)
2147 {
2148 char *data = head->write_buf;
2149 char *cp = strchr(data, ' ');
2150 struct ccs_domain_info *domain;
2151 unsigned int profile;
2152 if (!cp)
2153 return -EINVAL;
2154 *cp = '\0';
2155 domain = ccs_find_domain(cp + 1);
2156 profile = simple_strtoul(data, NULL, 10);
2157 if (domain && profile < MAX_PROFILES
2158 && (ccs_profile_ptr[profile] || !ccs_policy_loaded))
2159 domain->profile = (u8) profile;
2160 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
2161 return 0;
2162 }
2163
2164 /**
2165 * ccs_read_domain_profile - Read only domainname and profile.
2166 *
2167 * @head: Pointer to "struct ccs_io_buffer".
2168 *
2169 * Returns list of profile number and domainname pairs.
2170 *
2171 * This is equivalent to doing
2172 *
2173 * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
2174 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
2175 * domainname = $0; } else if ( $1 == "use_profile" ) {
2176 * print $2 " " domainname; domainname = ""; } } ; '
2177 */
2178 static int ccs_read_domain_profile(struct ccs_io_buffer *head)
2179 {
2180 struct list1_head *pos;
2181 if (head->read_eof)
2182 return 0;
2183 list1_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
2184 struct ccs_domain_info *domain;
2185 domain = list1_entry(pos, struct ccs_domain_info, list);
2186 if (domain->is_deleted)
2187 continue;
2188 if (!ccs_io_printf(head, "%u %s\n", domain->profile,
2189 domain->domainname->name))
2190 return 0;
2191 }
2192 head->read_eof = true;
2193 return 0;
2194 }
2195
2196 /**
2197 * ccs_write_pid: Specify PID to obtain domainname.
2198 *
2199 * @head: Pointer to "struct ccs_io_buffer".
2200 *
2201 * Returns 0.
2202 */
2203 static int ccs_write_pid(struct ccs_io_buffer *head)
2204 {
2205 head->read_eof = false;
2206 return 0;
2207 }
2208
2209 /**
2210 * ccs_read_pid - Read information of a process.
2211 *
2212 * @head: Pointer to "struct ccs_io_buffer".
2213 *
2214 * Returns the domainname which the specified PID is in or
2215 * process information of the specified PID on success,
2216 * empty string otherwise.
2217 */
2218 static int ccs_read_pid(struct ccs_io_buffer *head)
2219 {
2220 char *buf = head->write_buf;
2221 bool task_info = false;
2222 unsigned int pid;
2223 struct task_struct *p;
2224 struct ccs_domain_info *domain = NULL;
2225 u32 ccs_flags = 0;
2226 /* Accessing write_buf is safe because head->io_sem is held. */
2227 if (!buf)
2228 goto done; /* Do nothing if open(O_RDONLY). */
2229 if (head->read_avail || head->read_eof)
2230 goto done;
2231 head->read_eof = true;
2232 if (ccs_str_starts(&buf, "info "))
2233 task_info = true;
2234 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
2235 /***** CRITICAL SECTION START *****/
2236 read_lock(&tasklist_lock);
2237 p = find_task_by_pid(pid);
2238 if (p) {
2239 domain = ccs_task_domain(p);
2240 ccs_flags = p->ccs_flags;
2241 }
2242 read_unlock(&tasklist_lock);
2243 /***** CRITICAL SECTION END *****/
2244 if (!domain)
2245 goto done;
2246 if (!task_info)
2247 ccs_io_printf(head, "%u %u %s", pid, domain->profile,
2248 domain->domainname->name);
2249 else
2250 ccs_io_printf(head, "%u manager=%s execute_handler=%s "
2251 "state[0]=%u state[1]=%u state[2]=%u", pid,
2252 ccs_flags & CCS_TASK_IS_POLICY_MANAGER ?
2253 "yes" : "no",
2254 ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ?
2255 "yes" : "no",
2256 (u8) (ccs_flags >> 24),
2257 (u8) (ccs_flags >> 16),
2258 (u8) (ccs_flags >> 8));
2259 done:
2260 return 0;
2261 }
2262
2263 #ifdef CONFIG_TOMOYO
2264
2265 /**
2266 * ccs_write_exception_policy - Write exception policy.
2267 *
2268 * @head: Pointer to "struct ccs_io_buffer".
2269 *
2270 * Returns 0 on success, negative value otherwise.
2271 */
2272 static int ccs_write_exception_policy(struct ccs_io_buffer *head)
2273 {
2274 char *data = head->write_buf;
2275 bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
2276 if (ccs_str_starts(&data, KEYWORD_KEEP_DOMAIN))
2277 return ccs_write_domain_keeper_policy(data, false, is_delete);
2278 if (ccs_str_starts(&data, KEYWORD_NO_KEEP_DOMAIN))
2279 return ccs_write_domain_keeper_policy(data, true, is_delete);
2280 if (ccs_str_starts(&data, KEYWORD_INITIALIZE_DOMAIN))
2281 return ccs_write_domain_initializer_policy(data, false,
2282 is_delete);
2283 if (ccs_str_starts(&data, KEYWORD_NO_INITIALIZE_DOMAIN))
2284 return ccs_write_domain_initializer_policy(data, true,
2285 is_delete);
2286 if (ccs_str_starts(&data, KEYWORD_ALIAS))
2287 return ccs_write_alias_policy(data, is_delete);
2288 if (ccs_str_starts(&data, KEYWORD_AGGREGATOR))
2289 return ccs_write_aggregator_policy(data, is_delete);
2290 if (ccs_str_starts(&data, KEYWORD_ALLOW_READ))
2291 return ccs_write_globally_readable_policy(data, is_delete);
2292 if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
2293 return ccs_write_globally_usable_env_policy(data, is_delete);
2294 if (ccs_str_starts(&data, KEYWORD_FILE_PATTERN))
2295 return ccs_write_pattern_policy(data, is_delete);
2296 if (ccs_str_starts(&data, KEYWORD_PATH_GROUP))
2297 return ccs_write_path_group_policy(data, is_delete);
2298 if (ccs_str_starts(&data, KEYWORD_DENY_REWRITE))
2299 return ccs_write_no_rewrite_policy(data, is_delete);
2300 if (ccs_str_starts(&data, KEYWORD_ADDRESS_GROUP))
2301 return ccs_write_address_group_policy(data, is_delete);
2302 return -EINVAL;
2303 }
2304
2305 /**
2306 * ccs_read_exception_policy - Read exception policy.
2307 *
2308 * @head: Pointer to "struct ccs_io_buffer".
2309 *
2310 * Returns 0 on success, -EINVAL otherwise.
2311 */
2312 static int ccs_read_exception_policy(struct ccs_io_buffer *head)
2313 {
2314 if (!head->read_eof) {
2315 switch (head->read_step) {
2316 case 0:
2317 head->read_var2 = NULL;
2318 head->read_step = 1;
2319 case 1:
2320 if (!ccs_read_domain_keeper_policy(head))
2321 break;
2322 head->read_var2 = NULL;
2323 head->read_step = 2;
2324 case 2:
2325 if (!ccs_read_globally_readable_policy(head))
2326 break;
2327 head->read_var2 = NULL;
2328 head->read_step = 3;
2329 case 3:
2330 if (!ccs_read_globally_usable_env_policy(head))
2331 break;
2332 head->read_var2 = NULL;
2333 head->read_step = 4;
2334 case 4:
2335 if (!ccs_read_domain_initializer_policy(head))
2336 break;
2337 head->read_var2 = NULL;
2338 head->read_step = 5;
2339 case 5:
2340 if (!ccs_read_alias_policy(head))
2341 break;
2342 head->read_var2 = NULL;
2343 head->read_step = 6;
2344 case 6:
2345 if (!ccs_read_aggregator_policy(head))
2346 break;
2347 head->read_var2 = NULL;
2348 head->read_step = 7;
2349 case 7:
2350 if (!ccs_read_file_pattern(head))
2351 break;
2352 head->read_var2 = NULL;
2353 head->read_step = 8;
2354 case 8:
2355 if (!ccs_read_no_rewrite_policy(head))
2356 break;
2357 head->read_var2 = NULL;
2358 head->read_step = 9;
2359 case 9:
2360 if (!ccs_read_path_group_policy(head))
2361 break;
2362 head->read_var1 = NULL;
2363 head->read_var2 = NULL;
2364 head->read_step = 10;
2365 case 10:
2366 if (!ccs_read_address_group_policy(head))
2367 break;
2368 head->read_eof = true;
2369 break;
2370 default:
2371 return -EINVAL;
2372 }
2373 }
2374 return 0;
2375 }
2376
2377 #endif
2378
2379 #ifdef CONFIG_SAKURA
2380
2381 /**
2382 * ccs_write_system_policy - Write system policy.
2383 *
2384 * @head: Pointer to "struct ccs_io_buffer".
2385 *
2386 * Returns 0 on success, negative value otherwise.
2387 */
2388 static int ccs_write_system_policy(struct ccs_io_buffer *head)
2389 {
2390 char *data = head->write_buf;
2391 bool is_delete = false;
2392 if (ccs_str_starts(&data, KEYWORD_DELETE))
2393 is_delete = true;
2394 if (ccs_str_starts(&data, KEYWORD_ALLOW_MOUNT))
2395 return ccs_write_mount_policy(data, is_delete);
2396 if (ccs_str_starts(&data, KEYWORD_DENY_UNMOUNT))
2397 return ccs_write_no_umount_policy(data, is_delete);
2398 if (ccs_str_starts(&data, KEYWORD_ALLOW_CHROOT))
2399 return ccs_write_chroot_policy(data, is_delete);
2400 if (ccs_str_starts(&data, KEYWORD_ALLOW_PIVOT_ROOT))
2401 return ccs_write_pivot_root_policy(data, is_delete);
2402 if (ccs_str_starts(&data, KEYWORD_DENY_AUTOBIND))
2403 return ccs_write_reserved_port_policy(data, is_delete);
2404 return -EINVAL;
2405 }
2406
2407 /**
2408 * ccs_read_system_policy - Read system policy.
2409 *
2410 * @head: Pointer to "struct ccs_io_buffer".
2411 *
2412 * Returns 0 on success, -EINVAL otherwise.
2413 */
2414 static int ccs_read_system_policy(struct ccs_io_buffer *head)
2415 {
2416 if (!head->read_eof) {
2417 switch (head->read_step) {
2418 case 0:
2419 head->read_var2 = NULL;
2420 head->read_step = 1;
2421 case 1:
2422 if (!ccs_read_mount_policy(head))
2423 break;
2424 head->read_var2 = NULL;
2425 head->read_step = 2;
2426 case 2:
2427 if (!ccs_read_no_umount_policy(head))
2428 break;
2429 head->read_var2 = NULL;
2430 head->read_step = 3;
2431 case 3:
2432 if (!ccs_read_chroot_policy(head))
2433 break;
2434 head->read_var2 = NULL;
2435 head->read_step = 4;
2436 case 4:
2437 if (!ccs_read_pivot_root_policy(head))
2438 break;
2439 head->read_var2 = NULL;
2440 head->read_step = 5;
2441 case 5:
2442 if (!ccs_read_reserved_port_policy(head))
2443 break;
2444 head->read_eof = true;
2445 break;
2446 default:
2447 return -EINVAL;
2448 }
2449 }
2450 return 0;
2451 }
2452
2453 #endif
2454
2455 /* Path to the policy loader. The default is /sbin/ccs-init. */
2456 static const char *ccs_loader;
2457
2458 /**
2459 * ccs_loader_setup - Specify the policy loader to use.
2460 *
2461 * @str: Path to the policy loader.
2462 *
2463 * Returns 0.
2464 */
2465 static int __init ccs_loader_setup(char *str)
2466 {
2467 ccs_loader = str;
2468 return 0;
2469 }
2470
2471 __setup("CCS_loader=", ccs_loader_setup);
2472
2473 /**
2474 * ccs_policy_loader_exists - Check whether /sbin/ccs-init exists.
2475 *
2476 * Returns true if /sbin/ccs-init exists, false otherwise.
2477 */
2478 static bool ccs_policy_loader_exists(void)
2479 {
2480 /*
2481 * Don't activate MAC if the path given by 'CCS_loader=' option doesn't
2482 * exist. If the initrd includes /sbin/init but real-root-dev has not
2483 * mounted on / yet, activating MAC will block the system since
2484 * policies are not loaded yet.
2485 * Thus, let do_execve() call this function everytime.
2486 */
2487 struct nameidata nd;
2488 if (!ccs_loader)
2489 ccs_loader = "/sbin/ccs-init";
2490 if (path_lookup(ccs_loader, ccs_lookup_flags, &nd)) {
2491 printk(KERN_INFO "Not activating Mandatory Access Control now "
2492 "since %s doesn't exist.\n", ccs_loader);
2493 return false;
2494 }
2495 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
2496 path_put(&nd.path);
2497 #else
2498 path_release(&nd);
2499 #endif
2500 return true;
2501 }
2502
2503 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2504 /**
2505 * ccs_run_loader - Start /sbin/ccs-init .
2506 *
2507 * @unused: Not used.
2508 *
2509 * Returns PID of /sbin/ccs-init on success, negative value otherwise.
2510 */
2511 static int ccs_run_loader(void *unused)
2512 {
2513 char *argv[2];
2514 char *envp[3];
2515 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
2516 ccs_loader);
2517 argv[0] = (char *) ccs_loader;
2518 argv[1] = NULL;
2519 envp[0] = "HOME=/";
2520 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
2521 envp[2] = NULL;
2522 return exec_usermodehelper(argv[0], argv, envp);
2523 }
2524 #endif
2525
2526 /**
2527 * ccs_load_policy - Run external policy loader to load policy.
2528 *
2529 * @filename: The program about to start.
2530 *
2531 * This function checks whether @filename is /sbin/init , and if so
2532 * invoke /sbin/ccs-init and wait for the termination of /sbin/ccs-init
2533 * and then continues invocation of /sbin/init.
2534 * /sbin/ccs-init reads policy files in /etc/ccs/ directory and
2535 * writes to /proc/ccs/ interfaces.
2536 *
2537 * Returns nothing.
2538 */
2539 void ccs_load_policy(const char *filename)
2540 {
2541 if (ccs_policy_loaded)
2542 return;
2543 /*
2544 * Check filename is /sbin/init or /sbin/ccs-start.
2545 * /sbin/ccs-start is a dummy filename in case where /sbin/init can't
2546 * be passed.
2547 * You can create /sbin/ccs-start by "ln -s /bin/true /sbin/ccs-start".
2548 */
2549 if (strcmp(filename, "/sbin/init") &&
2550 strcmp(filename, "/sbin/ccs-start"))
2551 return;
2552 if (!ccs_policy_loader_exists())
2553 return;
2554 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
2555 {
2556 char *argv[2];
2557 char *envp[3];
2558 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
2559 ccs_loader);
2560 argv[0] = (char *) ccs_loader;
2561 argv[1] = NULL;
2562 envp[0] = "HOME=/";
2563 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
2564 envp[2] = NULL;
2565 call_usermodehelper(argv[0], argv, envp, 1);
2566 }
2567 #elif defined(TASK_DEAD)
2568 {
2569 /* Copied from kernel/kmod.c */
2570 struct task_struct *task = current;
2571 pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
2572 sigset_t tmpsig;
2573 spin_lock_irq(&task->sighand->siglock);
2574 tmpsig = task->blocked;
2575 siginitsetinv(&task->blocked,
2576 sigmask(SIGKILL) | sigmask(SIGSTOP));
2577 recalc_sigpending();
2578 spin_unlock_irq(&current->sighand->siglock);
2579 if (pid >= 0)
2580 waitpid(pid, NULL, __WCLONE);
2581 spin_lock_irq(&task->sighand->siglock);
2582 task->blocked = tmpsig;
2583 recalc_sigpending();
2584 spin_unlock_irq(&task->sighand->siglock);
2585 }
2586 #else
2587 {
2588 /* Copied from kernel/kmod.c */
2589 struct task_struct *task = current;
2590 pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
2591 sigset_t tmpsig;
2592 spin_lock_irq(&task->sigmask_lock);
2593 tmpsig = task->blocked;
2594 siginitsetinv(&task->blocked,
2595 sigmask(SIGKILL) | sigmask(SIGSTOP));
2596 recalc_sigpending(task);
2597 spin_unlock_irq(&task->sigmask_lock);
2598 if (pid >= 0)
2599 waitpid(pid, NULL, __WCLONE);
2600 spin_lock_irq(&task->sigmask_lock);
2601 task->blocked = tmpsig;
2602 recalc_sigpending(task);
2603 spin_unlock_irq(&task->sigmask_lock);
2604 }
2605 #endif
2606 #ifdef CONFIG_SAKURA
2607 printk(KERN_INFO "SAKURA: 1.6.7+ 2009/04/06\n");
2608 #endif
2609 #ifdef CONFIG_TOMOYO
2610 printk(KERN_INFO "TOMOYO: 1.6.7+ 2009/04/06\n");
2611 #endif
2612 printk(KERN_INFO "Mandatory Access Control activated.\n");
2613 ccs_policy_loaded = true;
2614 ccs_log_level = KERN_WARNING;
2615 { /* Check all profiles currently assigned to domains are defined. */
2616 struct ccs_domain_info *domain;
2617 list1_for_each_entry(domain, &ccs_domain_list, list) {
2618 const u8 profile = domain->profile;
2619 if (ccs_profile_ptr[profile])
2620 continue;
2621 panic("Profile %u (used by '%s') not defined.\n",
2622 profile, domain->domainname->name);
2623 }
2624 }
2625 }
2626
2627 /* Wait queue for ccs_query_list. */
2628 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
2629
2630 /* Lock for manipulating ccs_query_list. */
2631 static DEFINE_SPINLOCK(ccs_query_list_lock);
2632
2633 /* Structure for query. */
2634 struct ccs_query_entry {
2635 struct list_head list;
2636 char *query;
2637 int query_len;
2638 unsigned int serial;
2639 int timer;
2640 int answer;
2641 };
2642
2643 /* The list for "struct ccs_query_entry". */
2644 static LIST_HEAD(ccs_query_list);
2645
2646 /* Number of "struct file" referring /proc/ccs/query interface. */
2647 static atomic_t ccs_query_observers = ATOMIC_INIT(0);
2648
2649 /**
2650 * ccs_check_supervisor - Ask for the supervisor's decision.
2651 *
2652 * @r: Pointer to "struct ccs_request_info".
2653 * @fmt: The printf()'s format string, followed by parameters.
2654 *
2655 * Returns 0 if the supervisor decided to permit the access request which
2656 * violated the policy in enforcing mode, 1 if the supervisor decided to
2657 * retry the access request which violated the policy in enforcing mode,
2658 * -EPERM otherwise.
2659 */
2660 int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...)
2661 {
2662 va_list args;
2663 int error = -EPERM;
2664 int pos;
2665 int len;
2666 static unsigned int ccs_serial;
2667 struct ccs_query_entry *ccs_query_entry = NULL;
2668 char *header;
2669 if (!r->domain)
2670 r->domain = ccs_current_domain();
2671 if (!atomic_read(&ccs_query_observers)) {
2672 int i;
2673 if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2674 return -EPERM;
2675 for (i = 0; i < ccs_check_flags(r->domain, CCS_SLEEP_PERIOD);
2676 i++) {
2677 set_current_state(TASK_INTERRUPTIBLE);
2678 schedule_timeout(HZ / 10);
2679 }
2680 return -EPERM;
2681 }
2682 va_start(args, fmt);
2683 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2684 va_end(args);
2685 #ifdef CONFIG_TOMOYO
2686 header = ccs_init_audit_log(&len, r);
2687 #else
2688 header = ccs_alloc(1, true);
2689 #endif
2690 if (!header)
2691 goto out;
2692 ccs_query_entry = ccs_alloc(sizeof(*ccs_query_entry), true);
2693 if (!ccs_query_entry)
2694 goto out;
2695 ccs_query_entry->query = ccs_alloc(len, true);
2696 if (!ccs_query_entry->query)
2697 goto out;
2698 INIT_LIST_HEAD(&ccs_query_entry->list);
2699 /***** CRITICAL SECTION START *****/
2700 spin_lock(&ccs_query_list_lock);
2701 ccs_query_entry->serial = ccs_serial++;
2702 spin_unlock(&ccs_query_list_lock);
2703 /***** CRITICAL SECTION END *****/
2704 pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
2705 ccs_query_entry->serial, r->retry, header);
2706 ccs_free(header);
2707 header = NULL;
2708 va_start(args, fmt);
2709 vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);
2710 ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
2711 va_end(args);
2712 /***** CRITICAL SECTION START *****/
2713 spin_lock(&ccs_query_list_lock);
2714 list_add_tail(&ccs_query_entry->list, &ccs_query_list);
2715 spin_unlock(&ccs_query_list_lock);
2716 /***** CRITICAL SECTION END *****/
2717 ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);
2718 /* Give 10 seconds for supervisor's opinion. */
2719 for (ccs_query_entry->timer = 0;
2720 atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;
2721 ccs_query_entry->timer++) {
2722 wake_up(&ccs_query_wait);
2723 set_current_state(TASK_INTERRUPTIBLE);
2724 schedule_timeout(HZ / 10);
2725 if (ccs_query_entry->answer)
2726 break;
2727 }
2728 ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);
2729 /***** CRITICAL SECTION START *****/
2730 spin_lock(&ccs_query_list_lock);
2731 list_del(&ccs_query_entry->list);
2732 spin_unlock(&ccs_query_list_lock);
2733 /***** CRITICAL SECTION END *****/
2734 switch (ccs_query_entry->answer) {
2735 case 3: /* Asked to retry by administrator. */
2736 error = 1;
2737 r->retry++;
2738 break;
2739 case 1:
2740 /* Granted by administrator. */
2741 error = 0;
2742 break;
2743 case 0:
2744 /* Timed out. */
2745 break;
2746 default:
2747 /* Rejected by administrator. */
2748 break;
2749 }
2750 out:
2751 if (ccs_query_entry)
2752 ccs_free(ccs_query_entry->query);
2753 ccs_free(ccs_query_entry);
2754 ccs_free(header);
2755 return error;
2756 }
2757
2758 /**
2759 * ccs_poll_query - poll() for /proc/ccs/query.
2760 *
2761 * @file: Pointer to "struct file".
2762 * @wait: Pointer to "poll_table".
2763 *
2764 * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2765 *
2766 * Waits for access requests which violated policy in enforcing mode.
2767 */
2768 static int ccs_poll_query(struct file *file, poll_table *wait)
2769 {
2770 struct list_head *tmp;
2771 bool found = false;
2772 u8 i;
2773 for (i = 0; i < 2; i++) {
2774 /***** CRITICAL SECTION START *****/
2775 spin_lock(&ccs_query_list_lock);
2776 list_for_each(tmp, &ccs_query_list) {
2777 struct ccs_query_entry *ptr
2778 = list_entry(tmp, struct ccs_query_entry, list);
2779 if (ptr->answer)
2780 continue;
2781 found = true;
2782 break;
2783 }
2784 spin_unlock(&ccs_query_list_lock);
2785 /***** CRITICAL SECTION END *****/
2786 if (found)
2787 return POLLIN | POLLRDNORM;
2788 if (i)
2789 break;
2790 poll_wait(file, &ccs_query_wait, wait);
2791 }
2792 return 0;
2793 }
2794
2795 /**
2796 * ccs_read_query - Read access requests which violated policy in enforcing mode.
2797 *
2798 * @head: Pointer to "struct ccs_io_buffer".
2799 *
2800 * Returns 0.
2801 */
2802 static int ccs_read_query(struct ccs_io_buffer *head)
2803 {
2804 struct list_head *tmp;
2805 int pos = 0;
2806 int len = 0;
2807 char *buf;
2808 if (head->read_avail)
2809 return 0;
2810 if (head->read_buf) {
2811 ccs_free(head->read_buf);
2812 head->read_buf = NULL;
2813 head->readbuf_size = 0;
2814 }
2815 /***** CRITICAL SECTION START *****/
2816 spin_lock(&ccs_query_list_lock);
2817 list_for_each(tmp, &ccs_query_list) {
2818 struct ccs_query_entry *ptr
2819 = list_entry(tmp, struct ccs_query_entry, list);
2820 if (ptr->answer)
2821 continue;
2822 if (pos++ != head->read_step)
2823 continue;
2824 len = ptr->query_len;
2825 break;
2826 }
2827 spin_unlock(&ccs_query_list_lock);
2828 /***** CRITICAL SECTION END *****/
2829 if (!len) {
2830 head->read_step = 0;
2831 return 0;
2832 }
2833 buf = ccs_alloc(len, false);
2834 if (!buf)
2835 return 0;
2836 pos = 0;
2837 /***** CRITICAL SECTION START *****/
2838 spin_lock(&ccs_query_list_lock);
2839 list_for_each(tmp, &ccs_query_list) {
2840 struct ccs_query_entry *ptr
2841 = list_entry(tmp, struct ccs_query_entry, list);
2842 if (ptr->answer)
2843 continue;
2844 if (pos++ != head->read_step)
2845 continue;
2846 /*
2847 * Some query can be skipped because ccs_query_list
2848 * can change, but I don't care.
2849 */
2850 if (len == ptr->query_len)
2851 memmove(buf, ptr->query, len);
2852 break;
2853 }
2854 spin_unlock(&ccs_query_list_lock);
2855 /***** CRITICAL SECTION END *****/
2856 if (buf[0]) {
2857 head->read_avail = len;
2858 head->readbuf_size = head->read_avail;
2859 head->read_buf = buf;
2860 head->read_step++;
2861 } else {
2862 ccs_free(buf);
2863 }
2864 return 0;
2865 }
2866
2867 /**
2868 * ccs_write_answer - Write the supervisor's decision.
2869 *
2870 * @head: Pointer to "struct ccs_io_buffer".
2871 *
2872 * Returns 0 on success, -EINVAL otherwise.
2873 */
2874 static int ccs_write_answer(struct ccs_io_buffer *head)
2875 {
2876 char *data = head->write_buf;
2877 struct list_head *tmp;
2878 unsigned int serial;
2879 unsigned int answer;
2880 /***** CRITICAL SECTION START *****/
2881 spin_lock(&ccs_query_list_lock);
2882 list_for_each(tmp, &ccs_query_list) {
2883 struct ccs_query_entry *ptr
2884 = list_entry(tmp, struct ccs_query_entry, list);
2885 ptr->timer = 0;
2886 }
2887 spin_unlock(&ccs_query_list_lock);
2888 /***** CRITICAL SECTION END *****/
2889 if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2890 return -EINVAL;
2891 /***** CRITICAL SECTION START *****/
2892 spin_lock(&ccs_query_list_lock);
2893 list_for_each(tmp, &ccs_query_list) {
2894 struct ccs_query_entry *ptr
2895 = list_entry(tmp, struct ccs_query_entry, list);
2896 if (ptr->serial != serial)
2897 continue;
2898 if (!ptr->answer)
2899 ptr->answer = answer;
2900 break;
2901 }
2902 spin_unlock(&ccs_query_list_lock);
2903 /***** CRITICAL SECTION END *****/
2904 return 0;
2905 }
2906
2907 #if !defined(atomic_xchg) || LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 3)
2908
2909 /* Policy updates counter. */
2910 static unsigned int ccs_updates_counter[MAX_CCS_UPDATES_COUNTER];
2911
2912 /* Policy updates counter lock. */
2913 static DEFINE_SPINLOCK(ccs_updates_counter_lock);
2914
2915 /**
2916 * ccs_update_counter - Increment policy change counter.
2917 *
2918 * @index: Type of policy.
2919 *
2920 * Returns nothing.
2921 */
2922 void ccs_update_counter(const unsigned char index)
2923 {
2924 /***** CRITICAL SECTION START *****/
2925 spin_lock(&ccs_updates_counter_lock);
2926 if (index < MAX_CCS_UPDATES_COUNTER)
2927 ccs_updates_counter[index]++;
2928 spin_unlock(&ccs_updates_counter_lock);
2929 /***** CRITICAL SECTION END *****/
2930 }
2931
2932 /**
2933 * ccs_read_updates_counter - Check for policy change counter.
2934 *
2935 * @head: Pointer to "struct ccs_io_buffer".
2936 *
2937 * Returns how many times policy has changed since the previous check.
2938 */
2939 static int ccs_read_updates_counter(struct ccs_io_buffer *head)
2940 {
2941 unsigned int counter[MAX_CCS_UPDATES_COUNTER];
2942 if (head->read_eof)
2943 return 0;
2944 /***** CRITICAL SECTION START *****/
2945 spin_lock(&ccs_updates_counter_lock);
2946 memmove(counter, ccs_updates_counter, sizeof(ccs_updates_counter));
2947 memset(ccs_updates_counter, 0, sizeof(ccs_updates_counter));
2948 spin_unlock(&ccs_updates_counter_lock);
2949 /***** CRITICAL SECTION END *****/
2950 ccs_io_printf(head,
2951 "/proc/ccs/system_policy: %10u\n"
2952 "/proc/ccs/domain_policy: %10u\n"
2953 "/proc/ccs/exception_policy: %10u\n"
2954 "/proc/ccs/profile: %10u\n"
2955 "/proc/ccs/query: %10u\n"
2956 "/proc/ccs/manager: %10u\n"
2957 #ifdef CONFIG_TOMOYO_AUDIT
2958 "/proc/ccs/grant_log: %10u\n"
2959 "/proc/ccs/reject_log: %10u\n"
2960 #endif
2961 , counter[CCS_UPDATES_COUNTER_SYSTEM_POLICY]
2962 , counter[CCS_UPDATES_COUNTER_DOMAIN_POLICY]
2963 , counter[CCS_UPDATES_COUNTER_EXCEPTION_POLICY]
2964 , counter[CCS_UPDATES_COUNTER_PROFILE]
2965 , counter[CCS_UPDATES_COUNTER_QUERY]
2966 , counter[CCS_UPDATES_COUNTER_MANAGER]
2967 #ifdef CONFIG_TOMOYO_AUDIT
2968 , counter[CCS_UPDATES_COUNTER_GRANT_LOG]
2969 , counter[CCS_UPDATES_COUNTER_REJECT_LOG]
2970 #endif
2971 );
2972 head->read_eof = true;
2973 return 0;
2974 }
2975
2976 #else
2977
2978 /* Policy updates counter. */
2979 static atomic_t ccs_updates_counter[MAX_CCS_UPDATES_COUNTER];
2980
2981 /**
2982 * ccs_update_counter - Increment policy change counter.
2983 *
2984 * @index: Type of policy.
2985 *
2986 * Returns nothing.
2987 */
2988 void ccs_update_counter(const unsigned char index)
2989 {
2990 if (index < MAX_CCS_UPDATES_COUNTER)
2991 atomic_inc(&ccs_updates_counter[index]);
2992 }
2993
2994 /**
2995 * ccs_read_updates_counter - Check for policy change counter.
2996 *
2997 * @head: Pointer to "struct ccs_io_buffer".
2998 *
2999 * Returns how many times policy has changed since the previous check.
3000 */
3001 static int ccs_read_updates_counter(struct ccs_io_buffer *head)
3002 {
3003 if (head->read_eof)
3004 return 0;
3005 ccs_io_printf(head,
3006 "/proc/ccs/system_policy: %10u\n"
3007 "/proc/ccs/domain_policy: %10u\n"
3008 "/proc/ccs/exception_policy: %10u\n"
3009 "/proc/ccs/profile: %10u\n"
3010 "/proc/ccs/query: %10u\n"
3011 "/proc/ccs/manager: %10u\n"
3012 #ifdef CONFIG_TOMOYO_AUDIT
3013 "/proc/ccs/grant_log: %10u\n"
3014 "/proc/ccs/reject_log: %10u\n"
3015 #endif
3016 , atomic_xchg(&ccs_updates_counter
3017 [CCS_UPDATES_COUNTER_SYSTEM_POLICY], 0)
3018 , atomic_xchg(&ccs_updates_counter
3019 [CCS_UPDATES_COUNTER_DOMAIN_POLICY], 0)
3020 , atomic_xchg(&ccs_updates_counter
3021 [CCS_UPDATES_COUNTER_EXCEPTION_POLICY], 0)
3022 , atomic_xchg(&ccs_updates_counter
3023 [CCS_UPDATES_COUNTER_PROFILE], 0)
3024 , atomic_xchg(&ccs_updates_counter
3025 [CCS_UPDATES_COUNTER_QUERY], 0)
3026 , atomic_xchg(&ccs_updates_counter
3027 [CCS_UPDATES_COUNTER_MANAGER], 0)
3028 #ifdef CONFIG_TOMOYO_AUDIT
3029 , atomic_xchg(&ccs_updates_counter
3030 [CCS_UPDATES_COUNTER_GRANT_LOG], 0)
3031 , atomic_xchg(&ccs_updates_counter
3032 [CCS_UPDATES_COUNTER_REJECT_LOG], 0)
3033 #endif
3034 );
3035 head->read_eof = true;
3036 return 0;
3037 }
3038
3039 #endif
3040
3041 /**
3042 * ccs_read_version: Get version.
3043 *
3044 * @head: Pointer to "struct ccs_io_buffer".
3045 *
3046 * Returns version information.
3047 */
3048 static int ccs_read_version(struct ccs_io_buffer *head)
3049 {
3050 if (!head->read_eof) {
3051 ccs_io_printf(head, "1.6.7");
3052 head->read_eof = true;
3053 }
3054 return 0;
3055 }
3056
3057 /**
3058 * ccs_read_self_domain - Get the current process's domainname.
3059 *
3060 * @head: Pointer to "struct ccs_io_buffer".
3061 *
3062 * Returns the current process's domainname.
3063 */
3064 static int ccs_read_self_domain(struct ccs_io_buffer *head)
3065 {
3066 if (!head->read_eof) {
3067 /*
3068 * ccs_current_domain()->domainname != NULL
3069 * because every process belongs to a domain and
3070 * the domain's name cannot be NULL.
3071 */
3072 ccs_io_printf(head, "%s",
3073 ccs_current_domain()->domainname->name);
3074 head->read_eof = true;
3075 }
3076 return 0;
3077 }
3078
3079 /**
3080 * ccs_open_control - open() for /proc/ccs/ interface.
3081 *
3082 * @type: Type of interface.
3083 * @file: Pointer to "struct file".
3084 *
3085 * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
3086 */
3087 int ccs_open_control(const u8 type, struct file *file)
3088 {
3089 struct ccs_io_buffer *head = ccs_alloc(sizeof(*head), false);
3090 if (!head)
3091 return -ENOMEM;
3092 mutex_init(&head->io_sem);
3093 switch (type) {
3094 #ifdef CONFIG_SAKURA
3095 case CCS_SYSTEMPOLICY: /* /proc/ccs/system_policy */
3096 head->write = ccs_write_system_policy;
3097 head->read = ccs_read_system_policy;
3098 break;
3099 #endif
3100 #ifdef CONFIG_TOMOYO
3101 case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
3102 head->write = ccs_write_domain_policy;
3103 head->read = ccs_read_domain_policy;
3104 break;
3105 case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
3106 head->write = ccs_write_exception_policy;
3107 head->read = ccs_read_exception_policy;
3108 break;
3109 #ifdef CONFIG_TOMOYO_AUDIT
3110 case CCS_GRANTLOG: /* /proc/ccs/grant_log */
3111 head->poll = ccs_poll_grant_log;
3112 head->read = ccs_read_grant_log;
3113 break;
3114 case CCS_REJECTLOG: /* /proc/ccs/reject_log */
3115 head->poll = ccs_poll_reject_log;
3116 head->read = ccs_read_reject_log;
3117 break;
3118 #endif
3119 #endif
3120 case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
3121 head->read = ccs_read_self_domain;
3122 break;
3123 case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */
3124 head->write = ccs_write_domain_profile;
3125 head->read = ccs_read_domain_profile;
3126 break;
3127 case CCS_EXECUTE_HANDLER: /* /proc/ccs/.execute_handler */
3128 /* Allow execute_handler to read process's status. */
3129 if (!(current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
3130 ccs_free(head);
3131 return -EPERM;
3132 }
3133 /* fall through */
3134 case CCS_PROCESS_STATUS: /* /proc/ccs/.process_status */
3135 head->write = ccs_write_pid;
3136 head->read = ccs_read_pid;
3137 break;
3138 case CCS_VERSION: /* /proc/ccs/version */
3139 head->read = ccs_read_version;
3140 head->readbuf_size = 128;
3141 break;
3142 case CCS_MEMINFO: /* /proc/ccs/meminfo */
3143 head->write = ccs_write_memory_quota;
3144 head->read = ccs_read_memory_counter;
3145 head->readbuf_size = 512;
3146 break;
3147 case CCS_PROFILE: /* /proc/ccs/profile */
3148 head->write = ccs_write_profile;
3149 head->read = ccs_read_profile;
3150 break;
3151 case CCS_QUERY: /* /proc/ccs/query */
3152 head->poll = ccs_poll_query;
3153 head->write = ccs_write_answer;
3154 head->read = ccs_read_query;
3155 break;
3156 case CCS_MANAGER: /* /proc/ccs/manager */
3157 head->write = ccs_write_manager_policy;
3158 head->read = ccs_read_manager_policy;
3159 break;
3160 case CCS_UPDATESCOUNTER: /* /proc/ccs/.ccs_updates_counter */
3161 head->read = ccs_read_updates_counter;
3162 break;
3163 }
3164 if (!(file->f_mode & FMODE_READ)) {
3165 /*
3166 * No need to allocate read_buf since it is not opened
3167 * for reading.
3168 */
3169 head->read = NULL;
3170 head->poll = NULL;
3171 } else if (type != CCS_QUERY
3172 #ifdef CONFIG_TOMOYO_AUDIT
3173 && type != CCS_GRANTLOG && type != CCS_REJECTLOG
3174 #endif
3175 ) {
3176 /*
3177 * Don't allocate buffer for reading if the file is one of
3178 * /proc/ccs/grant_log , /proc/ccs/reject_log , /proc/ccs/query.
3179 */
3180 if (!head->readbuf_size)
3181 head->readbuf_size = 4096 * 2;
3182 head->read_buf = ccs_alloc(head->readbuf_size, false);
3183 if (!head->read_buf) {
3184 ccs_free(head);
3185 return -ENOMEM;
3186 }
3187 }
3188 if (!(file->f_mode & FMODE_WRITE)) {
3189 /*
3190 * No need to allocate write_buf since it is not opened
3191 * for writing.
3192 */
3193 head->write = NULL;
3194 } else if (head->write) {
3195 head->writebuf_size = 4096 * 2;
3196 head->write_buf = ccs_alloc(head->writebuf_size, false);
3197 if (!head->write_buf) {
3198 ccs_free(head->read_buf);
3199 ccs_free(head);
3200 return -ENOMEM;
3201 }
3202 }
3203 file->private_data = head;
3204 /*
3205 * Call the handler now if the file is /proc/ccs/self_domain
3206 * so that the user can use "cat < /proc/ccs/self_domain" to
3207 * know the current process's domainname.
3208 */
3209 if (type == CCS_SELFDOMAIN)
3210 ccs_read_control(file, NULL, 0);
3211 /*
3212 * If the file is /proc/ccs/query , increment the observer counter.
3213 * The obserber counter is used by ccs_check_supervisor() to see if
3214 * there is some process monitoring /proc/ccs/query.
3215 */
3216 else if (head->write == ccs_write_answer ||
3217 head->read == ccs_read_query)
3218 atomic_inc(&ccs_query_observers);
3219 return 0;
3220 }
3221
3222 /**
3223 * ccs_poll_control - poll() for /proc/ccs/ interface.
3224 *
3225 * @file: Pointer to "struct file".
3226 * @wait: Pointer to "poll_table".
3227 *
3228 * Waits for read readiness.
3229 * /proc/ccs/query is handled by /usr/lib/ccs/ccs-queryd and
3230 * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by
3231 * /usr/lib/ccs/ccs-auditd.
3232 */
3233 int ccs_poll_control(struct file *file, poll_table *wait)
3234 {
3235 struct ccs_io_buffer *head = file->private_data;
3236 if (!head->poll)
3237 return -ENOSYS;
3238 return head->poll(file, wait);
3239 }
3240
3241 /**
3242 * ccs_read_control - read() for /proc/ccs/ interface.
3243 *
3244 * @file: Pointer to "struct file".
3245 * @buffer: Poiner to buffer to write to.
3246 * @buffer_len: Size of @buffer.
3247 *
3248 * Returns bytes read on success, negative value otherwise.
3249 */
3250 int ccs_read_control(struct file *file, char __user *buffer,
3251 const int buffer_len)
3252 {
3253 int len = 0;
3254 struct ccs_io_buffer *head = file->private_data;
3255 char *cp;
3256 if (!head->read)
3257 return -ENOSYS;
3258 if (!access_ok(VERIFY_WRITE, buffer, buffer_len))
3259 return -EFAULT;
3260 if (mutex_lock_interruptible(&head->io_sem))
3261 return -EINTR;
3262 /* Call the policy handler. */
3263 len = head->read(head);
3264 if (len < 0)
3265 goto out;
3266 /* Write to buffer. */
3267 len = head->read_avail;
3268 if (len > buffer_len)
3269 len = buffer_len;
3270 if (!len)
3271 goto out;
3272 /* head->read_buf changes by some functions. */
3273 cp = head->read_buf;
3274 if (copy_to_user(buffer, cp, len)) {
3275 len = -EFAULT;
3276 goto out;
3277 }
3278 head->read_avail -= len;
3279 memmove(cp, cp + len, head->read_avail);
3280 out:
3281 mutex_unlock(&head->io_sem);
3282 return len;
3283 }
3284
3285 /**
3286 * ccs_write_control - write() for /proc/ccs/ interface.
3287 *
3288 * @file: Pointer to "struct file".
3289 * @buffer: Pointer to buffer to read from.
3290 * @buffer_len: Size of @buffer.
3291 *
3292 * Returns @buffer_len on success, negative value otherwise.
3293 */
3294 int ccs_write_control(struct file *file, const char __user *buffer,
3295 const int buffer_len)
3296 {
3297 struct ccs_io_buffer *head = file->private_data;
3298 int error = buffer_len;
3299 int avail_len = buffer_len;
3300 char *cp0 = head->write_buf;
3301 if (!head->write)
3302 return -ENOSYS;
3303 if (!access_ok(VERIFY_READ, buffer, buffer_len))
3304 return -EFAULT;
3305 /* Don't allow updating policies by non manager programs. */
3306 if (head->write != ccs_write_pid &&
3307 #ifdef CONFIG_TOMOYO
3308 head->write != ccs_write_domain_policy &&
3309 #endif
3310 !ccs_is_policy_manager())
3311 return -EPERM;
3312 if (mutex_lock_interruptible(&head->io_sem))
3313 return -EINTR;
3314 /* Read a line and dispatch it to the policy handler. */
3315 while (avail_len > 0) {
3316 char c;
3317 if (head->write_avail >= head->writebuf_size - 1) {
3318 error = -ENOMEM;
3319 break;
3320 } else if (get_user(c, buffer)) {
3321 error = -EFAULT;
3322 break;
3323 }
3324 buffer++;
3325 avail_len--;
3326 cp0[head->write_avail++] = c;
3327 if (c != '\n')
3328 continue;
3329 cp0[head->write_avail - 1] = '\0';
3330 head->write_avail = 0;
3331 ccs_normalize_line(cp0);
3332 head->write(head);
3333 }
3334 mutex_unlock(&head->io_sem);
3335 return error;
3336 }
3337
3338 /**
3339 * ccs_close_control - close() for /proc/ccs/ interface.
3340 *
3341 * @file: Pointer to "struct file".
3342 *
3343 * Releases memory and returns 0.
3344 */
3345 int ccs_close_control(struct file *file)
3346 {
3347 struct ccs_io_buffer *head = file->private_data;
3348 /*
3349 * If the file is /proc/ccs/query , decrement the observer counter.
3350 */
3351 if (head->write == ccs_write_answer || head->read == ccs_read_query)
3352 atomic_dec(&ccs_query_observers);
3353 /* Release memory used for policy I/O. */
3354 ccs_free(head->read_buf);
3355 head->read_buf = NULL;
3356 ccs_free(head->write_buf);
3357 head->write_buf = NULL;
3358 ccs_free(head);
3359 head = NULL;
3360 file->private_data = NULL;
3361 return 0;
3362 }
3363
3364 /**
3365 * ccs_alloc_acl_element - Allocate permanent memory for ACL entry.
3366 *
3367 * @acl_type: Type of ACL entry.
3368 * @condition: Pointer to condition part of the ACL entry. May be NULL.
3369 *
3370 * Returns pointer to the ACL entry on success, NULL otherwise.
3371 */
3372 void *ccs_alloc_acl_element(const u8 acl_type,
3373 const struct ccs_condition_list *condition)
3374 {
3375 int len;
3376 struct ccs_acl_info *ptr;
3377 switch (acl_type) {
3378 case TYPE_SINGLE_PATH_ACL:
3379 len = sizeof(struct ccs_single_path_acl_record);
3380 break;
3381 case TYPE_DOUBLE_PATH_ACL: