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

Subversion リポジトリの参照

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

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

trunk/1.5.x/ccs-patch/fs/ccs_common.c revision 813 by kumaneko, Tue Dec 18 05:35:28 2007 UTC trunk/1.6.x/ccs-patch/fs/ccs_common.c revision 1016 by kumaneko, Tue Mar 4 05:51:18 2008 UTC
# Line 3  Line 3 
3   *   *
4   * Common functions for SAKURA and TOMOYO.   * Common functions for SAKURA and TOMOYO.
5   *   *
6   * Copyright (C) 2005-2007  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.5.3-pre   2007/12/18   * Version: 1.6.0-pre   2008/03/04
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 32  static const int lookup_flags = LOOKUP_F Line 32  static const int lookup_flags = LOOKUP_F
32  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
33  #include <linux/ccs_proc.h>  #include <linux/ccs_proc.h>
34  #include <linux/tomoyo.h>  #include <linux/tomoyo.h>
35    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
36    #define find_task_by_pid find_task_by_vpid
37    #endif
38    
39  #ifdef CONFIG_TOMOYO_MAX_ACCEPT_ENTRY  #ifdef CONFIG_TOMOYO_MAX_ACCEPT_ENTRY
40  #define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)  #define MAX_ACCEPT_ENTRY (CONFIG_TOMOYO_MAX_ACCEPT_ENTRY)
# Line 52  static const int lookup_flags = LOOKUP_F Line 55  static const int lookup_flags = LOOKUP_F
55  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
56    
57  /* /sbin/init started? */  /* /sbin/init started? */
58  int sbin_init_started = 0;  bool sbin_init_started = false;
59    
60  const char *ccs_log_level = KERN_DEBUG;  const char *ccs_log_level = KERN_DEBUG;
61    
62    static const char *mode_4[4] = { "disabled", "learning", "permissive", "enforcing" };
63    static const char *mode_2[4] = { "disabled", "enabled", "enabled", "enabled" };
64    
65  static struct {  static struct {
66          const char *keyword;          const char *keyword;
67          unsigned int current_value;          unsigned int current_value;
# Line 82  static struct { Line 88  static struct {
88          [CCS_TOMOYO_ALT_EXEC]            = { "ALT_EXEC",            0, 0 }, /* Reserved for string. */          [CCS_TOMOYO_ALT_EXEC]            = { "ALT_EXEC",            0, 0 }, /* Reserved for string. */
89  };  };
90    
91    #ifdef CONFIG_TOMOYO
92    const char *capability_control_keyword[TOMOYO_MAX_CAPABILITY_INDEX] = {
93            [TOMOYO_INET_STREAM_SOCKET_CREATE]  = "inet_tcp_create",
94            [TOMOYO_INET_STREAM_SOCKET_LISTEN]  = "inet_tcp_listen",
95            [TOMOYO_INET_STREAM_SOCKET_CONNECT] = "inet_tcp_connect",
96            [TOMOYO_USE_INET_DGRAM_SOCKET]      = "use_inet_udp",
97            [TOMOYO_USE_INET_RAW_SOCKET]        = "use_inet_ip",
98            [TOMOYO_USE_ROUTE_SOCKET]           = "use_route",
99            [TOMOYO_USE_PACKET_SOCKET]          = "use_packet",
100            [TOMOYO_SYS_MOUNT]                  = "SYS_MOUNT",
101            [TOMOYO_SYS_UMOUNT]                 = "SYS_UMOUNT",
102            [TOMOYO_SYS_REBOOT]                 = "SYS_REBOOT",
103            [TOMOYO_SYS_CHROOT]                 = "SYS_CHROOT",
104            [TOMOYO_SYS_KILL]                   = "SYS_KILL",
105            [TOMOYO_SYS_VHANGUP]                = "SYS_VHANGUP",
106            [TOMOYO_SYS_SETTIME]                = "SYS_TIME",
107            [TOMOYO_SYS_NICE]                   = "SYS_NICE",
108            [TOMOYO_SYS_SETHOSTNAME]            = "SYS_SETHOSTNAME",
109            [TOMOYO_USE_KERNEL_MODULE]          = "use_kernel_module",
110            [TOMOYO_CREATE_FIFO]                = "create_fifo",
111            [TOMOYO_CREATE_BLOCK_DEV]           = "create_block_dev",
112            [TOMOYO_CREATE_CHAR_DEV]            = "create_char_dev",
113            [TOMOYO_CREATE_UNIX_SOCKET]         = "create_unix_socket",
114            [TOMOYO_SYS_LINK]                   = "SYS_LINK",
115            [TOMOYO_SYS_SYMLINK]                = "SYS_SYMLINK",
116            [TOMOYO_SYS_RENAME]                 = "SYS_RENAME",
117            [TOMOYO_SYS_UNLINK]                 = "SYS_UNLINK",
118            [TOMOYO_SYS_CHMOD]                  = "SYS_CHMOD",
119            [TOMOYO_SYS_CHOWN]                  = "SYS_CHOWN",
120            [TOMOYO_SYS_IOCTL]                  = "SYS_IOCTL",
121            [TOMOYO_SYS_KEXEC_LOAD]             = "SYS_KEXEC_LOAD",
122            [TOMOYO_SYS_PIVOT_ROOT]             = "SYS_PIVOT_ROOT",
123            [TOMOYO_SYS_PTRACE]                 = "SYS_PTRACE",
124    };
125    #endif
126    
127  struct profile {  struct profile {
128          unsigned int value[CCS_MAX_CONTROL_INDEX];          unsigned int value[CCS_MAX_CONTROL_INDEX];
129          const struct path_info *comment;          const struct path_info *comment;
130          const struct path_info *alt_exec;          const struct path_info *alt_exec;
131    #ifdef CONFIG_TOMOYO
132            unsigned char capability_value[TOMOYO_MAX_CAPABILITY_INDEX];
133    #endif
134  };  };
135    
136  static struct profile *profile_ptr[MAX_PROFILES];  static struct profile *profile_ptr[MAX_PROFILES];
137    static bool manage_by_non_root = false;
138    
139  /*************************  UTILITY FUNCTIONS  *************************/  /*************************  UTILITY FUNCTIONS  *************************/
140    
# Line 102  static int __init TOMOYO_Quiet_Setup(cha Line 148  static int __init TOMOYO_Quiet_Setup(cha
148  __setup("TOMOYO_QUIET", TOMOYO_Quiet_Setup);  __setup("TOMOYO_QUIET", TOMOYO_Quiet_Setup);
149  #endif  #endif
150    
 /* Am I root? */  
 static int isRoot(void)  
 {  
         return !current->uid && !current->euid;  
 }  
   
