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

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/ccs-patch/fs/ccs_common.c revision 121 by kumaneko, Fri Mar 9 09:21:38 2007 UTC trunk/1.5.x/ccs-patch/fs/ccs_common.c revision 853 by kumaneko, Wed Jan 2 07:32:11 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.3.2   2007/02/14   * Version: 1.5.3-pre   2008/01/02
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 28  static const int lookup_flags = LOOKUP_F Line 28  static const int lookup_flags = LOOKUP_F
28  #else  #else
29  static const int lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;  static const int lookup_flags = LOOKUP_FOLLOW | LOOKUP_POSITIVE;
30  #endif  #endif
 #include <linux/version.h>  
31  #include <linux/realpath.h>  #include <linux/realpath.h>
32  #include <linux/ccs_common.h>  #include <linux/ccs_common.h>
33  #include <linux/ccs_proc.h>  #include <linux/ccs_proc.h>
# Line 53  static const int lookup_flags = LOOKUP_F Line 52  static const int lookup_flags = LOOKUP_F
52  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
53    
54  /* /sbin/init started? */  /* /sbin/init started? */
55  int sbin_init_started = 0;  bool sbin_init_started = 0;
56    
57  const char *ccs_log_level = KERN_DEBUG;  const char *ccs_log_level = KERN_DEBUG;
58    
# Line 65  static struct { Line 64  static struct {
64          [CCS_PROFILE_COMMENT]            = { "COMMENT",             0, 0 }, /* Reserved for string. */          [CCS_PROFILE_COMMENT]            = { "COMMENT",             0, 0 }, /* Reserved for string. */
65          [CCS_TOMOYO_MAC_FOR_FILE]        = { "MAC_FOR_FILE",        0, 3 },          [CCS_TOMOYO_MAC_FOR_FILE]        = { "MAC_FOR_FILE",        0, 3 },
66          [CCS_TOMOYO_MAC_FOR_ARGV0]       = { "MAC_FOR_ARGV0",       0, 3 },          [CCS_TOMOYO_MAC_FOR_ARGV0]       = { "MAC_FOR_ARGV0",       0, 3 },
67            [CCS_TOMOYO_MAC_FOR_ENV]         = { "MAC_FOR_ENV",         0, 3 },
68          [CCS_TOMOYO_MAC_FOR_NETWORK]     = { "MAC_FOR_NETWORK",     0, 3 },          [CCS_TOMOYO_MAC_FOR_NETWORK]     = { "MAC_FOR_NETWORK",     0, 3 },
69          [CCS_TOMOYO_MAC_FOR_SIGNAL]      = { "MAC_FOR_SIGNAL",      0, 3 },          [CCS_TOMOYO_MAC_FOR_SIGNAL]      = { "MAC_FOR_SIGNAL",      0, 3 },
70          [CCS_SAKURA_DENY_CONCEAL_MOUNT]  = { "DENY_CONCEAL_MOUNT",  0, 3 },          [CCS_SAKURA_DENY_CONCEAL_MOUNT]  = { "DENY_CONCEAL_MOUNT",  0, 3 },
71          [CCS_SAKURA_RESTRICT_CHROOT]     = { "RESTRICT_CHROOT",     0, 3 },          [CCS_SAKURA_RESTRICT_CHROOT]     = { "RESTRICT_CHROOT",     0, 3 },
72          [CCS_SAKURA_RESTRICT_MOUNT]      = { "RESTRICT_MOUNT",      0, 3 },          [CCS_SAKURA_RESTRICT_MOUNT]      = { "RESTRICT_MOUNT",      0, 3 },
73          [CCS_SAKURA_RESTRICT_UNMOUNT]    = { "RESTRICT_UNMOUNT",    0, 3 },          [CCS_SAKURA_RESTRICT_UNMOUNT]    = { "RESTRICT_UNMOUNT",    0, 3 },
74          [CCS_SAKURA_DENY_PIVOT_ROOT]     = { "DENY_PIVOT_ROOT",     0, 3 },          [CCS_SAKURA_RESTRICT_PIVOT_ROOT] = { "RESTRICT_PIVOT_ROOT", 0, 3 },
75          [CCS_SAKURA_RESTRICT_AUTOBIND]   = { "RESTRICT_AUTOBIND",   0, 1 },          [CCS_SAKURA_RESTRICT_AUTOBIND]   = { "RESTRICT_AUTOBIND",   0, 1 },
76          [CCS_TOMOYO_MAX_ACCEPT_ENTRY]    = { "MAX_ACCEPT_ENTRY",    MAX_ACCEPT_ENTRY, INT_MAX },          [CCS_TOMOYO_MAX_ACCEPT_ENTRY]    = { "MAX_ACCEPT_ENTRY",    MAX_ACCEPT_ENTRY, INT_MAX },
77          [CCS_TOMOYO_MAX_GRANT_LOG]       = { "MAX_GRANT_LOG",       MAX_GRANT_LOG, INT_MAX },          [CCS_TOMOYO_MAX_GRANT_LOG]       = { "MAX_GRANT_LOG",       MAX_GRANT_LOG, INT_MAX },
78          [CCS_TOMOYO_MAX_REJECT_LOG]      = { "MAX_REJECT_LOG",      MAX_REJECT_LOG, INT_MAX },          [CCS_TOMOYO_MAX_REJECT_LOG]      = { "MAX_REJECT_LOG",      MAX_REJECT_LOG, INT_MAX },
79          [CCS_TOMOYO_VERBOSE]             = { "TOMOYO_VERBOSE",      1, 1 },          [CCS_TOMOYO_VERBOSE]             = { "TOMOYO_VERBOSE",      1, 1 },
80          [CCS_ALLOW_ENFORCE_GRACE]        = { "ALLOW_ENFORCE_GRACE", 0, 1 },          [CCS_ALLOW_ENFORCE_GRACE]        = { "ALLOW_ENFORCE_GRACE", 0, 1 },
81            [CCS_SLEEP_PERIOD]               = { "SLEEP_PERIOD",        0, 3000 }, /* in 0.1 second */
82            [CCS_TOMOYO_ALT_EXEC]            = { "ALT_EXEC",            0, 0 }, /* Reserved for string. */
83  };  };
84    
85  typedef struct {  struct profile {
86          unsigned int value[CCS_MAX_CONTROL_INDEX];          unsigned int value[CCS_MAX_CONTROL_INDEX];
87          const struct path_info *comment;          const struct path_info *comment;
88  } PROFILE;          const struct path_info *alt_exec;
89    };
90    
91  static PROFILE *profile_ptr[MAX_PROFILES];  static struct profile *profile_ptr[MAX_PROFILES];
92    
93  /*************************  UTILITY FUNCTIONS  *************************/  /*************************  UTILITY FUNCTIONS  *************************/
94    
# Line 128  static void NormalizeLine(unsigned char Line 131  static void NormalizeLine(unsigned char
131   *  Check whether the given filename follows the naming rules.   *  Check whether the given filename follows the naming rules.
132   *  Returns nonzero if follows, zero otherwise.   *  Returns nonzero if follows, zero otherwise.
133   */   */
134  int 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)
135  {  {
136          int contains_pattern = 0;          int contains_pattern = 0;
137          char c, d, e;          char c, d, e;
# Line 160  int IsCorrectPath(const char *filename, Line 163  int IsCorrectPath(const char *filename,
163                          case 'X':   /* "\X" */                          case 'X':   /* "\X" */
164                          case 'a':   /* "\a" */                          case 'a':   /* "\a" */
165                          case 'A':   /* "\A" */                          case 'A':   /* "\A" */
166                            case '-':   /* "\-" */
167                                  if (pattern_type == -1) break; /* Must not contain pattern */                                  if (pattern_type == -1) break; /* Must not contain pattern */
168                                  contains_pattern = 1;                                  contains_pattern = 1;
169                                  continue;                                  continue;
# Line 193  int IsCorrectPath(const char *filename, Line 197  int IsCorrectPath(const char *filename,
197   *  Check whether the given domainname follows the naming rules.   *  Check whether the given domainname follows the naming rules.
198   *  Returns nonzero if follows, zero otherwise.   *  Returns nonzero if follows, zero otherwise.
199   */   */
200  int IsCorrectDomain(const unsigned char *domainname, const char *function)  bool IsCorrectDomain(const unsigned char *domainname, const char *function)
201  {  {
202          unsigned char c, d, e;          unsigned char c, d, e;
203          const char *org_domainname = domainname;          const char *org_domainname = domainname;
# Line 233  int IsCorrectDomain(const unsigned char Line 237  int IsCorrectDomain(const unsigned char
237          return 0;          return 0;
238  }  }
239    
240    bool IsDomainDef(const unsigned char *buffer)
241    {
242            /* while (*buffer && (*buffer <= ' ' || *buffer >= 127)) buffer++; */
243            return strncmp(buffer, ROOT_NAME, ROOT_NAME_LEN) == 0;
244    }
245    
246    struct domain_info *FindDomain(const char *domainname0)
247    {
248            struct domain_info *domain;
249            struct path_info domainname;
250            domainname.name = domainname0;
251            fill_path_info(&domainname);
252            list1_for_each_entry(domain, &domain_list, list) {
253                    if (!domain->is_deleted && !pathcmp(&domainname, domain->domainname)) return domain;
254            }
255            return NULL;
256    }
257    
258  static int PathDepth(const char *pathname)  static int PathDepth(const char *pathname)
259  {  {
260          int i = 0;          int i = 0;
# Line 280  void fill_path_info(struct path_info *pt Line 302  void fill_path_info(struct path_info *pt
302          ptr->depth = PathDepth(name);          ptr->depth = PathDepth(name);
303  }  }
304    
305  static int FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)  static int FileMatchesToPattern2(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)
306  {  {
307          while (filename < filename_end && pattern < pattern_end) {          while (filename < filename_end && pattern < pattern_end) {
308                  if (*pattern != '\\') {                  if (*pattern != '\\') {
# Line 332  static int FileMatchesToPattern(const ch Line 354  static int FileMatchesToPattern(const ch
354                                  {                                  {
355                                          int i;                                          int i;
356                                          for (i = 0; i <= filename_end - filename; i++) {                                          for (i = 0; i <= filename_end - filename; i++) {
357                                                  if (FileMatchesToPattern(filename + i, filename_end, pattern + 1, pattern_end)) return 1;                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
358                                                  if ((c = filename[i]) == '.' && *pattern == '@') break;                                                  if ((c = filename[i]) == '.' && *pattern == '@') break;
359                                                  if (c == '\\') {                                                  if (c == '\\') {
360                                                          if ((c = filename[i + 1]) == '\\') {                                                          if ((c = filename[i + 1]) == '\\') {
# Line 357  static int FileMatchesToPattern(const ch Line 379  static int FileMatchesToPattern(const ch
379                                                  while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;                                                  while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;
380                                          }                                          }
381                                          for (i = 1; i <= j; i++) {                                          for (i = 1; i <= j; i++) {
382                                                  if (FileMatchesToPattern(filename + i, filename_end, pattern + 1, pattern_end)) return 1;                                                  if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
383                                          }                                          }
384                                  }                                  }
385                                  return 0; /* Not matched or bad pattern. */                                  return 0; /* Not matched or bad pattern. */
# Line 370  static int FileMatchesToPattern(const ch Line 392  static int FileMatchesToPattern(const ch
392          return (filename == filename_end && pattern == pattern_end);          return (filename == filename_end && pattern == pattern_end);
393  }  }
394    
395    static int FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end)
396    {
397            const char *pattern_start = pattern;
398            int first = 1;
399            int result;
400            while (pattern < pattern_end - 1) {
401                    if (*pattern++ != '\\' || *pattern++ != '-') continue;
402                    result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern - 2);
403                    if (first) result = !result;
404                    if (result) return 0;
405                    first = 0;
406                    pattern_start = pattern;
407            }
408            result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern_end);
409            return first ? result : !result;
410    }
411    
412  /*  /*
413   *  Check whether the given pathname matches to the given pattern.   *  Check whether the given pathname matches to the given pattern.
414   *  Returns nonzero if matches, zero otherwise.   *  Returns nonzero if matches, zero otherwise.
# Line 386  static int FileMatchesToPattern(const ch Line 425  static int FileMatchesToPattern(const ch
425   *    \x     1 hexadecimal digit.   *    \x     1 hexadecimal digit.
426   *    \A     More than or equals to 1 alphabet character.   *    \A     More than or equals to 1 alphabet character.
427   *    \a     1 alphabet character.   *    \a     1 alphabet character.
428     *    \-     Subtraction operator.
429   */   */
430    
431  int PathMatchesToPattern(const struct path_info *pathname0, const struct path_info *pattern0)  int PathMatchesToPattern(const struct path_info *pathname0, const struct path_info *pattern0)
432  {  {
433          //if (!pathname || !pattern) return 0;          /* if (!pathname || !pattern) return 0; */
434          const char *pathname = pathname0->name, *pattern = pattern0->name;          const char *pathname = pathname0->name, *pattern = pattern0->name;
435          const int len = pattern0->const_len;          const int len = pattern0->const_len;
436          if (!pattern0->is_patterned) return !pathcmp(pathname0, pattern0);          if (!pattern0->is_patterned) return !pathcmp(pathname0, pattern0);
# Line 410  int PathMatchesToPattern(const struct pa Line 450  int PathMatchesToPattern(const struct pa
450  }  }
451    
452  /*  /*
453   *  Transactional printf() to IO_BUFFER structure.   *  Transactional printf() to struct io_buffer structure.
454   *  snprintf() will truncate, but io_printf() won't.   *  snprintf() will truncate, but io_printf() won't.
455   *  Returns zero on success, nonzero otherwise.   *  Returns zero on success, nonzero otherwise.
456   */   */
457  int io_printf(IO_BUFFER *head, const char *fmt, ...)  int io_printf(struct io_buffer *head, const char *fmt, ...)
458  {  {
459          va_list args;          va_list args;
460          int len, pos = head->read_avail, size = head->readbuf_size - pos;          int len, pos = head->read_avail, size = head->readbuf_size - pos;
# Line 433  int io_printf(IO_BUFFER *head, const cha Line 473  int io_printf(IO_BUFFER *head, const cha
473   */   */
474  const char *GetEXE(void)  const char *GetEXE(void)
475  {  {
476          if (current->mm) {          struct mm_struct *mm = current->mm;
477                  struct vm_area_struct *vma = current->mm->mmap;          struct vm_area_struct *vma;
478                  while (vma) {          const char *cp = NULL;
479                          if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {          if (!mm) return NULL;
480                                  return realpath_from_dentry(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt);          down_read(&mm->mmap_sem);
481                          }          for (vma = mm->mmap; vma; vma = vma->vm_next) {
482                          vma = vma->vm_next;                  if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
483                            cp = realpath_from_dentry(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt);
484                            break;
485                  }                  }
486          }          }
487          return NULL;          up_read(&mm->mmap_sem);
488            return cp;
489  }  }
490    
491  const char *GetMSG(const int is_enforce)  const char *GetMSG(const bool is_enforce)
492  {  {
493          if (is_enforce) return "ERROR"; else return "WARNING";          if (is_enforce) return "ERROR"; else return "WARNING";
494  }  }
495    
496    const char *GetAltExec(void)
497    {
498            const u8 profile = current->domain_info->profile;
499            const struct path_info *alt_exec = profile_ptr[profile] ? profile_ptr[profile]->alt_exec : NULL;
500            return alt_exec ? alt_exec->name : NULL;
501    }
502    
503  /*************************  DOMAIN POLICY HANDLER  *************************/  /*************************  DOMAIN POLICY HANDLER  *************************/
504    
505  /* Check whether the given access control is enabled. */  /* Check whether the given access control is enabled. */
506  unsigned int CheckCCSFlags(const unsigned int index)  unsigned int CheckCCSFlags(const u8 index)
507  {  {
508          const u8 profile = current->domain_info->profile;          const u8 profile = current->domain_info->profile;
509          return sbin_init_started && index < CCS_MAX_CONTROL_INDEX          return sbin_init_started && index < CCS_MAX_CONTROL_INDEX
# Line 463  unsigned int CheckCCSFlags(const unsigne Line 513  unsigned int CheckCCSFlags(const unsigne
513                  && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;                  && profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0;
514  }  }
515    
516  unsigned int TomoyoVerboseMode(void)  bool TomoyoVerboseMode(void)
 {  
         return CheckCCSFlags(CCS_TOMOYO_VERBOSE);  
 }  
   
 /* Check whether the given access control is enforce mode. */  
 unsigned int CheckCCSEnforce(const unsigned int index)  
517  {  {
518          return CheckCCSFlags(index) == 3;          return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0;
519  }  }
520    
521  /* Check whether the given access control is accept mode. */  bool CheckDomainQuota(struct domain_info * const domain)
 unsigned int CheckCCSAccept(const unsigned int index)  
522  {  {
523          return CheckCCSFlags(index) == 1;          unsigned int count = 0;
524            struct acl_info *ptr;
525            if (!domain) return 1;
526            list1_for_each_entry(ptr, &domain->acl_info_list, list) {
527                    if (!ptr->is_deleted) count++;
528            }
529            if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 1;
530            if (!domain->quota_warned) {
531                    domain->quota_warned = 1;
532                    printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);
533            }
534            return 0;
535  }  }
536    
537  static PROFILE *FindOrAssignNewProfile(const unsigned int profile)  static struct profile *FindOrAssignNewProfile(const unsigned int profile)
538  {  {
539          static DECLARE_MUTEX(profile_lock);          static DEFINE_MUTEX(profile_lock);
540          PROFILE *ptr = NULL;          struct profile *ptr = NULL;
541          down(&profile_lock);          mutex_lock(&profile_lock);
542          if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {          if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {
543                  if ((ptr = (PROFILE *) alloc_element(sizeof(PROFILE))) != NULL) {                  if ((ptr = alloc_element(sizeof(*ptr))) != NULL) {
544                          int i;                          int i;
545                          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;
546                          mb(); /* Instead of using spinlock. */                          mb(); /* Avoid out-of-order execution. */
547                          profile_ptr[profile] = ptr;                          profile_ptr[profile] = ptr;
548                  }                  }
549          }          }
550          up(&profile_lock);          mutex_unlock(&profile_lock);
551          return ptr;          return ptr;
552  }  }
553    
554  static int profile_loaded = 0;  /* #define ALT_EXEC */
555    
556  static int SetStatus(IO_BUFFER *head)  static int SetProfile(struct io_buffer *head)
557  {  {
558          char *data = head->write_buf;          char *data = head->write_buf;
559          unsigned int i, value;          unsigned int i, value;
560          char *cp;          char *cp;
561          PROFILE *profile;          struct profile *profile;
562          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
563          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
564          if (data != cp) {          if (data != cp) {
# Line 516  static int SetStatus(IO_BUFFER *head) Line 570  static int SetStatus(IO_BUFFER *head)
570          cp = strchr(data, '=');          cp = strchr(data, '=');
571          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
572          *cp = '\0';          *cp = '\0';
573          profile_loaded = 1;          UpdateCounter(CCS_UPDATES_COUNTER_PROFILE);
         UpdateCounter(CCS_UPDATES_COUNTER_STATUS);  
574          if (strcmp(data, ccs_control_array[CCS_PROFILE_COMMENT].keyword) == 0) {          if (strcmp(data, ccs_control_array[CCS_PROFILE_COMMENT].keyword) == 0) {
575                  profile->comment = SaveName(cp + 1);                  profile->comment = SaveName(cp + 1);
576                  return 0;                  return 0;
577          }          }
578    #ifdef ALT_EXEC
579    #ifdef CONFIG_TOMOYO
580            if (strcmp(data, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword) == 0) {
581                    cp++;
582                    if (*cp && !IsCorrectPath(cp, 1, -1, -1, __FUNCTION__)) cp = "";
583                    profile->alt_exec = SaveName(cp);
584                    return 0;
585            }
586    #endif
587    #endif
588          if (sscanf(cp + 1, "%u", &value) != 1) return -EINVAL;          if (sscanf(cp + 1, "%u", &value) != 1) return -EINVAL;
589  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY  #ifdef CONFIG_TOMOYO
590          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) {
591                  return SetCapabilityStatus(data + KEYWORD_MAC_FOR_CAPABILITY_LEN, value, i);                  return SetCapabilityStatus(data + KEYWORD_MAC_FOR_CAPABILITY_LEN, value, i);
592          }          }
# Line 537  static int SetStatus(IO_BUFFER *head) Line 600  static int SetStatus(IO_BUFFER *head)
600          return -EINVAL;          return -EINVAL;
601  }  }
602    
603  static int ReadStatus(IO_BUFFER *head)  static int ReadProfile(struct io_buffer *head)
604  {  {
605          if (!head->read_eof) {          if (!head->read_eof) {
606                  if (!isRoot()) return -EPERM;                  if (!isRoot()) return -EPERM;
# Line 545  static int ReadStatus(IO_BUFFER *head) Line 608  static int ReadStatus(IO_BUFFER *head)
608                          int step;                          int step;
609                          for (step = head->read_step; step < MAX_PROFILES * CCS_MAX_CONTROL_INDEX; step++) {                          for (step = head->read_step; step < MAX_PROFILES * CCS_MAX_CONTROL_INDEX; step++) {
610                                  const int i = step / CCS_MAX_CONTROL_INDEX, j = step % CCS_MAX_CONTROL_INDEX;                                  const int i = step / CCS_MAX_CONTROL_INDEX, j = step % CCS_MAX_CONTROL_INDEX;
611                                  const PROFILE *profile = profile_ptr[i];                                  const struct profile *profile = profile_ptr[i];
612                                  head->read_step = step;                                  head->read_step = step;
613                                  if (!profile) continue;                                  if (!profile) continue;
614                                  switch (j) {                                  switch (j) {
615                                  case -1: // Dummy                                  case -1: /* Dummy */
616  #ifndef CONFIG_TOMOYO_MAC_FOR_FILE  #ifndef CONFIG_SAKURA
                                 case CCS_TOMOYO_MAC_FOR_FILE:  
 #endif  
 #ifndef CONFIG_TOMOYO_MAC_FOR_ARGV0  
                                 case CCS_TOMOYO_MAC_FOR_ARGV0:  
 #endif  
 #ifndef CONFIG_TOMOYO_MAC_FOR_NETWORK  
                                 case CCS_TOMOYO_MAC_FOR_NETWORK:  
 #endif  
 #ifndef CONFIG_TOMOYO_MAC_FOR_SIGNAL  
                                 case CCS_TOMOYO_MAC_FOR_SIGNAL:  
 #endif  
 #ifndef CONFIG_SAKURA_DENY_CONCEAL_MOUNT  
617                                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:                                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_CHROOT  
618                                  case CCS_SAKURA_RESTRICT_CHROOT:                                  case CCS_SAKURA_RESTRICT_CHROOT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_MOUNT  
619                                  case CCS_SAKURA_RESTRICT_MOUNT:                                  case CCS_SAKURA_RESTRICT_MOUNT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_UNMOUNT  
620                                  case CCS_SAKURA_RESTRICT_UNMOUNT:                                  case CCS_SAKURA_RESTRICT_UNMOUNT:
621  #endif                                  case CCS_SAKURA_RESTRICT_PIVOT_ROOT:
 #ifndef CONFIG_SAKURA_DENY_PIVOT_ROOT  
                                 case CCS_SAKURA_DENY_PIVOT_ROOT:  
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_AUTOBIND  
622                                  case CCS_SAKURA_RESTRICT_AUTOBIND:                                  case CCS_SAKURA_RESTRICT_AUTOBIND:
623  #endif  #endif
624  #ifndef CONFIG_TOMOYO  #ifndef CONFIG_TOMOYO
625                                    case CCS_TOMOYO_MAC_FOR_FILE:
626                                    case CCS_TOMOYO_MAC_FOR_ARGV0:
627                                    case CCS_TOMOYO_MAC_FOR_ENV:
628                                    case CCS_TOMOYO_MAC_FOR_NETWORK:
629                                    case CCS_TOMOYO_MAC_FOR_SIGNAL:
630                                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:                                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:
631                                  case CCS_TOMOYO_MAX_GRANT_LOG:                                  case CCS_TOMOYO_MAX_GRANT_LOG:
632                                  case CCS_TOMOYO_MAX_REJECT_LOG:                                  case CCS_TOMOYO_MAX_REJECT_LOG:
633                                  case CCS_TOMOYO_VERBOSE:                                  case CCS_TOMOYO_VERBOSE:
634  #endif  #endif
635    #ifndef ALT_EXEC
636                                    case CCS_TOMOYO_ALT_EXEC:
637                                    case CCS_SLEEP_PERIOD:
638    #endif
639                                          continue;                                          continue;
640                                  }                                  }
641                                  if (j == CCS_PROFILE_COMMENT) {                                  if (j == CCS_PROFILE_COMMENT) {
642                                          if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_PROFILE_COMMENT].keyword, profile->comment ? profile->comment->name : "")) break;                                          if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_PROFILE_COMMENT].keyword, profile->comment ? profile->comment->name : "")) break;
643                                    } else if (j == CCS_TOMOYO_ALT_EXEC) {
644                                            const struct path_info *alt_exec = profile->alt_exec;
645                                            if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword, alt_exec ? alt_exec->name : "")) break;
646                                  } else {                                  } else {
647                                          if (io_printf(head, "%u-%s=%u\n", i, ccs_control_array[j].keyword, profile->value[j])) break;                                          if (io_printf(head, "%u-%s=%u\n", i, ccs_control_array[j].keyword, profile->value[j])) break;
648                                  }                                  }
# Line 600  static int ReadStatus(IO_BUFFER *head) Line 653  static int ReadStatus(IO_BUFFER *head)
653                          }                          }
654                  }                  }
655                  if (head->read_var2) {                  if (head->read_var2) {
656  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY  #ifdef CONFIG_TOMOYO
657                          if (ReadCapabilityStatus(head) == 0) head->read_eof = 1;                          if (ReadCapabilityStatus(head) == 0)
 #else  
                         head->read_eof = 1;  
658  #endif  #endif
659                                    head->read_eof = 1;
660                  }                  }
661          }          }
662          return 0;          return 0;
# Line 612  static int ReadStatus(IO_BUFFER *head) Line 664  static int ReadStatus(IO_BUFFER *head)
664    
665  /*************************  POLICY MANAGER HANDLER  *************************/  /*************************  POLICY MANAGER HANDLER  *************************/
666    
667  typedef struct policy_manager_entry {  struct policy_manager_entry {
668          struct policy_manager_entry *next;          struct list1_head list;
669          const struct path_info *manager;          const struct path_info *manager;
670          u8 is_domain;          bool is_domain;
671          u8 is_deleted;          bool is_deleted;
672  } POLICY_MANAGER_ENTRY;  };
673    
674  static POLICY_MANAGER_ENTRY *policy_manager_list = NULL;  static LIST1_HEAD(policy_manager_list);
675    
676  static int AddManagerEntry(const char *manager, u8 is_delete)  static int AddManagerEntry(const char *manager, const bool is_delete)
677  {  {
678          POLICY_MANAGER_ENTRY *new_entry, *ptr;          struct policy_manager_entry *new_entry, *ptr;
679          static DECLARE_MUTEX(lock);          static DEFINE_MUTEX(lock);
680          const struct path_info *saved_manager;          const struct path_info *saved_manager;
681          int error = -ENOMEM;          int error = -ENOMEM;
682          u8 is_domain = 0;          bool is_domain = 0;
683          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
684          if (IsDomainDef(manager)) {          if (IsDomainDef(manager)) {
685                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;
# Line 636  static int AddManagerEntry(const char *m Line 688  static int AddManagerEntry(const char *m
688                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;
689          }          }
690          if ((saved_manager = SaveName(manager)) == NULL) return -ENOMEM;          if ((saved_manager = SaveName(manager)) == NULL) return -ENOMEM;
691          down(&lock);          mutex_lock(&lock);
692          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
693                  if (ptr->manager == saved_manager) {                  if (ptr->manager == saved_manager) {
694                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
695                          error = 0;                          error = 0;
# Line 648  static int AddManagerEntry(const char *m Line 700  static int AddManagerEntry(const char *m
700                  error = -ENOENT;                  error = -ENOENT;
701                  goto out;                  goto out;
702          }          }
703          if ((new_entry = (POLICY_MANAGER_ENTRY *) alloc_element(sizeof(POLICY_MANAGER_ENTRY))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
704          new_entry->manager = saved_manager;          new_entry->manager = saved_manager;
705          new_entry->is_domain = is_domain;          new_entry->is_domain = is_domain;
706          mb(); /* Instead of using spinlock. */          list1_add_tail_mb(&new_entry->list, &policy_manager_list);
         if ((ptr = policy_manager_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 policy_manager_list = new_entry;  
         }  
707          error = 0;          error = 0;
708   out:   out:
709          up(&lock);          mutex_unlock(&lock);
710          if (!error) UpdateCounter(CCS_UPDATES_COUNTER_MANAGER);          if (!error) UpdateCounter(CCS_UPDATES_COUNTER_MANAGER);
711          return error;          return error;
712  }  }
713    
714  static int AddManagerPolicy(IO_BUFFER *head)  static int AddManagerPolicy(struct io_buffer *head)
715  {  {
716          const char *data = head->write_buf;          const char *data = head->write_buf;
717          int is_delete = 0;          bool is_delete = 0;
718          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
719          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
720                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
# Line 676  static int AddManagerPolicy(IO_BUFFER *h Line 723  static int AddManagerPolicy(IO_BUFFER *h
723          return AddManagerEntry(data, is_delete);          return AddManagerEntry(data, is_delete);
724  }  }
725    
726  static int ReadManagerPolicy(IO_BUFFER *head)  static int ReadManagerPolicy(struct io_buffer *head)
727  {  {
728          if (!head->read_eof) {          struct list1_head *pos;
729                  POLICY_MANAGER_ENTRY *ptr = (POLICY_MANAGER_ENTRY *) head->read_var2;          if (head->read_eof) return 0;
730                  if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
731                  if (!ptr) ptr = policy_manager_list;          list1_for_each_cookie(pos, head->read_var2, &policy_manager_list) {
732                  while (ptr) {                  struct policy_manager_entry *ptr;
733                          head->read_var2 = (void *) ptr;                  ptr = list1_entry(pos, struct policy_manager_entry, list);
734                          if (!ptr->is_deleted && io_printf(head, "%s\n", ptr->manager->name)) break;                  if (ptr->is_deleted) continue;
735                          ptr = ptr->next;                  if (io_printf(head, "%s\n", ptr->manager->name)) return 0;
                 }  
                 if (!ptr) head->read_eof = 1;  
736          }          }
737            head->read_eof = 1;
738          return 0;          return 0;
739  }  }
740    
741  /* Check whether the current process is a policy manager. */  /* Check whether the current process is a policy manager. */
742  static int IsPolicyManager(void)  static int IsPolicyManager(void)
743  {  {
744          POLICY_MANAGER_ENTRY *ptr;          struct policy_manager_entry *ptr;
745          const char *exe;          const char *exe;
746          const struct path_info *domainname = current->domain_info->domainname;          const struct path_info *domainname = current->domain_info->domainname;
747            bool found = 0;
748          if (!sbin_init_started) return 1;          if (!sbin_init_started) return 1;
749          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
750                  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 1;
751          }          }
752          if ((exe = GetEXE()) == NULL) return 0;          if ((exe = GetEXE()) == NULL) return 0;
753          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
754                  if (!ptr->is_deleted && !ptr->is_domain && !strcmp(exe, ptr->manager->name)) break;                  if (!ptr->is_deleted && !ptr->is_domain && !strcmp(exe, ptr->manager->name)) {
755                            found = 1;
756                            break;
757                    }
758          }          }
759          if (!ptr) { /* Reduce error messages. */          if (!found) { /* Reduce error messages. */
760                  static pid_t last_pid = 0;                  static pid_t last_pid = 0;
761                  const pid_t pid = current->pid;                  const pid_t pid = current->pid;
762                  if (last_pid != pid) {                  if (last_pid != pid) {
763                          printk("%s is not permitted to update policies.\n", exe);                          printk("%s ( %s ) is not permitted to update policies.\n", domainname->name, exe);
764                          last_pid = pid;                          last_pid = pid;
765                  }                  }
766          }          }
767          ccs_free(exe);          ccs_free(exe);
768          return ptr ? 1 : 0;          return found;
769  }  }
770    
771  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
772    
773  /*************************  DOMAIN POLICY HANDLER  *************************/  /*************************  DOMAIN POLICY HANDLER  *************************/
774    
775  static int AddDomainPolicy(IO_BUFFER *head)  static char *FindConditionPart(char *data)
776    {
777            char *cp = strstr(data, " if "), *cp2;
778            if (cp) {
779                    while ((cp2 = strstr(cp + 3, " if ")) != NULL) cp = cp2;
780                    *cp++ = '\0';
781            }
782            return cp;
783    }
784    
785    static int AddDomainPolicy(struct io_buffer *head)
786  {  {
787          char *data = head->write_buf;          char *data = head->write_buf;
788          struct domain_info *domain = head->write_var1;          struct domain_info *domain = head->write_var1;
789          int is_delete = 0, is_select = 0, is_undelete = 0;          bool is_delete = 0, is_select = 0, is_undelete = 0;
790          unsigned int profile;          unsigned int profile;
791            const struct condition_list *cond = NULL;
792            char *cp;      
793          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
794          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
795                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
# Line 755  static int AddDomainPolicy(IO_BUFFER *he Line 817  static int AddDomainPolicy(IO_BUFFER *he
817                  return 0;                  return 0;
818          }          }
819          if (!domain) return -EINVAL;          if (!domain) return -EINVAL;
820    
821          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1 && profile < MAX_PROFILES) {          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1 && profile < MAX_PROFILES) {
822                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;
823  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY                  return 0;
824          } else if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {          }
825                  return AddCapabilityPolicy(data + KEYWORD_ALLOW_CAPABILITY_LEN, domain, is_delete);          cp = FindConditionPart(data);
826  #endif          if (cp && (cond = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;
827  #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK          if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {
828                    return AddCapabilityPolicy(data + KEYWORD_ALLOW_CAPABILITY_LEN, domain, cond, is_delete);
829          } else if (strncmp(data, KEYWORD_ALLOW_NETWORK, KEYWORD_ALLOW_NETWORK_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_NETWORK, KEYWORD_ALLOW_NETWORK_LEN) == 0) {
830                  return AddNetworkPolicy(data + KEYWORD_ALLOW_NETWORK_LEN, domain, is_delete);                  return AddNetworkPolicy(data + KEYWORD_ALLOW_NETWORK_LEN, domain, cond, is_delete);
 #endif  
 #ifdef CONFIG_TOMOYO_MAC_FOR_SIGNAL  
831          } else if (strncmp(data, KEYWORD_ALLOW_SIGNAL, KEYWORD_ALLOW_SIGNAL_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_SIGNAL, KEYWORD_ALLOW_SIGNAL_LEN) == 0) {
832                  return AddSignalPolicy(data + KEYWORD_ALLOW_SIGNAL_LEN, domain, is_delete);                  return AddSignalPolicy(data + KEYWORD_ALLOW_SIGNAL_LEN, domain, cond, is_delete);
 #endif  
 #ifdef CONFIG_TOMOYO_MAC_FOR_ARGV0  
833          } else if (strncmp(data, KEYWORD_ALLOW_ARGV0, KEYWORD_ALLOW_ARGV0_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_ARGV0, KEYWORD_ALLOW_ARGV0_LEN) == 0) {
834                  return AddArgv0Policy(data + KEYWORD_ALLOW_ARGV0_LEN, domain, is_delete);                  return AddArgv0Policy(data + KEYWORD_ALLOW_ARGV0_LEN, domain, cond, is_delete);
835  #endif          } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {
836                    return AddEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, domain, cond, is_delete);
837          } else {          } else {
838  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                  return AddFilePolicy(data, domain, cond, is_delete);
                 return AddFilePolicy(data, domain, is_delete);  
 #endif  
839          }          }
840          return -EINVAL;          return -EINVAL;
841  }  }
842    
843  static int ReadDomainPolicy(IO_BUFFER *head)  static int ReadDomainPolicy(struct io_buffer *head)
844  {  {
845          if (!head->read_eof) {          struct list1_head *dpos;
846                  struct domain_info *domain = head->read_var1;          struct list1_head *apos;
847                  switch (head->read_step) {          if (head->read_eof) return 0;
848                  case 0: break;          if (head->read_step == 0) {
                 case 1: goto step1;  
                 case 2: goto step2;  
                 case 3: goto step3;  
                 default: return -EINVAL;  
                 }  
849                  if (!isRoot()) return -EPERM;                  if (!isRoot()) return -EPERM;
850                  for (domain = &KERNEL_DOMAIN; domain; domain = domain->next) {                  head->read_step = 1;
851            }
852            list1_for_each_cookie(dpos, head->read_var1, &domain_list) {
853                    struct domain_info *domain;
854                    domain = list1_entry(dpos, struct domain_info, list);
855                    if (head->read_step != 1) goto acl_loop;
856                    if (domain->is_deleted) continue;
857                    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;
858                    head->read_step = 2;
859            acl_loop: ;
860                    if (head->read_step == 3) goto tail_mark;
861                    list1_for_each_cookie(apos, head->read_var2, &domain->acl_info_list) {
862                          struct acl_info *ptr;                          struct acl_info *ptr;
863                          if (domain->is_deleted) continue;                          int pos;
864                          head->read_var1 = domain;                          u8 acl_type;
865                          head->read_var2 = NULL; head->read_step = 1;                          ptr = list1_entry(apos, struct acl_info, list);
866                  step1:                          if (ptr->is_deleted) continue;
867                          if (io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n%s\n", domain->domainname->name, domain->profile, domain->quota_warned ? "quota_exceeded\n" : "")) break;                          pos = head->read_avail;
868                          head->read_var2 = (void *) domain->first_acl_ptr; head->read_step = 2;                          acl_type = ptr->type;
869                  step2:                          if (acl_type == TYPE_SINGLE_PATH_ACL) {
870                          for (ptr = (struct acl_info *) head->read_var2; ptr; ptr = ptr->next) {                                  struct single_acl_record *ptr2 = container_of(ptr, struct single_acl_record, head);
871                                  const u8 acl_type = ptr->type;                                  const bool b = ptr2->u_is_group;
872                                  const int pos = head->read_avail;                                  const u16 perm = ptr2->perm;
873                                  head->read_var2 = (void *) ptr;                                  u8 bit = head->read_bit;
874                                  if (ptr->is_deleted) continue;                                  while (bit < MAX_SINGLE_PATH_OPERATION) {
875                                  if (0) {                                          if (perm & (1 << bit)) {
876  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                                                  pos = head->read_avail;
877                                  } else if (acl_type == TYPE_FILE_ACL) {                                                  if (io_printf(head, "allow_%s %s%s ", sp_operation2keyword(bit),
878                                          const unsigned char b = ptr->u.b[1];                                                                b ? "@" : "", b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)
879                                          if (io_printf(head, "%d %s%s", ptr->u.b[0], b ? "@" : "", b ? ((FILE_ACL_RECORD *) ptr)->u.group->group_name->name : ((FILE_ACL_RECORD *) ptr)->u.filename->name)                                                      || DumpCondition(head, ptr->cond)) {
880                                                  || DumpCondition(head, ptr->cond)) {                                                          head->read_bit = bit;
881                                                  head->read_avail = pos; break;                                                          head->read_avail = pos;
882                                          }                                                          return 0;
883  #endif                                                  }
 #ifdef CONFIG_TOMOYO_MAC_FOR_ARGV0  
                                 } else if (acl_type == TYPE_ARGV0_ACL) {  
                                         if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s", ((ARGV0_ACL_RECORD *) ptr)->filename->name, ((ARGV0_ACL_RECORD *) ptr)->argv0->name) ||  
                                                 DumpCondition(head, ptr->cond)) {  
                                                 head->read_avail = pos; break;  
                                         }  
 #endif  
 #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY  
                                 } else if (acl_type == TYPE_CAPABILITY_ACL) {  
                                         if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", capability2keyword(ptr->u.w)) ||  
                                                 DumpCondition(head, ptr->cond)) {  
                                                 head->read_avail = pos; break;  
884                                          }                                          }
885  #endif                                          bit++;
886  #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK                                  }
887                                  } else if (acl_type == TYPE_IP_NETWORK_ACL) {                                  head->read_bit = 0;
888                                          if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", network2keyword(ptr->u.b[0]))) break;                          } else if (acl_type == TYPE_DOUBLE_PATH_ACL) {
889                                          switch (ptr->u.b[1]) {                                  struct double_acl_record *ptr2 = container_of(ptr, struct double_acl_record, head);
890                                          case IP_RECORD_TYPE_ADDRESS_GROUP:                                  const bool b0 = ptr2->u1_is_group, b1 = ptr2->u2_is_group;
891                                                  if (io_printf(head, "@%s", ((IP_NETWORK_ACL_RECORD *) ptr)->u.group->group_name->name)) goto print_ip_record_out;                                  const u8 perm = ptr2->perm;
892                                                  break;                                  u8 bit = head->read_bit;
893                                          case IP_RECORD_TYPE_IPv4:                                  while (bit < MAX_DOUBLE_PATH_OPERATION) {
894                                                  {                                          if (perm & (1 << bit)) {
895                                                          const u32 min_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv4.min, max_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv4.max;                                                  pos = head->read_avail;
896                                                          if (io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address))) goto print_ip_record_out;                                                  if (io_printf(head, "allow_%s %s%s %s%s", dp_operation2keyword(bit),
897                                                          if (min_address != max_address && io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address))) goto print_ip_record_out;                                                                b0 ? "@" : "", b0 ? ptr2->u1.group1->group_name->name : ptr2->u1.filename1->name,
898                                                                  b1 ? "@" : "", b1 ? ptr2->u2.group2->group_name->name : ptr2->u2.filename2->name)
899                                                        || DumpCondition(head, ptr->cond)) {
900                                                            head->read_bit = bit;
901                                                            head->read_avail = pos;
902                                                            return 0;
903                                                  }                                                  }
904                                                  break;                                          }
905                                          case IP_RECORD_TYPE_IPv6:                                          bit++;
906                                                  {                                  }
907                                                          char buf[64];                                  head->read_bit = 0;
908                                                          const u16 *min_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv6.min, *max_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv6.max;                          } else if (acl_type == TYPE_ARGV0_ACL) {
909                                                          print_ipv6(buf, sizeof(buf), min_address);                                  struct argv0_acl_record *ptr2 = container_of(ptr, struct argv0_acl_record, head);
910                                                          if (io_printf(head, "%s", buf)) goto print_ip_record_out;                                  if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
911                                                          if (memcmp(min_address, max_address, 16)) {                                                ptr2->filename->name, ptr2->argv0->name)) goto print_acl_rollback;
912                                                                  print_ipv6(buf, sizeof(buf), max_address);                          } else if (acl_type == TYPE_ENV_ACL) {
913                                                                  if (io_printf(head, "-%s", buf)) goto print_ip_record_out;                                  struct env_acl_record *ptr2 = container_of(ptr, struct env_acl_record, head);
914                                                          }                                  if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr2->env->name)) goto print_acl_rollback;
915                            } else if (acl_type == TYPE_CAPABILITY_ACL) {
916                                    struct capability_acl_record *ptr2 = container_of(ptr, struct capability_acl_record, head);
917                                    const u32 capability = ptr2->capability;
918                                    u8 bit = head->read_bit;
919                                    while (bit < TOMOYO_MAX_CAPABILITY_INDEX) {
920                                            if (capability & (1 << bit)) {
921                                                    pos = head->read_avail;
922                                                    if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", cap_operation2keyword(bit)) ||
923                                                        DumpCondition(head, ptr->cond)) {
924                                                            head->read_bit = bit;
925                                                            head->read_avail = pos;
926                                                            return 0;
927                                                  }                                                  }
                                                 break;  
928                                          }                                          }
929                                            bit++;
930                                    }
931                                    head->read_bit = 0;
932                            } else if (acl_type == TYPE_IP_NETWORK_ACL) {
933                                    struct ip_network_acl_record *ptr2 = container_of(ptr, struct ip_network_acl_record, head);
934                                    if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", net_operation2keyword(ptr2->operation_type))) goto print_acl_rollback;
935                                    switch (ptr2->record_type) {
936                                    case IP_RECORD_TYPE_ADDRESS_GROUP:
937                                            if (io_printf(head, "@%s", ptr2->u.group->group_name->name)) goto print_acl_rollback;
938                                            break;
939                                    case IP_RECORD_TYPE_IPv4:
940                                          {                                          {
941                                                  const u16 min_port = ((IP_NETWORK_ACL_RECORD *) ptr)->min_port, max_port = ((IP_NETWORK_ACL_RECORD *) ptr)->max_port;                                                  const u32 min_address = ptr2->u.ipv4.min, max_address = ptr2->u.ipv4.max;
942                                                  if (io_printf(head, " %u", min_port)) goto print_ip_record_out;                                                  if (io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address))) goto print_acl_rollback;
943                                                  if (min_port != max_port && io_printf(head, "-%u", max_port)) goto print_ip_record_out;                                                  if (min_address != max_address && io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address))) goto print_acl_rollback;
                                         }  
                                         if (DumpCondition(head, ptr->cond)) {  
                                         print_ip_record_out: ;  
                                         head->read_avail = pos; break;  
944                                          }                                          }
945  #endif                                          break;
946  #ifdef CONFIG_TOMOYO_MAC_FOR_SIGNAL                                  case IP_RECORD_TYPE_IPv6:
947                                  } else if (acl_type == TYPE_SIGNAL_ACL) {                                          {
948                                          if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr->u.w, ((SIGNAL_ACL_RECORD *) ptr)->domainname->name) ||                                                  char buf[64];
949                                                  DumpCondition(head, ptr->cond)) {                                                  const struct in6_addr *min_address = ptr2->u.ipv6.min, *max_address = ptr2->u.ipv6.max;
950                                                  head->read_avail = pos; break;                                                  print_ipv6(buf, sizeof(buf), min_address);
951                                          }                                                  if (io_printf(head, "%s", buf)) goto print_acl_rollback;
952  #endif                                                  if (min_address != max_address) {
953  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                                                          print_ipv6(buf, sizeof(buf), max_address);
954                                  } else {                                                          if (io_printf(head, "-%s", buf)) goto print_acl_rollback;
                                         const char *keyword = acltype2keyword(acl_type);  
                                         if (keyword) {  
                                                 if (acltype2paths(acl_type) == 2) {  
                                                         const u8 b0 = ptr->u.b[0], b1 = ptr->u.b[1];  
                                                         if (io_printf(head, "allow_%s %s%s %s%s", keyword, b0 ? "@" : "", b0 ? ((DOUBLE_ACL_RECORD *) ptr)->u1.group1->group_name->name : ((DOUBLE_ACL_RECORD *) ptr)->u1.filename1->name, b1 ? "@" : "", b1 ? ((DOUBLE_ACL_RECORD *) ptr)->u2.group2->group_name->name : ((DOUBLE_ACL_RECORD *) ptr)->u2.filename2->name)  
                                                                 || DumpCondition(head, ptr->cond)) {  
                                                                 head->read_avail = pos; break;  
                                                         }  
                                                 } else {  
                                                         const u8 b = ptr->u.b[0];  
                                                         if (io_printf(head, "allow_%s %s%s", keyword, b ? "@" : "", b ? ((SINGLE_ACL_RECORD *) ptr)->u.group->group_name->name : ((SINGLE_ACL_RECORD *) ptr)->u.filename->name)  
                                                                 || DumpCondition(head, ptr->cond)) {  
                                                                 head->read_avail = pos; break;  
                                                         }  
955                                                  }                                                  }
956                                          }                                          }
957  #endif                                          break;
958                                  }                                  }
959                                    {
960                                            const u16 min_port = ptr2->min_port, max_port = ptr2->max_port;
961                                            if (io_printf(head, " %u", min_port)) goto print_acl_rollback;
962                                            if (min_port != max_port && io_printf(head, "-%u", max_port)) goto print_acl_rollback;
963                                    }
964                            } else if (acl_type == TYPE_SIGNAL_ACL) {
965                                    struct signal_acl_record *ptr2 = container_of(ptr, struct signal_acl_record, head);
966                                    if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr2->sig, ptr2->domainname->name)) goto print_acl_rollback;
967                            } else {
968                                    BUG();
969                            }
970                            if (acl_type != TYPE_SINGLE_PATH_ACL && acl_type != TYPE_DOUBLE_PATH_ACL && acl_type != TYPE_CAPABILITY_ACL && DumpCondition(head, ptr->cond)) {
971                            print_acl_rollback: ;
972                            head->read_avail = pos;
973                            return 0;
974                          }                          }
                         if (ptr) break;  
                         head->read_var2 = NULL; head->read_step = 3;  
                 step3:  
                         if (io_printf(head, "\n")) break;  
