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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1719 by kumaneko, Mon Oct 20 05:22:50 2008 UTC revision 2201 by kumaneko, Thu Feb 26 06:06:13 2009 UTC
# Line 3  Line 3 
3   *   *
4   * Common functions for SAKURA and TOMOYO.   * Common functions for SAKURA and TOMOYO.
5   *   *
6   * Copyright (C) 2005-2008  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.5-pre   2008/10/20   * Version: 1.6.7-pre   2009/02/02
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 27  Line 27 
27  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
28  #include <linux/namei.h>  #include <linux/namei.h>
29  #include <linux/mount.h>  #include <linux/mount.h>
30  static const int lookup_flags = LOOKUP_FOLLOW;  static const int ccs_lookup_flags = LOOKUP_FOLLOW;
31  #else  #else
32  static const int lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;  static const int ccs_lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;
33  #endif  #endif
34  #include <linux/realpath.h>  #include <linux/realpath.h>
35  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
# Line 56  static const int lookup_flags = LOOKUP_F Line 56  static const int lookup_flags = LOOKUP_F
56  #endif  #endif
57    
58  /* Has /sbin/init started? */  /* Has /sbin/init started? */
59  bool sbin_init_started;  bool ccs_policy_loaded;
60    
61  /* Log level for SAKURA's printk(). */  /* Log level for SAKURA's printk(). */
62  const char *ccs_log_level = KERN_DEBUG;  const char *ccs_log_level = KERN_DEBUG;
63    
64  /* String table for functionality that takes 4 modes. */  /* String table for functionality that takes 4 modes. */
65  static const char *mode_4[4] = {  static const char *ccs_mode_4[4] = {
66          "disabled", "learning", "permissive", "enforcing"          "disabled", "learning", "permissive", "enforcing"
67  };  };
68  /* String table for functionality that takes 2 modes. */  /* String table for functionality that takes 2 modes. */
69  static const char *mode_2[4] = {  static const char *ccs_mode_2[4] = {
70          "disabled", "enabled", "enabled", "enabled"          "disabled", "enabled", "enabled", "enabled"
71  };  };
72    
# Line 100  static struct { Line 100  static struct {
100    
101  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
102  /* Capability name used by domain policy. */  /* Capability name used by domain policy. */
103  static const char *capability_control_keyword[TOMOYO_MAX_CAPABILITY_INDEX] = {  static const char *ccs_capability_control_keyword[TOMOYO_MAX_CAPABILITY_INDEX]
104    = {
105          [TOMOYO_INET_STREAM_SOCKET_CREATE]  = "inet_tcp_create",          [TOMOYO_INET_STREAM_SOCKET_CREATE]  = "inet_tcp_create",
106          [TOMOYO_INET_STREAM_SOCKET_LISTEN]  = "inet_tcp_listen",          [TOMOYO_INET_STREAM_SOCKET_LISTEN]  = "inet_tcp_listen",
107          [TOMOYO_INET_STREAM_SOCKET_CONNECT] = "inet_tcp_connect",          [TOMOYO_INET_STREAM_SOCKET_CONNECT] = "inet_tcp_connect",
# Line 136  static const char *capability_control_ke Line 137  static const char *capability_control_ke
137  #endif  #endif
138    
139  /* Profile table. Memory is allocated as needed. */  /* Profile table. Memory is allocated as needed. */
140  static struct profile {  static struct ccs_profile {
141          unsigned int value[CCS_MAX_CONTROL_INDEX];          unsigned int value[CCS_MAX_CONTROL_INDEX];
142          const struct path_info *comment;          const struct ccs_path_info *comment;
143  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
144          unsigned char capability_value[TOMOYO_MAX_CAPABILITY_INDEX];          unsigned char capability_value[TOMOYO_MAX_CAPABILITY_INDEX];
145  #endif  #endif
146  } *profile_ptr[MAX_PROFILES];  } *ccs_profile_ptr[MAX_PROFILES];
147    
148  /* Permit policy management by non-root user? */  /* Permit policy management by non-root user? */
149  static bool manage_by_non_root;  static bool ccs_manage_by_non_root;
150    
151  /* Utility functions. */  /* Utility functions. */
152    
153  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
154  /**  /**
155   * tomoyo_quiet_setup - Set TOMOYO_VERBOSE=0 by default.   * ccs_quiet_setup - Set TOMOYO_VERBOSE=0 by default.
156   *   *
157   * @str: Unused.   * @str: Unused.
158   *   *
159   * Returns 0.   * Returns 0.
160   */   */
161  static int __init tomoyo_quiet_setup(char *str)  static int __init ccs_quiet_setup(char *str)
162  {  {
163          ccs_control_array[CCS_TOMOYO_VERBOSE].current_value = 0;          ccs_control_array[CCS_TOMOYO_VERBOSE].current_value = 0;
164          return 0;          return 0;
165  }  }
166    
167  __setup("TOMOYO_QUIET", tomoyo_quiet_setup);  __setup("TOMOYO_QUIET", ccs_quiet_setup);
168  #endif  #endif
169    
170  /**  /**
171   * is_byte_range - Check whether the string isa \ooo style octal value.   * ccs_is_byte_range - Check whether the string isa \ooo style octal value.
172   *   *
173   * @str: Pointer to the string.   * @str: Pointer to the string.
174   *   *
175   * Returns true if @str is a \ooo style octal value, false otherwise.   * Returns true if @str is a \ooo style octal value, false otherwise.
176   */   */
177  static bool is_byte_range(const char *str)  static inline bool ccs_is_byte_range(const char *str)
178  {  {
179          return *str >= '0' && *str++ <= '3' &&          return *str >= '0' && *str++ <= '3' &&
180                  *str >= '0' && *str++ <= '7' &&                  *str >= '0' && *str++ <= '7' &&
# Line 181  static bool is_byte_range(const char *st Line 182  static bool is_byte_range(const char *st
182  }  }
183    
184  /**  /**
185   * is_decimal - Check whether the character is a decimal character.   * ccs_is_decimal - Check whether the character is a decimal character.
186   *   *
187   * @c: The character to check.   * @c: The character to check.
188   *   *
189   * Returns true if @c is a decimal character, false otherwise.   * Returns true if @c is a decimal character, false otherwise.
190   */   */
191  static bool is_decimal(const char c)  static inline bool ccs_is_decimal(const char c)
192  {  {
193          return c >= '0' && c <= '9';          return c >= '0' && c <= '9';
194  }  }
195    
196  /**  /**
197   * is_hexadecimal - Check whether the character is a hexadecimal character.   * ccs_is_hexadecimal - Check whether the character is a hexadecimal character.
198   *   *
199   * @c: The character to check.   * @c: The character to check.
200   *   *
201   * Returns true if @c is a hexadecimal character, false otherwise.   * Returns true if @c is a hexadecimal character, false otherwise.
202   */   */
203  static bool is_hexadecimal(const char c)  static inline bool ccs_is_hexadecimal(const char c)
204  {  {
205          return (c >= '0' && c <= '9') ||          return (c >= '0' && c <= '9') ||
206                  (c >= 'A' && c <= 'F') ||                  (c >= 'A' && c <= 'F') ||
# Line 207  static bool is_hexadecimal(const char c) Line 208  static bool is_hexadecimal(const char c)
208  }  }
209    
210  /**  /**
211   * is_alphabet_char - Check whether the character is an alphabet.   * ccs_is_alphabet_char - Check whether the character is an alphabet.
212   *   *
213   * @c: The character to check.   * @c: The character to check.
214   *   *
215   * Returns true if @c is an alphabet character, false otherwise.   * Returns true if @c is an alphabet character, false otherwise.
216   */   */
217  static bool is_alphabet_char(const char c)  static inline bool ccs_is_alphabet_char(const char c)
218  {  {
219          return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');          return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
220  }  }
221    
222  /**  /**
223   * make_byte - Make byte value from three octal characters.   * ccs_make_byte - Make byte value from three octal characters.
224   *   *
225   * @c1: The first character.   * @c1: The first character.
226   * @c2: The second character.   * @c2: The second character.
# Line 227  static bool is_alphabet_char(const char Line 228  static bool is_alphabet_char(const char
228   *   *
229   * Returns byte value.   * Returns byte value.
230   */   */
231  static u8 make_byte(const u8 c1, const u8 c2, const u8 c3)  static inline u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
232  {  {
233          return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');          return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
234  }  }
235    
236  /**  /**
237   * str_starts - Check whether the given string starts with the given keyword.   * ccs_str_starts - Check whether the given string starts with the given keyword.
238   *   *
239   * @src:  Pointer to pointer to the string.   * @src:  Pointer to pointer to the string.
240   * @find: Pointer to the keyword.   * @find: Pointer to the keyword.
# Line 243  static u8 make_byte(const u8 c1, const u Line 244  static u8 make_byte(const u8 c1, const u
244   * The @src is updated to point the first character after the @find   * The @src is updated to point the first character after the @find
245   * if @src starts with @find.   * if @src starts with @find.
246   */   */
247  static bool str_starts(char **src, const char *find)  static bool ccs_str_starts(char **src, const char *find)
248  {  {
249          const int len = strlen(find);          const int len = strlen(find);
250          char *tmp = *src;          char *tmp = *src;
# Line 255  static bool str_starts(char **src, const Line 256  static bool str_starts(char **src, const
256  }  }
257    
258  /**  /**
259   * normalize_line - Format string.   * ccs_normalize_line - Format string.
260   *   *
261   * @buffer: The line to normalize.   * @buffer: The line to normalize.
262   *   *
# Line 264  static bool str_starts(char **src, const Line 265  static bool str_starts(char **src, const
265   *   *
266   * Returns nothing.   * Returns nothing.
267   */   */
268  static void normalize_line(unsigned char *buffer)  static void ccs_normalize_line(unsigned char *buffer)
269  {  {
270          unsigned char *sp = buffer;          unsigned char *sp = buffer;
271          unsigned char *dp = buffer;          unsigned char *dp = buffer;
# Line 317  bool ccs_is_correct_path(const char *fil Line 318  bool ccs_is_correct_path(const char *fil
318                          goto out;                          goto out;
319          }          }
320          if (c)          if (c)
321                  c = *(strchr(filename, '\0') - 1);                  c = *(filename + strlen(filename) - 1);
322          if (end_type == 1) { /* Must end with '/' */          if (end_type == 1) { /* Must end with '/' */
323                  if (c != '/')                  if (c != '/')
324                          goto out;                          goto out;
# Line 325  bool ccs_is_correct_path(const char *fil Line 326  bool ccs_is_correct_path(const char *fil
326                  if (c == '/')                  if (c == '/')
327                          goto out;                          goto out;
328          }          }
329          while ((c = *filename++) != '\0') {          while (1) {
330                    c = *filename++;
331                    if (!c)
332                            break;
333                  if (c == '\\') {                  if (c == '\\') {
334                          switch ((c = *filename++)) {                          c = *filename++;
335                            switch (c) {
336                          case '\\':  /* "\\" */                          case '\\':  /* "\\" */
337                                  continue;                                  continue;
338                          case '$':   /* "\$" */                          case '$':   /* "\$" */
# Line 354  bool ccs_is_correct_path(const char *fil Line 359  bool ccs_is_correct_path(const char *fil
359                                  e = *filename++;                                  e = *filename++;
360                                  if (e < '0' || e > '7')                                  if (e < '0' || e > '7')
361                                          break;                                          break;
362                                  c = make_byte(c, d, e);                                  c = ccs_make_byte(c, d, e);
363                                  if (c && (c <= ' ' || c >= 127))                                  if (c && (c <= ' ' || c >= 127))
364                                          continue; /* pattern is not \000 */                                          continue; /* pattern is not \000 */
365                          }                          }
# Line 398  bool ccs_is_correct_domain(const unsigne Line 403  bool ccs_is_correct_domain(const unsigne
403                          goto out;                          goto out;
404                  if (*domainname++ != '/')                  if (*domainname++ != '/')
405                          goto out;                          goto out;
406                  while ((c = *domainname) != '\0' && c != ' ') {                  while (1) {
407                            c = *domainname;
408                            if (!c || c == ' ')
409                                    break;
410                          domainname++;                          domainname++;
411                          if (c == '\\') {                          if (c == '\\') {
412                                  c = *domainname++;                                  c = *domainname++;
# Line 415  bool ccs_is_correct_domain(const unsigne Line 423  bool ccs_is_correct_domain(const unsigne
423                                          e = *domainname++;                                          e = *domainname++;
424                                          if (e < '0' || e > '7')                                          if (e < '0' || e > '7')
425                                                  break;                                                  break;
426                                          c = make_byte(c, d, e);                                          c = ccs_make_byte(c, d, e);
427                                          if (c && (c <= ' ' || c >= 127))                                          if (c && (c <= ' ' || c >= 127))
428                                                  /* pattern is not \000 */                                                  /* pattern is not \000 */
429                                                  continue;                                                  continue;
# Line 455  bool ccs_is_domain_def(const unsigned ch Line 463  bool ccs_is_domain_def(const unsigned ch
463  struct domain_info *ccs_find_domain(const char *domainname)  struct domain_info *ccs_find_domain(const char *domainname)
464  {  {
465          struct domain_info *domain;          struct domain_info *domain;
466          struct path_info name;          struct ccs_path_info name;
467          name.name = domainname;          name.name = domainname;
468          ccs_fill_path_info(&name);          ccs_fill_path_info(&name);
469          list1_for_each_entry(domain, &domain_list, list) {          list1_for_each_entry(domain, &ccs_domain_list, list) {
470                  if (!domain->is_deleted &&                  if (!domain->is_deleted &&
471                      !ccs_pathcmp(&name, domain->domainname))                      !ccs_pathcmp(&name, domain->domainname))
472                          return domain;                          return domain;
# Line 467  struct domain_info *ccs_find_domain(cons Line 475  struct domain_info *ccs_find_domain(cons
475  }  }
476    
477  /**  /**
478   * path_depth - Evaluate the number of '/' in a string.   * ccs_path_depth - Evaluate the number of '/' in a string.
479   *   *
480   * @pathname: The string to evaluate.   * @pathname: The string to evaluate.
481   *   *
# Line 476  struct domain_info *ccs_find_domain(cons Line 484  struct domain_info *ccs_find_domain(cons
484   * I score 2 for each of the '/' in the @pathname   * I score 2 for each of the '/' in the @pathname
485   * and score 1 if the @pathname ends with '/'.   * and score 1 if the @pathname ends with '/'.
486   */   */
487  static int path_depth(const char *pathname)  static int ccs_path_depth(const char *pathname)
488  {  {
489          int i = 0;          int i = 0;
490          if (pathname) {          if (pathname) {
491                  char *ep = strchr(pathname, '\0');                  const char *ep = pathname + strlen(pathname);
492                  if (pathname < ep--) {                  if (pathname < ep--) {
493                          if (*ep != '/')                          if (*ep != '/')
494                                  i++;                                  i++;
# Line 493  static int path_depth(const char *pathna Line 501  static int path_depth(const char *pathna
501  }  }
502    
503  /**  /**
504   * const_part_length - Evaluate the initial length without a pattern in a token.   * ccs_const_part_length - Evaluate the initial length without a pattern in a token.
505   *   *
506   * @filename: The string to evaluate.   * @filename: The string to evaluate.
507   *   *
508   * Returns the initial length without a pattern in @filename.   * Returns the initial length without a pattern in @filename.
509   */   */
510  static int const_part_length(const char *filename)  static int ccs_const_part_length(const char *filename)
511  {  {
512          char c;          char c;
513          int len = 0;          int len = 0;
514          if (!filename)          if (!filename)
515                  return 0;                  return 0;
516          while ((c = *filename++) != '\0') {          while (1) {
517                    c = *filename++;
518                    if (!c)
519                            break;
520                  if (c != '\\') {                  if (c != '\\') {
521                          len++;                          len++;
522                          continue;                          continue;
# Line 534  static int const_part_length(const char Line 545  static int const_part_length(const char
545  }  }
546    
547  /**  /**
548   * ccs_fill_path_info - Fill in "struct path_info" members.   * ccs_fill_path_info - Fill in "struct ccs_path_info" members.
549   *   *
550   * @ptr: Pointer to "struct path_info" to fill in.   * @ptr: Pointer to "struct ccs_path_info" to fill in.
551   *   *
552   * The caller sets "struct path_info"->name.   * The caller sets "struct ccs_path_info"->name.
553   */   */
554  void ccs_fill_path_info(struct path_info *ptr)  void ccs_fill_path_info(struct ccs_path_info *ptr)
555  {  {
556          const char *name = ptr->name;          const char *name = ptr->name;
557          const int len = strlen(name);          const int len = strlen(name);
558          ptr->total_len = len;          ptr->total_len = len;
559          ptr->const_len = const_part_length(name);          ptr->const_len = ccs_const_part_length(name);
560          ptr->is_dir = len && (name[len - 1] == '/');          ptr->is_dir = len && (name[len - 1] == '/');
561          ptr->is_patterned = (ptr->const_len < len);          ptr->is_patterned = (ptr->const_len < len);
562          ptr->hash = full_name_hash(name, len);          ptr->hash = full_name_hash(name, len);
563          ptr->depth = path_depth(name);          ptr->depth = ccs_path_depth(name);
564  }  }
565    
566  /**  /**
567   * file_matches_to_pattern2 - Pattern matching without '/' character   * ccs_file_matches_pattern2 - Pattern matching without '/' character
568   * and "\-" pattern.   * and "\-" pattern.
569   *   *
570   * @filename:     The start of string to check.   * @filename:     The start of string to check.
# Line 563  void ccs_fill_path_info(struct path_info Line 574  void ccs_fill_path_info(struct path_info
574   *   *
575   * Returns true if @filename matches @pattern, false otherwise.   * Returns true if @filename matches @pattern, false otherwise.
576   */   */
577  static bool file_matches_to_pattern2(const char *filename,  static bool ccs_file_matches_pattern2(const char *filename,
578                                       const char *filename_end,                                        const char *filename_end,
579                                       const char *pattern,                                        const char *pattern,
580                                       const char *pattern_end)                                        const char *pattern_end)
581  {  {
582          while (filename < filename_end && pattern < pattern_end) {          while (filename < filename_end && pattern < pattern_end) {
583                  char c;                  char c;
# Line 586  static bool file_matches_to_pattern2(con Line 597  static bool file_matches_to_pattern2(con
597                          } else if (c == '\\') {                          } else if (c == '\\') {
598                                  if (filename[1] == '\\')                                  if (filename[1] == '\\')
599                                          filename++;                                          filename++;
600                                  else if (is_byte_range(filename + 1))                                  else if (ccs_is_byte_range(filename + 1))
601                                          filename += 3;                                          filename += 3;
602                                  else                                  else
603                                          return false;                                          return false;
# Line 599  static bool file_matches_to_pattern2(con Line 610  static bool file_matches_to_pattern2(con
610                                  return false;                                  return false;
611                          break;                          break;
612                  case '+':                  case '+':
613                          if (!is_decimal(c))                          if (!ccs_is_decimal(c))
614                                  return false;                                  return false;
615                          break;                          break;
616                  case 'x':                  case 'x':
617                          if (!is_hexadecimal(c))                          if (!ccs_is_hexadecimal(c))
618                                  return false;                                  return false;
619                          break;                          break;
620                  case 'a':                  case 'a':
621                          if (!is_alphabet_char(c))                          if (!ccs_is_alphabet_char(c))
622                                  return false;                                  return false;
623                          break;                          break;
624                  case '0':                  case '0':
625                  case '1':                  case '1':
626                  case '2':                  case '2':
627                  case '3':                  case '3':
628                          if (c == '\\' && is_byte_range(filename + 1)                          if (c == '\\' && ccs_is_byte_range(filename + 1)
629                              && strncmp(filename + 1, pattern, 3) == 0) {                              && strncmp(filename + 1, pattern, 3) == 0) {
630                                  filename += 3;                                  filename += 3;
631                                  pattern += 2;                                  pattern += 2;
# Line 624  static bool file_matches_to_pattern2(con Line 635  static bool file_matches_to_pattern2(con
635                  case '*':                  case '*':
636                  case '@':                  case '@':
637                          for (i = 0; i <= filename_end - filename; i++) {                          for (i = 0; i <= filename_end - filename; i++) {
638                                  if (file_matches_to_pattern2(filename + i,                                  if (ccs_file_matches_pattern2(filename + i,
639                                                               filename_end,                                                                filename_end,
640                                                               pattern + 1,                                                                pattern + 1,
641                                                               pattern_end))                                                                pattern_end))
642                                          return true;                                          return true;
643                                  c = filename[i];                                  c = filename[i];
644                                  if (c == '.' && *pattern == '@')                                  if (c == '.' && *pattern == '@')
# Line 636  static bool file_matches_to_pattern2(con Line 647  static bool file_matches_to_pattern2(con
647                                          continue;                                          continue;
648                                  if (filename[i + 1] == '\\')                                  if (filename[i + 1] == '\\')
649                                          i++;                                          i++;
650                                  else if (is_byte_range(filename + i + 1))                                  else if (ccs_is_byte_range(filename + i + 1))
651                                          i += 3;                                          i += 3;
652                                  else                                  else
653                                          break; /* Bad pattern. */                                          break; /* Bad pattern. */
# Line 646  static bool file_matches_to_pattern2(con Line 657  static bool file_matches_to_pattern2(con
657                          j = 0;                          j = 0;
658                          c = *pattern;                          c = *pattern;
659                          if (c == '$') {                          if (c == '$') {
660                                  while (is_decimal(filename[j]))                                  while (ccs_is_decimal(filename[j]))
661                                          j++;                                          j++;
662                          } else if (c == 'X') {                          } else if (c == 'X') {
663                                  while (is_hexadecimal(filename[j]))                                  while (ccs_is_hexadecimal(filename[j]))
664                                          j++;                                          j++;
665                          } else if (c == 'A') {                          } else if (c == 'A') {
666                                  while (is_alphabet_char(filename[j]))                                  while (ccs_is_alphabet_char(filename[j]))
667                                          j++;                                          j++;
668                          }                          }
669                          for (i = 1; i <= j; i++) {                          for (i = 1; i <= j; i++) {
670                                  if (file_matches_to_pattern2(filename + i,                                  if (ccs_file_matches_pattern2(filename + i,
671                                                               filename_end,                                                                filename_end,
672                                                               pattern + 1,                                                                pattern + 1,
673                                                               pattern_end))                                                                pattern_end))
674                                          return true;                                          return true;
675                          }                          }
676                          return false; /* Not matched or bad pattern. */                          return false; /* Not matched or bad pattern. */
# Line 674  static bool file_matches_to_pattern2(con Line 685  static bool file_matches_to_pattern2(con
685  }  }
686    
687  /**  /**
688   * file_matches_to_pattern - Pattern matching without without '/' character.   * ccs_file_matches_pattern - Pattern matching without without '/' character.
689   *   *
690   * @filename:     The start of string to check.   * @filename:     The start of string to check.
691   * @filename_end: The end of string to check.   * @filename_end: The end of string to check.
# Line 683  static bool file_matches_to_pattern2(con Line 694  static bool file_matches_to_pattern2(con
694   *   *
695   * Returns true if @filename matches @pattern, false otherwise.   * Returns true if @filename matches @pattern, false otherwise.
696   */   */
697  static bool file_matches_to_pattern(const char *filename,  static bool ccs_file_matches_pattern(const char *filename,
698                                      const char *filename_end,                                       const char *filename_end,
699                                      const char *pattern,                                       const char *pattern,
700                                      const char *pattern_end)                                       const char *pattern_end)
701  {  {
702          const char *pattern_start = pattern;          const char *pattern_start = pattern;
703          bool first = true;          bool first = true;
# Line 695  static bool file_matches_to_pattern(cons Line 706  static bool file_matches_to_pattern(cons
706                  /* Split at "\-" pattern. */                  /* Split at "\-" pattern. */
707                  if (*pattern++ != '\\' || *pattern++ != '-')                  if (*pattern++ != '\\' || *pattern++ != '-')
708                          continue;                          continue;
709                  result = file_matches_to_pattern2(filename, filename_end,                  result = ccs_file_matches_pattern2(filename, filename_end,
710                                                    pattern_start, pattern - 2);                                                     pattern_start, pattern - 2);
711                  if (first)                  if (first)
712                          result = !result;                          result = !result;
713                  if (result)                  if (result)
# Line 704  static bool file_matches_to_pattern(cons Line 715  static bool file_matches_to_pattern(cons
715                  first = false;                  first = false;
716                  pattern_start = pattern;                  pattern_start = pattern;
717          }          }
718          result = file_matches_to_pattern2(filename, filename_end,          result = ccs_file_matches_pattern2(filename, filename_end,
719                                            pattern_start, pattern_end);                                             pattern_start, pattern_end);
720          return first ? result : !result;          return first ? result : !result;
721  }  }
722    
# Line 730  static bool file_matches_to_pattern(cons Line 741  static bool file_matches_to_pattern(cons
741   *   \a     1 alphabet character.   *   \a     1 alphabet character.
742   *   \-     Subtraction operator.   *   \-     Subtraction operator.
743   */   */
744  bool ccs_path_matches_pattern(const struct path_info *filename,  bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
745                                const struct path_info *pattern)                                const struct ccs_path_info *pattern)
746  {  {
747          /*          /*
748            if (!filename || !pattern)            if (!filename || !pattern)
# Line 756  bool ccs_path_matches_pattern(const stru Line 767  bool ccs_path_matches_pattern(const stru
767                  const char *f_delimiter = strchr(f, '/');                  const char *f_delimiter = strchr(f, '/');
768                  const char *p_delimiter = strchr(p, '/');                  const char *p_delimiter = strchr(p, '/');
769                  if (!f_delimiter)                  if (!f_delimiter)
770                          f_delimiter = strchr(f, '\0');                          f_delimiter = f + strlen(f);
771                  if (!p_delimiter)                  if (!p_delimiter)
772                          p_delimiter = strchr(p, '\0');                          p_delimiter = p + strlen(p);
773                  if (!file_matches_to_pattern(f, f_delimiter, p, p_delimiter))                  if (!ccs_file_matches_pattern(f, f_delimiter, p, p_delimiter))
774                          return false;                          return false;
775                  f = f_delimiter;                  f = f_delimiter;
776                  if (*f)                  if (*f)
# Line 884  unsigned int ccs_check_flags(const struc Line 895  unsigned int ccs_check_flags(const struc
895          if (!domain)          if (!domain)
896                  domain = current->domain_info;                  domain = current->domain_info;
897          profile = domain->profile;          profile = domain->profile;
898          return sbin_init_started && index < CCS_MAX_CONTROL_INDEX          return ccs_policy_loaded && index < CCS_MAX_CONTROL_INDEX
899  #if MAX_PROFILES != 256  #if MAX_PROFILES != 256
900                  && profile < MAX_PROFILES                  && profile < MAX_PROFILES
901  #endif  #endif
902                  && profile_ptr[profile] ?                  && ccs_profile_ptr[profile] ?
903                  profile_ptr[profile]->value[index] : 0;                  ccs_profile_ptr[profile]->value[index] : 0;
904  }  }
905    
906  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
# Line 906  static u8 ccs_check_capability_flags(con Line 917  static u8 ccs_check_capability_flags(con
917  {  {
918          const u8 profile = domain ? domain->profile :          const u8 profile = domain ? domain->profile :
919                  current->domain_info->profile;                  current->domain_info->profile;
920          return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX          return ccs_policy_loaded && index < TOMOYO_MAX_CAPABILITY_INDEX
921  #if MAX_PROFILES != 256  #if MAX_PROFILES != 256
922                  && profile < MAX_PROFILES                  && profile < MAX_PROFILES
923  #endif  #endif
924                  && profile_ptr[profile] ?                  && ccs_profile_ptr[profile] ?
925                  profile_ptr[profile]->capability_value[index] : 0;                  ccs_profile_ptr[profile]->capability_value[index] : 0;
926  }  }
927    
928  /**  /**
# Line 924  static u8 ccs_check_capability_flags(con Line 935  static u8 ccs_check_capability_flags(con
935  const char *ccs_cap2keyword(const u8 operation)  const char *ccs_cap2keyword(const u8 operation)
936  {  {
937          return operation < TOMOYO_MAX_CAPABILITY_INDEX          return operation < TOMOYO_MAX_CAPABILITY_INDEX
938                  ? capability_control_keyword[operation] : NULL;                  ? ccs_capability_control_keyword[operation] : NULL;
939  }  }
940    
941  #endif  #endif
# Line 951  void ccs_init_request_info(struct ccs_re Line 962  void ccs_init_request_info(struct ccs_re
962                  r->mode = ccs_check_capability_flags(domain, index                  r->mode = ccs_check_capability_flags(domain, index
963                                                       - CCS_MAX_CONTROL_INDEX);                                                       - CCS_MAX_CONTROL_INDEX);
964  #endif  #endif
         r->tomoyo_flags = current->tomoyo_flags;  
965  }  }
966    
967  /**  /**
# Line 977  bool ccs_verbose_mode(const struct domai Line 987  bool ccs_verbose_mode(const struct domai
987  bool ccs_check_domain_quota(struct domain_info * const domain)  bool ccs_check_domain_quota(struct domain_info * const domain)
988  {  {
989          unsigned int count = 0;          unsigned int count = 0;
990          struct acl_info *ptr;          struct ccs_acl_info *ptr;
991          if (!domain)          if (!domain)
992                  return true;                  return true;
993          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
994                  if (ptr->type & ACL_DELETED)                  if (ptr->type & ACL_DELETED)
995                          continue;                          continue;
996                  switch (ccs_acl_type2(ptr)) {                  switch (ccs_acl_type2(ptr)) {
997                          struct single_path_acl_record *acl1;                          struct ccs_single_path_acl_record *acl1;
998                          struct double_path_acl_record *acl2;                          struct ccs_double_path_acl_record *acl2;
999                          u16 perm;                          u16 perm;
1000                  case TYPE_SINGLE_PATH_ACL:                  case TYPE_SINGLE_PATH_ACL:
1001                          acl1 = container_of(ptr, struct single_path_acl_record,                          acl1 = container_of(ptr,
1002                                                struct ccs_single_path_acl_record,
1003                                              head);                                              head);
1004                          perm = acl1->perm;                          perm = acl1->perm;
1005                          if (perm & (1 << TYPE_EXECUTE_ACL))                          if (perm & (1 << TYPE_EXECUTE_ACL))
# Line 1020  bool ccs_check_domain_quota(struct domai Line 1031  bool ccs_check_domain_quota(struct domai
1031                                  count++;                                  count++;
1032                          break;                          break;
1033                  case TYPE_DOUBLE_PATH_ACL:                  case TYPE_DOUBLE_PATH_ACL:
1034                          acl2 = container_of(ptr, struct double_path_acl_record,                          acl2 = container_of(ptr,
1035                                                struct ccs_double_path_acl_record,
1036                                              head);                                              head);
1037                          perm = acl2->perm;                          perm = acl2->perm;
1038                          if (perm & (1 << TYPE_LINK_ACL))                          if (perm & (1 << TYPE_LINK_ACL))
# Line 1051  bool ccs_check_domain_quota(struct domai Line 1063  bool ccs_check_domain_quota(struct domai
1063   *   *
1064   * @profile: Profile number to create.   * @profile: Profile number to create.
1065   *   *
1066   * Returns pointer to "struct profile" on success, NULL otherwise.   * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
1067   */   */
1068  static struct profile *ccs_find_or_assign_new_profile(const unsigned int  static struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int
1069                                                        profile)                                                            profile)
1070  {  {
1071          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
1072          struct profile *ptr = NULL;          struct ccs_profile *ptr = NULL;
1073          mutex_lock(&lock);          mutex_lock(&lock);
1074          if (profile < MAX_PROFILES) {          if (profile < MAX_PROFILES) {
1075                  ptr = profile_ptr[profile];                  ptr = ccs_profile_ptr[profile];
1076                  if (ptr)                  if (ptr)
1077                          goto ok;                          goto ok;
1078                  ptr = ccs_alloc_element(sizeof(*ptr));                  ptr = ccs_alloc_element(sizeof(*ptr));
# Line 1074  static struct profile *ccs_find_or_assig Line 1086  static struct profile *ccs_find_or_assig
1086                           * because they are always 0.                           * because they are always 0.
1087                           */                           */
1088                          mb(); /* Avoid out-of-order execution. */                          mb(); /* Avoid out-of-order execution. */
1089                          profile_ptr[profile] = ptr;                          ccs_profile_ptr[profile] = ptr;
1090                  }                  }
1091          }          }
1092   ok:   ok:
# Line 1083  static struct profile *ccs_find_or_assig Line 1095  static struct profile *ccs_find_or_assig
1095  }  }
1096    
1097  /**  /**
1098   * write_profile - Write profile table.   * ccs_write_profile - Write profile table.
1099   *   *
1100   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1101   *   *
1102   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1103   */   */
1104  static int write_profile(struct ccs_io_buffer *head)  static int ccs_write_profile(struct ccs_io_buffer *head)
1105  {  {
1106          char *data = head->write_buf;          char *data = head->write_buf;
1107          unsigned int i;          unsigned int i;
1108          unsigned int value;          unsigned int value;
1109          char *cp;          char *cp;
1110          struct profile *profile;          struct ccs_profile *ccs_profile;
1111          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
1112          if (data != cp) {          if (data != cp) {
1113                  if (*cp != '-')                  if (*cp != '-')
1114                          return -EINVAL;                          return -EINVAL;
1115                  data = cp + 1;                  data = cp + 1;
1116          }          }
1117          profile = ccs_find_or_assign_new_profile(i);          ccs_profile = ccs_find_or_assign_new_profile(i);
1118          if (!profile)          if (!ccs_profile)
1119                  return -EINVAL;                  return -EINVAL;
1120          cp = strchr(data, '=');          cp = strchr(data, '=');
1121          if (!cp)          if (!cp)
# Line 1111  static int write_profile(struct ccs_io_b Line 1123  static int write_profile(struct ccs_io_b
1123          *cp = '\0';          *cp = '\0';
1124          ccs_update_counter(CCS_UPDATES_COUNTER_PROFILE);          ccs_update_counter(CCS_UPDATES_COUNTER_PROFILE);
1125          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
1126                  profile->comment = ccs_save_name(cp + 1);                  ccs_profile->comment = ccs_save_name(cp + 1);
1127                  return 0;                  return 0;
1128          }          }
1129  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1130          if (str_starts(&data, KEYWORD_MAC_FOR_CAPABILITY)) {          if (ccs_str_starts(&data, KEYWORD_MAC_FOR_CAPABILITY)) {
1131                  if (sscanf(cp + 1, "%u", &value) != 1) {                  if (sscanf(cp + 1, "%u", &value) != 1) {
1132                          for (i = 0; i < 4; i++) {                          for (i = 0; i < 4; i++) {
1133                                  if (strcmp(cp + 1, mode_4[i]))                                  if (strcmp(cp + 1, ccs_mode_4[i]))
1134                                          continue;                                          continue;
1135                                  value = i;                                  value = i;
1136                                  break;                                  break;
# Line 1129  static int write_profile(struct ccs_io_b Line 1141  static int write_profile(struct ccs_io_b
1141                  if (value > 3)                  if (value > 3)
1142                          value = 3;                          value = 3;
1143                  for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) {                  for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) {
1144                          if (strcmp(data, capability_control_keyword[i]))                          if (strcmp(data, ccs_capability_control_keyword[i]))
1145                                  continue;                                  continue;
1146                          profile->capability_value[i] = value;                          ccs_profile->capability_value[i] = value;
1147                          return 0;                          return 0;
1148                  }                  }
1149                  return -EINVAL;                  return -EINVAL;
# Line 1146  static int write_profile(struct ccs_io_b Line 1158  static int write_profile(struct ccs_io_b
1158                          switch (i) {                          switch (i) {
1159                          case CCS_SAKURA_RESTRICT_AUTOBIND:                          case CCS_SAKURA_RESTRICT_AUTOBIND:
1160                          case CCS_TOMOYO_VERBOSE:                          case CCS_TOMOYO_VERBOSE:
1161                                  modes = mode_2;                                  modes = ccs_mode_2;
1162                                  break;                                  break;
1163                          default:                          default:
1164                                  modes = mode_4;                                  modes = ccs_mode_4;
1165                                  break;                                  break;
1166                          }                          }
1167                          for (j = 0; j < 4; j++) {                          for (j = 0; j < 4; j++) {
# Line 1169  static int write_profile(struct ccs_io_b Line 1181  static int write_profile(struct ccs_io_b
1181                          if (value == 1)                          if (value == 1)
1182                                  value = 2; /* learning mode is not supported. */                                  value = 2; /* learning mode is not supported. */
1183                  }                  }
1184                  profile->value[i] = value;                  ccs_profile->value[i] = value;
1185                  return 0;                  return 0;
1186          }          }
1187          return -EINVAL;          return -EINVAL;
1188  }  }
1189    
1190  /**  /**
1191   * read_profile - Read profile table.   * ccs_read_profile - Read profile table.
1192   *   *
1193   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1194   *   *
1195   * Returns 0.   * Returns 0.
1196   */   */
1197  static int read_profile(struct ccs_io_buffer *head)  static int ccs_read_profile(struct ccs_io_buffer *head)
1198  {  {
1199          static const int total          static const int ccs_total
1200                  = CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX + 1;                  = CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX + 1;
1201          int step;          int step;
1202          if (head->read_eof)          if (head->read_eof)
1203                  return 0;                  return 0;
1204          for (step = head->read_step; step < MAX_PROFILES * total; step++) {          for (step = head->read_step; step < MAX_PROFILES * ccs_total; step++) {
1205                  const u8 index = step / total;                  const u8 index = step / ccs_total;
1206                  u8 type = step % total;                  u8 type = step % ccs_total;
1207                  const struct profile *profile = profile_ptr[index];                  const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];
1208                  head->read_step = step;                  head->read_step = step;
1209                  if (!profile)                  if (!ccs_profile)
1210                          continue;                          continue;
1211  #if !defined(CONFIG_SAKURA) || !defined(CONFIG_TOMOYO)  #if !defined(CONFIG_SAKURA) || !defined(CONFIG_TOMOYO)
1212                  switch (type) {                  switch (type - 1) {
1213  #ifndef CONFIG_SAKURA  #ifndef CONFIG_SAKURA
1214                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:
1215                  case CCS_SAKURA_RESTRICT_CHROOT:                  case CCS_SAKURA_RESTRICT_CHROOT:
# Line 1222  static int read_profile(struct ccs_io_bu Line 1234  static int read_profile(struct ccs_io_bu
1234  #endif  #endif
1235                  if (!type) { /* Print profile' comment tag. */                  if (!type) { /* Print profile' comment tag. */
1236                          if (!ccs_io_printf(head, "%u-COMMENT=%s\n",                          if (!ccs_io_printf(head, "%u-COMMENT=%s\n",
1237                                             index, profile->comment ?                                             index, ccs_profile->comment ?
1238                                             profile->comment->name : ""))                                             ccs_profile->comment->name : ""))
1239                                  break;                                  break;
1240                          continue;                          continue;
1241                  }                  }
# Line 1231  static int read_profile(struct ccs_io_bu Line 1243  static int read_profile(struct ccs_io_bu
1243                  if (type >= CCS_MAX_CONTROL_INDEX) {                  if (type >= CCS_MAX_CONTROL_INDEX) {
1244  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1245                          const int i = type - CCS_MAX_CONTROL_INDEX;                          const int i = type - CCS_MAX_CONTROL_INDEX;
1246                          const u8 value = profile->capability_value[i];                          const u8 value = ccs_profile->capability_value[i];
1247                          if (!ccs_io_printf(head,                          if (!ccs_io_printf(head,
1248                                             "%u-" KEYWORD_MAC_FOR_CAPABILITY                                             "%u-" KEYWORD_MAC_FOR_CAPABILITY
1249                                             "%s=%s\n", index,                                             "%s=%s\n", index,
1250                                             capability_control_keyword[i],                                             ccs_capability_control_keyword[i],
1251                                             mode_4[value]))                                             ccs_mode_4[value]))
1252                                  break;                                  break;
1253  #endif  #endif
1254                  } else {                  } else {
1255                          const unsigned int value = profile->value[type];                          const unsigned int value = ccs_profile->value[type];
1256                          const char **modes = NULL;                          const char **modes = NULL;
1257                          const char *keyword = ccs_control_array[type].keyword;                          const char *keyword = ccs_control_array[type].keyword;
1258                          switch (ccs_control_array[type].max_value) {                          switch (ccs_control_array[type].max_value) {
1259                          case 3:                          case 3:
1260                                  modes = mode_4;                                  modes = ccs_mode_4;
1261                                  break;                                  break;
1262                          case 1:                          case 1:
1263                                  modes = mode_2;                                  modes = ccs_mode_2;
1264                                  break;                                  break;
1265                          }                          }
1266                          if (modes) {                          if (modes) {
# Line 1262  static int read_profile(struct ccs_io_bu Line 1274  static int read_profile(struct ccs_io_bu
1274                          }                          }
1275                  }                  }
1276          }          }
1277          if (step == MAX_PROFILES * total)          if (step == MAX_PROFILES * ccs_total)
1278                  head->read_eof = true;                  head->read_eof = true;
1279          return 0;          return 0;
1280  }  }
1281    
1282  /* Structure for policy manager. */  /* Structure for policy manager. */
1283  struct policy_manager_entry {  struct ccs_policy_manager_entry {
1284          struct list1_head list;          struct list1_head list;
1285          /* A path to program or a domainname. */          /* A path to program or a domainname. */
1286          const struct path_info *manager;          const struct ccs_path_info *manager;
1287          bool is_domain;  /* True if manager is a domainname. */          bool is_domain;  /* True if manager is a domainname. */
1288          bool is_deleted; /* True if this entry is deleted. */          bool is_deleted; /* True if this entry is deleted. */
1289  };  };
1290    
1291  /* The list for "struct policy_manager_entry". */  /* The list for "struct ccs_policy_manager_entry". */
1292  static LIST1_HEAD(policy_manager_list);  static LIST1_HEAD(ccs_policy_manager_list);
1293    
1294  /**  /**
1295   * update_manager_entry - Add a manager entry.   * ccs_update_manager_entry - Add a manager entry.
1296   *   *
1297   * @manager:   The path to manager or the domainnamme.   * @manager:   The path to manager or the domainnamme.
1298   * @is_delete: True if it is a delete request.   * @is_delete: True if it is a delete request.
1299   *   *
1300   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1301   */   */
1302  static int update_manager_entry(const char *manager, const bool is_delete)  static int ccs_update_manager_entry(const char *manager, const bool is_delete)
1303  {  {
1304          struct policy_manager_entry *new_entry;          struct ccs_policy_manager_entry *new_entry;
1305          struct policy_manager_entry *ptr;          struct ccs_policy_manager_entry *ptr;
1306          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
1307          const struct path_info *saved_manager;          const struct ccs_path_info *saved_manager;
1308          int error = -ENOMEM;          int error = -ENOMEM;
1309          bool is_domain = false;          bool is_domain = false;
1310          if (ccs_is_domain_def(manager)) {          if (ccs_is_domain_def(manager)) {
# Line 1307  static int update_manager_entry(const ch Line 1319  static int update_manager_entry(const ch
1319          if (!saved_manager)          if (!saved_manager)
1320                  return -ENOMEM;                  return -ENOMEM;
1321          mutex_lock(&lock);          mutex_lock(&lock);
1322          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1323                  if (ptr->manager != saved_manager)                  if (ptr->manager != saved_manager)
1324                          continue;                          continue;
1325                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
# Line 1323  static int update_manager_entry(const ch Line 1335  static int update_manager_entry(const ch
1335                  goto out;                  goto out;
1336          new_entry->manager = saved_manager;          new_entry->manager = saved_manager;
1337          new_entry->is_domain = is_domain;          new_entry->is_domain = is_domain;
1338          list1_add_tail_mb(&new_entry->list, &policy_manager_list);          list1_add_tail_mb(&new_entry->list, &ccs_policy_manager_list);
1339          error = 0;          error = 0;
1340   out:   out:
1341          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 1333  static int update_manager_entry(const ch Line 1345  static int update_manager_entry(const ch
1345  }  }
1346    
1347  /**  /**
1348   * write_manager_policy - Write manager policy.   * ccs_write_manager_policy - Write manager policy.
1349   *   *
1350   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1351   *   *
1352   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1353   */   */
1354  static int write_manager_policy(struct ccs_io_buffer *head)  static int ccs_write_manager_policy(struct ccs_io_buffer *head)
1355  {  {
1356          char *data = head->write_buf;          char *data = head->write_buf;
1357          bool is_delete = str_starts(&data, KEYWORD_DELETE);          bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
1358          if (!strcmp(data, "manage_by_non_root")) {          if (!strcmp(data, "manage_by_non_root")) {
1359                  manage_by_non_root = !is_delete;                  ccs_manage_by_non_root = !is_delete;
1360                  return 0;                  return 0;
1361          }          }
1362          return update_manager_entry(data, is_delete);          return ccs_update_manager_entry(data, is_delete);
1363  }  }
1364    
1365  /**  /**
1366   * read_manager_policy - Read manager policy.   * ccs_read_manager_policy - Read manager policy.
1367   *   *
1368   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1369   *   *
1370   * Returns 0.   * Returns 0.
1371   */   */
1372  static int read_manager_policy(struct ccs_io_buffer *head)  static int ccs_read_manager_policy(struct ccs_io_buffer *head)
1373  {  {
1374          struct list1_head *pos;          struct list1_head *pos;
1375          if (head->read_eof)          if (head->read_eof)
1376                  return 0;                  return 0;
1377          list1_for_each_cookie(pos, head->read_var2, &policy_manager_list) {          list1_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {
1378                  struct policy_manager_entry *ptr;                  struct ccs_policy_manager_entry *ptr;
1379                  ptr = list1_entry(pos, struct policy_manager_entry, list);                  ptr = list1_entry(pos, struct ccs_policy_manager_entry, list);
1380                  if (ptr->is_deleted)                  if (ptr->is_deleted)
1381                          continue;                          continue;
1382                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
# Line 1375  static int read_manager_policy(struct cc Line 1387  static int read_manager_policy(struct cc
1387  }  }
1388    
1389  /**  /**
1390   * is_policy_manager - Check whether the current process is a policy manager.   * ccs_is_policy_manager - Check whether the current process is a policy manager.
1391   *   *
1392   * Returns true if the current process is permitted to modify policy   * Returns true if the current process is permitted to modify policy
1393   * via /proc/ccs/ interface.   * via /proc/ccs/ interface.
1394   */   */
1395  static bool is_policy_manager(void)  static bool ccs_is_policy_manager(void)
1396  {  {
1397          struct policy_manager_entry *ptr;          struct ccs_policy_manager_entry *ptr;
1398          const char *exe;          const char *exe;
1399          struct task_struct *task = current;          struct task_struct *task = current;
1400          const struct path_info *domainname = task->domain_info->domainname;          const struct ccs_path_info *domainname = task->domain_info->domainname;
1401          bool found = false;          bool found = false;
1402          if (!sbin_init_started)          if (!ccs_policy_loaded)
1403                  return true;                  return true;
1404          if (task->tomoyo_flags & CCS_TASK_IS_POLICY_MANAGER)          if (task->tomoyo_flags & CCS_TASK_IS_POLICY_MANAGER)
1405                  return true;                  return true;
1406          if (!manage_by_non_root && (task->uid || task->euid))          if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
1407                  return false;                  return false;
1408          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1409                  if (!ptr->is_deleted && ptr->is_domain                  if (!ptr->is_deleted && ptr->is_domain
1410                      && !ccs_pathcmp(domainname, ptr->manager)) {                      && !ccs_pathcmp(domainname, ptr->manager)) {
1411                          /* Set manager flag. */                          /* Set manager flag. */
# Line 1404  static bool is_policy_manager(void) Line 1416  static bool is_policy_manager(void)
1416          exe = ccs_get_exe();          exe = ccs_get_exe();
1417          if (!exe)          if (!exe)
1418                  return false;                  return false;
1419          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &ccs_policy_manager_list, list) {
1420                  if (!ptr->is_deleted && !ptr->is_domain                  if (!ptr->is_deleted && !ptr->is_domain
1421                      && !strcmp(exe, ptr->manager->name)) {                      && !strcmp(exe, ptr->manager->name)) {
1422                          found = true;                          found = true;
# Line 1414  static bool is_policy_manager(void) Line 1426  static bool is_policy_manager(void)
1426                  }                  }
1427          }          }
1428          if (!found) { /* Reduce error messages. */          if (!found) { /* Reduce error messages. */
1429                  static pid_t last_pid;                  static pid_t ccs_last_pid;
1430                  const pid_t pid = current->pid;                  const pid_t pid = current->pid;
1431                  if (last_pid != pid) {                  if (ccs_last_pid != pid) {
1432                          printk(KERN_WARNING "%s ( %s ) is not permitted to "                          printk(KERN_WARNING "%s ( %s ) is not permitted to "
1433                                 "update policies.\n", domainname->name, exe);                                 "update policies.\n", domainname->name, exe);
1434                          last_pid = pid;                          ccs_last_pid = pid;
1435                  }                  }
1436          }          }
1437          ccs_free(exe);          ccs_free(exe);
# Line 1440  static char *ccs_find_condition_part(cha Line 1452  static char *ccs_find_condition_part(cha
1452  {  {
1453          char *cp = strstr(data, " if ");          char *cp = strstr(data, " if ");
1454          if (cp) {          if (cp) {
1455                  char *cp2;                  while (1) {
1456                  while ((cp2 = strstr(cp + 3, " if ")) != NULL)                          char *cp2 = strstr(cp + 3, " if ");
1457                            if (!cp2)
1458                                    break;
1459                          cp = cp2;                          cp = cp2;
1460                    }
1461                  *cp++ = '\0';                  *cp++ = '\0';
1462          } else {          } else {
1463                  cp = strstr(data, " ; set ");                  cp = strstr(data, " ; set ");
# Line 1453  static char *ccs_find_condition_part(cha Line 1468  static char *ccs_find_condition_part(cha
1468  }  }
1469    
1470  /**  /**
1471   * is_select_one - Parse select command.   * ccs_is_select_one - Parse select command.
1472   *   *
1473   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1474   * @data: String to parse.   * @data: String to parse.
1475   *   *
1476   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1477   */   */
1478  static bool is_select_one(struct ccs_io_buffer *head, const char *data)  static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)
1479  {  {
1480          unsigned int pid;          unsigned int pid;
1481          struct domain_info *domain = NULL;          struct domain_info *domain = NULL;
1482            if (!strcmp(data, "allow_execute")) {
1483                    head->read_execute_only = true;
1484                    return true;
1485            }
1486          if (sscanf(data, "pid=%u", &pid) == 1) {          if (sscanf(data, "pid=%u", &pid) == 1) {
1487                  struct task_struct *p;                  struct task_struct *p;
1488                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
# Line 1478  static bool is_select_one(struct ccs_io_ Line 1497  static bool is_select_one(struct ccs_io_
1497                          domain = ccs_find_domain(data + 7);                          domain = ccs_find_domain(data + 7);
1498          } else          } else
1499                  return false;                  return false;
1500            head->write_var1 = domain;
1501            /* Accessing read_buf is safe because head->io_sem is held. */
1502            if (!head->read_buf)
1503                    return true; /* Do nothing if open(O_WRONLY). */
1504          head->read_avail = 0;          head->read_avail = 0;
1505          ccs_io_printf(head, "# select %s\n", data);          ccs_io_printf(head, "# select %s\n", data);
1506          head->read_single_domain = true;          head->read_single_domain = true;
# Line 1485  static bool is_select_one(struct ccs_io_ Line 1508  static bool is_select_one(struct ccs_io_
1508          if (domain) {          if (domain) {
1509                  struct domain_info *d;                  struct domain_info *d;
1510                  head->read_var1 = NULL;                  head->read_var1 = NULL;
1511                  list1_for_each_entry(d, &domain_list, list) {                  list1_for_each_entry(d, &ccs_domain_list, list) {
1512                          if (d == domain)                          if (d == domain)
1513                                  break;                                  break;
1514                          head->read_var1 = &d->list;                          head->read_var1 = &d->list;
# Line 1496  static bool is_select_one(struct ccs_io_ Line 1519  static bool is_select_one(struct ccs_io_
1519                  if (domain->is_deleted)                  if (domain->is_deleted)
1520                          ccs_io_printf(head, "# This is a deleted domain.\n");                          ccs_io_printf(head, "# This is a deleted domain.\n");
1521          }          }
         head->write_var1 = domain;  
1522          return true;          return true;
1523  }  }
1524    
1525  /**  /**
1526   * write_domain_policy - Write domain policy.   * ccs_write_domain_policy - Write domain policy.
1527   *   *
1528   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1529   *   *
1530   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1531   */   */
1532  static int write_domain_policy(struct ccs_io_buffer *head)  static int ccs_write_domain_policy(struct ccs_io_buffer *head)
1533  {  {
1534          char *data = head->write_buf;          char *data = head->write_buf;
1535          struct domain_info *domain = head->write_var1;          struct domain_info *domain = head->write_var1;
# Line 1515  static int write_domain_policy(struct cc Line 1537  static int write_domain_policy(struct cc
1537          bool is_select = false;          bool is_select = false;
1538          bool is_undelete = false;          bool is_undelete = false;
1539          unsigned int profile;          unsigned int profile;
1540          const struct condition_list *cond = NULL;          const struct ccs_condition_list *cond = NULL;
1541          char *cp;          char *cp;
1542          if (str_starts(&data, KEYWORD_DELETE))          if (ccs_str_starts(&data, KEYWORD_DELETE))
1543                  is_delete = true;                  is_delete = true;
1544          else if (str_starts(&data, KEYWORD_SELECT))          else if (ccs_str_starts(&data, KEYWORD_SELECT))
1545                  is_select = true;                  is_select = true;
1546          else if (str_starts(&data, KEYWORD_UNDELETE))          else if (ccs_str_starts(&data, KEYWORD_UNDELETE))
1547                  is_undelete = true;                  is_undelete = true;
1548          if (is_select && is_select_one(head, data))          if (is_select && ccs_is_select_one(head, data))
1549                  return 0;                  return 0;
1550          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
1551          if (!is_policy_manager())          if (!ccs_is_policy_manager())
1552                  return -EPERM;                  return -EPERM;
1553          if (ccs_is_domain_def(data)) {          if (ccs_is_domain_def(data)) {
1554                  domain = NULL;                  domain = NULL;
# Line 1547  static int write_domain_policy(struct cc Line 1569  static int write_domain_policy(struct cc
1569    
1570          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1
1571              && profile < MAX_PROFILES) {              && profile < MAX_PROFILES) {
1572                  if (profile_ptr[profile] || !sbin_init_started)                  if (ccs_profile_ptr[profile] || !ccs_policy_loaded)
1573                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
1574                  return 0;                  return 0;
1575          }          }
# Line 1567  static int write_domain_policy(struct cc Line 1589  static int write_domain_policy(struct cc
1589                  if (!cond)                  if (!cond)
1590                          return -EINVAL;                          return -EINVAL;
1591          }          }
1592          if (str_starts(&data, KEYWORD_ALLOW_CAPABILITY))          if (ccs_str_starts(&data, KEYWORD_ALLOW_CAPABILITY))
1593                  return ccs_write_capability_policy(data, domain, cond,                  return ccs_write_capability_policy(data, domain, cond,
1594                                                     is_delete);                                                     is_delete);
1595          else if (str_starts(&data, KEYWORD_ALLOW_NETWORK))          else if (ccs_str_starts(&data, KEYWORD_ALLOW_NETWORK))
1596                  return ccs_write_network_policy(data, domain, cond, is_delete);                  return ccs_write_network_policy(data, domain, cond, is_delete);
1597          else if (str_starts(&data, KEYWORD_ALLOW_SIGNAL))          else if (ccs_str_starts(&data, KEYWORD_ALLOW_SIGNAL))
1598                  return ccs_write_signal_policy(data, domain, cond, is_delete);                  return ccs_write_signal_policy(data, domain, cond, is_delete);
1599          else if (str_starts(&data, KEYWORD_ALLOW_ARGV0))          else if (ccs_str_starts(&data, KEYWORD_ALLOW_ARGV0))
1600                  return ccs_write_argv0_policy(data, domain, cond, is_delete);                  return ccs_write_argv0_policy(data, domain, cond, is_delete);
1601          else if (str_starts(&data, KEYWORD_ALLOW_ENV))          else if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
1602                  return ccs_write_env_policy(data, domain, cond, is_delete);                  return ccs_write_env_policy(data, domain, cond, is_delete);
1603          else          else
1604                  return ccs_write_file_policy(data, domain, cond, is_delete);                  return ccs_write_file_policy(data, domain, cond, is_delete);
1605  }  }
1606    
1607  /**  /**
1608   * print_single_path_acl - Print a single path ACL entry.   * ccs_print_single_path_acl - Print a single path ACL entry.
1609   *   *
1610   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1611   * @ptr:  Pointer to "struct single_path_acl_record".   * @ptr:  Pointer to "struct ccs_single_path_acl_record".
1612   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1613   *   *
1614   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1615   */   */
1616  static bool print_single_path_acl(struct ccs_io_buffer *head,  static bool ccs_print_single_path_acl(struct ccs_io_buffer *head,
1617                                    struct single_path_acl_record *ptr,                                        struct ccs_single_path_acl_record *ptr,
1618                                    const struct condition_list *cond)                                        const struct ccs_condition_list *cond)
1619  {  {
1620          int pos;          int pos;
1621          u8 bit;          u8 bit;
# Line 1610  static bool print_single_path_acl(struct Line 1632  static bool print_single_path_acl(struct
1632                  const char *msg;                  const char *msg;
1633                  if (!(perm & (1 << bit)))                  if (!(perm & (1 << bit)))
1634                          continue;                          continue;
1635                    if (head->read_execute_only && bit != TYPE_EXECUTE_ACL)
1636                            continue;
1637                  /* Print "read/write" instead of "read" and "write". */                  /* Print "read/write" instead of "read" and "write". */
1638                  if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)                  if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)
1639                      && (perm & (1 << TYPE_READ_WRITE_ACL)))                      && (perm & (1 << TYPE_READ_WRITE_ACL)))
# Line 1630  static bool print_single_path_acl(struct Line 1654  static bool print_single_path_acl(struct
1654  }  }
1655    
1656  /**  /**
1657   * print_double_path_acl - Print a double path ACL entry.   * ccs_print_double_path_acl - Print a double path ACL entry.
1658   *   *
1659   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1660   * @ptr:  Pointer to "struct double_path_acl_record".   * @ptr:  Pointer to "struct ccs_double_path_acl_record".
1661   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1662   *   *
1663   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1664   */   */
1665  static bool print_double_path_acl(struct ccs_io_buffer *head,  static bool ccs_print_double_path_acl(struct ccs_io_buffer *head,
1666                                    struct double_path_acl_record *ptr,                                        struct ccs_double_path_acl_record *ptr,
1667                                    const struct condition_list *cond)                                        const struct ccs_condition_list *cond)
1668  {  {
1669          int pos;          int pos;
1670          const char *atmark1 = "";          const char *atmark1 = "";
# Line 1681  static bool print_double_path_acl(struct Line 1705  static bool print_double_path_acl(struct
1705  }  }
1706    
1707  /**  /**
1708   * print_argv0_acl - Print an argv[0] ACL entry.   * ccs_print_argv0_acl - Print an argv[0] ACL entry.
1709   *   *
1710   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1711   * @ptr:  Pointer to "struct argv0_acl_record".   * @ptr:  Pointer to "struct ccs_argv0_acl_record".
1712   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1713   *   *
1714   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1715   */   */
1716  static bool print_argv0_acl(struct ccs_io_buffer *head,  static bool ccs_print_argv0_acl(struct ccs_io_buffer *head,
1717                              struct argv0_acl_record *ptr,                                  struct ccs_argv0_acl_record *ptr,
1718                              const struct condition_list *cond)                                  const struct ccs_condition_list *cond)
1719  {  {
1720          int pos = head->read_avail;          int pos = head->read_avail;
1721          if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",          if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
# Line 1706  static bool print_argv0_acl(struct ccs_i Line 1730  static bool print_argv0_acl(struct ccs_i
1730  }  }
1731    
1732  /**  /**
1733   * print_env_acl - Print an evironment variable name's ACL entry.   * ccs_print_env_acl - Print an evironment variable name's ACL entry.
1734   *   *
1735   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1736   * @ptr:  Pointer to "struct env_acl_record".   * @ptr:  Pointer to "struct ccs_env_acl_record".
1737   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1738   *   *
1739   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1740   */   */
1741  static bool print_env_acl(struct ccs_io_buffer *head,  static bool ccs_print_env_acl(struct ccs_io_buffer *head,
1742                            struct env_acl_record *ptr,                                struct ccs_env_acl_record *ptr,
1743                            const struct condition_list *cond)                                const struct ccs_condition_list *cond)
1744  {  {
1745          int pos = head->read_avail;          int pos = head->read_avail;
1746          if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))          if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))
# Line 1730  static bool print_env_acl(struct ccs_io_ Line 1754  static bool print_env_acl(struct ccs_io_
1754  }  }
1755    
1756  /**  /**
1757   * print_capability_acl - Print a capability ACL entry.   * ccs_print_capability_acl - Print a capability ACL entry.
1758   *   *
1759   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1760   * @ptr:  Pointer to "struct capability_acl_record".   * @ptr:  Pointer to "struct ccs_capability_acl_record".
1761   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1762   *   *
1763   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1764   */   */
1765  static bool print_capability_acl(struct ccs_io_buffer *head,  static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
1766                                   struct capability_acl_record *ptr,                                       struct ccs_capability_acl_record *ptr,
1767                                   const struct condition_list *cond)                                       const struct ccs_condition_list *cond)
1768  {  {
1769          int pos = head->read_avail;          int pos = head->read_avail;
1770          if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",          if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",
# Line 1755  static bool print_capability_acl(struct Line 1779  static bool print_capability_acl(struct
1779  }  }
1780    
1781  /**  /**
1782   * print_ipv4_entry - Print IPv4 address of a network ACL entry.   * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
1783   *   *
1784   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1785   * @ptr:  Pointer to "struct ip_network_acl_record".   * @ptr:  Pointer to "struct ccs_ip_network_acl_record".
1786   *   *
1787   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1788   */   */
1789  static bool print_ipv4_entry(struct ccs_io_buffer *head,  static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
1790                               struct ip_network_acl_record *ptr)                                   struct ccs_ip_network_acl_record *ptr)
1791  {  {
1792          const u32 min_address = ptr->u.ipv4.min;          const u32 min_address = ptr->u.ipv4.min;
1793          const u32 max_address = ptr->u.ipv4.max;          const u32 max_address = ptr->u.ipv4.max;
# Line 1776  static bool print_ipv4_entry(struct ccs_ Line 1800  static bool print_ipv4_entry(struct ccs_
1800  }  }
1801    
1802  /**  /**
1803   * print_ipv6_entry - Print IPv6 address of a network ACL entry.   * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
1804   *   *
1805   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1806   * @ptr:  Pointer to "struct ip_network_acl_record".   * @ptr:  Pointer to "struct ccs_ip_network_acl_record".
1807   *   *
1808   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1809   */   */
1810  static bool print_ipv6_entry(struct ccs_io_buffer *head,  static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
1811                               struct ip_network_acl_record *ptr)                                   struct ccs_ip_network_acl_record *ptr)
1812  {  {
1813          char buf[64];          char buf[64];
1814          const struct in6_addr *min_address = ptr->u.ipv6.min;          const struct in6_addr *min_address = ptr->u.ipv6.min;
# Line 1801  static bool print_ipv6_entry(struct ccs_ Line 1825  static bool print_ipv6_entry(struct ccs_
1825  }  }
1826    
1827  /**  /**
1828   * print_port_entry - Print port number of a network ACL entry.   * ccs_print_port_entry - Print port number of a network ACL entry.
1829   *   *
1830   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1831   * @ptr:  Pointer to "struct ip_network_acl_record".   * @ptr:  Pointer to "struct ccs_ip_network_acl_record".
1832   *   *
1833   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1834   */   */
1835  static bool print_port_entry(struct ccs_io_buffer *head,  static bool ccs_print_port_entry(struct ccs_io_buffer *head,
1836                               struct ip_network_acl_record *ptr)                                   struct ccs_ip_network_acl_record *ptr)
1837  {  {
1838          const u16 min_port = ptr->min_port, max_port = ptr->max_port;          const u16 min_port = ptr->min_port;
1839            const u16 max_port = ptr->max_port;
1840          if (!ccs_io_printf(head, " %u", min_port))          if (!ccs_io_printf(head, " %u", min_port))
1841                  return false;                  return false;
1842          if (min_port != max_port && !ccs_io_printf(head, "-%u", max_port))          if (min_port != max_port && !ccs_io_printf(head, "-%u", max_port))
# Line 1820  static bool print_port_entry(struct ccs_ Line 1845  static bool print_port_entry(struct ccs_
1845  }  }
1846    
1847  /**  /**
1848   * print_network_acl - Print a network ACL entry.   * ccs_print_network_acl - Print a network ACL entry.
1849   *   *
1850   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1851   * @ptr:  Pointer to "struct ip_network_acl_record".   * @ptr:  Pointer to "struct ccs_ip_network_acl_record".
1852   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1853   *   *
1854   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1855   */   */
1856  static bool print_network_acl(struct ccs_io_buffer *head,  static bool ccs_print_network_acl(struct ccs_io_buffer *head,
1857                                struct ip_network_acl_record *ptr,                                    struct ccs_ip_network_acl_record *ptr,
1858                                const struct condition_list *cond)                                    const struct ccs_condition_list *cond)
1859  {  {
1860          int pos = head->read_avail;          int pos = head->read_avail;
1861          if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",          if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",
# Line 1842  static bool print_network_acl(struct ccs Line 1867  static bool print_network_acl(struct ccs
1867                          goto out;                          goto out;
1868                  break;                  break;
1869          case IP_RECORD_TYPE_IPv4:          case IP_RECORD_TYPE_IPv4:
1870                  if (!print_ipv4_entry(head, ptr))                  if (!ccs_print_ipv4_entry(head, ptr))
1871                          goto out;                          goto out;
1872                  break;                  break;
1873          case IP_RECORD_TYPE_IPv6:          case IP_RECORD_TYPE_IPv6:
1874                  if (!print_ipv6_entry(head, ptr))                  if (!ccs_print_ipv6_entry(head, ptr))
1875                          goto out;                          goto out;
1876                  break;                  break;
1877          }          }
1878          if (!print_port_entry(head, ptr))          if (!ccs_print_port_entry(head, ptr))
1879                  goto out;                  goto out;
1880          if (!ccs_print_condition(head, cond))          if (!ccs_print_condition(head, cond))
1881                  goto out;                  goto out;
# Line 1861  static bool print_network_acl(struct ccs Line 1886  static bool print_network_acl(struct ccs
1886  }  }
1887    
1888  /**  /**
1889   * print_signal_acl - Print a signal ACL entry.   * ccs_print_signal_acl - Print a signal ACL entry.
1890   *   *
1891   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1892   * @ptr:  Pointer to "struct signale_acl_record".   * @ptr:  Pointer to "struct signale_acl_record".
1893   * @cond: Pointer to "struct condition_list". May be NULL.   * @cond: Pointer to "struct ccs_condition_list". May be NULL.
1894   *   *
1895   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1896   */   */
1897  static bool print_signal_acl(struct ccs_io_buffer *head,  static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
1898                               struct signal_acl_record *ptr,                                   struct ccs_signal_acl_record *ptr,
1899                               const struct condition_list *cond)                                   const struct ccs_condition_list *cond)
1900  {  {
1901          int pos = head->read_avail;          int pos = head->read_avail;
1902          if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",          if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",
# Line 1886  static bool print_signal_acl(struct ccs_ Line 1911  static bool print_signal_acl(struct ccs_
1911  }  }
1912    
1913  /**  /**
1914   * print_execute_handler_record - Print an execute handler ACL entry.   * ccs_print_execute_handler_record - Print an execute handler ACL entry.
1915   *   *
1916   * @head:    Pointer to "struct ccs_io_buffer".   * @head:    Pointer to "struct ccs_io_buffer".
1917   * @keyword: Name of the keyword.   * @keyword: Name of the keyword.
1918   * @ptr:     Pointer to "struct execute_handler_record".   * @ptr:     Pointer to "struct ccs_execute_handler_record".
1919   *   *
1920   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1921   */   */
1922  static bool print_execute_handler_record(struct ccs_io_buffer *head,  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1923                                           const char *keyword,                                               const char *keyword,
1924                                           struct execute_handler_record *ptr)                                               struct ccs_execute_handler_record *
1925                                                 ptr)
1926  {  {
1927          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1928  }  }
1929    
1930  /**  /**
1931   * print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1932   *   *
1933   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1934   * @ptr:  Pointer to an ACL entry.   * @ptr:  Pointer to an ACL entry.
1935   *   *
1936   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1937   */   */
1938  static bool print_entry(struct ccs_io_buffer *head, struct acl_info *ptr)  static bool ccs_print_entry(struct ccs_io_buffer *head,
1939                                struct ccs_acl_info *ptr)
1940  {  {
1941          const struct condition_list *cond = ccs_get_condition_part(ptr);          const struct ccs_condition_list *cond = ccs_get_condition_part(ptr);
1942          const u8 acl_type = ccs_acl_type2(ptr);          const u8 acl_type = ccs_acl_type2(ptr);
1943          if (acl_type & ACL_DELETED)          if (acl_type & ACL_DELETED)
1944                  return true;                  return true;
1945          if (acl_type == TYPE_SINGLE_PATH_ACL) {          if (acl_type == TYPE_SINGLE_PATH_ACL) {
1946                  struct single_path_acl_record *acl                  struct ccs_single_path_acl_record *acl
1947                          = container_of(ptr, struct single_path_acl_record,                          = container_of(ptr, struct ccs_single_path_acl_record,
1948                                         head);                                         head);
1949                  return print_single_path_acl(head, acl, cond);                  return ccs_print_single_path_acl(head, acl, cond);
1950          }          }
1951            if (acl_type == TYPE_EXECUTE_HANDLER) {
1952                    struct ccs_execute_handler_record *acl
1953                            = container_of(ptr, struct ccs_execute_handler_record,
1954                                           head);
1955                    const char *keyword = KEYWORD_EXECUTE_HANDLER;
1956                    return ccs_print_execute_handler_record(head, keyword, acl);
1957            }
1958            if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {
1959                    struct ccs_execute_handler_record *acl
1960                            = container_of(ptr, struct ccs_execute_handler_record,
1961                                           head);
1962                    const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;
1963                    return ccs_print_execute_handler_record(head, keyword, acl);
1964            }
1965            if (head->read_execute_only)
1966                    return true;
1967          if (acl_type == TYPE_DOUBLE_PATH_ACL) {          if (acl_type == TYPE_DOUBLE_PATH_ACL) {
1968                  struct double_path_acl_record *acl                  struct ccs_double_path_acl_record *acl
1969                          = container_of(ptr, struct double_path_acl_record,                          = container_of(ptr, struct ccs_double_path_acl_record,
1970                                         head);                                         head);
1971                  return print_double_path_acl(head, acl, cond);                  return ccs_print_double_path_acl(head, acl, cond);
1972          }          }
1973          if (acl_type == TYPE_ARGV0_ACL) {          if (acl_type == TYPE_ARGV0_ACL) {
1974                  struct argv0_acl_record *acl                  struct ccs_argv0_acl_record *acl
1975                          = container_of(ptr, struct argv0_acl_record, head);                          = container_of(ptr, struct ccs_argv0_acl_record, head);
1976                  return print_argv0_acl(head, acl, cond);                  return ccs_print_argv0_acl(head, acl, cond);
1977          }          }
1978          if (acl_type == TYPE_ENV_ACL) {          if (acl_type == TYPE_ENV_ACL) {
1979                  struct env_acl_record *acl                  struct ccs_env_acl_record *acl
1980                          = container_of(ptr, struct env_acl_record, head);                          = container_of(ptr, struct ccs_env_acl_record, head);
1981                  return print_env_acl(head, acl, cond);                  return ccs_print_env_acl(head, acl, cond);
1982          }          }
1983          if (acl_type == TYPE_CAPABILITY_ACL) {          if (acl_type == TYPE_CAPABILITY_ACL) {
1984                  struct capability_acl_record *acl                  struct ccs_capability_acl_record *acl
1985                          = container_of(ptr, struct capability_acl_record, head);                          = container_of(ptr, struct ccs_capability_acl_record,
1986                  return print_capability_acl(head, acl, cond);                                         head);
1987                    return ccs_print_capability_acl(head, acl, cond);
1988          }          }
1989          if (acl_type == TYPE_IP_NETWORK_ACL) {          if (acl_type == TYPE_IP_NETWORK_ACL) {
1990                  struct ip_network_acl_record *acl                  struct ccs_ip_network_acl_record *acl
1991                          = container_of(ptr, struct ip_network_acl_record, head);                          = container_of(ptr, struct ccs_ip_network_acl_record,
                 return print_network_acl(head, acl, cond);  
         }  
         if (acl_type == TYPE_SIGNAL_ACL) {  
                 struct signal_acl_record *acl  
                         = container_of(ptr, struct signal_acl_record, head);  
                 return print_signal_acl(head, acl, cond);  
         }  
         if (acl_type == TYPE_EXECUTE_HANDLER) {  
                 struct execute_handler_record *acl  
                         = container_of(ptr, struct execute_handler_record,  
1992                                         head);                                         head);
1993                  const char *keyword = KEYWORD_EXECUTE_HANDLER;                  return ccs_print_network_acl(head, acl, cond);
                 return print_execute_handler_record(head, keyword, acl);  
1994          }          }
1995          if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {          if (acl_type == TYPE_SIGNAL_ACL) {
1996                  struct execute_handler_record *acl                  struct ccs_signal_acl_record *acl
1997                          = container_of(ptr, struct execute_handler_record,                          = container_of(ptr, struct ccs_signal_acl_record, head);
1998                                         head);                  return ccs_print_signal_acl(head, acl, cond);
                 const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;  
                 return print_execute_handler_record(head, keyword, acl);  
1999          }          }
2000          /* Workaround for gcc 3.2.2's inline bug. */          /* Workaround for gcc 3.2.2's inline bug. */
2001          if (acl_type & ACL_DELETED)          if (acl_type & ACL_DELETED)
# Line 1974  static bool print_entry(struct ccs_io_bu Line 2005  static bool print_entry(struct ccs_io_bu
2005  }  }
2006    
2007  /**  /**
2008   * read_domain_policy - Read domain policy.   * ccs_read_domain_policy - Read domain policy.
2009   *   *
2010   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2011   *   *
2012   * Returns 0.   * Returns 0.
2013   */   */
2014  static int read_domain_policy(struct ccs_io_buffer *head)  static int ccs_read_domain_policy(struct ccs_io_buffer *head)
2015  {  {
2016          struct list1_head *dpos;          struct list1_head *dpos;
2017          struct list1_head *apos;          struct list1_head *apos;
# Line 1988  static int read_domain_policy(struct ccs Line 2019  static int read_domain_policy(struct ccs
2019                  return 0;                  return 0;
2020          if (head->read_step == 0)          if (head->read_step == 0)
2021                  head->read_step = 1;                  head->read_step = 1;
2022          list1_for_each_cookie(dpos, head->read_var1, &domain_list) {          list1_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
2023                  struct domain_info *domain;                  struct domain_info *domain;
2024                  const char *quota_exceeded = "";                  const char *quota_exceeded = "";
2025                  const char *transition_failed = "";                  const char *transition_failed = "";
# Line 2024  static int read_domain_policy(struct ccs Line 2055  static int read_domain_policy(struct ccs
2055                  /* Print ACL entries in the domain. */                  /* Print ACL entries in the domain. */
2056                  list1_for_each_cookie(apos, head->read_var2,                  list1_for_each_cookie(apos, head->read_var2,
2057                                        &domain->acl_info_list) {                                        &domain->acl_info_list) {
2058                          struct acl_info *ptr                          struct ccs_acl_info *ptr
2059                                  = list1_entry(apos, struct acl_info, list);                                  = list1_entry(apos, struct ccs_acl_info, list);
2060                          if (!print_entry(head, ptr))                          if (!ccs_print_entry(head, ptr))
2061                                  return 0;                                  return 0;
2062                  }                  }
2063                  head->read_step = 3;                  head->read_step = 3;
# Line 2044  static int read_domain_policy(struct ccs Line 2075  static int read_domain_policy(struct ccs
2075  #endif  #endif
2076    
2077  /**  /**
2078   * write_domain_profile - Assign profile for specified domain.   * ccs_write_domain_profile - Assign profile for specified domain.
2079   *   *
2080   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2081   *   *
# Line 2055  static int read_domain_policy(struct ccs Line 2086  static int read_domain_policy(struct ccs
2086   *     ( echo "select " $domainname; echo "use_profile " $profile ) |   *     ( echo "select " $domainname; echo "use_profile " $profile ) |
2087   *     /usr/lib/ccs/loadpolicy -d   *     /usr/lib/ccs/loadpolicy -d
2088   */   */
2089  static int write_domain_profile(struct ccs_io_buffer *head)  static int ccs_write_domain_profile(struct ccs_io_buffer *head)
2090  {  {
2091          char *data = head->write_buf;          char *data = head->write_buf;
2092          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
# Line 2067  static int write_domain_profile(struct c Line 2098  static int write_domain_profile(struct c
2098          domain = ccs_find_domain(cp + 1);          domain = ccs_find_domain(cp + 1);
2099          profile = simple_strtoul(data, NULL, 10);          profile = simple_strtoul(data, NULL, 10);
2100          if (domain && profile < MAX_PROFILES          if (domain && profile < MAX_PROFILES
2101              && (profile_ptr[profile] || !sbin_init_started))              && (ccs_profile_ptr[profile] || !ccs_policy_loaded))
2102                  domain->profile = (u8) profile;                  domain->profile = (u8) profile;
2103          ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);          ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
2104          return 0;          return 0;
2105  }  }
2106    
2107  /**  /**
2108   * read_domain_profile - Read only domainname and profile.   * ccs_read_domain_profile - Read only domainname and profile.
2109   *   *
2110   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2111   *   *
# Line 2087  static int write_domain_profile(struct c Line 2118  static int write_domain_profile(struct c
2118   *     domainname = $0; } else if ( $1 == "use_profile" ) {   *     domainname = $0; } else if ( $1 == "use_profile" ) {
2119   *     print $2 " " domainname; domainname = ""; } } ; '   *     print $2 " " domainname; domainname = ""; } } ; '
2120   */   */
2121  static int read_domain_profile(struct ccs_io_buffer *head)  static int ccs_read_domain_profile(struct ccs_io_buffer *head)
2122  {  {
2123          struct list1_head *pos;          struct list1_head *pos;
2124          if (head->read_eof)          if (head->read_eof)
2125                  return 0;                  return 0;
2126          list1_for_each_cookie(pos, head->read_var1, &domain_list) {          list1_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
2127                  struct domain_info *domain;                  struct domain_info *domain;
2128                  domain = list1_entry(pos, struct domain_info, list);                  domain = list1_entry(pos, struct domain_info, list);
2129                  if (domain->is_deleted)                  if (domain->is_deleted)
# Line 2106  static int read_domain_profile(struct cc Line 2137  static int read_domain_profile(struct cc
2137  }  }
2138    
2139  /**  /**
2140   * write_pid: Specify PID to obtain domainname.   * ccs_write_pid: Specify PID to obtain domainname.
2141   *   *
2142   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2143   *   *
2144   * Returns 0.   * Returns 0.
2145   */   */
2146  static int write_pid(struct ccs_io_buffer *head)  static int ccs_write_pid(struct ccs_io_buffer *head)
2147  {  {
2148          head->read_eof = false;          head->read_eof = false;
2149          return 0;          return 0;
2150  }  }
2151    
2152  /**  /**
2153   * read_pid - Read information of a process.   * ccs_read_pid - Read information of a process.
2154   *   *
2155   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2156   *   *
# Line 2127  static int write_pid(struct ccs_io_buffe Line 2158  static int write_pid(struct ccs_io_buffe
2158   * process information of the specified PID on success,   * process information of the specified PID on success,
2159   * empty string otherwise.   * empty string otherwise.
2160   */   */
2161  static int read_pid(struct ccs_io_buffer *head)  static int ccs_read_pid(struct ccs_io_buffer *head)
2162  {  {
         /* Accessing write_buf is safe because head->io_sem is held. */  
2163          char *buf = head->write_buf;          char *buf = head->write_buf;
2164          bool task_info = false;          bool task_info = false;
2165          unsigned int pid;          unsigned int pid;
2166          struct task_struct *p;          struct task_struct *p;
2167          struct domain_info *domain = NULL;          struct domain_info *domain = NULL;
2168          u32 tomoyo_flags = 0;          u32 tomoyo_flags = 0;
2169            /* Accessing write_buf is safe because head->io_sem is held. */
2170            if (!buf)
2171                    goto done; /* Do nothing if open(O_RDONLY). */
2172          if (head->read_avail || head->read_eof)          if (head->read_avail || head->read_eof)
2173                  goto done;                  goto done;
2174          head->read_eof = true;          head->read_eof = true;
2175          if (str_starts(&buf, "info "))          if (ccs_str_starts(&buf, "info "))
2176                  task_info = true;                  task_info = true;
2177          pid = (unsigned int) simple_strtoul(buf, NULL, 10);          pid = (unsigned int) simple_strtoul(buf, NULL, 10);
2178          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
# Line 2173  static int read_pid(struct ccs_io_buffer Line 2206  static int read_pid(struct ccs_io_buffer
2206  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2207    
2208  /**  /**
2209   * write_exception_policy - Write exception policy.   * ccs_write_exception_policy - Write exception policy.
2210   *   *
2211   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2212   *   *
2213   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
2214   */   */
2215  static int write_exception_policy(struct ccs_io_buffer *head)  static int ccs_write_exception_policy(struct ccs_io_buffer *head)
2216  {  {
2217          char *data = head->write_buf;          char *data = head->write_buf;
2218          bool is_delete = str_starts(&data, KEYWORD_DELETE);          bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
2219          if (str_starts(&data, KEYWORD_KEEP_DOMAIN))          if (ccs_str_starts(&data, KEYWORD_KEEP_DOMAIN))
2220                  return ccs_write_domain_keeper_policy(data, false, is_delete);                  return ccs_write_domain_keeper_policy(data, false, is_delete);
2221          if (str_starts(&data, KEYWORD_NO_KEEP_DOMAIN))          if (ccs_str_starts(&data, KEYWORD_NO_KEEP_DOMAIN))
2222                  return ccs_write_domain_keeper_policy(data, true, is_delete);                  return ccs_write_domain_keeper_policy(data, true, is_delete);
2223          if (str_starts(&data, KEYWORD_INITIALIZE_DOMAIN))          if (ccs_str_starts(&data, KEYWORD_INITIALIZE_DOMAIN))
2224                  return ccs_write_domain_initializer_policy(data, false,                  return ccs_write_domain_initializer_policy(data, false,
2225                                                             is_delete);                                                             is_delete);
2226          if (str_starts(&data, KEYWORD_NO_INITIALIZE_DOMAIN))          if (ccs_str_starts(&data, KEYWORD_NO_INITIALIZE_DOMAIN))
2227                  return ccs_write_domain_initializer_policy(data, true,                  return ccs_write_domain_initializer_policy(data, true,
2228                                                             is_delete);                                                             is_delete);
2229          if (str_starts(&data, KEYWORD_ALIAS))          if (ccs_str_starts(&data, KEYWORD_ALIAS))
2230                  return ccs_write_alias_policy(data, is_delete);                  return ccs_write_alias_policy(data, is_delete);
2231          if (str_starts(&data, KEYWORD_AGGREGATOR))          if (ccs_str_starts(&data, KEYWORD_AGGREGATOR))
2232                  return ccs_write_aggregator_policy(data, is_delete);                  return ccs_write_aggregator_policy(data, is_delete);
2233          if (str_starts(&data, KEYWORD_ALLOW_READ))          if (ccs_str_starts(&data, KEYWORD_ALLOW_READ))
2234                  return ccs_write_globally_readable_policy(data, is_delete);                  return ccs_write_globally_readable_policy(data, is_delete);
2235          if (str_starts(&data, KEYWORD_ALLOW_ENV))          if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
2236                  return ccs_write_globally_usable_env_policy(data, is_delete);                  return ccs_write_globally_usable_env_policy(data, is_delete);
2237          if (str_starts(&data, KEYWORD_FILE_PATTERN))          if (ccs_str_starts(&data, KEYWORD_FILE_PATTERN))
2238                  return ccs_write_pattern_policy(data, is_delete);                  return ccs_write_pattern_policy(data, is_delete);
2239          if (str_starts(&data, KEYWORD_PATH_GROUP))          if (ccs_str_starts(&data, KEYWORD_PATH_GROUP))
2240                  return ccs_write_path_group_policy(data, is_delete);                  return ccs_write_path_group_policy(data, is_delete);
2241          if (str_starts(&data, KEYWORD_DENY_REWRITE))          if (ccs_str_starts(&data, KEYWORD_DENY_REWRITE))
2242                  return ccs_write_no_rewrite_policy(data, is_delete);                  return ccs_write_no_rewrite_policy(data, is_delete);
2243          if (str_starts(&data, KEYWORD_ADDRESS_GROUP))          if (ccs_str_starts(&data, KEYWORD_ADDRESS_GROUP))
2244                  return ccs_write_address_group_policy(data, is_delete);                  return ccs_write_address_group_policy(data, is_delete);
2245          return -EINVAL;          return -EINVAL;
2246  }  }
2247    
2248  /**  /**
2249   * read_exception_policy - Read exception policy.   * ccs_read_exception_policy - Read exception policy.
2250   *   *
2251   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2252   *   *
2253   * Returns 0 on success, -EINVAL otherwise.   * Returns 0 on success, -EINVAL otherwise.
2254   */   */
2255  static int read_exception_policy(struct ccs_io_buffer *head)  static int ccs_read_exception_policy(struct ccs_io_buffer *head)
2256  {  {
2257          if (!head->read_eof) {          if (!head->read_eof) {
2258                  switch (head->read_step) {                  switch (head->read_step) {
# Line 2289  static int read_exception_policy(struct Line 2322  static int read_exception_policy(struct
2322  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
2323    
2324  /**  /**
2325   * write_system_policy - Write system policy.   * ccs_write_system_policy - Write system policy.
2326   *   *
2327   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2328   *   *
2329   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
2330   */   */
2331  static int write_system_policy(struct ccs_io_buffer *head)  static int ccs_write_system_policy(struct ccs_io_buffer *head)
2332  {  {
2333          char *data = head->write_buf;          char *data = head->write_buf;
2334          bool is_delete = false;          bool is_delete = false;
2335          if (str_starts(&data, KEYWORD_DELETE))          if (ccs_str_starts(&data, KEYWORD_DELETE))
2336                  is_delete = true;                  is_delete = true;
2337          if (str_starts(&data, KEYWORD_ALLOW_MOUNT))          if (ccs_str_starts(&data, KEYWORD_ALLOW_MOUNT))
2338                  return ccs_write_mount_policy(data, is_delete);                  return ccs_write_mount_policy(data, is_delete);
2339          if (str_starts(&data, KEYWORD_DENY_UNMOUNT))          if (ccs_str_starts(&data, KEYWORD_DENY_UNMOUNT))
2340                  return ccs_write_no_umount_policy(data, is_delete);                  return ccs_write_no_umount_policy(data, is_delete);
2341          if (str_starts(&data, KEYWORD_ALLOW_CHROOT))          if (ccs_str_starts(&data, KEYWORD_ALLOW_CHROOT))
2342                  return ccs_write_chroot_policy(data, is_delete);                  return ccs_write_chroot_policy(data, is_delete);
2343          if (str_starts(&data, KEYWORD_ALLOW_PIVOT_ROOT))          if (ccs_str_starts(&data, KEYWORD_ALLOW_PIVOT_ROOT))
2344                  return ccs_write_pivot_root_policy(data, is_delete);                  return ccs_write_pivot_root_policy(data, is_delete);
2345          if (str_starts(&data, KEYWORD_DENY_AUTOBIND))          if (ccs_str_starts(&data, KEYWORD_DENY_AUTOBIND))
2346                  return ccs_write_reserved_port_policy(data, is_delete);                  return ccs_write_reserved_port_policy(data, is_delete);
2347          return -EINVAL;          return -EINVAL;
2348  }  }
2349    
2350  /**  /**
2351   * read_system_policy - Read system policy.   * ccs_read_system_policy - Read system policy.
2352   *   *
2353   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2354   *   *
2355   * Returns 0 on success, -EINVAL otherwise.   * Returns 0 on success, -EINVAL otherwise.
2356   */   */
2357  static int read_system_policy(struct ccs_io_buffer *head)  static int ccs_read_system_policy(struct ccs_io_buffer *head)
2358  {  {
2359          if (!head->read_eof) {          if (!head->read_eof) {
2360                  switch (head->read_step) {                  switch (head->read_step) {
# Line 2366  static int read_system_policy(struct ccs Line 2399  static int read_system_policy(struct ccs
2399  static const char *ccs_loader;  static const char *ccs_loader;
2400    
2401  /**  /**
2402   * loader_setup - Specify the policy loader to use.   * ccs_loader_setup - Specify the policy loader to use.
2403   *   *
2404   * @str: Path to the policy loader.   * @str: Path to the policy loader.
2405   *   *
2406   * Returns 0.   * Returns 0.
2407   */   */
2408  static int __init loader_setup(char *str)  static int __init ccs_loader_setup(char *str)
2409  {  {
2410          ccs_loader = str;          ccs_loader = str;
2411          return 0;          return 0;
2412  }  }
2413    
2414  __setup("CCS_loader=", loader_setup);  __setup("CCS_loader=", ccs_loader_setup);
2415    
2416  /**  /**
2417   * policy_loader_exists - Check whether /sbin/ccs-init exists.   * ccs_policy_loader_exists - Check whether /sbin/ccs-init exists.
2418   *   *
2419   * Returns true if /sbin/ccs-init exists, false otherwise.   * Returns true if /sbin/ccs-init exists, false otherwise.
2420   */   */
2421  static bool policy_loader_exists(void)  static bool ccs_policy_loader_exists(void)
2422  {  {
2423          /*          /*
2424           * Don't activate MAC if the path given by 'CCS_loader=' option doesn't           * Don't activate MAC if the path given by 'CCS_loader=' option doesn't
# Line 2397  static bool policy_loader_exists(void) Line 2430  static bool policy_loader_exists(void)
2430          struct nameidata nd;          struct nameidata nd;
2431          if (!ccs_loader)          if (!ccs_loader)
2432                  ccs_loader = "/sbin/ccs-init";                  ccs_loader = "/sbin/ccs-init";
2433          if (path_lookup(ccs_loader, lookup_flags, &nd)) {          if (path_lookup(ccs_loader, ccs_lookup_flags, &nd)) {
2434                  printk(KERN_INFO "Not activating Mandatory Access Control now "                  printk(KERN_INFO "Not activating Mandatory Access Control now "
2435                         "since %s doesn't exist.\n", ccs_loader);                         "since %s doesn't exist.\n", ccs_loader);
2436                  return false;                  return false;
# Line 2412  static bool policy_loader_exists(void) Line 2445  static bool policy_loader_exists(void)
2445    
2446  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
2447  /**  /**
2448   * run_ccs_loader - Start /sbin/ccs-init .   * ccs_run_loader - Start /sbin/ccs-init .
2449   *   *
2450   * @unused: Not used.   * @unused: Not used.
2451   *   *
2452   * Returns PID of /sbin/ccs-init on success, negative value otherwise.   * Returns PID of /sbin/ccs-init on success, negative value otherwise.
2453   */   */
2454  static int run_ccs_loader(void *unused)  static int ccs_run_loader(void *unused)
2455  {  {
2456          char *argv[2];          char *argv[2];
2457          char *envp[3];          char *envp[3];
# Line 2448  static int run_ccs_loader(void *unused) Line 2481  static int run_ccs_loader(void *unused)
2481   */   */
2482  void ccs_load_policy(const char *filename)  void ccs_load_policy(const char *filename)
2483  {  {
2484          if (sbin_init_started)          if (ccs_policy_loaded)
2485                  return;                  return;
2486          /*          /*
2487           * Check filename is /sbin/init or /sbin/ccs-start.           * Check filename is /sbin/init or /sbin/ccs-start.
# Line 2459  void ccs_load_policy(const char *filenam Line 2492  void ccs_load_policy(const char *filenam
2492          if (strcmp(filename, "/sbin/init") &&          if (strcmp(filename, "/sbin/init") &&
2493              strcmp(filename, "/sbin/ccs-start"))              strcmp(filename, "/sbin/ccs-start"))
2494                  return;                  return;
2495          if (!policy_loader_exists())          if (!ccs_policy_loader_exists())
2496                  return;                  return;
2497  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
2498          {          {
# Line 2478  void ccs_load_policy(const char *filenam Line 2511  void ccs_load_policy(const char *filenam
2511          {          {
2512                  /* Copied from kernel/kmod.c */                  /* Copied from kernel/kmod.c */
2513                  struct task_struct *task = current;                  struct task_struct *task = current;
2514                  pid_t pid = kernel_thread(run_ccs_loader, NULL, 0);                  pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
2515                  sigset_t tmpsig;                  sigset_t tmpsig;
2516                  spin_lock_irq(&task->sighand->siglock);                  spin_lock_irq(&task->sighand->siglock);
2517                  tmpsig = task->blocked;                  tmpsig = task->blocked;
# Line 2497  void ccs_load_policy(const char *filenam Line 2530  void ccs_load_policy(const char *filenam
2530          {          {
2531                  /* Copied from kernel/kmod.c */                  /* Copied from kernel/kmod.c */
2532                  struct task_struct *task = current;                  struct task_struct *task = current;
2533                  pid_t pid = kernel_thread(run_ccs_loader, NULL, 0);                  pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
2534                  sigset_t tmpsig;                  sigset_t tmpsig;
2535                  spin_lock_irq(&task->sigmask_lock);                  spin_lock_irq(&task->sigmask_lock);
2536                  tmpsig = task->blocked;                  tmpsig = task->blocked;
# Line 2514  void ccs_load_policy(const char *filenam Line 2547  void ccs_load_policy(const char *filenam
2547          }          }
2548  #endif  #endif
2549  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
2550          printk(KERN_INFO "SAKURA: 1.6.5-pre   2008/10/20\n");          printk(KERN_INFO "SAKURA: 1.6.7-pre   2009/02/02\n");
2551  #endif  #endif
2552  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2553          printk(KERN_INFO "TOMOYO: 1.6.5-pre   2008/10/20\n");          printk(KERN_INFO "TOMOYO: 1.6.7-pre   2009/02/02\n");
2554  #endif  #endif
2555          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
2556          sbin_init_started = true;          ccs_policy_loaded = true;
2557          ccs_log_level = KERN_WARNING;          ccs_log_level = KERN_WARNING;
2558          { /* Check all profiles currently assigned to domains are defined. */          { /* Check all profiles currently assigned to domains are defined. */
2559                  struct domain_info *domain;                  struct domain_info *domain;
2560                  list1_for_each_entry(domain, &domain_list, list) {                  list1_for_each_entry(domain, &ccs_domain_list, list) {
2561                          const u8 profile = domain->profile;                          const u8 profile = domain->profile;
2562                          if (profile_ptr[profile])                          if (ccs_profile_ptr[profile])
2563                                  continue;                                  continue;
2564                          panic("Profile %u (used by '%s') not defined.\n",                          panic("Profile %u (used by '%s') not defined.\n",
2565                                profile, domain->domainname->name);                                profile, domain->domainname->name);
# Line 2534  void ccs_load_policy(const char *filenam Line 2567  void ccs_load_policy(const char *filenam
2567          }          }
2568  }  }
2569    
2570  /* Wait queue for query_list. */  /* Wait queue for ccs_query_list. */
2571  static DECLARE_WAIT_QUEUE_HEAD(query_wait);  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
2572    
2573  /* Lock for manipulating query_list. */  /* Lock for manipulating ccs_query_list. */
2574  static DEFINE_SPINLOCK(query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
2575    
2576  /* Structure for query. */  /* Structure for query. */
2577  struct query_entry {  struct ccs_query_entry {
2578          struct list_head list;          struct list_head list;
2579          char *query;          char *query;
2580          int query_len;          int query_len;
# Line 2550  struct query_entry { Line 2583  struct query_entry {
2583          int answer;          int answer;
2584  };  };
2585    
2586  /* The list for "struct query_entry". */  /* The list for "struct ccs_query_entry". */
2587  static LIST_HEAD(query_list);  static LIST_HEAD(ccs_query_list);
2588    
2589  /* Number of "struct file" referring /proc/ccs/query interface. */  /* Number of "struct file" referring /proc/ccs/query interface. */
2590  static atomic_t queryd_watcher = ATOMIC_INIT(0);  static atomic_t ccs_query_observers = ATOMIC_INIT(0);
2591    
2592  /**  /**
2593   * ccs_check_supervisor - Ask for the supervisor's decision.   * ccs_check_supervisor - Ask for the supervisor's decision.
# Line 2573  int ccs_check_supervisor(struct ccs_requ Line 2606  int ccs_check_supervisor(struct ccs_requ
2606          int error = -EPERM;          int error = -EPERM;
2607          int pos;          int pos;
2608          int len;          int len;
2609          static unsigned int serial;          static unsigned int ccs_serial;
2610          struct query_entry *query_entry = NULL;          struct ccs_query_entry *ccs_query_entry = NULL;
2611          char *header;          char *header;
2612          if (!r->domain)          if (!r->domain)
2613                  r->domain = current->domain_info;                  r->domain = current->domain_info;
2614          if (!atomic_read(&queryd_watcher)) {          if (!atomic_read(&ccs_query_observers)) {
2615                  int i;                  int i;
2616                  if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2617                          return -EPERM;                          return -EPERM;
# Line 2595  int ccs_check_supervisor(struct ccs_requ Line 2628  int ccs_check_supervisor(struct ccs_requ
2628  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2629          header = ccs_init_audit_log(&len, r);          header = ccs_init_audit_log(&len, r);
2630  #else  #else
2631          header = ccs_alloc(1);          header = ccs_alloc(1, true);
2632  #endif  #endif
2633          if (!header)          if (!header)
2634                  goto out;                  goto out;
2635          query_entry = ccs_alloc(sizeof(*query_entry));          ccs_query_entry = ccs_alloc(sizeof(*ccs_query_entry), true);
2636          if (!query_entry)          if (!ccs_query_entry)
2637                  goto out;                  goto out;
2638          query_entry->query = ccs_alloc(len);          ccs_query_entry->query = ccs_alloc(len, true);
2639          if (!query_entry->query)          if (!ccs_query_entry->query)
2640                  goto out;                  goto out;
2641          INIT_LIST_HEAD(&query_entry->list);          INIT_LIST_HEAD(&ccs_query_entry->list);
2642          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2643          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2644          query_entry->serial = serial++;          ccs_query_entry->serial = ccs_serial++;
2645          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2646          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2647          pos = snprintf(query_entry->query, len - 1, "Q%u-%hu\n%s",          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
2648                         query_entry->serial, r->retry, header);                         ccs_query_entry->serial, r->retry, header);
2649          ccs_free(header);          ccs_free(header);
2650          header = NULL;          header = NULL;
2651          va_start(args, fmt);          va_start(args, fmt);
2652          vsnprintf(query_entry->query + pos, len - 1 - pos, fmt, args);          vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);
2653          query_entry->query_len = strlen(query_entry->query) + 1;          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
2654          va_end(args);          va_end(args);
2655          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2656          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2657          list_add_tail(&query_entry->list, &query_list);          list_add_tail(&ccs_query_entry->list, &ccs_query_list);
2658          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2659          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2660          ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);          ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);
2661          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
2662          for (query_entry->timer = 0; atomic_read(&queryd_watcher)          for (ccs_query_entry->timer = 0;
2663                       && query_entry->timer < 100; query_entry->timer++) {               atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;
2664                  wake_up(&query_wait);               ccs_query_entry->timer++) {
2665                    wake_up(&ccs_query_wait);
2666                  set_current_state(TASK_INTERRUPTIBLE);                  set_current_state(TASK_INTERRUPTIBLE);
2667                  schedule_timeout(HZ / 10);                  schedule_timeout(HZ / 10);
2668                  if (query_entry->answer)                  if (ccs_query_entry->answer)
2669                          break;                          break;
2670          }          }
2671          ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);          ccs_update_counter(CCS_UPDATES_COUNTER_QUERY);
2672          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2673          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2674          list_del(&query_entry->list);          list_del(&ccs_query_entry->list);
2675          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2676          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2677          switch (query_entry->answer) {          switch (ccs_query_entry->answer) {
2678          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
2679                  error = 1;                  error = 1;
2680                    r->retry++;
2681                  break;                  break;
2682          case 1:          case 1:
2683                  /* Granted by administrator. */                  /* Granted by administrator. */
# Line 2656  int ccs_check_supervisor(struct ccs_requ Line 2691  int ccs_check_supervisor(struct ccs_requ
2691                  break;                  break;
2692          }          }
2693   out:   out:
2694          if (query_entry)          if (ccs_query_entry)
2695                  ccs_free(query_entry->query);                  ccs_free(ccs_query_entry->query);
2696          ccs_free(query_entry);          ccs_free(ccs_query_entry);
2697          ccs_free(header);          ccs_free(header);
2698          return error;          return error;
2699  }  }
2700    
2701  /**  /**
2702   * poll_query - poll() for /proc/ccs/query.   * ccs_poll_query - poll() for /proc/ccs/query.
2703   *   *
2704   * @file: Pointer to "struct file".   * @file: Pointer to "struct file".
2705   * @wait: Pointer to "poll_table".   * @wait: Pointer to "poll_table".
# Line 2673  int ccs_check_supervisor(struct ccs_requ Line 2708  int ccs_check_supervisor(struct ccs_requ
2708   *   *
2709   * Waits for access requests which violated policy in enforcing mode.   * Waits for access requests which violated policy in enforcing mode.
2710   */   */
2711  static int poll_query(struct file *file, poll_table *wait)  static int ccs_poll_query(struct file *file, poll_table *wait)
2712  {  {
2713          struct list_head *tmp;          struct list_head *tmp;
2714          bool found = false;          bool found = false;
2715          u8 i;          u8 i;
2716          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2717                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
2718                  spin_lock(&query_list_lock);                  spin_lock(&ccs_query_list_lock);
2719                  list_for_each(tmp, &query_list) {                  list_for_each(tmp, &ccs_query_list) {
2720                          struct query_entry *ptr                          struct ccs_query_entry *ptr
2721                                  = list_entry(tmp, struct query_entry, list);                                  = list_entry(tmp, struct ccs_query_entry, list);
2722                          if (ptr->answer)                          if (ptr->answer)
2723                                  continue;                                  continue;
2724                          found = true;                          found = true;
2725                          break;                          break;
2726                  }                  }
2727                  spin_unlock(&query_list_lock);                  spin_unlock(&ccs_query_list_lock);
2728                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
2729                  if (found)                  if (found)
2730                          return POLLIN | POLLRDNORM;                          return POLLIN | POLLRDNORM;
2731                  if (i)                  if (i)
2732                          break;                          break;
2733                  poll_wait(file, &query_wait, wait);                  poll_wait(file, &ccs_query_wait, wait);
2734          }          }
2735          return 0;          return 0;
2736  }  }
2737    
2738  /**  /**
2739   * read_query - Read access requests which violated policy in enforcing mode.   * ccs_read_query - Read access requests which violated policy in enforcing mode.
2740   *   *
2741   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2742   *   *
2743   * Returns 0.   * Returns 0.
2744   */   */
2745  static int read_query(struct ccs_io_buffer *head)  static int ccs_read_query(struct ccs_io_buffer *head)
2746  {  {
2747          struct list_head *tmp;          struct list_head *tmp;
2748          int pos = 0;          int pos = 0;
# Line 2721  static int read_query(struct ccs_io_buff Line 2756  static int read_query(struct ccs_io_buff
2756                  head->readbuf_size = 0;                  head->readbuf_size = 0;
2757          }          }
2758          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2759          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2760          list_for_each(tmp, &query_list) {          list_for_each(tmp, &ccs_query_list) {
2761                  struct query_entry *ptr                  struct ccs_query_entry *ptr
2762                          = list_entry(tmp, struct query_entry, list);                          = list_entry(tmp, struct ccs_query_entry, list);
2763                  if (ptr->answer)                  if (ptr->answer)
2764                          continue;                          continue;
2765                  if (pos++ != head->read_step)                  if (pos++ != head->read_step)
# Line 2732  static int read_query(struct ccs_io_buff Line 2767  static int read_query(struct ccs_io_buff
2767                  len = ptr->query_len;                  len = ptr->query_len;
2768                  break;                  break;
2769          }          }
2770          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2771          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2772          if (!len) {          if (!len) {
2773                  head->read_step = 0;                  head->read_step = 0;
2774                  return 0;                  return 0;
2775          }          }
2776          buf = ccs_alloc(len);          buf = ccs_alloc(len, false);
2777          if (!buf)          if (!buf)
2778                  return 0;                  return 0;
2779          pos = 0;          pos = 0;
2780          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2781          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2782          list_for_each(tmp, &query_list) {          list_for_each(tmp, &ccs_query_list) {
2783                  struct query_entry *ptr                  struct ccs_query_entry *ptr
2784                          = list_entry(tmp, struct query_entry, list);                          = list_entry(tmp, struct ccs_query_entry, list);
2785                  if (ptr->answer)                  if (ptr->answer)
2786                          continue;                          continue;
2787                  if (pos++ != head->read_step)                  if (pos++ != head->read_step)
2788                          continue;                          continue;
2789                  /*                  /*
2790                   * Some query can be skipped because query_list                   * Some query can be skipped because ccs_query_list
2791                   * can change, but I don't care.                   * can change, but I don't care.
2792                   */                   */
2793                  if (len == ptr->query_len)                  if (len == ptr->query_len)
2794                          memmove(buf, ptr->query, len);                          memmove(buf, ptr->query, len);
2795                  break;                  break;
2796          }          }
2797          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2798          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2799          if (buf[0]) {          if (buf[0]) {
2800                  head->read_avail = len;                  head->read_avail = len;
# Line 2773  static int read_query(struct ccs_io_buff Line 2808  static int read_query(struct ccs_io_buff
2808  }  }
2809    
2810  /**  /**
2811   * write_answer - Write the supervisor's decision.   * ccs_write_answer - Write the supervisor's decision.
2812   *   *
2813   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2814   *   *
2815   * Returns 0 on success, -EINVAL otherwise.   * Returns 0 on success, -EINVAL otherwise.
2816   */   */
2817  static int write_answer(struct ccs_io_buffer *head)  static int ccs_write_answer(struct ccs_io_buffer *head)
2818  {  {
2819          char *data = head->write_buf;          char *data = head->write_buf;
2820          struct list_head *tmp;          struct list_head *tmp;
2821          unsigned int serial;          unsigned int serial;
2822          unsigned int answer;          unsigned int answer;
2823          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2824          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2825          list_for_each(tmp, &query_list) {          list_for_each(tmp, &ccs_query_list) {
2826                  struct query_entry *ptr                  struct ccs_query_entry *ptr
2827                          = list_entry(tmp, struct query_entry, list);                          = list_entry(tmp, struct ccs_query_entry, list);
2828                  ptr->timer = 0;                  ptr->timer = 0;
2829          }          }
2830          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2831          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2832          if (sscanf(data, "A%u=%u", &serial, &answer) != 2)          if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2833                  return -EINVAL;                  return -EINVAL;
2834          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2835          spin_lock(&query_list_lock);          spin_lock(&ccs_query_list_lock);
2836          list_for_each(tmp, &query_list) {          list_for_each(tmp, &ccs_query_list) {
2837                  struct query_entry *ptr                  struct ccs_query_entry *ptr
2838                          = list_entry(tmp, struct query_entry, list);                          = list_entry(tmp, struct ccs_query_entry, list);
2839                  if (ptr->serial != serial)                  if (ptr->serial != serial)
2840                          continue;                          continue;
2841                  if (!ptr->answer)                  if (!ptr->answer)
2842                          ptr->answer = answer;                          ptr->answer = answer;
2843                  break;                  break;
2844          }          }
2845          spin_unlock(&query_list_lock);          spin_unlock(&ccs_query_list_lock);
2846          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2847          return 0;          return 0;
2848  }  }
2849    
2850  /* Policy updates counter. */  /* Policy updates counter. */
2851  static unsigned int updates_counter[MAX_CCS_UPDATES_COUNTER];  static unsigned int ccs_updates_counter[MAX_CCS_UPDATES_COUNTER];
2852    
2853  /* Policy updates counter lock. */  /* Policy updates counter lock. */
2854  static DEFINE_SPINLOCK(updates_counter_lock);  static DEFINE_SPINLOCK(ccs_updates_counter_lock);
2855    
2856  /**  /**
2857   * ccs_update_counter - Increment policy change counter.   * ccs_update_counter - Increment policy change counter.
# Line 2828  static DEFINE_SPINLOCK(updates_counter_l Line 2863  static DEFINE_SPINLOCK(updates_counter_l
2863  void ccs_update_counter(const unsigned char index)  void ccs_update_counter(const unsigned char index)
2864  {  {
2865          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
2866          spin_lock(&updates_counter_lock);          spin_lock(&ccs_updates_counter_lock);
2867          if (index < MAX_CCS_UPDATES_COUNTER)          if (index < MAX_CCS_UPDATES_COUNTER)
2868                  updates_counter[index]++;                  ccs_updates_counter[index]++;
2869          spin_unlock(&updates_counter_lock);          spin_unlock(&ccs_updates_counter_lock);
2870          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
2871  }  }
2872    
2873  /**  /**
2874   * read_updates_counter - Check for policy change counter.   * ccs_read_updates_counter - Check for policy change counter.
2875   *   *
2876   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2877   *   *
2878   * Returns how many times policy has changed since the previous check.   * Returns how many times policy has changed since the previous check.
2879   */   */
2880  static int read_updates_counter(struct ccs_io_buffer *head)  static int ccs_read_updates_counter(struct ccs_io_buffer *head)
2881  {  {
2882          if (!head->read_eof) {          if (!head->read_eof) {
2883                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];
2884                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
2885                  spin_lock(&updates_counter_lock);                  spin_lock(&ccs_updates_counter_lock);
2886                  memmove(counter, updates_counter, sizeof(updates_counter));                  memmove(counter, ccs_updates_counter,
2887                  memset(updates_counter, 0, sizeof(updates_counter));                          sizeof(ccs_updates_counter));
2888                  spin_unlock(&updates_counter_lock);                  memset(ccs_updates_counter, 0, sizeof(ccs_updates_counter));
2889                    spin_unlock(&ccs_updates_counter_lock);
2890                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
2891                  ccs_io_printf(head,                  ccs_io_printf(head,
2892                                "/proc/ccs/system_policy:    %10u\n"                                "/proc/ccs/system_policy:    %10u\n"
# Line 2875  static int read_updates_counter(struct c Line 2911  static int read_updates_counter(struct c
2911  }  }
2912    
2913  /**  /**
2914   * read_version: Get version.   * ccs_read_version: Get version.
2915   *   *
2916   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2917   *   *
2918   * Returns version information.   * Returns version information.
2919   */   */
2920  static int read_version(struct ccs_io_buffer *head)  static int ccs_read_version(struct ccs_io_buffer *head)
2921  {  {
2922          if (!head->read_eof) {          if (!head->read_eof) {
2923                  ccs_io_printf(head, "1.6.5-pre");                  ccs_io_printf(head, "1.6.7-pre");
2924                  head->read_eof = true;                  head->read_eof = true;
2925          }          }
2926          return 0;          return 0;
2927  }  }
2928    
2929  /**  /**
2930   * read_self_domain - Get the current process's domainname.   * ccs_read_self_domain - Get the current process's domainname.
2931   *   *
2932   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
2933   *   *
2934   * Returns the current process's domainname.   * Returns the current process's domainname.
2935   */   */
2936  static int read_self_domain(struct ccs_io_buffer *head)  static int ccs_read_self_domain(struct ccs_io_buffer *head)
2937  {  {
2938          if (!head->read_eof) {          if (!head->read_eof) {
2939                  /*                  /*
# Line 2922  static int read_self_domain(struct ccs_i Line 2958  static int read_self_domain(struct ccs_i
2958   */   */
2959  int ccs_open_control(const u8 type, struct file *file)  int ccs_open_control(const u8 type, struct file *file)
2960  {  {
2961          struct ccs_io_buffer *head = ccs_alloc(sizeof(*head));          struct ccs_io_buffer *head = ccs_alloc(sizeof(*head), false);
2962          if (!head)          if (!head)
2963                  return -ENOMEM;                  return -ENOMEM;
2964          mutex_init(&head->io_sem);          mutex_init(&head->io_sem);
2965          switch (type) {          switch (type) {
2966  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
2967          case CCS_SYSTEMPOLICY: /* /proc/ccs/system_policy */          case CCS_SYSTEMPOLICY: /* /proc/ccs/system_policy */
2968                  head->write = write_system_policy;                  head->write = ccs_write_system_policy;
2969                  head->read = read_system_policy;                  head->read = ccs_read_system_policy;
2970                  break;                  break;
2971  #endif  #endif
2972  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
2973          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
2974                  head->write = write_domain_policy;                  head->write = ccs_write_domain_policy;
2975                  head->read = read_domain_policy;                  head->read = ccs_read_domain_policy;
2976                  break;                  break;
2977          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
2978                  head->write = write_exception_policy;                  head->write = ccs_write_exception_policy;
2979                  head->read = read_exception_policy;                  head->read = ccs_read_exception_policy;
2980                  break;                  break;
2981          case CCS_GRANTLOG: /* /proc/ccs/grant_log */          case CCS_GRANTLOG: /* /proc/ccs/grant_log */
2982                  head->poll = ccs_poll_grant_log;                  head->poll = ccs_poll_grant_log;
# Line 2952  int ccs_open_control(const u8 type, stru Line 2988  int ccs_open_control(const u8 type, stru
2988                  break;                  break;
2989  #endif  #endif
2990          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
2991                  head->read = read_self_domain;                  head->read = ccs_read_self_domain;
2992                  break;                  break;
2993          case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */          case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */
2994                  head->write = write_domain_profile;                  head->write = ccs_write_domain_profile;
2995                  head->read = read_domain_profile;                  head->read = ccs_read_domain_profile;
2996                  break;                  break;
2997            case CCS_EXECUTE_HANDLER: /* /proc/ccs/.execute_handler */
2998                    /* Allow execute_handler to read process's status. */
2999                    if (!(current->tomoyo_flags & TOMOYO_TASK_IS_EXECUTE_HANDLER)) {
3000                            ccs_free(head);
3001                            return -EPERM;
3002                    }
3003                    /* fall through */
3004          case CCS_PROCESS_STATUS: /* /proc/ccs/.process_status */          case CCS_PROCESS_STATUS: /* /proc/ccs/.process_status */
3005                  head->write = write_pid;                  head->write = ccs_write_pid;
3006                  head->read = read_pid;                  head->read = ccs_read_pid;
3007                  break;                  break;
3008          case CCS_VERSION: /* /proc/ccs/version */          case CCS_VERSION: /* /proc/ccs/version */
3009                  head->read = read_version;                  head->read = ccs_read_version;
3010                  head->readbuf_size = 128;                  head->readbuf_size = 128;
3011                  break;                  break;
3012          case CCS_MEMINFO: /* /proc/ccs/meminfo */          case CCS_MEMINFO: /* /proc/ccs/meminfo */
# Line 2972  int ccs_open_control(const u8 type, stru Line 3015  int ccs_open_control(const u8 type, stru
3015                  head->readbuf_size = 512;                  head->readbuf_size = 512;
3016                  break;                  break;
3017          case CCS_PROFILE: /* /proc/ccs/profile */          case CCS_PROFILE: /* /proc/ccs/profile */
3018                  head->write = write_profile;                  head->write = ccs_write_profile;
3019                  head->read = read_profile;                  head->read = ccs_read_profile;
3020                  break;                  break;
3021          case CCS_QUERY: /* /proc/ccs/query */          case CCS_QUERY: /* /proc/ccs/query */
3022                  head->poll = poll_query;                  head->poll = ccs_poll_query;
3023                  head->write = write_answer;                  head->write = ccs_write_answer;
3024                  head->read = read_query;                  head->read = ccs_read_query;
3025                  break;                  break;
3026          case CCS_MANAGER: /* /proc/ccs/manager */          case CCS_MANAGER: /* /proc/ccs/manager */
3027                  head->write = write_manager_policy;                  head->write = ccs_write_manager_policy;
3028                  head->read = read_manager_policy;                  head->read = ccs_read_manager_policy;
3029                  break;                  break;
3030          case CCS_UPDATESCOUNTER: /* /proc/ccs/.updates_counter */          case CCS_UPDATESCOUNTER: /* /proc/ccs/.ccs_updates_counter */
3031                  head->read = read_updates_counter;                  head->read = ccs_read_updates_counter;
3032                  break;                  break;
3033          }          }
3034          if (!(file->f_mode & FMODE_READ)) {          if (!(file->f_mode & FMODE_READ)) {
# Line 3003  int ccs_open_control(const u8 type, stru Line 3046  int ccs_open_control(const u8 type, stru
3046                   */                   */
3047                  if (!head->readbuf_size)                  if (!head->readbuf_size)
3048                          head->readbuf_size = 4096 * 2;                          head->readbuf_size = 4096 * 2;
3049                  head->read_buf = ccs_alloc(head->readbuf_size);                  head->read_buf = ccs_alloc(head->readbuf_size, false);
3050                  if (!head->read_buf) {                  if (!head->read_buf) {
3051                          ccs_free(head);                          ccs_free(head);
3052                          return -ENOMEM;                          return -ENOMEM;
# Line 3017  int ccs_open_control(const u8 type, stru Line 3060  int ccs_open_control(const u8 type, stru
3060                  head->write = NULL;                  head->write = NULL;
3061          } else if (head->write) {          } else if (head->write) {
3062                  head->writebuf_size = 4096 * 2;                  head->writebuf_size = 4096 * 2;
3063                  head->write_buf = ccs_alloc(head->writebuf_size);                  head->write_buf = ccs_alloc(head->writebuf_size, false);
3064                  if (!head->write_buf) {                  if (!head->write_buf) {
3065                          ccs_free(head->read_buf);                          ccs_free(head->read_buf);
3066                          ccs_free(head);                          ccs_free(head);
# Line 3033  int ccs_open_control(const u8 type, stru Line 3076  int ccs_open_control(const u8 type, stru
3076          if (type == CCS_SELFDOMAIN)          if (type == CCS_SELFDOMAIN)
3077                  ccs_read_control(file, NULL, 0);                  ccs_read_control(file, NULL, 0);
3078          /*          /*
3079           * If the file is /proc/ccs/query , increment the monitor count.           * If the file is /proc/ccs/query , increment the observer counter.
3080           * The monitor count is used by ccs_check_supervisor() to see if           * The obserber counter is used by ccs_check_supervisor() to see if
3081           * there is some process monitoring /proc/ccs/query.           * there is some process monitoring /proc/ccs/query.
3082           */           */
3083          else if (head->write == write_answer || head->read == read_query)          else if (head->write == ccs_write_answer ||
3084                  atomic_inc(&queryd_watcher);                   head->read == ccs_read_query)
3085                    atomic_inc(&ccs_query_observers);
3086          return 0;          return 0;
3087  }  }
3088    
# Line 3126  int ccs_write_control(struct file *file, Line 3170  int ccs_write_control(struct file *file,
3170          if (!access_ok(VERIFY_READ, buffer, buffer_len))          if (!access_ok(VERIFY_READ, buffer, buffer_len))
3171                  return -EFAULT;                  return -EFAULT;
3172          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
3173          if (head->write != write_pid &&          if (head->write != ccs_write_pid &&
3174  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
3175              head->write != write_domain_policy &&              head->write != ccs_write_domain_policy &&
3176  #endif  #endif
3177              !is_policy_manager())              !ccs_is_policy_manager())
3178                  return -EPERM;                  return -EPERM;
3179          if (mutex_lock_interruptible(&head->io_sem))          if (mutex_lock_interruptible(&head->io_sem))
3180                  return -EINTR;                  return -EINTR;
# Line 3151  int ccs_write_control(struct file *file, Line 3195  int ccs_write_control(struct file *file,
3195                          continue;                          continue;
3196                  cp0[head->write_avail - 1] = '\0';                  cp0[head->write_avail - 1] = '\0';
3197                  head->write_avail = 0;                  head->write_avail = 0;
3198                  normalize_line(cp0);                  ccs_normalize_line(cp0);
3199                  head->write(head);                  head->write(head);
3200          }          }
3201          mutex_unlock(&head->io_sem);          mutex_unlock(&head->io_sem);
# Line 3169  int ccs_close_control(struct file *file) Line 3213  int ccs_close_control(struct file *file)
3213  {  {
3214          struct ccs_io_buffer *head = file->private_data;          struct ccs_io_buffer *head = file->private_data;
3215          /*          /*
3216           * If the file is /proc/ccs/query , decrement the monitor count.           * If the file is /proc/ccs/query , decrement the observer counter.
3217           */           */
3218          if (head->write == write_answer || head->read == read_query)          if (head->write == ccs_write_answer || head->read == ccs_read_query)
3219                  atomic_dec(&queryd_watcher);                  atomic_dec(&ccs_query_observers);
3220          /* Release memory used for policy I/O. */          /* Release memory used for policy I/O. */
3221          ccs_free(head->read_buf);          ccs_free(head->read_buf);
3222          head->read_buf = NULL;          head->read_buf = NULL;
# Line 3193  int ccs_close_control(struct file *file) Line 3237  int ccs_close_control(struct file *file)
3237   * Returns pointer to the ACL entry on success, NULL otherwise.   * Returns pointer to the ACL entry on success, NULL otherwise.
3238   */   */
3239  void *ccs_alloc_acl_element(const u8 acl_type,  void *ccs_alloc_acl_element(const u8 acl_type,
3240                              const struct condition_list *condition)                              const struct ccs_condition_list *condition)
3241  {  {
3242          int len;          int len;
3243          struct acl_info *ptr;          struct ccs_acl_info *ptr;
3244          switch (acl_type) {          switch (acl_type) {
3245          case TYPE_SINGLE_PATH_ACL:          case TYPE_SINGLE_PATH_ACL:
3246                  len = sizeof(struct single_path_acl_record);                  len = sizeof(struct ccs_single_path_acl_record);
3247                  break;                  break;
3248          case TYPE_DOUBLE_PATH_ACL:          case TYPE_DOUBLE_PATH_ACL:
3249                  len = sizeof(struct double_path_acl_record);                  len = sizeof(struct ccs_double_path_acl_record);
3250                  break;                  break;
3251          case TYPE_ARGV0_ACL:          case TYPE_ARGV0_ACL:
3252                  len = sizeof(struct argv0_acl_record);                  len = sizeof(struct ccs_argv0_acl_record);
3253                  break;                  break;
3254          case TYPE_ENV_ACL:          case TYPE_ENV_ACL:
3255                  len = sizeof(struct env_acl_record);                  len = sizeof(struct ccs_env_acl_record);
3256                  break;                  break;
3257          case TYPE_CAPABILITY_ACL:          case TYPE_CAPABILITY_ACL:
3258                  len = sizeof(struct capability_acl_record);                  len = sizeof(struct ccs_capability_acl_record);
3259                  break;                  break;
3260          case TYPE_IP_NETWORK_ACL:          case TYPE_IP_NETWORK_ACL:
3261                  len = sizeof(struct ip_network_acl_record);                  len = sizeof(struct ccs_ip_network_acl_record);
3262                  break;                  break;
3263          case TYPE_SIGNAL_ACL:          case TYPE_SIGNAL_ACL:
3264                  len = sizeof(struct signal_acl_record);                  len = sizeof(struct ccs_signal_acl_record);
3265                  break;                  break;
3266          case TYPE_EXECUTE_HANDLER:          case TYPE_EXECUTE_HANDLER:
3267          case TYPE_DENIED_EXECUTE_HANDLER:          case TYPE_DENIED_EXECUTE_HANDLER:
3268                  len = sizeof(struct execute_handler_record);                  len = sizeof(struct ccs_execute_handler_record);
3269                  break;                  break;
3270          default:          default:
3271                  return NULL;                  return NULL;
3272          }          }
3273          /*          /*
3274           * If the ACL doesn't have condition part, reduce memory usage           * If the ACL doesn't have condition part, reduce memory usage
3275           * by eliminating sizeof(struct condition_list *).           * by eliminating sizeof(struct ccs_condition_list *).
3276           */           */
3277          if (!condition)          if (!condition)
3278                  len -= sizeof(ptr->access_me_via_ccs_get_condition_part);                  len -= sizeof(ptr->access_me_via_ccs_get_condition_part);
# Line 3241  void *ccs_alloc_acl_element(const u8 acl Line 3285  void *ccs_alloc_acl_element(const u8 acl
3285                  return ptr;                  return ptr;
3286          }          }
3287          /*          /*
3288           * Substract sizeof(struct condition_list *) because I eliminated           * Substract sizeof(struct ccs_condition_list *) because I eliminated
3289           * sizeof(struct condition_list *) from "struct acl_info"           * sizeof(struct ccs_condition_list *) from "struct ccs_acl_info"
3290           * but I must return the start address of "struct acl_info".           * but I must return the start address of "struct ccs_acl_info".
3291           */           */
3292          ptr = (void *) (((u8 *) ptr)          ptr = (void *) (((u8 *) ptr)
3293                          - sizeof(ptr->access_me_via_ccs_get_condition_part));                          - sizeof(ptr->access_me_via_ccs_get_condition_part));
3294          ptr->type = acl_type;          ptr->type = acl_type;
3295          return ptr;          return ptr;
3296  }  }
   
 /**  
  * ccs_get_condition_part - Get condition part of the given ACL entry.  
  *  
  * @acl: Pointer to "struct acl_info". Pointer to an ACL entry.  
  *  
  * Returns pointer to the condition part if the ACL has it, NULL otherwise.  
  */  
 const struct condition_list *ccs_get_condition_part(const struct acl_info *acl)  
 {  
         return (acl->type & ACL_WITH_CONDITION) ?  
                 acl->access_me_via_ccs_get_condition_part : NULL;  
 }  

Legend:
Removed from v.1719  
changed lines
  Added in v.2201

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