151  /*  /*
152   * Format string.   * Format string.
153   * Leading and trailing whitespaces are removed.   * Leading and trailing whitespaces are removed.
# Line 116  static int isRoot(void) Line 156  static int isRoot(void)
156  static void NormalizeLine(unsigned char *buffer)  static void NormalizeLine(unsigned char *buffer)
157  {  {
158          unsigned char *sp = buffer, *dp = buffer;          unsigned char *sp = buffer, *dp = buffer;
159          int first = 1;          bool first = true;
160          while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;          while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;
161          while (*sp) {          while (*sp) {
162                  if (!first) *dp++ = ' ';                  if (!first) *dp++ = ' ';
163                  first = 0;                  first = false;
164                  while (*sp > ' ' && *sp < 127) *dp++ = *sp++;                  while (*sp > ' ' && *sp < 127) *dp++ = *sp++;
165                  while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;                  while (*sp && (*sp <= ' ' || *sp >= 127)) sp++;
166          }          }
# Line 129  static void NormalizeLine(unsigned char Line 169  static void NormalizeLine(unsigned char
169    
170  /*  /*
171   *  Check whether the given filename follows the naming rules.   *  Check whether the given filename follows the naming rules.
172   *  Returns nonzero if follows, zero otherwise.   *  Returns true if follows, false otherwise.
173   */   */
174  bool IsCorrectPath(const char *filename, const int start_type, const int pattern_type, const int end_type, const char *function)  bool IsCorrectPath(const char *filename, const s8 start_type, const s8 pattern_type, const s8 end_type, const char *function)
175  {  {
176          int contains_pattern = 0;          bool contains_pattern = false;
177          char c, d, e;          char c, d, e;
178          const char *original_filename = filename;          const char *original_filename = filename;
179          if (!filename) goto out;          if (!filename) goto out;
# Line 165  bool IsCorrectPath(const char *filename, Line 205  bool IsCorrectPath(const char *filename,
205                          case 'A':   /* "\A" */                          case 'A':   /* "\A" */
206                          case '-':   /* "\-" */                          case '-':   /* "\-" */
207                                  if (pattern_type == -1) break; /* Must not contain pattern */                                  if (pattern_type == -1) break; /* Must not contain pattern */
208                                  contains_pattern = 1;                                  contains_pattern = true;
209                                  continue;                                  continue;
210                          case '0':   /* "\ooo" */                          case '0':   /* "\ooo" */
211                          case '1':                          case '1':
# Line 187  bool IsCorrectPath(const char *filename, Line 227  bool IsCorrectPath(const char *filename,
227          if (pattern_type == 1) { /* Must contain pattern */          if (pattern_type == 1) { /* Must contain pattern */
228                  if (!contains_pattern) goto out;                  if (!contains_pattern) goto out;
229          }          }
230          return 1;          return true;
231   out:   out:
232          printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, original_filename);          printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, original_filename);
233          return 0;          return false;
234  }  }
235    
236  /*  /*
237   *  Check whether the given domainname follows the naming rules.   *  Check whether the given domainname follows the naming rules.
238   *  Returns nonzero if follows, zero otherwise.   *  Returns true if follows, false otherwise.
239   */   */
240  bool IsCorrectDomain(const unsigned char *domainname, const char *function)  bool IsCorrectDomain(const unsigned char *domainname, const char *function)
241  {  {
# Line 203  bool IsCorrectDomain(const unsigned char Line 243  bool IsCorrectDomain(const unsigned char
243          const char *org_domainname = domainname;          const char *org_domainname = domainname;
244          if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN)) goto out;          if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN)) goto out;
245          domainname += ROOT_NAME_LEN;          domainname += ROOT_NAME_LEN;
246          if (!*domainname) return 1;          if (!*domainname) return true;
247          do {          do {
248                  if (*domainname++ != ' ') goto out;                  if (*domainname++ != ' ') goto out;
249                  if (*domainname++ != '/') goto out;                  if (*domainname++ != '/') goto out;
# Line 231  bool IsCorrectDomain(const unsigned char Line 271  bool IsCorrectDomain(const unsigned char
271                          }                          }
272                  }                  }
273          } while (*domainname);          } while (*domainname);
274          return 1;          return true;
275   out:   out:
276          printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function, org_domainname);          printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function, org_domainname);
277          return 0;          return false;
278  }  }
279    
280  bool IsDomainDef(const unsigned char *buffer)  bool IsDomainDef(const unsigned char *buffer)
# Line 302  void fill_path_info(struct path_info *pt Line 342  void fill_path_info(struct path_info *pt
342          ptr->depth = PathDepth(name);          ptr->depth = PathDepth(name);
343  }  }
344    
345  static int FileMatchesToPattern2(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)  static bool FileMatchesToPattern2(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)
346  {  {
347          while (filename < filename_end && pattern < pattern_end) {          while (filename < filename_end && pattern < pattern_end) {
348                  if (*pattern != '\\') {                  if (*pattern != '\\') {
349                          if (*filename++ != *pattern++) return 0;                          if (*filename++ != *pattern++) return false;
350                  } else {                  } else {
351                          char c = *filename;                          char c = *filename;
352                          pattern++;                          pattern++;
353                          switch (*pattern) {                          switch (*pattern) {
354                          case '?':                          case '?':
355                                  if (c == '/') {                                  if (c == '/') {
356                                          return 0;                                          return false;
357                                  } else if (c == '\\') {                                  } else if (c == '\\') {
358                                          if ((c = filename[1]) == '\\') {                                          if ((c = filename[1]) == '\\') {
359                                                  filename++; /* safe because filename is \\ */                                                  filename++; /* safe because filename is \\ */
360                                          } else if (c >= '0' && c <= '3' && (c = filename[2]) >= '0' && c <= '7' && (c = filename[3]) >= '0' && c <= '7') {                                          } else if (c >= '0' && c <= '3' && (c = filename[2]) >= '0' && c <= '7' && (c = filename[3]) >= '0' && c <= '7') {
361                                                  filename += 3; /* safe because filename is \ooo */                                                  filename += 3; /* safe because filename is \ooo */
362                                          } else {                                          } else {
363                                                  return 0;                                                  return false;
364                                          }                                          }
365                                  }                                  }
366                                  break;                                  break;
367                          case '\\':                          case '\\':
368                                  if (c != '\\') return 0;                                  if (c != '\\') return false;
369                                  if (*++filename != '\\') return 0; /* safe because *filename != '\0' */                                  if (*++filename != '\\') return false; /* safe because *filename != '\0' */
370                                  break;                                  break;
371                          case '+':                          case '+':
372                                  if (c < '0' || c > '9') return 0;                                  if (c < '0' || c > '9') return false;
373                                  break;                                  break;
374                          case 'x':                          case 'x':
375                                  if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) return 0;                                  if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) return false;
376                                  break;                                  break;
377                          case 'a':                          case 'a':
378                                  if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) return 0;                                  if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) return false;
379                                  break;                                  break;
380                          case '0':                          case '0':
381                          case '1':                          case '1':
# Line 348  static int FileMatchesToPattern2(const c Line 388  static int FileMatchesToPattern2(const c
388                                          pattern += 2; /* safe because pattern is \ooo  */                                          pattern += 2; /* safe because pattern is \ooo  */
389                                          break;                                          break;
390                                  }                                  }
391                                  return 0; /* Not matched. */                                  return false; /* Not matched. */
392                          case '*':                          case '*':
393                          case '@':                          case '@':
394                                  {                                  {
395                                          int i;                                          int i;
396                                          for (i = 0; i <= filename_end - filename; i++) {                                          for (i = 0; i <= filename_end - filename; i++) {
397                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return true;
398                                                  if ((c = filename[i]) == '.' && *pattern == '@') break;                                                  if ((c = filename[i]) == '.' && *pattern == '@') break;
399                                                  if (c == '\\') {                                                  if (c == '\\') {
400                                                          if ((c = filename[i + 1]) == '\\') {                                                          if ((c = filename[i + 1]) == '\\') {
# Line 366  static int FileMatchesToPattern2(const c Line 406  static int FileMatchesToPattern2(const c
406                                                          }                                                          }
407                                                  }                                                  }
408                                          }                                          }
409                                          return 0; /* Not matched. */                                          return false; /* Not matched. */
410                                  }                                  }
411                          default:                          default:
412                                  {                                  {
# Line 379  static int FileMatchesToPattern2(const c Line 419  static int FileMatchesToPattern2(const c
419                                                  while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;                                                  while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;
420                                          }                                          }
421                                          for (i = 1; i <= j; i++) {                                          for (i = 1; i <= j; i++) {
422                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return true;
423                                          }                                          }
424                                  }                                  }
425                                  return 0; /* Not matched or bad pattern. */                                  return false; /* Not matched or bad pattern. */
426                          }                          }
427                          filename++; /* safe because *filename != '\0' */                          filename++; /* safe because *filename != '\0' */
428                          pattern++; /* safe because *pattern != '\0' */                          pattern++; /* safe because *pattern != '\0' */
# Line 392  static int FileMatchesToPattern2(const c Line 432  static int FileMatchesToPattern2(const c
432          return (filename == filename_end && pattern == pattern_end);          return (filename == filename_end && pattern == pattern_end);
433  }  }
434    
435  static int FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)  static bool FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)
436  {  {
437          const char *pattern_start = pattern;          const char *pattern_start = pattern;
438          int first = 1;          bool first = true;
439          int result;          bool result;
440          while (pattern < pattern_end - 1) {          while (pattern < pattern_end - 1) {
441                  if (*pattern++ != '\\' || *pattern++ != '-') continue;                  if (*pattern++ != '\\' || *pattern++ != '-') continue;
442                  result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern - 2);                  result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern - 2);
443                  if (first) result = !result;                  if (first) result = !result;
444                  if (result) return 0;                  if (result) return false;
445                  first = 0;                  first = false;
446                  pattern_start = pattern;                  pattern_start = pattern;
447          }          }
448          result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern_end);          result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern_end);
# Line 411  static int FileMatchesToPattern(const ch Line 451  static int FileMatchesToPattern(const ch
451    
452  /*  /*
453   *  Check whether the given pathname matches to the given pattern.   *  Check whether the given pathname matches to the given pattern.
454   *  Returns nonzero if matches, zero otherwise.   *  Returns true if matches, false otherwise.
455   *   *
456   *  The following patterns are available.   *  The following patterns are available.
457   *    \\     \ itself.   *    \\     \ itself.
# Line 428  static int FileMatchesToPattern(const ch Line 468  static int FileMatchesToPattern(const ch
468   *    \-     Subtraction operator.   *    \-     Subtraction operator.
469   */   */
470    
471  int PathMatchesToPattern(const struct path_info *pathname0, const struct path_info *pattern0)  bool PathMatchesToPattern(const struct path_info *pathname0, const struct path_info *pattern0)
472  {  {
473          /* if (!pathname || !pattern) return 0; */          /* if (!pathname || !pattern) return false; */
474          const char *pathname = pathname0->name, *pattern = pattern0->name;          const char *pathname = pathname0->name, *pattern = pattern0->name;
475          const int len = pattern0->const_len;          const int len = pattern0->const_len;
476          if (!pattern0->is_patterned) return !pathcmp(pathname0, pattern0);          if (!pattern0->is_patterned) return !pathcmp(pathname0, pattern0);
477          if (pathname0->depth != pattern0->depth) return 0;          if (pathname0->depth != pattern0->depth) return false;
478          if (strncmp(pathname, pattern, len)) return 0;          if (strncmp(pathname, pattern, len)) return false;
479          pathname += len; pattern += len;          pathname += len; pattern += len;
480          while (*pathname && *pattern) {          while (*pathname && *pattern) {
481                  const char *pathname_delimiter = strchr(pathname, '/'), *pattern_delimiter = strchr(pattern, '/');                  const char *pathname_delimiter = strchr(pathname, '/'), *pattern_delimiter = strchr(pattern, '/');
482                  if (!pathname_delimiter) pathname_delimiter = strchr(pathname, '\0');                  if (!pathname_delimiter) pathname_delimiter = strchr(pathname, '\0');
483                  if (!pattern_delimiter) pattern_delimiter = strchr(pattern, '\0');                  if (!pattern_delimiter) pattern_delimiter = strchr(pattern, '\0');
484                  if (!FileMatchesToPattern(pathname, pathname_delimiter, pattern, pattern_delimiter)) return 0;                  if (!FileMatchesToPattern(pathname, pathname_delimiter, pattern, pattern_delimiter)) return false;
485                  pathname = *pathname_delimiter ? pathname_delimiter + 1 : pathname_delimiter;                  pathname = *pathname_delimiter ? pathname_delimiter + 1 : pathname_delimiter;
486                  pattern = *pattern_delimiter ? pattern_delimiter + 1 : pattern_delimiter;                  pattern = *pattern_delimiter ? pattern_delimiter + 1 : pattern_delimiter;
487          }          }
# Line 503  const char *GetAltExec(void) Line 543  const char *GetAltExec(void)
543  /*************************  DOMAIN POLICY HANDLER  *************************/  /*************************  DOMAIN POLICY HANDLER  *************************/
544    
545  /* Check whether the given access control is enabled. */  /* Check whether the given access control is enabled. */
546  unsigned int CheckCCSFlags(const unsigned int index)  unsigned int CheckCCSFlags_NoSleepCheck(const u8 index)
547  {  {
548          const u8 profile = current->domain_info->profile;          const u8 profile = current->domain_info->profile;
549          return sbin_init_started && index < CCS_MAX_CONTROL_INDEX          return sbin_init_started && index < CCS_MAX_CONTROL_INDEX
# Line 513  unsigned int CheckCCSFlags(const unsigne Line 553  unsigned int CheckCCSFlags(const unsigne
553                  && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;                  && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;
554  }  }
555    
556  bool TomoyoVerboseMode(void)  static bool sleep_check(void)
557  {  {
558          return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0;  #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
559            if (unlikely(in_interrupt()))
560    #else
561            if (unlikely(in_atomic()))
562    #endif
563            {
564                    static u8 count = 20;
565                    if (count) {
566                            count--;
567                            printk(KERN_ERR "BUG: sleeping function called from invalid context.\n");
568                            dump_stack();
569                    }
570                    return false;
571            }
572            return true;
573  }  }
574    
575  /* Check whether the given access control is enforce mode. */  unsigned int CheckCCSFlags(const u8 index)
576  bool CheckCCSEnforce(const unsigned int index)  {
577            return sleep_check() ? CheckCCSFlags_NoSleepCheck(index) : 0;
578    }
579    
580    #ifdef CONFIG_TOMOYO
581    /* Check whether the given capability control is enabled. */
582    u8 CheckCapabilityFlags(const u8 index)
583  {  {
584          return CheckCCSFlags(index) == 3;          const u8 profile = current->domain_info->profile;
585            return sbin_init_started && index < TOMOYO_MAX_CAPABILITY_INDEX
586    #if MAX_PROFILES != 256
587                    && profile < MAX_PROFILES
588    #endif
589                    && sleep_check()
590                    && profile_ptr[profile] ? profile_ptr[profile]->capability_value[index] : 0;
591    }
592    
593    const char *cap_operation2keyword(const u8 operation)
594    {
595            return operation < TOMOYO_MAX_CAPABILITY_INDEX ? capability_control_keyword[operation] : NULL;
596    }
597    
598    #endif
599    
600    bool TomoyoVerboseMode(void)
601    {
602            return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0;
603  }  }
604    
605  bool CheckDomainQuota(struct domain_info * const domain)  bool CheckDomainQuota(struct domain_info * const domain)
606  {  {
607          unsigned int count = 0;          unsigned int count = 0;
608          struct acl_info *ptr;          struct acl_info *ptr;
609          if (!domain) return 1;          if (!domain) return true;
610          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
611                  if (!ptr->is_deleted) count++;                  if (!(ptr->type & ACL_DELETED)) count++;
612          }          }
613          if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 1;          if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return true;
614          if (!domain->quota_warned) {          if (!domain->quota_warned) {
615                  domain->quota_warned = 1;                  domain->quota_warned = true;
616                  printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);                  printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);
617          }          }
618          return 0;          return false;
 }  
   
 /* Check whether the given access control is learning mode. */  
 bool CheckCCSAccept(const unsigned int index, struct domain_info * const domain)  
 {  
         if (CheckCCSFlags(index) != 1) return 0;  
         return CheckDomainQuota(domain);  
619  }  }
620    
621  static struct profile *FindOrAssignNewProfile(const unsigned int profile)  static struct profile *FindOrAssignNewProfile(const unsigned int profile)
# Line 556  static struct profile *FindOrAssignNewPr Line 627  static struct profile *FindOrAssignNewPr
627                  if ((ptr = alloc_element(sizeof(*ptr))) != NULL) {                  if ((ptr = alloc_element(sizeof(*ptr))) != NULL) {
628                          int i;                          int i;
629                          for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) ptr->value[i] = ccs_control_array[i].current_value;                          for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) ptr->value[i] = ccs_control_array[i].current_value;
630                            /* Needn't to initialize "ptr->capability_value" because they are always 0. */
631                          mb(); /* Avoid out-of-order execution. */                          mb(); /* Avoid out-of-order execution. */
632                          profile_ptr[profile] = ptr;                          profile_ptr[profile] = ptr;
633                  }                  }
# Line 564  static struct profile *FindOrAssignNewPr Line 636  static struct profile *FindOrAssignNewPr
636          return ptr;          return ptr;
637  }  }
638    
 /* #define ALT_EXEC */  
   
