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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26