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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2540 - (show annotations) (download) (as text)
Thu May 14 00:08:32 2009 UTC (15 years ago) by kumaneko
Original Path: branches/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 91367 byte(s)


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