639  static int SetProfile(struct io_buffer *head)  static int SetProfile(struct io_buffer *head)
640  {  {
641          char *data = head->write_buf;          char *data = head->write_buf;
642          unsigned int i, value;          unsigned int i, value;
643          char *cp;          char *cp;
644          struct profile *profile;          struct profile *profile;
         if (!isRoot()) return -EPERM;  
645          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
646          if (data != cp) {          if (data != cp) {
647                  if (*cp != '-') return -EINVAL;                  if (*cp != '-') return -EINVAL;
# Line 588  static int SetProfile(struct io_buffer * Line 657  static int SetProfile(struct io_buffer *
657                  profile->comment = SaveName(cp + 1);                  profile->comment = SaveName(cp + 1);
658                  return 0;                  return 0;
659          }          }
 #ifdef ALT_EXEC  
660  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
661          if (strcmp(data, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword) == 0) {          if (strcmp(data, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword) == 0) {
662                  cp++;                  cp++;
# Line 597  static int SetProfile(struct io_buffer * Line 665  static int SetProfile(struct io_buffer *
665                  return 0;                  return 0;
666          }          }
667  #endif  #endif
 #endif  
         if (sscanf(cp + 1, "%u", &value) != 1) return -EINVAL;  
668  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
669          if (strncmp(data, KEYWORD_MAC_FOR_CAPABILITY, KEYWORD_MAC_FOR_CAPABILITY_LEN) == 0) {          if (strncmp(data, KEYWORD_MAC_FOR_CAPABILITY, KEYWORD_MAC_FOR_CAPABILITY_LEN) == 0) {
670                  return SetCapabilityStatus(data + KEYWORD_MAC_FOR_CAPABILITY_LEN, value, i);                  if (sscanf(cp + 1, "%u", &value) != 1) {
671                            for (i = 0; i < 4; i++) {
672                                    if (strcmp(cp + 1, mode_4[i])) continue;
673                                    value = i;
674                                    break;
675                            }
676                            if (i == 4) return -EINVAL;
677                    }
678                    if (value > 3) value = 3;
679                    data += KEYWORD_MAC_FOR_CAPABILITY_LEN;
680                    for (i = 0; i < TOMOYO_MAX_CAPABILITY_INDEX; i++) {
681                            if (strcmp(data, capability_control_keyword[i])) continue;
682                            profile->capability_value[i] = value;
683                            return 0;
684                    }
685                    return -EINVAL;
686          }          }
687  #endif  #endif
688          for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {          for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {
689                  if (strcmp(data, ccs_control_array[i].keyword)) continue;                  if (strcmp(data, ccs_control_array[i].keyword)) continue;
690                  if (value > ccs_control_array[i].max_value) value = ccs_control_array[i].max_value;                  if (sscanf(cp + 1, "%u", &value) != 1) {
691                            int j;
692                            const char **modes;
693                            switch (i) {
694                            case CCS_SAKURA_RESTRICT_AUTOBIND:
695                            case CCS_TOMOYO_VERBOSE:
696                            case CCS_ALLOW_ENFORCE_GRACE:
697                                    modes = mode_2;
698                                    break;
699                            default:
700                                    modes = mode_4;
701                                    break;
702                            }
703                            for (j = 0; j < 4; j++) {
704                                    if (strcmp(cp + 1, modes[j])) continue;
705                                    value = j;
706                                    break;
707                            }
708                            if (j == 4) return -EINVAL;
709                    } else if (value > ccs_control_array[i].max_value) {
710                            value = ccs_control_array[i].max_value;
711                    }
712                    switch (i) {
713                    case CCS_SAKURA_DENY_CONCEAL_MOUNT:
714                    case CCS_SAKURA_RESTRICT_UNMOUNT:
715                            if (value == 1) value = 2; /* learning mode is not supported. */
716                    }
717                  profile->value[i] = value;                  profile->value[i] = value;
718                  return 0;                  return 0;
719          }          }
# Line 615  static int SetProfile(struct io_buffer * Line 722  static int SetProfile(struct io_buffer *
722    
723  static int ReadProfile(struct io_buffer *head)  static int ReadProfile(struct io_buffer *head)
724  {  {
725          if (!head->read_eof) {          int step;
726                  if (!isRoot()) return -EPERM;          if (head->read_eof) return 0;
727                  if (!head->read_var2) {          for (step = head->read_step; step < MAX_PROFILES * (CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX); step++) {
728                          int step;                  const int i = step / (CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX), j = step % (CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX);
729                          for (step = head->read_step; step < MAX_PROFILES * CCS_MAX_CONTROL_INDEX; step++) {                  const struct profile *profile = profile_ptr[i];
730                                  const int i = step / CCS_MAX_CONTROL_INDEX, j = step % CCS_MAX_CONTROL_INDEX;                  head->read_step = step;
731                                  const struct profile *profile = profile_ptr[i];                  if (!profile) continue;
732                                  head->read_step = step;                  switch (j) {
733                                  if (!profile) continue;                  case -1: /* Dummy */
                                 switch (j) {  
                                 case -1: /* Dummy */  
734  #ifndef CONFIG_SAKURA  #ifndef CONFIG_SAKURA
735                                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:
736                                  case CCS_SAKURA_RESTRICT_CHROOT:                  case CCS_SAKURA_RESTRICT_CHROOT:
737                                  case CCS_SAKURA_RESTRICT_MOUNT:                  case CCS_SAKURA_RESTRICT_MOUNT:
738                                  case CCS_SAKURA_RESTRICT_UNMOUNT:                  case CCS_SAKURA_RESTRICT_UNMOUNT:
739                                  case CCS_SAKURA_RESTRICT_PIVOT_ROOT:                  case CCS_SAKURA_RESTRICT_PIVOT_ROOT:
740                                  case CCS_SAKURA_RESTRICT_AUTOBIND:                  case CCS_SAKURA_RESTRICT_AUTOBIND:
741  #endif  #endif
742  #ifndef CONFIG_TOMOYO  #ifndef CONFIG_TOMOYO
743                                  case CCS_TOMOYO_MAC_FOR_FILE:                  case CCS_TOMOYO_MAC_FOR_FILE:
744                                  case CCS_TOMOYO_MAC_FOR_ARGV0:                  case CCS_TOMOYO_MAC_FOR_ARGV0:
745                                  case CCS_TOMOYO_MAC_FOR_ENV:                  case CCS_TOMOYO_MAC_FOR_ENV:
746                                  case CCS_TOMOYO_MAC_FOR_NETWORK:                  case CCS_TOMOYO_MAC_FOR_NETWORK:
747                                  case CCS_TOMOYO_MAC_FOR_SIGNAL:                  case CCS_TOMOYO_MAC_FOR_SIGNAL:
748                                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:
749                                  case CCS_TOMOYO_MAX_GRANT_LOG:                  case CCS_TOMOYO_MAX_GRANT_LOG:
750                                  case CCS_TOMOYO_MAX_REJECT_LOG:                  case CCS_TOMOYO_MAX_REJECT_LOG:
751                                  case CCS_TOMOYO_VERBOSE:                  case CCS_TOMOYO_VERBOSE:
752  #endif  #endif
753  #ifndef ALT_EXEC                          continue;
754                                  case CCS_TOMOYO_ALT_EXEC:                  }
755                                  case CCS_SLEEP_PERIOD:                  if (j == CCS_PROFILE_COMMENT) {
756                            if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_PROFILE_COMMENT].keyword, profile->comment ? profile->comment->name : "")) break;
757                    } else if (j == CCS_TOMOYO_ALT_EXEC) {
758                            const struct path_info *alt_exec = profile->alt_exec;
759                            if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword, alt_exec ? alt_exec->name : "")) break;
760                    } else if (j >= CCS_MAX_CONTROL_INDEX) {
761    #ifdef CONFIG_TOMOYO
762                            const int k = j - CCS_MAX_CONTROL_INDEX;
763                            if (io_printf(head, "%u-" KEYWORD_MAC_FOR_CAPABILITY "%s=%s\n", i, capability_control_keyword[k], mode_4[profile->capability_value[k]])) break;
764  #endif  #endif
765                                          continue;                  } else {
766                                  }                          const unsigned int value = profile->value[j];
767                                  if (j == CCS_PROFILE_COMMENT) {                          const char **modes = NULL;
768                                          if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_PROFILE_COMMENT].keyword, profile->comment ? profile->comment->name : "")) break;                          switch (ccs_control_array[j].max_value) {
769                                  } else if (j == CCS_TOMOYO_ALT_EXEC) {                          case 3:
770                                          const struct path_info *alt_exec = profile->alt_exec;                                  modes = mode_4;
771                                          if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword, alt_exec ? alt_exec->name : "")) break;                                  break;
772                                  } else {                          case 1:
773                                          if (io_printf(head, "%u-%s=%u\n", i, ccs_control_array[j].keyword, profile->value[j])) break;                                  modes = mode_2;
774                                  }                                  break;
775                          }                          }
776                          if (step == MAX_PROFILES * CCS_MAX_CONTROL_INDEX) {                          if (modes) {
777                                  head->read_var2 = (void *) "";                                  if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[j].keyword, modes[value])) break;
778                                  head->read_step = 0;                          } else {
779                                    if (io_printf(head, "%u-%s=%u\n", i, ccs_control_array[j].keyword, value)) break;
780                          }                          }
781                  }                  }
                 if (head->read_var2) {  
 #ifdef CONFIG_TOMOYO  
                         if (ReadCapabilityStatus(head) == 0)  
 #endif  
                                 head->read_eof = 1;  
                 }  
