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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1120 - (show annotations) (download) (as text)
Mon Apr 21 05:34:24 2008 UTC (16 years, 1 month ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/ccs_common.c
File MIME type: text/x-csrc
File size: 81604 byte(s)


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

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