975                  }                  }
976                  if (!domain) head->read_eof = 1;                  head->read_step = 3;
977            tail_mark: ;
978                    if (io_printf(head, "\n")) return 0;
979                    head->read_step = 1;
980          }          }
981            head->read_eof = 1;
982          return 0;          return 0;
983  }  }
984    
985  static int ReadDomainProfile(IO_BUFFER *head)  #endif
986    
987    static int UpdateDomainProfile(struct io_buffer *head)
988  {  {
989          if (!head->read_eof) {          char *data = head->write_buf;
990            char *cp = strchr(data, ' ');
991            struct domain_info *domain;
992            unsigned int profile;
993            if (!isRoot()) return -EPERM;
994            if (!cp) return -EINVAL;
995            *cp = '\0';
996            domain = FindDomain(cp + 1);
997            profile = simple_strtoul(data, NULL, 10);
998            if (domain && profile < MAX_PROFILES && (profile_ptr[profile] || !sbin_init_started)) domain->profile = (u8) profile;
999            UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
1000            return 0;
1001    }
1002    
1003    static int ReadDomainProfile(struct io_buffer *head)
1004    {
1005            struct list1_head *pos;
1006            if (head->read_eof) return 0;
1007            if (!isRoot()) return -EPERM;
1008            list1_for_each_cookie(pos, head->read_var1, &domain_list) {
1009                  struct domain_info *domain;                  struct domain_info *domain;
1010                  if (head->read_step == 0) {                  domain = list1_entry(pos, struct domain_info, list);
1011                          head->read_var1 = &KERNEL_DOMAIN;                  if (domain->is_deleted) continue;
1012                          head->read_step = 1;                  if (io_printf(head, "%u %s\n", domain->profile, domain->domainname->name)) return 0;
                 }  
                 if (!isRoot()) return -EPERM;  
                 for (domain = head->read_var1; domain; domain = domain->next) {  
                         if (domain->is_deleted) continue;  
                         head->read_var1 = domain;  
                         if (io_printf(head, "%u %s\n", domain->profile, domain->domainname->name)) break;  
                 }  
                 if (!domain) head->read_eof = 1;  
1013          }          }
1014            head->read_eof = 1;
1015          return 0;          return 0;
1016  }  }
1017    
1018  static int WritePID(IO_BUFFER *head)  static int WritePID(struct io_buffer *head)
1019  {  {
1020          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);
1021          head->read_eof = 0;          head->read_eof = 0;
1022          return 0;          return 0;
1023  }  }
1024    
1025  static int ReadPID(IO_BUFFER *head)  static int ReadPID(struct io_buffer *head)
1026  {  {
1027          if (head->read_avail == 0 && !head->read_eof) {          if (head->read_avail == 0 && !head->read_eof) {
1028                  const int pid = head->read_step;                  const int pid = head->read_step;
# Line 949  static int ReadPID(IO_BUFFER *head) Line 1040  static int ReadPID(IO_BUFFER *head)
1040          return 0;          return 0;
1041  }  }
1042    
 static int UpdateDomainProfile(IO_BUFFER *head)  
 {  
         char *data = head->write_buf;  
         char *cp = strchr(data, ' ');  
         struct domain_info *domain;  
         unsigned int profile;  
         if (!isRoot()) return -EPERM;  
         if (!cp) return -EINVAL;  
         *cp = '\0';  
         domain = FindDomain(cp + 1);  
         profile = simple_strtoul(data, NULL, 10);  
         if (domain && profile < MAX_PROFILES && (profile_ptr[profile] || !sbin_init_started)) domain->profile = (u8) profile;  
         UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
         return 0;  
 }  
   
 #endif  
   
1043  /*************************  EXCEPTION POLICY HANDLER  *************************/  /*************************  EXCEPTION POLICY HANDLER  *************************/
1044    
1045  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1046    
1047  static int AddExceptionPolicy(IO_BUFFER *head)  static int AddExceptionPolicy(struct io_buffer *head)
1048  {  {
1049          char *data = head->write_buf;          char *data = head->write_buf;
1050          int is_delete = 0;          bool is_delete = 0;
1051          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
1052          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
1053          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
# Line 986  static int AddExceptionPolicy(IO_BUFFER Line 1059  static int AddExceptionPolicy(IO_BUFFER
1059          } else if (strncmp(data, KEYWORD_NO_KEEP_DOMAIN, KEYWORD_NO_KEEP_DOMAIN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_NO_KEEP_DOMAIN, KEYWORD_NO_KEEP_DOMAIN_LEN) == 0) {
1060                  return AddDomainKeeperPolicy(data + KEYWORD_NO_KEEP_DOMAIN_LEN, 1, is_delete);                  return AddDomainKeeperPolicy(data + KEYWORD_NO_KEEP_DOMAIN_LEN, 1, is_delete);
1061          } else if (strncmp(data, KEYWORD_INITIALIZE_DOMAIN, KEYWORD_INITIALIZE_DOMAIN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_INITIALIZE_DOMAIN, KEYWORD_INITIALIZE_DOMAIN_LEN) == 0) {
1062                  return AddDomainInitializerPolicy(data + KEYWORD_INITIALIZE_DOMAIN_LEN, 0, is_delete, 0);                  return AddDomainInitializerPolicy(data + KEYWORD_INITIALIZE_DOMAIN_LEN, 0, is_delete);
1063          } else if (strncmp(data, KEYWORD_NO_INITIALIZE_DOMAIN, KEYWORD_NO_INITIALIZE_DOMAIN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_NO_INITIALIZE_DOMAIN, KEYWORD_NO_INITIALIZE_DOMAIN_LEN) == 0) {
1064                  return AddDomainInitializerPolicy(data + KEYWORD_NO_INITIALIZE_DOMAIN_LEN, 1, is_delete, 0);                  return AddDomainInitializerPolicy(data + KEYWORD_NO_INITIALIZE_DOMAIN_LEN, 1, is_delete);
         } else if (strncmp(data, KEYWORD_INITIALIZER, KEYWORD_INITIALIZER_LEN) == 0) {  
                 return AddDomainInitializerPolicy(data + KEYWORD_INITIALIZER_LEN, 0, is_delete, 1);  
         } else if (strncmp(data, KEYWORD_NO_INITIALIZER, KEYWORD_NO_INITIALIZER_LEN) == 0) {  
                 return AddDomainInitializerPolicy(data + KEYWORD_NO_INITIALIZER_LEN, 1, is_delete, 1);  
1065          } else if (strncmp(data, KEYWORD_ALIAS, KEYWORD_ALIAS_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALIAS, KEYWORD_ALIAS_LEN) == 0) {
1066                  return AddAliasPolicy(data + KEYWORD_ALIAS_LEN, is_delete);                  return AddAliasPolicy(data + KEYWORD_ALIAS_LEN, is_delete);
1067          } else if (strncmp(data, KEYWORD_AGGREGATOR, KEYWORD_AGGREGATOR_LEN) == 0) {          } else if (strncmp(data, KEYWORD_AGGREGATOR, KEYWORD_AGGREGATOR_LEN) == 0) {
1068                  return AddAggregatorPolicy(data + KEYWORD_AGGREGATOR_LEN, is_delete);                  return AddAggregatorPolicy(data + KEYWORD_AGGREGATOR_LEN, is_delete);
 #ifdef CONFIG_TOMOYO_MAC_FOR_FILE  
1069          } else if (strncmp(data, KEYWORD_ALLOW_READ, KEYWORD_ALLOW_READ_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_READ, KEYWORD_ALLOW_READ_LEN) == 0) {
1070                  return AddGloballyReadablePolicy(data + KEYWORD_ALLOW_READ_LEN, is_delete);                  return AddGloballyReadablePolicy(data + KEYWORD_ALLOW_READ_LEN, is_delete);
1071            } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {
1072                    return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete);
1073          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {
1074                  return AddPatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);                  return AddFilePatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);
1075          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {
1076                  return AddGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);                  return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);
1077          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {
1078                  return AddNoRewritePolicy(data + KEYWORD_DENY_REWRITE_LEN, is_delete);                  return AddNoRewritePolicy(data + KEYWORD_DENY_REWRITE_LEN, is_delete);
 #endif  
 #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK  
1079          } else if (strncmp(data, KEYWORD_ADDRESS_GROUP, KEYWORD_ADDRESS_GROUP_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ADDRESS_GROUP, KEYWORD_ADDRESS_GROUP_LEN) == 0) {
1080                  return AddAddressGroupPolicy(data + KEYWORD_ADDRESS_GROUP_LEN, is_delete);                  return AddAddressGroupPolicy(data + KEYWORD_ADDRESS_GROUP_LEN, is_delete);
 #endif  
1081          }          }
1082          return -EINVAL;          return -EINVAL;
1083  }  }
1084    
1085  static int ReadExceptionPolicy(IO_BUFFER *head)  static int ReadExceptionPolicy(struct io_buffer *head)
1086  {  {
1087          if (!head->read_eof) {          if (!head->read_eof) {
1088                  switch (head->read_step) {                  switch (head->read_step) {
# Line 1026  static int ReadExceptionPolicy(IO_BUFFER Line 1093  static int ReadExceptionPolicy(IO_BUFFER
1093                          if (ReadDomainKeeperPolicy(head)) break;                          if (ReadDomainKeeperPolicy(head)) break;
1094                          head->read_var2 = NULL; head->read_step = 2;                          head->read_var2 = NULL; head->read_step = 2;
1095                  case 2:                  case 2:
 #ifdef CONFIG_TOMOYO_MAC_FOR_FILE  
1096                          if (ReadGloballyReadablePolicy(head)) break;                          if (ReadGloballyReadablePolicy(head)) break;
 #endif  
1097                          head->read_var2 = NULL; head->read_step = 3;                          head->read_var2 = NULL; head->read_step = 3;
1098                  case 3:                  case 3:
1099                          if (ReadDomainInitializerPolicy(head)) break;                          if (ReadGloballyUsableEnvPolicy(head)) break;
1100                          head->read_var2 = NULL; head->read_step = 4;                          head->read_var2 = NULL; head->read_step = 4;
1101                  case 4:                  case 4:
1102                          if (ReadAliasPolicy(head)) break;                          if (ReadDomainInitializerPolicy(head)) break;
1103                          head->read_var2 = NULL; head->read_step = 5;                          head->read_var2 = NULL; head->read_step = 5;
1104                  case 5:                  case 5:
1105                          if (ReadAggregatorPolicy(head)) break;                          if (ReadAliasPolicy(head)) break;
1106                          head->read_var2 = NULL; head->read_step = 6;                          head->read_var2 = NULL; head->read_step = 6;
1107                  case 6:                  case 6:
1108  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadAggregatorPolicy(head)) break;
                         if (ReadPatternPolicy(head)) break;  
 #endif  
1109                          head->read_var2 = NULL; head->read_step = 7;                          head->read_var2 = NULL; head->read_step = 7;
1110                  case 7:                  case 7:
1111  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadFilePatternPolicy(head)) break;
                         if (ReadNoRewritePolicy(head)) break;  
 #endif  
1112                          head->read_var2 = NULL; head->read_step = 8;                          head->read_var2 = NULL; head->read_step = 8;
1113                  case 8:                  case 8:
1114  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadNoRewritePolicy(head)) break;
                         if (ReadGroupPolicy(head)) break;  
 #endif  
1115                          head->read_var2 = NULL; head->read_step = 9;                          head->read_var2 = NULL; head->read_step = 9;
1116                  case 9:                  case 9:
1117  #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK                          if (ReadPathGroupPolicy(head)) break;
1118                            head->read_var1 = head->read_var2 = NULL; head->read_step = 10;
1119                    case 10:
1120                          if (ReadAddressGroupPolicy(head)) break;                          if (ReadAddressGroupPolicy(head)) break;
 #endif  
1121                          head->read_eof = 1;                          head->read_eof = 1;
1122                          break;                          break;
1123                  default:                  default:
# Line 1073  static int ReadExceptionPolicy(IO_BUFFER Line 1133  static int ReadExceptionPolicy(IO_BUFFER
1133    
1134  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1135    
1136  static int AddSystemPolicy(IO_BUFFER *head)  static int AddSystemPolicy(struct io_buffer *head)
1137  {  {
1138          char *data = head->write_buf;          char *data = head->write_buf;
1139          int is_delete = 0;          bool is_delete = 0;
1140          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
1141          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
1142          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
1143                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
1144                  is_delete = 1;                  is_delete = 1;
1145          }          }
 #ifdef CONFIG_SAKURA_RESTRICT_MOUNT  
1146          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)
1147                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);
 #endif  
 #ifdef CONFIG_SAKURA_RESTRICT_UNMOUNT  
1148          if (strncmp(data, KEYWORD_DENY_UNMOUNT, KEYWORD_DENY_UNMOUNT_LEN) == 0)          if (strncmp(data, KEYWORD_DENY_UNMOUNT, KEYWORD_DENY_UNMOUNT_LEN) == 0)
1149                  return AddNoUmountPolicy(data + KEYWORD_DENY_UNMOUNT_LEN, is_delete);                  return AddNoUmountPolicy(data + KEYWORD_DENY_UNMOUNT_LEN, is_delete);
 #endif  
 #ifdef CONFIG_SAKURA_RESTRICT_CHROOT  
1150          if (strncmp(data, KEYWORD_ALLOW_CHROOT, KEYWORD_ALLOW_CHROOT_LEN) == 0)          if (strncmp(data, KEYWORD_ALLOW_CHROOT, KEYWORD_ALLOW_CHROOT_LEN) == 0)
1151                  return AddChrootPolicy(data + KEYWORD_ALLOW_CHROOT_LEN, is_delete);                  return AddChrootPolicy(data + KEYWORD_ALLOW_CHROOT_LEN, is_delete);
1152  #endif          if (strncmp(data, KEYWORD_ALLOW_PIVOT_ROOT, KEYWORD_ALLOW_PIVOT_ROOT_LEN) == 0)
1153  #ifdef CONFIG_SAKURA_RESTRICT_AUTOBIND                  return AddPivotRootPolicy(data + KEYWORD_ALLOW_PIVOT_ROOT_LEN, is_delete);
1154          if (strncmp(data, KEYWORD_DENY_AUTOBIND, KEYWORD_DENY_AUTOBIND_LEN) == 0)          if (strncmp(data, KEYWORD_DENY_AUTOBIND, KEYWORD_DENY_AUTOBIND_LEN) == 0)
1155                  return AddReservedPortPolicy(data + KEYWORD_DENY_AUTOBIND_LEN, is_delete);                  return AddReservedPortPolicy(data + KEYWORD_DENY_AUTOBIND_LEN, is_delete);
 #endif  
1156          return -EINVAL;          return -EINVAL;
1157  }  }
1158    
1159  static int ReadSystemPolicy(IO_BUFFER *head)  static int ReadSystemPolicy(struct io_buffer *head)
1160  {  {
1161          if (!head->read_eof) {          if (!head->read_eof) {
1162                  switch (head->read_step) {                  switch (head->read_step) {
# Line 1110  static int ReadSystemPolicy(IO_BUFFER *h Line 1164  static int ReadSystemPolicy(IO_BUFFER *h
1164                          if (!isRoot()) return -EPERM;                          if (!isRoot()) return -EPERM;
1165                          head->read_var2 = NULL; head->read_step = 1;                          head->read_var2 = NULL; head->read_step = 1;
1166                  case 1:                  case 1:
 #ifdef CONFIG_SAKURA_RESTRICT_MOUNT  
1167                          if (ReadMountPolicy(head)) break;                          if (ReadMountPolicy(head)) break;
 #endif  
1168                          head->read_var2 = NULL; head->read_step = 2;                          head->read_var2 = NULL; head->read_step = 2;
1169                  case 2:                  case 2:
 #ifdef CONFIG_SAKURA_RESTRICT_UNMOUNT  
1170                          if (ReadNoUmountPolicy(head)) break;                          if (ReadNoUmountPolicy(head)) break;
 #endif  
1171                          head->read_var2 = NULL; head->read_step = 3;                          head->read_var2 = NULL; head->read_step = 3;
1172                  case 3:                  case 3:
 #ifdef CONFIG_SAKURA_RESTRICT_CHROOT  
1173                          if (ReadChrootPolicy(head)) break;                          if (ReadChrootPolicy(head)) break;
 #endif  
1174                          head->read_var2 = NULL; head->read_step = 4;                          head->read_var2 = NULL; head->read_step = 4;
1175                  case 4:                  case 4:
1176  #ifdef CONFIG_SAKURA_RESTRICT_AUTOBIND                          if (ReadPivotRootPolicy(head)) break;
1177                            head->read_var2 = NULL; head->read_step = 5;
1178                    case 5:
1179                          if (ReadReservedPortPolicy(head)) break;                          if (ReadReservedPortPolicy(head)) break;
 #endif  
1180                          head->read_eof = 1;                          head->read_eof = 1;
1181                          break;                          break;
1182                  default:                  default:
# Line 1141  static int ReadSystemPolicy(IO_BUFFER *h Line 1190  static int ReadSystemPolicy(IO_BUFFER *h
1190    
1191  /*************************  POLICY LOADER  *************************/  /*************************  POLICY LOADER  *************************/
1192    
1193    static int profile_loaded = 0;
1194    
1195  static const char *ccs_loader = NULL;  static const char *ccs_loader = NULL;
1196    
1197  static int __init CCS_loader_Setup(char *str)  static int __init CCS_loader_Setup(char *str)
# Line 1169  void CCS_LoadPolicy(const char *filename Line 1220  void CCS_LoadPolicy(const char *filename
1220           */           */
1221          {          {
1222                  struct nameidata nd;                  struct nameidata nd;
1223                  if (!ccs_loader) ccs_loader = "/.init";                  if (!ccs_loader) ccs_loader = "/sbin/ccs-init";
1224                  if (path_lookup(ccs_loader, lookup_flags, &nd)) {                  if (path_lookup(ccs_loader, lookup_flags, &nd)) {
1225                          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);
1226                          return;                          return;
1227                  }                  }
1228                  path_release(&nd);                  path_release(&nd);
1229          }          }
1230                    if (!profile_loaded) {
1231                    char *argv[2], *envp[3];
1232                    printk("Calling %s to load policy. Please wait.\n", ccs_loader);
1233                    argv[0] = (char *) ccs_loader;
1234                    argv[1] = NULL;
1235                    envp[0] = "HOME=/";
1236                    envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
1237                    envp[2] = NULL;
1238    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1239                    call_usermodehelper(argv[0], argv, envp, 1);
1240    #else
1241                    call_usermodehelper(argv[0], argv, envp);
1242    #endif
1243                    while (!profile_loaded) {
1244                            set_current_state(TASK_INTERRUPTIBLE);
1245                            schedule_timeout(HZ / 10);
1246                    }
1247            }
1248  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1249          printk("SAKURA: 1.3.3-pre5   2007/03/09\n");          printk("SAKURA: 1.5.3-pre   2008/01/02\n");
1250  #endif  #endif
1251  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1252          printk("TOMOYO: 1.3.3-pre5   2007/03/09\n");          printk("TOMOYO: 1.5.3-pre   2008/01/02\n");
1253  #endif  #endif
1254          if (!profile_loaded) panic("No profiles loaded. Run policy loader using 'init=' option.\n");          //if (!profile_loaded) panic("No profiles loaded. Run policy loader using 'init=' option.\n");
1255          printk("Mandatory Access Control activated.\n");          printk("Mandatory Access Control activated.\n");
1256          sbin_init_started = 1;          sbin_init_started = 1;
1257          ccs_log_level = KERN_WARNING;          ccs_log_level = KERN_WARNING;
1258          { /* Check all profiles currently assigned to domains are defined. */          { /* Check all profiles currently assigned to domains are defined. */
1259                  struct domain_info *domain;                  struct domain_info *domain;
1260                  for (domain = &KERNEL_DOMAIN; domain; domain = domain->next) {                  list1_for_each_entry(domain, &domain_list, list) {
1261                          const u8 profile = domain->profile;                          const u8 profile = domain->profile;
1262                          if (!profile_ptr[profile]) panic("Profile %u (used by '%s') not defined.\n", profile, domain->domainname->name);                          if (!profile_ptr[profile]) panic("Profile %u (used by '%s') not defined.\n", profile, domain->domainname->name);
1263                  }                  }
1264          }          }
1265  }  }
# Line 1203  static DECLARE_WAIT_QUEUE_HEAD(query_wai Line 1271  static DECLARE_WAIT_QUEUE_HEAD(query_wai
1271    
1272  static spinlock_t query_lock = SPIN_LOCK_UNLOCKED;  static spinlock_t query_lock = SPIN_LOCK_UNLOCKED;
1273    
1274  typedef struct query_entry {  struct query_entry {
1275          struct list_head list;          struct list_head list;
1276          char *query;          char *query;
1277          int query_len;          int query_len;
1278          unsigned int serial;          unsigned int serial;
1279          int timer;          int timer;
1280          int answer;          int answer;
1281  } QUERY_ENTRY;  };
1282    
1283  static LIST_HEAD(query_list);  static LIST_HEAD(query_list);
1284  static atomic_t queryd_watcher = ATOMIC_INIT(0);  static atomic_t queryd_watcher = ATOMIC_INIT(0);
# Line 1221  int CheckSupervisor(const char *fmt, ... Line 1289  int CheckSupervisor(const char *fmt, ...
1289          int error = -EPERM;          int error = -EPERM;
1290          int pos, len;          int pos, len;
1291          static unsigned int serial = 0;          static unsigned int serial = 0;
1292          QUERY_ENTRY *query_entry;          struct query_entry *query_entry;
1293          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE)) return -EPERM;          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) {
1294          if (!atomic_read(&queryd_watcher)) return -EPERM;  #ifdef ALT_EXEC
1295                    if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) {
1296                            int i;
1297                            for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) {
1298                                    set_current_state(TASK_INTERRUPTIBLE);
1299                                    schedule_timeout(HZ / 10);
1300                            }
1301                    }
1302    #endif
1303                    return -EPERM;
1304            }
1305          va_start(args, fmt);          va_start(args, fmt);
1306          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
1307          va_end(args);          va_end(args);
1308          if ((query_entry = (QUERY_ENTRY *) ccs_alloc(sizeof(QUERY_ENTRY))) == NULL ||          if ((query_entry = ccs_alloc(sizeof(*query_entry))) == NULL ||
1309                  (query_entry->query = ccs_alloc(len)) == NULL) goto out;                  (query_entry->query = ccs_alloc(len)) == NULL) goto out;
1310          INIT_LIST_HEAD(&query_entry->list);          INIT_LIST_HEAD(&query_entry->list);
1311          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
# Line 1296  static int PollQuery(struct file *file, Line 1374  static int PollQuery(struct file *file,
1374          return 0;          return 0;
1375  }  }
1376    
1377  static int ReadQuery(IO_BUFFER *head)  static int ReadQuery(struct io_buffer *head)
1378  {  {
1379          struct list_head *tmp;          struct list_head *tmp;
1380          int pos = 0, len = 0;          int pos = 0, len = 0;
# Line 1309  static int ReadQuery(IO_BUFFER *head) Line 1387  static int ReadQuery(IO_BUFFER *head)
1387          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1388          spin_lock(&query_lock);          spin_lock(&query_lock);
1389          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1390                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1391                  if (pos++ == head->read_step) {                  if (pos++ == head->read_step) {
1392                          len = ptr->query_len;                          len = ptr->query_len;
1393                          break;                          break;
# Line 1321  static int ReadQuery(IO_BUFFER *head) Line 1399  static int ReadQuery(IO_BUFFER *head)
1399                  head->read_step = 0;                  head->read_step = 0;
1400                  return 0;                  return 0;
1401          }          }
1402          if ((buf = (char *) ccs_alloc(len)) != NULL) {          if ((buf = ccs_alloc(len)) != NULL) {
1403                  pos = 0;                  pos = 0;
1404                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
1405                  spin_lock(&query_lock);                  spin_lock(&query_lock);
1406                  list_for_each(tmp, &query_list) {                  list_for_each(tmp, &query_list) {
1407                          QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                          struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1408                          if (pos++ == head->read_step) {                          if (pos++ == head->read_step) {
1409                                  /* Some query can be skiipped since query_list can change, but I don't care. */                                  /* Some query can be skiipped since query_list can change, but I don't care. */
1410                                  if (len == ptr->query_len) memmove(buf, ptr->query, len);                                  if (len == ptr->query_len) memmove(buf, ptr->query, len);
# Line 1346  static int ReadQuery(IO_BUFFER *head) Line 1424  static int ReadQuery(IO_BUFFER *head)
1424          return 0;          return 0;
1425  }  }
1426    
1427  static int WriteAnswer(IO_BUFFER *head)  static int WriteAnswer(struct io_buffer *head)
1428  {  {
1429          char *data = head->write_buf;          char *data = head->write_buf;
1430          struct list_head *tmp;          struct list_head *tmp;
# Line 1354  static int WriteAnswer(IO_BUFFER *head) Line 1432  static int WriteAnswer(IO_BUFFER *head)
1432          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1433          spin_lock(&query_lock);          spin_lock(&query_lock);
1434          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1435                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1436                  ptr->timer = 0;                  ptr->timer = 0;
1437          }          }
1438          spin_unlock(&query_lock);          spin_unlock(&query_lock);
# Line 1363  static int WriteAnswer(IO_BUFFER *head) Line 1441  static int WriteAnswer(IO_BUFFER *head)
1441          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1442          spin_lock(&query_lock);          spin_lock(&query_lock);
1443          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1444                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1445                  if (ptr->serial != serial) continue;                  if (ptr->serial != serial) continue;
1446                  if (!ptr->answer) ptr->answer = answer;                  if (!ptr->answer) ptr->answer = answer;
1447                  break;                  break;
# Line 1388  void UpdateCounter(const unsigned char i Line 1466  void UpdateCounter(const unsigned char i
1466          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
1467  }  }
1468    
1469  static int ReadUpdatesCounter(IO_BUFFER *head)  static int ReadUpdatesCounter(struct io_buffer *head)
1470  {  {
1471          if (!head->read_eof) {          if (!head->read_eof) {
1472                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];
# Line 1399  static int ReadUpdatesCounter(IO_BUFFER Line 1477  static int ReadUpdatesCounter(IO_BUFFER
1477                  spin_unlock(&updates_counter_lock);                  spin_unlock(&updates_counter_lock);
1478                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
1479                  io_printf(head,                  io_printf(head,
1480                                    "/proc/ccs/policy/system_policy:    %10u\n"                                    "/proc/ccs/system_policy:    %10u\n"
1481                                    "/proc/ccs/policy/domain_policy:    %10u\n"                                    "/proc/ccs/domain_policy:    %10u\n"
1482                                    "/proc/ccs/policy/exception_policy: %10u\n"                                    "/proc/ccs/exception_policy: %10u\n"
1483                                    "/proc/ccs/status:                  %10u\n"                                    "/proc/ccs/profile:          %10u\n"
1484                                    "/proc/ccs/policy/query:            %10u\n"                                    "/proc/ccs/query:            %10u\n"
1485                                    "/proc/ccs/policy/manager:          %10u\n"                                    "/proc/ccs/manager:          %10u\n"
1486                                    "/proc/ccs/info/grant_log:          %10u\n"                                    "/proc/ccs/grant_log:        %10u\n"
1487                                    "/proc/ccs/info/reject_log:         %10u\n",                                    "/proc/ccs/reject_log:       %10u\n",
1488                                    counter[CCS_UPDATES_COUNTER_SYSTEM_POLICY],                                    counter[CCS_UPDATES_COUNTER_SYSTEM_POLICY],
1489                                    counter[CCS_UPDATES_COUNTER_DOMAIN_POLICY],                                    counter[CCS_UPDATES_COUNTER_DOMAIN_POLICY],
1490                                    counter[CCS_UPDATES_COUNTER_EXCEPTION_POLICY],                                    counter[CCS_UPDATES_COUNTER_EXCEPTION_POLICY],
1491                                    counter[CCS_UPDATES_COUNTER_STATUS],                                    counter[CCS_UPDATES_COUNTER_PROFILE],
1492                                    counter[CCS_UPDATES_COUNTER_QUERY],                                    counter[CCS_UPDATES_COUNTER_QUERY],
1493                                    counter[CCS_UPDATES_COUNTER_MANAGER],                                    counter[CCS_UPDATES_COUNTER_MANAGER],
1494                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],
# Line 1420  static int ReadUpdatesCounter(IO_BUFFER Line 1498  static int ReadUpdatesCounter(IO_BUFFER
1498          return 0;          return 0;
1499  }  }
1500    
1501  static int ReadMemoryCounter(IO_BUFFER *head)  static int ReadVersion(struct io_buffer *head)
1502    {
1503            if (!head->read_eof) {
1504                    if (io_printf(head, "1.5.3-pre") == 0) head->read_eof = 1;
1505            }
1506            return 0;
1507    }
1508    
1509    static int ReadMemoryCounter(struct io_buffer *head)
1510  {  {
1511          if (!head->read_eof) {          if (!head->read_eof) {
1512                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();
# Line 1429  static int ReadMemoryCounter(IO_BUFFER * Line 1515  static int ReadMemoryCounter(IO_BUFFER *
1515          return 0;          return 0;
1516  }  }
1517    
1518  int CCS_OpenControl(const int type, struct file *file)  static int ReadSelfDomain(struct io_buffer *head)
1519  {  {
1520          IO_BUFFER *head = (IO_BUFFER *) ccs_alloc(sizeof(IO_BUFFER));          if (!head->read_eof) {
1521                    io_printf(head, "%s", current->domain_info->domainname->name);
1522                    head->read_eof = 1;
1523            }
1524            return 0;
1525    }
1526    
1527    int CCS_OpenControl(const u8 type, struct file *file)
1528    {
1529            struct io_buffer *head = ccs_alloc(sizeof(*head));
1530          if (!head) return -ENOMEM;          if (!head) return -ENOMEM;
1531          init_MUTEX(&head->read_sem);          mutex_init(&head->read_sem);
1532          init_MUTEX(&head->write_sem);          mutex_init(&head->write_sem);
1533          switch (type) {          switch (type) {
1534    #ifdef CONFIG_SAKURA
1535            case CCS_SYSTEMPOLICY:
1536                    head->write = AddSystemPolicy;
1537                    head->read = ReadSystemPolicy;
1538                    break;
1539    #endif
1540  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1541          case CCS_POLICY_DOMAINPOLICY:          case CCS_DOMAINPOLICY:
1542                  head->write = AddDomainPolicy;                  head->write = AddDomainPolicy;
1543                  head->read = ReadDomainPolicy;                  head->read = ReadDomainPolicy;
1544                  break;                  break;
1545          case CCS_POLICY_EXCEPTIONPOLICY:          case CCS_EXCEPTIONPOLICY:
1546                  head->write = AddExceptionPolicy;                  head->write = AddExceptionPolicy;
1547                  head->read = ReadExceptionPolicy;                  head->read = ReadExceptionPolicy;
1548                  break;                  break;
1549          case CCS_POLICY_DOMAIN_STATUS:          case CCS_GRANTLOG:
                 head->write = UpdateDomainProfile;  
                 head->read = ReadDomainProfile;  
                 break;  
         case CCS_INFO_PROCESS_STATUS:  
                 head->write = WritePID;  
                 head->read = ReadPID;  
                 break;  
 #ifdef CONFIG_TOMOYO_AUDIT  
         case CCS_INFO_GRANTLOG:  
1550                  head->poll = PollGrantLog;                  head->poll = PollGrantLog;
1551                  head->read = ReadGrantLog;                  head->read = ReadGrantLog;
1552                  break;                  break;
1553          case CCS_INFO_REJECTLOG:          case CCS_REJECTLOG:
1554                  head->poll = PollRejectLog;                  head->poll = PollRejectLog;
1555                  head->read = ReadRejectLog;                  head->read = ReadRejectLog;
1556                  break;                  break;
1557  #endif  #endif
1558          case CCS_INFO_SELFDOMAIN:          case CCS_SELFDOMAIN:
1559                  head->read = ReadSelfDomain;                  head->read = ReadSelfDomain;
1560                  break;                  break;
1561  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE          case CCS_DOMAIN_STATUS:
1562          case CCS_INFO_MAPPING:                  head->write = UpdateDomainProfile;
1563                  if (!sbin_init_started) head->write = SetPermissionMapping;                  head->read = ReadDomainProfile;
                 head->read = ReadPermissionMapping;  
1564                  break;                  break;
1565  #endif          case CCS_PROCESS_STATUS:
1566  #endif                  head->write = WritePID;
1567  #ifdef CONFIG_SAKURA                  head->read = ReadPID;
         case CCS_POLICY_SYSTEMPOLICY:  
                 head->write = AddSystemPolicy;  
                 head->read = ReadSystemPolicy;  
1568                  break;                  break;
1569  #endif          case CCS_VERSION:
1570          case CCS_INFO_MEMINFO:                  head->read = ReadVersion;
1571                    head->readbuf_size = 128;
1572                    break;
1573            case CCS_MEMINFO:
1574                  head->read = ReadMemoryCounter;                  head->read = ReadMemoryCounter;
1575                  head->readbuf_size = 128;                  head->readbuf_size = 128;
1576                  break;                  break;
1577          case CCS_STATUS:          case CCS_PROFILE:
1578                  head->write = SetStatus;                  head->write = SetProfile;
1579                  head->read = ReadStatus;                  head->read = ReadProfile;
1580                  break;                  break;
1581          case CCS_POLICY_QUERY:          case CCS_QUERY:
1582                  head->poll = PollQuery;                  head->poll = PollQuery;
1583                  head->write = WriteAnswer;                  head->write = WriteAnswer;
1584                  head->read = ReadQuery;                  head->read = ReadQuery;
1585                  break;                  break;
1586          case CCS_POLICY_MANAGER:          case CCS_MANAGER:
1587                  head->write = AddManagerPolicy;                  head->write = AddManagerPolicy;
1588                  head->read = ReadManagerPolicy;                  head->read = ReadManagerPolicy;
1589                  break;                  break;
1590          case CCS_INFO_UPDATESCOUNTER:          case CCS_UPDATESCOUNTER:
1591                  head->read = ReadUpdatesCounter;                  head->read = ReadUpdatesCounter;
1592                  break;                  break;
1593          }          }
1594          if (type != CCS_INFO_GRANTLOG && type != CCS_INFO_REJECTLOG && type != CCS_POLICY_QUERY) {          if (type != CCS_GRANTLOG && type != CCS_REJECTLOG && type != CCS_QUERY) {
1595                  if (!head->readbuf_size) head->readbuf_size = PAGE_SIZE * 2;                  if (!head->readbuf_size) head->readbuf_size = PAGE_SIZE * 2;
1596                  if ((head->read_buf = ccs_alloc(head->readbuf_size)) == NULL) {                  if ((head->read_buf = ccs_alloc(head->readbuf_size)) == NULL) {
1597                          ccs_free(head);                          ccs_free(head);
# Line 1516  int CCS_OpenControl(const int type, stru Line 1607  int CCS_OpenControl(const int type, stru
1607                  }                  }
1608          }          }
1609          file->private_data = head;          file->private_data = head;
1610          if (type == CCS_INFO_SELFDOMAIN) CCS_ReadControl(file, NULL, 0);          if (type == CCS_SELFDOMAIN) CCS_ReadControl(file, NULL, 0);
1611          else if (head->write == WriteAnswer) atomic_inc(&queryd_watcher);          else if (head->write == WriteAnswer) atomic_inc(&queryd_watcher);
1612          return 0;          return 0;
1613  }  }
1614    
1615  static int CopyToUser(IO_BUFFER *head, char __user * buffer, int buffer_len)  static int CopyToUser(struct io_buffer *head, char __user * buffer, int buffer_len)
1616  {  {
1617          int len = head->read_avail;          int len = head->read_avail;
1618          char *cp = head->read_buf;          char *cp = head->read_buf;
# Line 1536  static int CopyToUser(IO_BUFFER *head, c Line 1627  static int CopyToUser(IO_BUFFER *head, c
1627    
1628  int CCS_PollControl(struct file *file, poll_table *wait)  int CCS_PollControl(struct file *file, poll_table *wait)
1629  {  {
1630          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1631          if (!head->poll) return -ENOSYS;          if (!head->poll) return -ENOSYS;
1632          return head->poll(file, wait);          return head->poll(file, wait);
1633  }  }
# Line 1544  int CCS_PollControl(struct file *file, p Line 1635  int CCS_PollControl(struct file *file, p
1635  int CCS_ReadControl(struct file *file, char __user *buffer, const int buffer_len)  int CCS_ReadControl(struct file *file, char __user *buffer, const int buffer_len)
1636  {  {
1637          int len = 0;          int len = 0;
1638          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1639          if (!head->read) return -ENOSYS;          if (!head->read) return -ENOSYS;
1640          if (!access_ok(VERIFY_WRITE, buffer, buffer_len)) return -EFAULT;          if (!access_ok(VERIFY_WRITE, buffer, buffer_len)) return -EFAULT;
1641          if (down_interruptible(&head->read_sem)) return -EINTR;          if (mutex_lock_interruptible(&head->read_sem)) return -EINTR;
1642          len = head->read(head);          len = head->read(head);
1643          if (len >= 0) len = CopyToUser(head, buffer, buffer_len);          if (len >= 0) len = CopyToUser(head, buffer, buffer_len);
1644          up(&head->read_sem);          mutex_unlock(&head->read_sem);
1645          return len;          return len;
1646  }  }
1647    
1648  int CCS_WriteControl(struct file *file, const char __user *buffer, const int buffer_len)  int CCS_WriteControl(struct file *file, const char __user *buffer, const int buffer_len)
1649  {  {
1650          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1651          int error = buffer_len;          int error = buffer_len;
1652          int avail_len = buffer_len;          int avail_len = buffer_len;
1653          char *cp0 = head->write_buf;          char *cp0 = head->write_buf;
# Line 1566  int CCS_WriteControl(struct file *file, Line 1657  int CCS_WriteControl(struct file *file,
1657          if (head->write != WritePID && !IsPolicyManager()) {          if (head->write != WritePID && !IsPolicyManager()) {
1658                  return -EPERM; /* Forbid updating policies for non manager programs. */                  return -EPERM; /* Forbid updating policies for non manager programs. */
1659          }          }
1660          if (down_interruptible(&head->write_sem)) return -EINTR;          if (mutex_lock_interruptible(&head->write_sem)) return -EINTR;
1661          while (avail_len > 0) {          while (avail_len > 0) {
1662                  char c;                  char c;
1663                  if (head->write_avail >= head->writebuf_size - 1) {                  if (head->write_avail >= head->writebuf_size - 1) {
# Line 1584  int CCS_WriteControl(struct file *file, Line 1675  int CCS_WriteControl(struct file *file,
1675                  NormalizeLine(cp0);                  NormalizeLine(cp0);
1676                  head->write(head);                  head->write(head);
1677          }          }
1678          up(&head->write_sem);          mutex_unlock(&head->write_sem);
1679          return error;          return error;
1680  }  }
1681    
1682    
1683  int CCS_CloseControl(struct file *file)  int CCS_CloseControl(struct file *file)
1684  {  {
1685          IO_BUFFER *head = file->private_data;          struct io_buffer *head = file->private_data;
1686          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);
1687            else if (head->read == ReadMemoryCounter) profile_loaded = 1;
1688          ccs_free(head->read_buf); head->read_buf = NULL;          ccs_free(head->read_buf); head->read_buf = NULL;
1689          ccs_free(head->write_buf); head->write_buf = NULL;          ccs_free(head->write_buf); head->write_buf = NULL;
1690          ccs_free(head); head = NULL;          ccs_free(head); head = NULL;
1691          file->private_data = NULL;          file->private_data = NULL;
1692          return 0;          return 0;
1693  }  }
   
 EXPORT_SYMBOL(CheckCCSFlags);  
 EXPORT_SYMBOL(CheckCCSEnforce);  
 EXPORT_SYMBOL(CheckCCSAccept);  

Legend:
Removed from v.121  
changed lines
  Added in v.853

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