782          }          }
783            if (step == MAX_PROFILES * (CCS_MAX_CONTROL_INDEX + TOMOYO_MAX_CAPABILITY_INDEX)) head->read_eof = true;
784          return 0;          return 0;
785  }  }
786    
# Line 692  static int AddManagerEntry(const char *m Line 801  static int AddManagerEntry(const char *m
801          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
802          const struct path_info *saved_manager;          const struct path_info *saved_manager;
803          int error = -ENOMEM;          int error = -ENOMEM;
804          bool is_domain = 0;          bool is_domain = false;
         if (!isRoot()) return -EPERM;  
805          if (IsDomainDef(manager)) {          if (IsDomainDef(manager)) {
806                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;
807                  is_domain = 1;                  is_domain = true;
808          } else {          } else {
809                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;
810          }          }
# Line 727  static int AddManagerEntry(const char *m Line 835  static int AddManagerEntry(const char *m
835  static int AddManagerPolicy(struct io_buffer *head)  static int AddManagerPolicy(struct io_buffer *head)
836  {  {
837          const char *data = head->write_buf;          const char *data = head->write_buf;
838          bool is_delete = 0;          bool is_delete = false;
         if (!isRoot()) return -EPERM;  
839          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
840                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
841                  is_delete = 1;                  is_delete = true;
842            }
843            if (strcmp(data, "manage_by_non_root") == 0) {
844                    manage_by_non_root = is_delete;
845                    return 0;
846          }          }
847          return AddManagerEntry(data, is_delete);          return AddManagerEntry(data, is_delete);
848  }  }
# Line 740  static int ReadManagerPolicy(struct io_b Line 851  static int ReadManagerPolicy(struct io_b
851  {  {
852          struct list1_head *pos;          struct list1_head *pos;
853          if (head->read_eof) return 0;          if (head->read_eof) return 0;
         if (!isRoot()) return -EPERM;  
854          list1_for_each_cookie(pos, head->read_var2, &policy_manager_list) {          list1_for_each_cookie(pos, head->read_var2, &policy_manager_list) {
855                  struct policy_manager_entry *ptr;                  struct policy_manager_entry *ptr;
856                  ptr = list1_entry(pos, struct policy_manager_entry, list);                  ptr = list1_entry(pos, struct policy_manager_entry, list);
857                  if (ptr->is_deleted) continue;                  if (ptr->is_deleted) continue;
858                  if (io_printf(head, "%s\n", ptr->manager->name)) return 0;                  if (io_printf(head, "%s\n", ptr->manager->name)) return 0;
859          }          }
860          head->read_eof = 1;          head->read_eof = true;
861          return 0;          return 0;
862  }  }
863    
864  /* Check whether the current process is a policy manager. */  /* Check whether the current process is a policy manager. */
865  static int IsPolicyManager(void)  static bool IsPolicyManager(void)
866  {  {
867          struct policy_manager_entry *ptr;          struct policy_manager_entry *ptr;
868          const char *exe;          const char *exe;
869          const struct path_info *domainname = current->domain_info->domainname;          const struct task_struct *task = current;
870          bool found = 0;          const struct path_info *domainname = task->domain_info->domainname;
871          if (!sbin_init_started) return 1;          bool found = false;
872            if (!sbin_init_started) return true;
873            if (!manage_by_non_root && (task->uid || task->euid)) return false;
874          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
875                  if (!ptr->is_deleted && ptr->is_domain && !pathcmp(domainname, ptr->manager)) return 1;                  if (!ptr->is_deleted && ptr->is_domain && !pathcmp(domainname, ptr->manager)) return true;
876          }          }
877          if ((exe = GetEXE()) == NULL) return 0;          if ((exe = GetEXE()) == NULL) return false;
878          list1_for_each_entry(ptr, &policy_manager_list, list) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
879                  if (!ptr->is_deleted && !ptr->is_domain && !strcmp(exe, ptr->manager->name)) {                  if (!ptr->is_deleted && !ptr->is_domain && !strcmp(exe, ptr->manager->name)) {
880                          found = 1;                          found = true;
881                          break;                          break;
882                  }                  }
883          }          }
# Line 791  static char *FindConditionPart(char *dat Line 903  static char *FindConditionPart(char *dat
903          if (cp) {          if (cp) {
904                  while ((cp2 = strstr(cp + 3, " if ")) != NULL) cp = cp2;                  while ((cp2 = strstr(cp + 3, " if ")) != NULL) cp = cp2;
905                  *cp++ = '\0';                  *cp++ = '\0';
906            } else if ((cp = strstr(data, " ; set ")) != NULL) {
907                    *cp++ = '\0';
908          }          }
909          return cp;          return cp;
910  }  }
# Line 799  static int AddDomainPolicy(struct io_buf Line 913  static int AddDomainPolicy(struct io_buf
913  {  {
914          char *data = head->write_buf;          char *data = head->write_buf;
915          struct domain_info *domain = head->write_var1;          struct domain_info *domain = head->write_var1;
916          bool is_delete = 0, is_select = 0, is_undelete = 0;          bool is_delete = false, is_select = false, is_undelete = false;
917          unsigned int profile;          unsigned int profile;
918          const struct condition_list *cond = NULL;          const struct condition_list *cond = NULL;
919          char *cp;                char *cp;
         if (!isRoot()) return -EPERM;  
920          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
921                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
922                  is_delete = 1;                  is_delete = true;
923          } else if (strncmp(data, KEYWORD_SELECT, KEYWORD_SELECT_LEN) == 0) {          } else if (strncmp(data, KEYWORD_SELECT, KEYWORD_SELECT_LEN) == 0) {
924                  data += KEYWORD_SELECT_LEN;                  data += KEYWORD_SELECT_LEN;
925                  is_select = 1;                  is_select = true;
926          } else if (strncmp(data, KEYWORD_UNDELETE, KEYWORD_UNDELETE_LEN) == 0) {          } else if (strncmp(data, KEYWORD_UNDELETE, KEYWORD_UNDELETE_LEN) == 0) {
927                  data += KEYWORD_UNDELETE_LEN;                  data += KEYWORD_UNDELETE_LEN;
928                  is_undelete = 1;                  is_undelete = true;
929          }          }
         UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
930          if (IsDomainDef(data)) {          if (IsDomainDef(data)) {
931                  if (is_delete) {                  if (is_delete) {
932                          DeleteDomain(data);                          DeleteDomain(data);
# Line 827  static int AddDomainPolicy(struct io_buf Line 939  static int AddDomainPolicy(struct io_buf
939                          domain = FindOrAssignNewDomain(data, 0);                          domain = FindOrAssignNewDomain(data, 0);
940                  }                  }
941                  head->write_var1 = domain;                  head->write_var1 = domain;
942                    UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
943                  return 0;                  return 0;
944          }          }
945          if (!domain) return -EINVAL;          if (!domain) return -EINVAL;
# Line 835  static int AddDomainPolicy(struct io_buf Line 948  static int AddDomainPolicy(struct io_buf
948                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;
949                  return 0;                  return 0;
950          }          }
951            if (strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_READ) == 0) {
952                    if (!is_delete) domain->flags |= DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ;
953                    else domain->flags &= ~DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ;
954                    return 0;
955            }
956            if (strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_ENV) == 0) {
957                    if (!is_delete) domain->flags |= DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV;
958                    else domain->flags &= ~DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV;
959                    return 0;
960            }
961            if (strcmp(data, KEYWORD_FORCE_ALT_EXEC) == 0) {
962                    if (!is_delete) domain->flags |= DOMAIN_FLAGS_FORCE_ALT_EXEC;
963                    else domain->flags &= ~DOMAIN_FLAGS_FORCE_ALT_EXEC;
964                    return 0;
965            }
966          cp = FindConditionPart(data);          cp = FindConditionPart(data);
967          if (cp && (cond = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;          if (cp && (cond = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;
968          if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {          if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {
# Line 853  static int AddDomainPolicy(struct io_buf Line 981  static int AddDomainPolicy(struct io_buf
981          return -EINVAL;          return -EINVAL;
982  }  }
983    
984    static bool print_single_path_acl(struct io_buffer *head, struct single_path_acl_record *ptr, const struct condition_list *cond)
985    {
986            int pos;
987            u8 bit;
988            const bool b = ptr->u_is_group;
989            const u16 perm = ptr->perm;
990            for (bit = head->read_bit; bit < MAX_SINGLE_PATH_OPERATION; bit++) {
991                    const char *msg;
992                    if (!(perm & (1 << bit))) continue;
993                    /* Print "read/write" instead of "read" and "write". */
994                    if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL) && (perm & (1 << TYPE_READ_WRITE_ACL))) continue;
995                    msg = sp_operation2keyword(bit);
996                    pos = head->read_avail;
997                    if (b && io_printf(head, "allow_%s @%s ", msg, ptr->u.group->group_name->name)) goto out;
998                    if (!b && io_printf(head, "allow_%s %s ", msg, ptr->u.filename->name)) goto out;
999                    if (DumpCondition(head, cond)) goto out;
1000            }
1001            head->read_bit = 0;
1002            return true;
1003     out:
1004            head->read_bit = bit;
1005            head->read_avail = pos;
1006            return false;
1007    }
1008    
1009    static bool print_double_path_acl(struct io_buffer *head, struct double_path_acl_record *ptr, const struct condition_list *cond)
1010    {
1011            int pos;
1012            const bool b0 = ptr->u1_is_group, b1 = ptr->u2_is_group;
1013            const u8 perm = ptr->perm;
1014            u8 bit;
1015            for (bit = head->read_bit; bit < MAX_DOUBLE_PATH_OPERATION; bit++) {
1016                    const char *msg;
1017                    if (!(perm & (1 << bit))) continue;
1018                    msg = dp_operation2keyword(bit);
1019                    pos = head->read_avail;
1020                    if (io_printf(head, "allow_%s ", msg)) goto out;
1021                    if (b0 && io_printf(head, "@%s ", ptr->u1.group1->group_name->name)) goto out;
1022                    if (!b0 && io_printf(head, "%s ", ptr->u1.filename1->name)) goto out;
1023                    if (b1 && io_printf(head, "@%s", ptr->u2.group2->group_name->name)) goto out;
1024                    if (!b1 && io_printf(head, "%s", ptr->u2.filename2->name)) goto out;
1025                    if (DumpCondition(head, cond)) goto out;
1026            }
1027            head->read_bit = 0;
1028            return true;
1029     out:
1030            head->read_bit = bit;
1031            head->read_avail = pos;
1032            return false;
1033    }
1034    
1035    static bool print_argv0_acl(struct io_buffer *head, struct argv0_acl_record *ptr, const struct condition_list *cond)
1036    {
1037            int pos = head->read_avail;
1038            if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
1039                          ptr->filename->name, ptr->argv0->name)) goto out;
1040            if (DumpCondition(head, cond)) goto out;
1041            return true;
1042     out:
1043            head->read_avail = pos;
1044            return false;
1045    }
1046    
1047    static bool print_env_acl(struct io_buffer *head, struct env_acl_record *ptr, const struct condition_list *cond)
1048    {
1049            int pos = head->read_avail;
1050            if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name)) goto out;
1051            if (DumpCondition(head, cond)) goto out;
1052            return true;
1053     out:
1054            head->read_avail = pos;
1055            return false;
1056    }
1057    
1058    static bool print_capability_acl(struct io_buffer *head, struct capability_acl_record *ptr, const struct condition_list *cond)
1059    {
1060            int pos = head->read_avail;
1061            if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", cap_operation2keyword(ptr->operation))) goto out;
1062            if (DumpCondition(head, cond)) goto out;
1063            return true;
1064     out:
1065            head->read_avail = pos;
1066            return false;
1067    }
1068    
1069    static bool print_network_acl(struct io_buffer *head, struct ip_network_acl_record *ptr, const struct condition_list *cond)
1070    {
1071            int pos = head->read_avail;
1072            if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", net_operation2keyword(ptr->operation_type))) goto out;
1073            switch (ptr->record_type) {
1074            case IP_RECORD_TYPE_ADDRESS_GROUP:
1075                    if (io_printf(head, "@%s", ptr->u.group->group_name->name)) goto out;
1076                    break;
1077            case IP_RECORD_TYPE_IPv4:
1078                    {
1079                            const u32 min_address = ptr->u.ipv4.min, max_address = ptr->u.ipv4.max;
1080                            if (io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address))) goto out;
1081                            if (min_address != max_address && io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address))) goto out;
1082                    }
1083                    break;
1084            case IP_RECORD_TYPE_IPv6:
1085                    {
1086                            char buf[64];
1087                            const struct in6_addr *min_address = ptr->u.ipv6.min, *max_address = ptr->u.ipv6.max;
1088                            print_ipv6(buf, sizeof(buf), min_address);
1089                            if (io_printf(head, "%s", buf)) goto out;
1090                            if (min_address != max_address) {
1091                                    print_ipv6(buf, sizeof(buf), max_address);
1092                                    if (io_printf(head, "-%s", buf)) goto out;
1093                            }
1094                    }
1095                    break;
1096            }
1097            {
1098                    const u16 min_port = ptr->min_port, max_port = ptr->max_port;
1099                    if (io_printf(head, " %u", min_port)) goto out;
1100                    if (min_port != max_port && io_printf(head, "-%u", max_port)) goto out;
1101            }
1102            if (DumpCondition(head, cond)) goto out;
1103            return true;
1104     out:
1105            head->read_avail = pos;
1106            return false;
1107    }
1108    
1109    static bool print_signal_acl(struct io_buffer *head, struct signal_acl_record *ptr, const struct condition_list *cond)
1110    {
1111            int pos = head->read_avail;
1112            if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr->sig, ptr->domainname->name)) goto out;
1113            if (DumpCondition(head, cond)) goto out;
1114            return true;
1115     out:
1116            head->read_avail = pos;
1117            return false;
1118    }
1119    
1120  static int ReadDomainPolicy(struct io_buffer *head)  static int ReadDomainPolicy(struct io_buffer *head)
1121  {  {
1122          struct list1_head *dpos;          struct list1_head *dpos;
1123          struct list1_head *apos;          struct list1_head *apos;
1124          if (head->read_eof) return 0;          if (head->read_eof) return 0;
1125          if (head->read_step == 0) {          if (head->read_step == 0) head->read_step = 1;
                 if (!isRoot()) return -EPERM;  
                 head->read_step = 1;  
         }  
1126          list1_for_each_cookie(dpos, head->read_var1, &domain_list) {          list1_for_each_cookie(dpos, head->read_var1, &domain_list) {
1127                  struct domain_info *domain;                  struct domain_info *domain;
1128                  domain = list1_entry(dpos, struct domain_info, list);                  domain = list1_entry(dpos, struct domain_info, list);
1129                  if (head->read_step != 1) goto acl_loop;                  if (head->read_step != 1) goto acl_loop;
1130                  if (domain->is_deleted) continue;                  if (domain->is_deleted) continue;
1131                  if (io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n%s\n", domain->domainname->name, domain->profile, domain->quota_warned ? "quota_exceeded\n" : "")) return 0;                  if (io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n%s\n%s%s%s", domain->domainname->name, domain->profile, domain->quota_warned ? "quota_exceeded\n" : "", domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ ? KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n" : "", domain->flags & DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_ENV ? KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n" : "", domain->flags & DOMAIN_FLAGS_FORCE_ALT_EXEC ? KEYWORD_FORCE_ALT_EXEC "\n" : "")) return 0;
1132                  head->read_step = 2;                  head->read_step = 2;
1133          acl_loop: ;          acl_loop: ;
1134                  if (head->read_step == 3) goto tail_mark;                  if (head->read_step == 3) goto tail_mark;
1135                  list1_for_each_cookie(apos, head->read_var2, &domain->acl_info_list) {                  list1_for_each_cookie(apos, head->read_var2, &domain->acl_info_list) {
1136                          struct acl_info *ptr;                          struct acl_info *ptr;
                         int pos;  
1137                          u8 acl_type;                          u8 acl_type;
1138                            const struct condition_list *cond;
1139                          ptr = list1_entry(apos, struct acl_info, list);                          ptr = list1_entry(apos, struct acl_info, list);
1140                          if (ptr->is_deleted) continue;                          cond = GetConditionPart(ptr);
1141                          pos = head->read_avail;                          acl_type = ptr->type & ~ACL_WITH_CONDITION;
1142                          acl_type = ptr->type;                          if (acl_type & ACL_DELETED) {
1143                          if (acl_type == TYPE_FILE_ACL) {                                  /* Deleted entry. */
1144                                  struct file_acl_record *ptr2 = container_of(ptr, struct file_acl_record, head);                          } else if (acl_type == TYPE_SINGLE_PATH_ACL) {
1145                                  const unsigned char b = ptr2->u_is_group;                                  if (!print_single_path_acl(head, container_of(ptr, struct single_path_acl_record, head), cond)) return 0;
1146                                  if (io_printf(head, "%d %s%s", ptr2->perm,                          } else if (acl_type == TYPE_DOUBLE_PATH_ACL) {
1147                                                b ? "@" : "",                                  if (!print_double_path_acl(head, container_of(ptr, struct double_path_acl_record, head), cond)) return 0;
                                               b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback;  
1148                          } else if (acl_type == TYPE_ARGV0_ACL) {                          } else if (acl_type == TYPE_ARGV0_ACL) {
1149                                  struct argv0_acl_record *ptr2 = container_of(ptr, struct argv0_acl_record, head);                                  if (!print_argv0_acl(head, container_of(ptr, struct argv0_acl_record, head), cond)) return 0;
                                 if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",  
                                               ptr2->filename->name, ptr2->argv0->name)) goto print_acl_rollback;  
1150                          } else if (acl_type == TYPE_ENV_ACL) {                          } else if (acl_type == TYPE_ENV_ACL) {
1151                                  struct env_acl_record *ptr2 = container_of(ptr, struct env_acl_record, head);                                  if (!print_env_acl(head, container_of(ptr, struct env_acl_record, head), cond)) return 0;
                                 if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr2->env->name)) goto print_acl_rollback;  
1152                          } else if (acl_type == TYPE_CAPABILITY_ACL) {                          } else if (acl_type == TYPE_CAPABILITY_ACL) {
1153                                  struct capability_acl_record *ptr2 = container_of(ptr, struct capability_acl_record, head);                                  if (!print_capability_acl(head, container_of(ptr, struct capability_acl_record, head), cond)) return 0;
                                 if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", capability2keyword(ptr2->capability))) goto print_acl_rollback;  
1154                          } else if (acl_type == TYPE_IP_NETWORK_ACL) {                          } else if (acl_type == TYPE_IP_NETWORK_ACL) {
1155                                  struct ip_network_acl_record *ptr2 = container_of(ptr, struct ip_network_acl_record, head);                                  if (!print_network_acl(head, container_of(ptr, struct ip_network_acl_record, head), cond)) return 0;
                                 if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", network2keyword(ptr2->operation_type))) goto print_acl_rollback;  
                                 switch (ptr2->record_type) {  
                                 case IP_RECORD_TYPE_ADDRESS_GROUP:  
                                         if (io_printf(head, "@%s", ptr2->u.group->group_name->name)) goto print_acl_rollback;  
                                         break;  
                                 case IP_RECORD_TYPE_IPv4:  
                                         {  
                                                 const u32 min_address = ptr2->u.ipv4.min, max_address = ptr2->u.ipv4.max;  
                                                 if (io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address))) goto print_acl_rollback;  
                                                 if (min_address != max_address && io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address))) goto print_acl_rollback;  
                                         }  
                                         break;  
                                 case IP_RECORD_TYPE_IPv6:  
                                         {  
                                                 char buf[64];  
                                                 const struct in6_addr *min_address = ptr2->u.ipv6.min, *max_address = ptr2->u.ipv6.max;  
                                                 print_ipv6(buf, sizeof(buf), min_address);  
                                                 if (io_printf(head, "%s", buf)) goto print_acl_rollback;  
                                                 if (min_address != max_address) {  
                                                         print_ipv6(buf, sizeof(buf), max_address);  
                                                         if (io_printf(head, "-%s", buf)) goto print_acl_rollback;  
                                                 }  
                                         }  
                                         break;  
                                 }  
                                 {  
                                         const u16 min_port = ptr2->min_port, max_port = ptr2->max_port;  
                                         if (io_printf(head, " %u", min_port)) goto print_acl_rollback;  
                                         if (min_port != max_port && io_printf(head, "-%u", max_port)) goto print_acl_rollback;  
                                 }  
1156                          } else if (acl_type == TYPE_SIGNAL_ACL) {                          } else if (acl_type == TYPE_SIGNAL_ACL) {
1157                                  struct signal_acl_record *ptr2 = container_of(ptr, struct signal_acl_record, head);                                  if (!print_signal_acl(head, container_of(ptr, struct signal_acl_record, head), cond)) return 0;
                                 if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr2->sig, ptr2->domainname->name)) goto print_acl_rollback;  
1158                          } else {                          } else {
1159                                  const char *keyword = acltype2keyword(acl_type);                                  BUG();
                                 if (!keyword) continue;  
                                 if (acltype2paths(acl_type) == 2) {  
                                         struct double_acl_record *ptr2 = container_of(ptr, struct double_acl_record, head);  
                                         const bool b0 = ptr2->u1_is_group, b1 = ptr2->u2_is_group;  
                                         if (io_printf(head, "allow_%s %s%s %s%s", keyword,  
                                                       b0 ? "@" : "", b0 ? ptr2->u1.group1->group_name->name : ptr2->u1.filename1->name,  
                                                       b1 ? "@" : "", b1 ? ptr2->u2.group2->group_name->name : ptr2->u2.filename2->name)) goto print_acl_rollback;  
                                 } else {  
                                         struct single_acl_record *ptr2 = container_of(ptr, struct single_acl_record, head);  
                                         const bool b = ptr2->u_is_group;  
                                         if (io_printf(head, "allow_%s %s%s", keyword,  
                                                       b ? "@" : "", b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback;  
                                 }  
                         }  
                         if (DumpCondition(head, ptr->cond)) {  
                         print_acl_rollback: ;  
                         head->read_avail = pos;  
                         return 0;  
1160                          }                          }
1161                  }                  }
1162                  head->read_step = 3;                  head->read_step = 3;
# Line 957  static int ReadDomainPolicy(struct io_bu Line 1164  static int ReadDomainPolicy(struct io_bu
1164                  if (io_printf(head, "\n")) return 0;                  if (io_printf(head, "\n")) return 0;
1165                  head->read_step = 1;                  head->read_step = 1;
1166          }          }
1167          head->read_eof = 1;          head->read_eof = true;
1168          return 0;          return 0;
1169  }  }
1170    
# Line 969  static int UpdateDomainProfile(struct io Line 1176  static int UpdateDomainProfile(struct io
1176          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
1177          struct domain_info *domain;          struct domain_info *domain;
1178          unsigned int profile;          unsigned int profile;
         if (!isRoot()) return -EPERM;  
1179          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
1180          *cp = '\0';          *cp = '\0';
1181          domain = FindDomain(cp + 1);          domain = FindDomain(cp + 1);
# Line 983  static int ReadDomainProfile(struct io_b Line 1189  static int ReadDomainProfile(struct io_b
1189  {  {
1190          struct list1_head *pos;          struct list1_head *pos;
1191          if (head->read_eof) return 0;          if (head->read_eof) return 0;
         if (!isRoot()) return -EPERM;  
1192          list1_for_each_cookie(pos, head->read_var1, &domain_list) {          list1_for_each_cookie(pos, head->read_var1, &domain_list) {
1193                  struct domain_info *domain;                  struct domain_info *domain;
1194                  domain = list1_entry(pos, struct domain_info, list);                  domain = list1_entry(pos, struct domain_info, list);
1195                  if (domain->is_deleted) continue;                  if (domain->is_deleted) continue;
1196                  if (io_printf(head, "%u %s\n", domain->profile, domain->domainname->name)) return 0;                  if (io_printf(head, "%u %s\n", domain->profile, domain->domainname->name)) return 0;
1197          }          }
1198          head->read_eof = 1;          head->read_eof = true;
1199          return 0;          return 0;
1200  }  }
1201    
1202  static int WritePID(struct io_buffer *head)  static int WritePID(struct io_buffer *head)
1203  {  {
1204          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);
1205          head->read_eof = 0;          head->read_eof = false;
1206          return 0;          return 0;
1207  }  }
1208    
# Line 1014  static int ReadPID(struct io_buffer *hea Line 1219  static int ReadPID(struct io_buffer *hea
1219                  read_unlock(&tasklist_lock);                  read_unlock(&tasklist_lock);
1220                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
1221                  if (domain) io_printf(head, "%d %u %s", pid, domain->profile, domain->domainname->name);                  if (domain) io_printf(head, "%d %u %s", pid, domain->profile, domain->domainname->name);
1222                  head->read_eof = 1;                  head->read_eof = true;
1223          }          }
1224          return 0;          return 0;
1225  }  }
# Line 1026  static int ReadPID(struct io_buffer *hea Line 1231  static int ReadPID(struct io_buffer *hea
1231  static int AddExceptionPolicy(struct io_buffer *head)  static int AddExceptionPolicy(struct io_buffer *head)
1232  {  {
1233          char *data = head->write_buf;          char *data = head->write_buf;
1234          bool is_delete = 0;          bool is_delete = false;
         if (!isRoot()) return -EPERM;  
1235          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
1236          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
1237                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
1238                  is_delete = 1;                  is_delete = true;
1239          }          }
1240          if (strncmp(data, KEYWORD_KEEP_DOMAIN, KEYWORD_KEEP_DOMAIN_LEN) == 0) {          if (strncmp(data, KEYWORD_KEEP_DOMAIN, KEYWORD_KEEP_DOMAIN_LEN) == 0) {
1241                  return AddDomainKeeperPolicy(data + KEYWORD_KEEP_DOMAIN_LEN, 0, is_delete);                  return AddDomainKeeperPolicy(data + KEYWORD_KEEP_DOMAIN_LEN, 0, is_delete);
# Line 1050  static int AddExceptionPolicy(struct io_ Line 1254  static int AddExceptionPolicy(struct io_
1254          } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {
1255                  return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete);                  return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete);
1256          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {
1257                  return AddPatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);                  return AddFilePatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);
1258          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {
1259                  return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);                  return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);
1260          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {
# Line 1066  static int ReadExceptionPolicy(struct io Line 1270  static int ReadExceptionPolicy(struct io
1270          if (!head->read_eof) {          if (!head->read_eof) {
1271                  switch (head->read_step) {                  switch (head->read_step) {
1272                  case 0:                  case 0:
                         if (!isRoot()) return -EPERM;  
1273                          head->read_var2 = NULL; head->read_step = 1;                          head->read_var2 = NULL; head->read_step = 1;
1274                  case 1:                  case 1:
1275                          if (ReadDomainKeeperPolicy(head)) break;                          if (ReadDomainKeeperPolicy(head)) break;
# Line 1087  static int ReadExceptionPolicy(struct io Line 1290  static int ReadExceptionPolicy(struct io
1290                          if (ReadAggregatorPolicy(head)) break;                          if (ReadAggregatorPolicy(head)) break;
1291                          head->read_var2 = NULL; head->read_step = 7;                          head->read_var2 = NULL; head->read_step = 7;
1292                  case 7:                  case 7:
1293                          if (ReadPatternPolicy(head)) break;                          if (ReadFilePatternPolicy(head)) break;
1294                          head->read_var2 = NULL; head->read_step = 8;                          head->read_var2 = NULL; head->read_step = 8;
1295                  case 8:                  case 8:
1296                          if (ReadNoRewritePolicy(head)) break;                          if (ReadNoRewritePolicy(head)) break;
# Line 1097  static int ReadExceptionPolicy(struct io Line 1300  static int ReadExceptionPolicy(struct io
1300                          head->read_var1 = head->read_var2 = NULL; head->read_step = 10;                          head->read_var1 = head->read_var2 = NULL; head->read_step = 10;
1301                  case 10:                  case 10:
1302                          if (ReadAddressGroupPolicy(head)) break;                          if (ReadAddressGroupPolicy(head)) break;
1303                          head->read_eof = 1;                          head->read_eof = true;
1304                          break;                          break;
1305                  default:                  default:
1306                          return -EINVAL;                          return -EINVAL;
# Line 1115  static int ReadExceptionPolicy(struct io Line 1318  static int ReadExceptionPolicy(struct io
1318  static int AddSystemPolicy(struct io_buffer *head)  static int AddSystemPolicy(struct io_buffer *head)
1319  {  {
1320          char *data = head->write_buf;          char *data = head->write_buf;
1321          bool is_delete = 0;          bool is_delete = false;
         if (!isRoot()) return -EPERM;  
1322          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
1323          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
1324                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
1325                  is_delete = 1;                  is_delete = true;
1326          }          }
1327          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)
1328                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);
# Line 1140  static int ReadSystemPolicy(struct io_bu Line 1342  static int ReadSystemPolicy(struct io_bu
1342          if (!head->read_eof) {          if (!head->read_eof) {
1343                  switch (head->read_step) {                  switch (head->read_step) {
1344                  case 0:                  case 0:
                         if (!isRoot()) return -EPERM;  
1345                          head->read_var2 = NULL; head->read_step = 1;                          head->read_var2 = NULL; head->read_step = 1;
1346                  case 1:                  case 1:
1347                          if (ReadMountPolicy(head)) break;                          if (ReadMountPolicy(head)) break;
# Line 1156  static int ReadSystemPolicy(struct io_bu Line 1357  static int ReadSystemPolicy(struct io_bu
1357                          head->read_var2 = NULL; head->read_step = 5;                          head->read_var2 = NULL; head->read_step = 5;
1358                  case 5:                  case 5:
1359                          if (ReadReservedPortPolicy(head)) break;                          if (ReadReservedPortPolicy(head)) break;
1360                          head->read_eof = 1;                          head->read_eof = true;
1361                          break;                          break;
1362                  default:                  default:
1363                          return -EINVAL;                          return -EINVAL;
# Line 1169  static int ReadSystemPolicy(struct io_bu Line 1370  static int ReadSystemPolicy(struct io_bu
1370    
1371  /*************************  POLICY LOADER  *************************/  /*************************  POLICY LOADER  *************************/
1372    
1373  static int profile_loaded = 0;  static bool profile_loaded = false;
1374    
1375  static const char *ccs_loader = NULL;  static const char *ccs_loader = NULL;
1376    
# Line 1204  void CCS_LoadPolicy(const char *filename Line 1405  void CCS_LoadPolicy(const char *filename
1405                          printk("Not activating Mandatory Access Control now since %s doesn't exist.\n", ccs_loader);                          printk("Not activating Mandatory Access Control now since %s doesn't exist.\n", ccs_loader);
1406                          return;                          return;
1407                  }                  }
1408    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
1409                    path_put(&nd.path);
1410    #else
1411                  path_release(&nd);                  path_release(&nd);
1412    #endif
1413          }          }
1414          if (!profile_loaded) {          if (!profile_loaded) {
1415                  char *argv[2], *envp[3];                  char *argv[2], *envp[3];
# Line 1225  void CCS_LoadPolicy(const char *filename Line 1430  void CCS_LoadPolicy(const char *filename
1430                  }                  }
1431          }          }
1432  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1433          printk("SAKURA: 1.5.3-pre   2007/12/18\n");          printk("SAKURA: 1.6.0-pre   2008/03/04\n");
1434  #endif  #endif
1435  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1436          printk("TOMOYO: 1.5.3-pre   2007/12/17\n");          printk("TOMOYO: 1.6.0-pre   2008/03/04\n");
1437  #endif  #endif
         //if (!profile_loaded) panic("No profiles loaded. Run policy loader using 'init=' option.\n");  
1438          printk("Mandatory Access Control activated.\n");          printk("Mandatory Access Control activated.\n");
1439          sbin_init_started = 1;          sbin_init_started = true;
1440          ccs_log_level = KERN_WARNING;          ccs_log_level = KERN_WARNING;
1441          { /* Check all profiles currently assigned to domains are defined. */          { /* Check all profiles currently assigned to domains are defined. */
1442                  struct domain_info *domain;                  struct domain_info *domain;
# Line 1243  void CCS_LoadPolicy(const char *filename Line 1447  void CCS_LoadPolicy(const char *filename
1447          }          }
1448  }  }
1449    
   
1450  /*************************  MAC Decision Delayer  *************************/  /*************************  MAC Decision Delayer  *************************/
1451    
1452  static DECLARE_WAIT_QUEUE_HEAD(query_wait);  static DECLARE_WAIT_QUEUE_HEAD(query_wait);
# Line 1270  int CheckSupervisor(const char *fmt, ... Line 1473  int CheckSupervisor(const char *fmt, ...
1473          static unsigned int serial = 0;          static unsigned int serial = 0;
1474          struct query_entry *query_entry;          struct query_entry *query_entry;
1475          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) {          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) {
 #ifdef ALT_EXEC  
1476                  if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) {                  if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) {
1477                          int i;                          int i;
1478                          for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) {                          for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) {
# Line 1278  int CheckSupervisor(const char *fmt, ... Line 1480  int CheckSupervisor(const char *fmt, ...
1480                                  schedule_timeout(HZ / 10);                                  schedule_timeout(HZ / 10);
1481                          }                          }
1482                  }                  }
 #endif  
1483                  return -EPERM;                  return -EPERM;
1484          }          }
1485          va_start(args, fmt);          va_start(args, fmt);
# Line 1336  int CheckSupervisor(const char *fmt, ... Line 1537  int CheckSupervisor(const char *fmt, ...
1537    
1538  static int PollQuery(struct file *file, poll_table *wait)  static int PollQuery(struct file *file, poll_table *wait)
1539  {  {
1540          int found;          bool found;
1541          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1542          spin_lock(&query_lock);          spin_lock(&query_lock);
1543          found = !list_empty(&query_list);          found = !list_empty(&query_list);
# Line 1472  static int ReadUpdatesCounter(struct io_ Line 1673  static int ReadUpdatesCounter(struct io_
1673                                    counter[CCS_UPDATES_COUNTER_MANAGER],                                    counter[CCS_UPDATES_COUNTER_MANAGER],
1674                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],
1675                                    counter[CCS_UPDATES_COUNTER_REJECT_LOG]);                                    counter[CCS_UPDATES_COUNTER_REJECT_LOG]);
1676                  head->read_eof = 1;                  head->read_eof = true;
1677          }          }
1678          return 0;          return 0;
1679  }  }
# Line 1480  static int ReadUpdatesCounter(struct io_ Line 1681  static int ReadUpdatesCounter(struct io_
1681  static int ReadVersion(struct io_buffer *head)  static int ReadVersion(struct io_buffer *head)
1682  {  {
1683          if (!head->read_eof) {          if (!head->read_eof) {
1684                  if (io_printf(head, "1.5.3-pre") == 0) head->read_eof = 1;                  if (io_printf(head, "1.6.0-pre") == 0) head->read_eof = true;
1685          }          }
1686          return 0;          return 0;
1687  }  }
# Line 1489  static int ReadMemoryCounter(struct io_b Line 1690  static int ReadMemoryCounter(struct io_b
1690  {  {
1691          if (!head->read_eof) {          if (!head->read_eof) {
1692                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();
1693                  if (io_printf(head, "Shared:  %10u\nPrivate: %10u\nDynamic: %10u\nTotal:   %10u\n", shared, private, dynamic, shared + private + dynamic) == 0) head->read_eof = 1;                  if (io_printf(head, "Shared:  %10u\nPrivate: %10u\nDynamic: %10u\nTotal:   %10u\n", shared, private, dynamic, shared + private + dynamic) == 0) head->read_eof = true;
1694          }          }
1695          return 0;          return 0;
1696  }  }
# Line 1498  static int ReadSelfDomain(struct io_buff Line 1699  static int ReadSelfDomain(struct io_buff
1699  {  {
1700          if (!head->read_eof) {          if (!head->read_eof) {
1701                  io_printf(head, "%s", current->domain_info->domainname->name);                  io_printf(head, "%s", current->domain_info->domainname->name);
1702                  head->read_eof = 1;                  head->read_eof = true;
1703          }          }
1704          return 0;          return 0;
1705  }  }
1706    
1707  int CCS_OpenControl(const int type, struct file *file)  int CCS_OpenControl(const u8 type, struct file *file)
1708  {  {
1709          struct io_buffer *head = ccs_alloc(sizeof(*head));          struct io_buffer *head = ccs_alloc(sizeof(*head));
1710          if (!head) return -ENOMEM;          if (!head) return -ENOMEM;
# Line 1632  int CCS_WriteControl(struct file *file, Line 1833  int CCS_WriteControl(struct file *file,
1833          char *cp0 = head->write_buf;          char *cp0 = head->write_buf;
1834          if (!head->write) return -ENOSYS;          if (!head->write) return -ENOSYS;
1835          if (!access_ok(VERIFY_READ, buffer, buffer_len)) return -EFAULT;          if (!access_ok(VERIFY_READ, buffer, buffer_len)) return -EFAULT;
         if (!isRoot()) return -EPERM;  
1836          if (head->write != WritePID && !IsPolicyManager()) {          if (head->write != WritePID && !IsPolicyManager()) {
1837                  return -EPERM; /* Forbid updating policies for non manager programs. */                  return -EPERM; /* Forbid updating policies for non manager programs. */
1838          }          }
# Line 1663  int CCS_CloseControl(struct file *file) Line 1863  int CCS_CloseControl(struct file *file)
1863  {  {
1864          struct io_buffer *head = file->private_data;          struct io_buffer *head = file->private_data;
1865          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);
1866          else if (head->read == ReadMemoryCounter) profile_loaded = 1;          else if (head->read == ReadMemoryCounter) profile_loaded = true;
1867          ccs_free(head->read_buf); head->read_buf = NULL;          ccs_free(head->read_buf); head->read_buf = NULL;
1868          ccs_free(head->write_buf); head->write_buf = NULL;          ccs_free(head->write_buf); head->write_buf = NULL;
1869          ccs_free(head); head = NULL;          ccs_free(head); head = NULL;
1870          file->private_data = NULL;          file->private_data = NULL;
1871          return 0;          return 0;
1872  }  }
1873    
1874    void *alloc_acl_element(const u8 acl_type, const struct condition_list *condition)
1875    {
1876            int len;
1877            struct acl_info *ptr;
1878            switch (acl_type) {
1879            case TYPE_SINGLE_PATH_ACL:
1880                    len = sizeof(struct single_path_acl_record);
1881                    break;
1882            case TYPE_DOUBLE_PATH_ACL:
1883                    len = sizeof(struct double_path_acl_record);
1884                    break;
1885            case TYPE_ARGV0_ACL:
1886                    len = sizeof(struct argv0_acl_record);
1887                    break;
1888            case TYPE_ENV_ACL:
1889                    len = sizeof(struct env_acl_record);
1890                    break;
1891            case TYPE_CAPABILITY_ACL:
1892                    len = sizeof(struct capability_acl_record);
1893                    break;
1894            case TYPE_IP_NETWORK_ACL:
1895                    len = sizeof(struct ip_network_acl_record);
1896                    break;
1897            case TYPE_SIGNAL_ACL:
1898                    len = sizeof(struct signal_acl_record);
1899                    break;
1900            default:
1901                    return NULL;
1902            }
1903            if (!condition) len -= sizeof(ptr->cond);
1904            ptr = alloc_element(len);
1905            if (!ptr) return NULL;
1906            if (condition) {
1907                    ptr->cond = condition;
1908                    ptr->type = acl_type | ACL_WITH_CONDITION;
1909                    return ptr;
1910            }
1911            ptr = (void *) (((u8 *) ptr) - sizeof(ptr->cond));
1912            ptr->type = acl_type;
1913            return ptr;
1914    }
1915    
1916    const struct condition_list *GetConditionPart(const struct acl_info *acl)
1917    {
1918            return (acl->type & ACL_WITH_CONDITION) ? acl->cond : NULL;
1919    }

Legend:
Removed from v.813  
changed lines
  Added in v.1016

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