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

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 813 by kumaneko, Tue Dec 18 05:35:28 2007 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2007  NTT DATA CORPORATION   * Copyright (C) 2005-2007  NTT DATA CORPORATION
7   *   *
8   * Version: 1.3.2   2007/02/14   * Version: 1.5.3-pre   2007/12/18
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 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 int start_type, const int pattern_type, const int 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. */
# 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)
517  {  {
518          return CheckCCSFlags(CCS_TOMOYO_VERBOSE);          return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0;
519  }  }
520    
521  /* Check whether the given access control is enforce mode. */  /* Check whether the given access control is enforce mode. */
522  unsigned int CheckCCSEnforce(const unsigned int index)  bool CheckCCSEnforce(const unsigned int index)
523  {  {
524          return CheckCCSFlags(index) == 3;          return CheckCCSFlags(index) == 3;
525  }  }
526    
527  /* Check whether the given access control is accept mode. */  bool CheckDomainQuota(struct domain_info * const domain)
528  unsigned int CheckCCSAccept(const unsigned int index)  {
529            unsigned int count = 0;
530            struct acl_info *ptr;
531            if (!domain) return 1;
532            list1_for_each_entry(ptr, &domain->acl_info_list, list) {
533                    if (!ptr->is_deleted) count++;
534            }
535            if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 1;
536            if (!domain->quota_warned) {
537                    domain->quota_warned = 1;
538                    printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);
539            }
540            return 0;
541    }
542    
543    /* Check whether the given access control is learning mode. */
544    bool CheckCCSAccept(const unsigned int index, struct domain_info * const domain)
545  {  {
546          return CheckCCSFlags(index) == 1;          if (CheckCCSFlags(index) != 1) return 0;
547            return CheckDomainQuota(domain);
548  }  }
549    
550  static PROFILE *FindOrAssignNewProfile(const unsigned int profile)  static struct profile *FindOrAssignNewProfile(const unsigned int profile)
551  {  {
552          static DECLARE_MUTEX(profile_lock);          static DEFINE_MUTEX(profile_lock);
553          PROFILE *ptr = NULL;          struct profile *ptr = NULL;
554          down(&profile_lock);          mutex_lock(&profile_lock);
555          if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {          if (profile < MAX_PROFILES && (ptr = profile_ptr[profile]) == NULL) {
556                  if ((ptr = (PROFILE *) alloc_element(sizeof(PROFILE))) != NULL) {                  if ((ptr = alloc_element(sizeof(*ptr))) != NULL) {
557                          int i;                          int i;
558                          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;
559                          mb(); /* Instead of using spinlock. */                          mb(); /* Avoid out-of-order execution. */
560                          profile_ptr[profile] = ptr;                          profile_ptr[profile] = ptr;
561                  }                  }
562          }          }
563          up(&profile_lock);          mutex_unlock(&profile_lock);
564          return ptr;          return ptr;
565  }  }
566    
567  static int profile_loaded = 0;  /* #define ALT_EXEC */
568    
569  static int SetStatus(IO_BUFFER *head)  static int SetProfile(struct io_buffer *head)
570  {  {
571          char *data = head->write_buf;          char *data = head->write_buf;
572          unsigned int i, value;          unsigned int i, value;
573          char *cp;          char *cp;
574          PROFILE *profile;          struct profile *profile;
575          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
576          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
577          if (data != cp) {          if (data != cp) {
# Line 516  static int SetStatus(IO_BUFFER *head) Line 583  static int SetStatus(IO_BUFFER *head)
583          cp = strchr(data, '=');          cp = strchr(data, '=');
584          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
585          *cp = '\0';          *cp = '\0';
586          profile_loaded = 1;          UpdateCounter(CCS_UPDATES_COUNTER_PROFILE);
         UpdateCounter(CCS_UPDATES_COUNTER_STATUS);  
587          if (strcmp(data, ccs_control_array[CCS_PROFILE_COMMENT].keyword) == 0) {          if (strcmp(data, ccs_control_array[CCS_PROFILE_COMMENT].keyword) == 0) {
588                  profile->comment = SaveName(cp + 1);                  profile->comment = SaveName(cp + 1);
589                  return 0;                  return 0;
590          }          }
591    #ifdef ALT_EXEC
592    #ifdef CONFIG_TOMOYO
593            if (strcmp(data, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword) == 0) {
594                    cp++;
595                    if (*cp && !IsCorrectPath(cp, 1, -1, -1, __FUNCTION__)) cp = "";
596                    profile->alt_exec = SaveName(cp);
597                    return 0;
598            }
599    #endif
600    #endif
601          if (sscanf(cp + 1, "%u", &value) != 1) return -EINVAL;          if (sscanf(cp + 1, "%u", &value) != 1) return -EINVAL;
602  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY  #ifdef CONFIG_TOMOYO
603          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) {
604                  return SetCapabilityStatus(data + KEYWORD_MAC_FOR_CAPABILITY_LEN, value, i);                  return SetCapabilityStatus(data + KEYWORD_MAC_FOR_CAPABILITY_LEN, value, i);
605          }          }
# Line 537  static int SetStatus(IO_BUFFER *head) Line 613  static int SetStatus(IO_BUFFER *head)
613          return -EINVAL;          return -EINVAL;
614  }  }
615    
616  static int ReadStatus(IO_BUFFER *head)  static int ReadProfile(struct io_buffer *head)
617  {  {
618          if (!head->read_eof) {          if (!head->read_eof) {
619                  if (!isRoot()) return -EPERM;                  if (!isRoot()) return -EPERM;
# Line 545  static int ReadStatus(IO_BUFFER *head) Line 621  static int ReadStatus(IO_BUFFER *head)
621                          int step;                          int step;
622                          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++) {
623                                  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;
624                                  const PROFILE *profile = profile_ptr[i];                                  const struct profile *profile = profile_ptr[i];
625                                  head->read_step = step;                                  head->read_step = step;
626                                  if (!profile) continue;                                  if (!profile) continue;
627                                  switch (j) {                                  switch (j) {
628                                  case -1: // Dummy                                  case -1: /* Dummy */
629  #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  
630                                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:                                  case CCS_SAKURA_DENY_CONCEAL_MOUNT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_CHROOT  
631                                  case CCS_SAKURA_RESTRICT_CHROOT:                                  case CCS_SAKURA_RESTRICT_CHROOT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_MOUNT  
632                                  case CCS_SAKURA_RESTRICT_MOUNT:                                  case CCS_SAKURA_RESTRICT_MOUNT:
 #endif  
 #ifndef CONFIG_SAKURA_RESTRICT_UNMOUNT  
633                                  case CCS_SAKURA_RESTRICT_UNMOUNT:                                  case CCS_SAKURA_RESTRICT_UNMOUNT:
634  #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  
635                                  case CCS_SAKURA_RESTRICT_AUTOBIND:                                  case CCS_SAKURA_RESTRICT_AUTOBIND:
636  #endif  #endif
637  #ifndef CONFIG_TOMOYO  #ifndef CONFIG_TOMOYO
638                                    case CCS_TOMOYO_MAC_FOR_FILE:
639                                    case CCS_TOMOYO_MAC_FOR_ARGV0:
640                                    case CCS_TOMOYO_MAC_FOR_ENV:
641                                    case CCS_TOMOYO_MAC_FOR_NETWORK:
642                                    case CCS_TOMOYO_MAC_FOR_SIGNAL:
643                                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:                                  case CCS_TOMOYO_MAX_ACCEPT_ENTRY:
644                                  case CCS_TOMOYO_MAX_GRANT_LOG:                                  case CCS_TOMOYO_MAX_GRANT_LOG:
645                                  case CCS_TOMOYO_MAX_REJECT_LOG:                                  case CCS_TOMOYO_MAX_REJECT_LOG:
646                                  case CCS_TOMOYO_VERBOSE:                                  case CCS_TOMOYO_VERBOSE:
647  #endif  #endif
648    #ifndef ALT_EXEC
649                                    case CCS_TOMOYO_ALT_EXEC:
650                                    case CCS_SLEEP_PERIOD:
651    #endif
652                                          continue;                                          continue;
653                                  }                                  }
654                                  if (j == CCS_PROFILE_COMMENT) {                                  if (j == CCS_PROFILE_COMMENT) {
655                                          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;
656                                    } else if (j == CCS_TOMOYO_ALT_EXEC) {
657                                            const struct path_info *alt_exec = profile->alt_exec;
658                                            if (io_printf(head, "%u-%s=%s\n", i, ccs_control_array[CCS_TOMOYO_ALT_EXEC].keyword, alt_exec ? alt_exec->name : "")) break;
659                                  } else {                                  } else {
660                                          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;
661                                  }                                  }
# Line 600  static int ReadStatus(IO_BUFFER *head) Line 666  static int ReadStatus(IO_BUFFER *head)
666                          }                          }
667                  }                  }
668                  if (head->read_var2) {                  if (head->read_var2) {
669  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY  #ifdef CONFIG_TOMOYO
670                          if (ReadCapabilityStatus(head) == 0) head->read_eof = 1;                          if (ReadCapabilityStatus(head) == 0)
 #else  
                         head->read_eof = 1;  
671  #endif  #endif
672                                    head->read_eof = 1;
673                  }                  }
674          }          }
675          return 0;          return 0;
# Line 612  static int ReadStatus(IO_BUFFER *head) Line 677  static int ReadStatus(IO_BUFFER *head)
677    
678  /*************************  POLICY MANAGER HANDLER  *************************/  /*************************  POLICY MANAGER HANDLER  *************************/
679    
680  typedef struct policy_manager_entry {  struct policy_manager_entry {
681          struct policy_manager_entry *next;          struct list1_head list;
682          const struct path_info *manager;          const struct path_info *manager;
683          u8 is_domain;          bool is_domain;
684          u8 is_deleted;          bool is_deleted;
685  } POLICY_MANAGER_ENTRY;  };
686    
687  static POLICY_MANAGER_ENTRY *policy_manager_list = NULL;  static LIST1_HEAD(policy_manager_list);
688    
689  static int AddManagerEntry(const char *manager, u8 is_delete)  static int AddManagerEntry(const char *manager, const bool is_delete)
690  {  {
691          POLICY_MANAGER_ENTRY *new_entry, *ptr;          struct policy_manager_entry *new_entry, *ptr;
692          static DECLARE_MUTEX(lock);          static DEFINE_MUTEX(lock);
693          const struct path_info *saved_manager;          const struct path_info *saved_manager;
694          int error = -ENOMEM;          int error = -ENOMEM;
695          u8 is_domain = 0;          bool is_domain = 0;
696          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
697          if (IsDomainDef(manager)) {          if (IsDomainDef(manager)) {
698                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectDomain(manager, __FUNCTION__)) return -EINVAL;
# Line 636  static int AddManagerEntry(const char *m Line 701  static int AddManagerEntry(const char *m
701                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;                  if (!IsCorrectPath(manager, 1, -1, -1, __FUNCTION__)) return -EINVAL;
702          }          }
703          if ((saved_manager = SaveName(manager)) == NULL) return -ENOMEM;          if ((saved_manager = SaveName(manager)) == NULL) return -ENOMEM;
704          down(&lock);          mutex_lock(&lock);
705          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
706                  if (ptr->manager == saved_manager) {                  if (ptr->manager == saved_manager) {
707                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
708                          error = 0;                          error = 0;
# Line 648  static int AddManagerEntry(const char *m Line 713  static int AddManagerEntry(const char *m
713                  error = -ENOENT;                  error = -ENOENT;
714                  goto out;                  goto out;
715          }          }
716          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;
717          new_entry->manager = saved_manager;          new_entry->manager = saved_manager;
718          new_entry->is_domain = is_domain;          new_entry->is_domain = is_domain;
719          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;  
         }  
720          error = 0;          error = 0;
721   out:   out:
722          up(&lock);          mutex_unlock(&lock);
723          if (!error) UpdateCounter(CCS_UPDATES_COUNTER_MANAGER);          if (!error) UpdateCounter(CCS_UPDATES_COUNTER_MANAGER);
724          return error;          return error;
725  }  }
726    
727  static int AddManagerPolicy(IO_BUFFER *head)  static int AddManagerPolicy(struct io_buffer *head)
728  {  {
729          const char *data = head->write_buf;          const char *data = head->write_buf;
730          int is_delete = 0;          bool is_delete = 0;
731          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
732          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
733                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
# Line 676  static int AddManagerPolicy(IO_BUFFER *h Line 736  static int AddManagerPolicy(IO_BUFFER *h
736          return AddManagerEntry(data, is_delete);          return AddManagerEntry(data, is_delete);
737  }  }
738    
739  static int ReadManagerPolicy(IO_BUFFER *head)  static int ReadManagerPolicy(struct io_buffer *head)
740  {  {
741          if (!head->read_eof) {          struct list1_head *pos;
742                  POLICY_MANAGER_ENTRY *ptr = (POLICY_MANAGER_ENTRY *) head->read_var2;          if (head->read_eof) return 0;
743                  if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
744                  if (!ptr) ptr = policy_manager_list;          list1_for_each_cookie(pos, head->read_var2, &policy_manager_list) {
745                  while (ptr) {                  struct policy_manager_entry *ptr;
746                          head->read_var2 = (void *) ptr;                  ptr = list1_entry(pos, struct policy_manager_entry, list);
747                          if (!ptr->is_deleted && io_printf(head, "%s\n", ptr->manager->name)) break;                  if (ptr->is_deleted) continue;
748                          ptr = ptr->next;                  if (io_printf(head, "%s\n", ptr->manager->name)) return 0;
                 }  
                 if (!ptr) head->read_eof = 1;  
749          }          }
750            head->read_eof = 1;
751          return 0;          return 0;
752  }  }
753    
754  /* Check whether the current process is a policy manager. */  /* Check whether the current process is a policy manager. */
755  static int IsPolicyManager(void)  static int IsPolicyManager(void)
756  {  {
757          POLICY_MANAGER_ENTRY *ptr;          struct policy_manager_entry *ptr;
758          const char *exe;          const char *exe;
759          const struct path_info *domainname = current->domain_info->domainname;          const struct path_info *domainname = current->domain_info->domainname;
760            bool found = 0;
761          if (!sbin_init_started) return 1;          if (!sbin_init_started) return 1;
762          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
763                  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;
764          }          }
765          if ((exe = GetEXE()) == NULL) return 0;          if ((exe = GetEXE()) == NULL) return 0;
766          for (ptr = policy_manager_list; ptr; ptr = ptr->next) {          list1_for_each_entry(ptr, &policy_manager_list, list) {
767                  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)) {
768                            found = 1;
769                            break;
770                    }
771          }          }
772          if (!ptr) { /* Reduce error messages. */          if (!found) { /* Reduce error messages. */
773                  static pid_t last_pid = 0;                  static pid_t last_pid = 0;
774                  const pid_t pid = current->pid;                  const pid_t pid = current->pid;
775                  if (last_pid != pid) {                  if (last_pid != pid) {
776                          printk("%s is not permitted to update policies.\n", exe);                          printk("%s ( %s ) is not permitted to update policies.\n", domainname->name, exe);
777                          last_pid = pid;                          last_pid = pid;
778                  }                  }
779          }          }
780          ccs_free(exe);          ccs_free(exe);
781          return ptr ? 1 : 0;          return found;
782  }  }
783    
784  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
785    
786  /*************************  DOMAIN POLICY HANDLER  *************************/  /*************************  DOMAIN POLICY HANDLER  *************************/
787    
788  static int AddDomainPolicy(IO_BUFFER *head)  static char *FindConditionPart(char *data)
789    {
790            char *cp = strstr(data, " if "), *cp2;
791            if (cp) {
792                    while ((cp2 = strstr(cp + 3, " if ")) != NULL) cp = cp2;
793                    *cp++ = '\0';
794            }
795            return cp;
796    }
797    
798    static int AddDomainPolicy(struct io_buffer *head)
799  {  {
800          char *data = head->write_buf;          char *data = head->write_buf;
801          struct domain_info *domain = head->write_var1;          struct domain_info *domain = head->write_var1;
802          int is_delete = 0, is_select = 0, is_undelete = 0;          bool is_delete = 0, is_select = 0, is_undelete = 0;
803          unsigned int profile;          unsigned int profile;
804            const struct condition_list *cond = NULL;
805            char *cp;      
806          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
807          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
808                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
# Line 755  static int AddDomainPolicy(IO_BUFFER *he Line 830  static int AddDomainPolicy(IO_BUFFER *he
830                  return 0;                  return 0;
831          }          }
832          if (!domain) return -EINVAL;          if (!domain) return -EINVAL;
833    
834          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1 && profile < MAX_PROFILES) {          if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1 && profile < MAX_PROFILES) {
835                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;                  if (profile_ptr[profile] || !sbin_init_started) domain->profile = (u8) profile;
836  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY                  return 0;
837          } else if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {          }
838                  return AddCapabilityPolicy(data + KEYWORD_ALLOW_CAPABILITY_LEN, domain, is_delete);          cp = FindConditionPart(data);
839  #endif          if (cp && (cond = FindOrAssignNewCondition(cp)) == NULL) return -EINVAL;
840  #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK          if (strncmp(data, KEYWORD_ALLOW_CAPABILITY, KEYWORD_ALLOW_CAPABILITY_LEN) == 0) {
841                    return AddCapabilityPolicy(data + KEYWORD_ALLOW_CAPABILITY_LEN, domain, cond, is_delete);
842          } else if (strncmp(data, KEYWORD_ALLOW_NETWORK, KEYWORD_ALLOW_NETWORK_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_NETWORK, KEYWORD_ALLOW_NETWORK_LEN) == 0) {
843                  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  
844          } else if (strncmp(data, KEYWORD_ALLOW_SIGNAL, KEYWORD_ALLOW_SIGNAL_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_SIGNAL, KEYWORD_ALLOW_SIGNAL_LEN) == 0) {
845                  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  
846          } else if (strncmp(data, KEYWORD_ALLOW_ARGV0, KEYWORD_ALLOW_ARGV0_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_ARGV0, KEYWORD_ALLOW_ARGV0_LEN) == 0) {
847                  return AddArgv0Policy(data + KEYWORD_ALLOW_ARGV0_LEN, domain, is_delete);                  return AddArgv0Policy(data + KEYWORD_ALLOW_ARGV0_LEN, domain, cond, is_delete);
848  #endif          } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {
849                    return AddEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, domain, cond, is_delete);
850          } else {          } else {
851  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                  return AddFilePolicy(data, domain, cond, is_delete);
                 return AddFilePolicy(data, domain, is_delete);  
 #endif  
852          }          }
853          return -EINVAL;          return -EINVAL;
854  }  }
855    
856  static int ReadDomainPolicy(IO_BUFFER *head)  static int ReadDomainPolicy(struct io_buffer *head)
857  {  {
858          if (!head->read_eof) {          struct list1_head *dpos;
859                  struct domain_info *domain = head->read_var1;          struct list1_head *apos;
860                  switch (head->read_step) {          if (head->read_eof) return 0;
861                  case 0: break;          if (head->read_step == 0) {
                 case 1: goto step1;  
                 case 2: goto step2;  
                 case 3: goto step3;  
                 default: return -EINVAL;  
                 }  
862                  if (!isRoot()) return -EPERM;                  if (!isRoot()) return -EPERM;
863                  for (domain = &KERNEL_DOMAIN; domain; domain = domain->next) {                  head->read_step = 1;
864            }
865            list1_for_each_cookie(dpos, head->read_var1, &domain_list) {
866                    struct domain_info *domain;
867                    domain = list1_entry(dpos, struct domain_info, list);
868                    if (head->read_step != 1) goto acl_loop;
869                    if (domain->is_deleted) continue;
870                    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;
871                    head->read_step = 2;
872            acl_loop: ;
873                    if (head->read_step == 3) goto tail_mark;
874                    list1_for_each_cookie(apos, head->read_var2, &domain->acl_info_list) {
875                          struct acl_info *ptr;                          struct acl_info *ptr;
876                          if (domain->is_deleted) continue;                          int pos;
877                          head->read_var1 = domain;                          u8 acl_type;
878                          head->read_var2 = NULL; head->read_step = 1;                          ptr = list1_entry(apos, struct acl_info, list);
879                  step1:                          if (ptr->is_deleted) continue;
880                          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;
881                          head->read_var2 = (void *) domain->first_acl_ptr; head->read_step = 2;                          acl_type = ptr->type;
882                  step2:                          if (acl_type == TYPE_FILE_ACL) {
883                          for (ptr = (struct acl_info *) head->read_var2; ptr; ptr = ptr->next) {                                  struct file_acl_record *ptr2 = container_of(ptr, struct file_acl_record, head);
884                                  const u8 acl_type = ptr->type;                                  const unsigned char b = ptr2->u_is_group;
885                                  const int pos = head->read_avail;                                  if (io_printf(head, "%d %s%s", ptr2->perm,
886                                  head->read_var2 = (void *) ptr;                                                b ? "@" : "",
887                                  if (ptr->is_deleted) continue;                                                b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback;
888                                  if (0) {                          } else if (acl_type == TYPE_ARGV0_ACL) {
889  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                                  struct argv0_acl_record *ptr2 = container_of(ptr, struct argv0_acl_record, head);
890                                  } else if (acl_type == TYPE_FILE_ACL) {                                  if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
891                                          const unsigned char b = ptr->u.b[1];                                                ptr2->filename->name, ptr2->argv0->name)) goto print_acl_rollback;
892                                          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)                          } else if (acl_type == TYPE_ENV_ACL) {
893                                                  || DumpCondition(head, ptr->cond)) {                                  struct env_acl_record *ptr2 = container_of(ptr, struct env_acl_record, head);
894                                                  head->read_avail = pos; break;                                  if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr2->env->name)) goto print_acl_rollback;
895                                          }                          } else if (acl_type == TYPE_CAPABILITY_ACL) {
896  #endif                                  struct capability_acl_record *ptr2 = container_of(ptr, struct capability_acl_record, head);
897  #ifdef CONFIG_TOMOYO_MAC_FOR_ARGV0                                  if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", capability2keyword(ptr2->capability))) goto print_acl_rollback;
898                                  } else if (acl_type == TYPE_ARGV0_ACL) {                          } else if (acl_type == TYPE_IP_NETWORK_ACL) {
899                                          if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s", ((ARGV0_ACL_RECORD *) ptr)->filename->name, ((ARGV0_ACL_RECORD *) ptr)->argv0->name) ||                                  struct ip_network_acl_record *ptr2 = container_of(ptr, struct ip_network_acl_record, head);
900                                                  DumpCondition(head, ptr->cond)) {                                  if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", network2keyword(ptr2->operation_type))) goto print_acl_rollback;
901                                                  head->read_avail = pos; break;                                  switch (ptr2->record_type) {
902                                          }                                  case IP_RECORD_TYPE_ADDRESS_GROUP:
903  #endif                                          if (io_printf(head, "@%s", ptr2->u.group->group_name->name)) goto print_acl_rollback;
904  #ifdef CONFIG_TOMOYO_MAC_FOR_CAPABILITY                                          break;
905                                  } else if (acl_type == TYPE_CAPABILITY_ACL) {                                  case IP_RECORD_TYPE_IPv4:
                                         if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", capability2keyword(ptr->u.w)) ||  
                                                 DumpCondition(head, ptr->cond)) {  
                                                 head->read_avail = pos; break;  
                                         }  
 #endif  
 #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK  
                                 } else if (acl_type == TYPE_IP_NETWORK_ACL) {  
                                         if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", network2keyword(ptr->u.b[0]))) break;  
                                         switch (ptr->u.b[1]) {  
                                         case IP_RECORD_TYPE_ADDRESS_GROUP:  
                                                 if (io_printf(head, "@%s", ((IP_NETWORK_ACL_RECORD *) ptr)->u.group->group_name->name)) goto print_ip_record_out;  
                                                 break;  
                                         case IP_RECORD_TYPE_IPv4:  
                                                 {  
                                                         const u32 min_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv4.min, max_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv4.max;  
                                                         if (io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address))) goto print_ip_record_out;  
                                                         if (min_address != max_address && io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address))) goto print_ip_record_out;  
                                                 }  
                                                 break;  
                                         case IP_RECORD_TYPE_IPv6:  
                                                 {  
                                                         char buf[64];  
                                                         const u16 *min_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv6.min, *max_address = ((IP_NETWORK_ACL_RECORD *) ptr)->u.ipv6.max;  
                                                         print_ipv6(buf, sizeof(buf), min_address);  
                                                         if (io_printf(head, "%s", buf)) goto print_ip_record_out;  
                                                         if (memcmp(min_address, max_address, 16)) {  
                                                                 print_ipv6(buf, sizeof(buf), max_address);  
                                                                 if (io_printf(head, "-%s", buf)) goto print_ip_record_out;  
                                                         }  
                                                 }  
                                                 break;  
                                         }  
906                                          {                                          {
907                                                  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;
908                                                  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;
909                                                  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;  
910                                          }                                          }
911  #endif                                          break;
912  #ifdef CONFIG_TOMOYO_MAC_FOR_SIGNAL                                  case IP_RECORD_TYPE_IPv6:
913                                  } else if (acl_type == TYPE_SIGNAL_ACL) {                                          {
914                                          if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr->u.w, ((SIGNAL_ACL_RECORD *) ptr)->domainname->name) ||                                                  char buf[64];
915                                                  DumpCondition(head, ptr->cond)) {                                                  const struct in6_addr *min_address = ptr2->u.ipv6.min, *max_address = ptr2->u.ipv6.max;
916                                                  head->read_avail = pos; break;                                                  print_ipv6(buf, sizeof(buf), min_address);
917                                          }                                                  if (io_printf(head, "%s", buf)) goto print_acl_rollback;
918  #endif                                                  if (min_address != max_address) {
919  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                                                          print_ipv6(buf, sizeof(buf), max_address);
920                                  } 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;  
                                                         }  
921                                                  }                                                  }
922                                          }                                          }
923  #endif                                          break;
924                                    }
925                                    {
926                                            const u16 min_port = ptr2->min_port, max_port = ptr2->max_port;
927                                            if (io_printf(head, " %u", min_port)) goto print_acl_rollback;
928                                            if (min_port != max_port && io_printf(head, "-%u", max_port)) goto print_acl_rollback;
929                                    }
930                            } else if (acl_type == TYPE_SIGNAL_ACL) {
931                                    struct signal_acl_record *ptr2 = container_of(ptr, struct signal_acl_record, head);
932                                    if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr2->sig, ptr2->domainname->name)) goto print_acl_rollback;
933                            } else {
934                                    const char *keyword = acltype2keyword(acl_type);
935                                    if (!keyword) continue;
936                                    if (acltype2paths(acl_type) == 2) {
937                                            struct double_acl_record *ptr2 = container_of(ptr, struct double_acl_record, head);
938                                            const bool b0 = ptr2->u1_is_group, b1 = ptr2->u2_is_group;
939                                            if (io_printf(head, "allow_%s %s%s %s%s", keyword,
940                                                          b0 ? "@" : "", b0 ? ptr2->u1.group1->group_name->name : ptr2->u1.filename1->name,
941                                                          b1 ? "@" : "", b1 ? ptr2->u2.group2->group_name->name : ptr2->u2.filename2->name)) goto print_acl_rollback;
942                                    } else {
943                                            struct single_acl_record *ptr2 = container_of(ptr, struct single_acl_record, head);
944                                            const bool b = ptr2->u_is_group;
945                                            if (io_printf(head, "allow_%s %s%s", keyword,
946                                                          b ? "@" : "", b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback;
947                                  }                                  }
948                          }                          }
949                          if (ptr) break;                          if (DumpCondition(head, ptr->cond)) {
950                          head->read_var2 = NULL; head->read_step = 3;                          print_acl_rollback: ;
951                  step3:                          head->read_avail = pos;
952                          if (io_printf(head, "\n")) break;                          return 0;
953                            }
954                  }                  }
955                  if (!domain) head->read_eof = 1;                  head->read_step = 3;
956            tail_mark: ;
957                    if (io_printf(head, "\n")) return 0;
958                    head->read_step = 1;
959          }          }
960            head->read_eof = 1;
961          return 0;          return 0;
962  }  }
963    
964  static int ReadDomainProfile(IO_BUFFER *head)  #endif
965    
966    static int UpdateDomainProfile(struct io_buffer *head)
967  {  {
968          if (!head->read_eof) {          char *data = head->write_buf;
969            char *cp = strchr(data, ' ');
970            struct domain_info *domain;
971            unsigned int profile;
972            if (!isRoot()) return -EPERM;
973            if (!cp) return -EINVAL;
974            *cp = '\0';
975            domain = FindDomain(cp + 1);
976            profile = simple_strtoul(data, NULL, 10);
977            if (domain && profile < MAX_PROFILES && (profile_ptr[profile] || !sbin_init_started)) domain->profile = (u8) profile;
978            UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
979            return 0;
980    }
981    
982    static int ReadDomainProfile(struct io_buffer *head)
983    {
984            struct list1_head *pos;
985            if (head->read_eof) return 0;
986            if (!isRoot()) return -EPERM;
987            list1_for_each_cookie(pos, head->read_var1, &domain_list) {
988                  struct domain_info *domain;                  struct domain_info *domain;
989                  if (head->read_step == 0) {                  domain = list1_entry(pos, struct domain_info, list);
990                          head->read_var1 = &KERNEL_DOMAIN;                  if (domain->is_deleted) continue;
991                          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;  
992          }          }
993            head->read_eof = 1;
994          return 0;          return 0;
995  }  }
996    
997  static int WritePID(IO_BUFFER *head)  static int WritePID(struct io_buffer *head)
998  {  {
999          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);          head->read_step = (int) simple_strtoul(head->write_buf, NULL, 10);
1000          head->read_eof = 0;          head->read_eof = 0;
1001          return 0;          return 0;
1002  }  }
1003    
1004  static int ReadPID(IO_BUFFER *head)  static int ReadPID(struct io_buffer *head)
1005  {  {
1006          if (head->read_avail == 0 && !head->read_eof) {          if (head->read_avail == 0 && !head->read_eof) {
1007                  const int pid = head->read_step;                  const int pid = head->read_step;
# Line 949  static int ReadPID(IO_BUFFER *head) Line 1019  static int ReadPID(IO_BUFFER *head)
1019          return 0;          return 0;
1020  }  }
1021    
 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  
   
1022  /*************************  EXCEPTION POLICY HANDLER  *************************/  /*************************  EXCEPTION POLICY HANDLER  *************************/
1023    
1024  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1025    
1026  static int AddExceptionPolicy(IO_BUFFER *head)  static int AddExceptionPolicy(struct io_buffer *head)
1027  {  {
1028          char *data = head->write_buf;          char *data = head->write_buf;
1029          int is_delete = 0;          bool is_delete = 0;
1030          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
1031          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
1032          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 1038  static int AddExceptionPolicy(IO_BUFFER
1038          } 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) {
1039                  return AddDomainKeeperPolicy(data + KEYWORD_NO_KEEP_DOMAIN_LEN, 1, is_delete);                  return AddDomainKeeperPolicy(data + KEYWORD_NO_KEEP_DOMAIN_LEN, 1, is_delete);
1040          } else if (strncmp(data, KEYWORD_INITIALIZE_DOMAIN, KEYWORD_INITIALIZE_DOMAIN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_INITIALIZE_DOMAIN, KEYWORD_INITIALIZE_DOMAIN_LEN) == 0) {
1041                  return AddDomainInitializerPolicy(data + KEYWORD_INITIALIZE_DOMAIN_LEN, 0, is_delete, 0);                  return AddDomainInitializerPolicy(data + KEYWORD_INITIALIZE_DOMAIN_LEN, 0, is_delete);
1042          } 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) {
1043                  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);  
1044          } else if (strncmp(data, KEYWORD_ALIAS, KEYWORD_ALIAS_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALIAS, KEYWORD_ALIAS_LEN) == 0) {
1045                  return AddAliasPolicy(data + KEYWORD_ALIAS_LEN, is_delete);                  return AddAliasPolicy(data + KEYWORD_ALIAS_LEN, is_delete);
1046          } else if (strncmp(data, KEYWORD_AGGREGATOR, KEYWORD_AGGREGATOR_LEN) == 0) {          } else if (strncmp(data, KEYWORD_AGGREGATOR, KEYWORD_AGGREGATOR_LEN) == 0) {
1047                  return AddAggregatorPolicy(data + KEYWORD_AGGREGATOR_LEN, is_delete);                  return AddAggregatorPolicy(data + KEYWORD_AGGREGATOR_LEN, is_delete);
 #ifdef CONFIG_TOMOYO_MAC_FOR_FILE  
1048          } else if (strncmp(data, KEYWORD_ALLOW_READ, KEYWORD_ALLOW_READ_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ALLOW_READ, KEYWORD_ALLOW_READ_LEN) == 0) {
1049                  return AddGloballyReadablePolicy(data + KEYWORD_ALLOW_READ_LEN, is_delete);                  return AddGloballyReadablePolicy(data + KEYWORD_ALLOW_READ_LEN, is_delete);
1050            } else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) {
1051                    return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete);
1052          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {          } else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) {
1053                  return AddPatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);                  return AddPatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete);
1054          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {          } else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) {
1055                  return AddGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);                  return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete);
1056          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {          } else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) {
1057                  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  
1058          } else if (strncmp(data, KEYWORD_ADDRESS_GROUP, KEYWORD_ADDRESS_GROUP_LEN) == 0) {          } else if (strncmp(data, KEYWORD_ADDRESS_GROUP, KEYWORD_ADDRESS_GROUP_LEN) == 0) {
1059                  return AddAddressGroupPolicy(data + KEYWORD_ADDRESS_GROUP_LEN, is_delete);                  return AddAddressGroupPolicy(data + KEYWORD_ADDRESS_GROUP_LEN, is_delete);
 #endif  
1060          }          }
1061          return -EINVAL;          return -EINVAL;
1062  }  }
1063    
1064  static int ReadExceptionPolicy(IO_BUFFER *head)  static int ReadExceptionPolicy(struct io_buffer *head)
1065  {  {
1066          if (!head->read_eof) {          if (!head->read_eof) {
1067                  switch (head->read_step) {                  switch (head->read_step) {
# Line 1026  static int ReadExceptionPolicy(IO_BUFFER Line 1072  static int ReadExceptionPolicy(IO_BUFFER
1072                          if (ReadDomainKeeperPolicy(head)) break;                          if (ReadDomainKeeperPolicy(head)) break;
1073                          head->read_var2 = NULL; head->read_step = 2;                          head->read_var2 = NULL; head->read_step = 2;
1074                  case 2:                  case 2:
 #ifdef CONFIG_TOMOYO_MAC_FOR_FILE  
1075                          if (ReadGloballyReadablePolicy(head)) break;                          if (ReadGloballyReadablePolicy(head)) break;
 #endif  
1076                          head->read_var2 = NULL; head->read_step = 3;                          head->read_var2 = NULL; head->read_step = 3;
1077                  case 3:                  case 3:
1078                          if (ReadDomainInitializerPolicy(head)) break;                          if (ReadGloballyUsableEnvPolicy(head)) break;
1079                          head->read_var2 = NULL; head->read_step = 4;                          head->read_var2 = NULL; head->read_step = 4;
1080                  case 4:                  case 4:
1081                          if (ReadAliasPolicy(head)) break;                          if (ReadDomainInitializerPolicy(head)) break;
1082                          head->read_var2 = NULL; head->read_step = 5;                          head->read_var2 = NULL; head->read_step = 5;
1083                  case 5:                  case 5:
1084                          if (ReadAggregatorPolicy(head)) break;                          if (ReadAliasPolicy(head)) break;
1085                          head->read_var2 = NULL; head->read_step = 6;                          head->read_var2 = NULL; head->read_step = 6;
1086                  case 6:                  case 6:
1087  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadAggregatorPolicy(head)) break;
                         if (ReadPatternPolicy(head)) break;  
 #endif  
1088                          head->read_var2 = NULL; head->read_step = 7;                          head->read_var2 = NULL; head->read_step = 7;
1089                  case 7:                  case 7:
1090  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadPatternPolicy(head)) break;
                         if (ReadNoRewritePolicy(head)) break;  
 #endif  
1091                          head->read_var2 = NULL; head->read_step = 8;                          head->read_var2 = NULL; head->read_step = 8;
1092                  case 8:                  case 8:
1093  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE                          if (ReadNoRewritePolicy(head)) break;
                         if (ReadGroupPolicy(head)) break;  
 #endif  
1094                          head->read_var2 = NULL; head->read_step = 9;                          head->read_var2 = NULL; head->read_step = 9;
1095                  case 9:                  case 9:
1096  #ifdef CONFIG_TOMOYO_MAC_FOR_NETWORK                          if (ReadPathGroupPolicy(head)) break;
1097                            head->read_var1 = head->read_var2 = NULL; head->read_step = 10;
1098                    case 10:
1099                          if (ReadAddressGroupPolicy(head)) break;                          if (ReadAddressGroupPolicy(head)) break;
 #endif  
1100                          head->read_eof = 1;                          head->read_eof = 1;
1101                          break;                          break;
1102                  default:                  default:
# Line 1073  static int ReadExceptionPolicy(IO_BUFFER Line 1112  static int ReadExceptionPolicy(IO_BUFFER
1112    
1113  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1114    
1115  static int AddSystemPolicy(IO_BUFFER *head)  static int AddSystemPolicy(struct io_buffer *head)
1116  {  {
1117          char *data = head->write_buf;          char *data = head->write_buf;
1118          int is_delete = 0;          bool is_delete = 0;
1119          if (!isRoot()) return -EPERM;          if (!isRoot()) return -EPERM;
1120          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY);
1121          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {          if (strncmp(data, KEYWORD_DELETE, KEYWORD_DELETE_LEN) == 0) {
1122                  data += KEYWORD_DELETE_LEN;                  data += KEYWORD_DELETE_LEN;
1123                  is_delete = 1;                  is_delete = 1;
1124          }          }
 #ifdef CONFIG_SAKURA_RESTRICT_MOUNT  
1125          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)          if (strncmp(data, KEYWORD_ALLOW_MOUNT, KEYWORD_ALLOW_MOUNT_LEN) == 0)
1126                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);                  return AddMountPolicy(data + KEYWORD_ALLOW_MOUNT_LEN, is_delete);
 #endif  
 #ifdef CONFIG_SAKURA_RESTRICT_UNMOUNT  
1127          if (strncmp(data, KEYWORD_DENY_UNMOUNT, KEYWORD_DENY_UNMOUNT_LEN) == 0)          if (strncmp(data, KEYWORD_DENY_UNMOUNT, KEYWORD_DENY_UNMOUNT_LEN) == 0)
1128                  return AddNoUmountPolicy(data + KEYWORD_DENY_UNMOUNT_LEN, is_delete);                  return AddNoUmountPolicy(data + KEYWORD_DENY_UNMOUNT_LEN, is_delete);
 #endif  
 #ifdef CONFIG_SAKURA_RESTRICT_CHROOT  
1129          if (strncmp(data, KEYWORD_ALLOW_CHROOT, KEYWORD_ALLOW_CHROOT_LEN) == 0)          if (strncmp(data, KEYWORD_ALLOW_CHROOT, KEYWORD_ALLOW_CHROOT_LEN) == 0)
1130                  return AddChrootPolicy(data + KEYWORD_ALLOW_CHROOT_LEN, is_delete);                  return AddChrootPolicy(data + KEYWORD_ALLOW_CHROOT_LEN, is_delete);
1131  #endif          if (strncmp(data, KEYWORD_ALLOW_PIVOT_ROOT, KEYWORD_ALLOW_PIVOT_ROOT_LEN) == 0)
1132  #ifdef CONFIG_SAKURA_RESTRICT_AUTOBIND                  return AddPivotRootPolicy(data + KEYWORD_ALLOW_PIVOT_ROOT_LEN, is_delete);
1133          if (strncmp(data, KEYWORD_DENY_AUTOBIND, KEYWORD_DENY_AUTOBIND_LEN) == 0)          if (strncmp(data, KEYWORD_DENY_AUTOBIND, KEYWORD_DENY_AUTOBIND_LEN) == 0)
1134                  return AddReservedPortPolicy(data + KEYWORD_DENY_AUTOBIND_LEN, is_delete);                  return AddReservedPortPolicy(data + KEYWORD_DENY_AUTOBIND_LEN, is_delete);
 #endif  
1135          return -EINVAL;          return -EINVAL;
1136  }  }
1137    
1138  static int ReadSystemPolicy(IO_BUFFER *head)  static int ReadSystemPolicy(struct io_buffer *head)
1139  {  {
1140          if (!head->read_eof) {          if (!head->read_eof) {
1141                  switch (head->read_step) {                  switch (head->read_step) {
# Line 1110  static int ReadSystemPolicy(IO_BUFFER *h Line 1143  static int ReadSystemPolicy(IO_BUFFER *h
1143                          if (!isRoot()) return -EPERM;                          if (!isRoot()) return -EPERM;
1144                          head->read_var2 = NULL; head->read_step = 1;                          head->read_var2 = NULL; head->read_step = 1;
1145                  case 1:                  case 1:
 #ifdef CONFIG_SAKURA_RESTRICT_MOUNT  
1146                          if (ReadMountPolicy(head)) break;                          if (ReadMountPolicy(head)) break;
 #endif  
1147                          head->read_var2 = NULL; head->read_step = 2;                          head->read_var2 = NULL; head->read_step = 2;
1148                  case 2:                  case 2:
 #ifdef CONFIG_SAKURA_RESTRICT_UNMOUNT  
1149                          if (ReadNoUmountPolicy(head)) break;                          if (ReadNoUmountPolicy(head)) break;
 #endif  
1150                          head->read_var2 = NULL; head->read_step = 3;                          head->read_var2 = NULL; head->read_step = 3;
1151                  case 3:                  case 3:
 #ifdef CONFIG_SAKURA_RESTRICT_CHROOT  
1152                          if (ReadChrootPolicy(head)) break;                          if (ReadChrootPolicy(head)) break;
 #endif  
1153                          head->read_var2 = NULL; head->read_step = 4;                          head->read_var2 = NULL; head->read_step = 4;
1154                  case 4:                  case 4:
1155  #ifdef CONFIG_SAKURA_RESTRICT_AUTOBIND                          if (ReadPivotRootPolicy(head)) break;
1156                            head->read_var2 = NULL; head->read_step = 5;
1157                    case 5:
1158                          if (ReadReservedPortPolicy(head)) break;                          if (ReadReservedPortPolicy(head)) break;
 #endif  
1159                          head->read_eof = 1;                          head->read_eof = 1;
1160                          break;                          break;
1161                  default:                  default:
# Line 1141  static int ReadSystemPolicy(IO_BUFFER *h Line 1169  static int ReadSystemPolicy(IO_BUFFER *h
1169    
1170  /*************************  POLICY LOADER  *************************/  /*************************  POLICY LOADER  *************************/
1171    
1172    static int profile_loaded = 0;
1173    
1174  static const char *ccs_loader = NULL;  static const char *ccs_loader = NULL;
1175    
1176  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 1199  void CCS_LoadPolicy(const char *filename
1199           */           */
1200          {          {
1201                  struct nameidata nd;                  struct nameidata nd;
1202                  if (!ccs_loader) ccs_loader = "/.init";                  if (!ccs_loader) ccs_loader = "/sbin/ccs-init";
1203                  if (path_lookup(ccs_loader, lookup_flags, &nd)) {                  if (path_lookup(ccs_loader, lookup_flags, &nd)) {
1204                          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);
1205                          return;                          return;
1206                  }                  }
1207                  path_release(&nd);                  path_release(&nd);
1208          }          }
1209                    if (!profile_loaded) {
1210                    char *argv[2], *envp[3];
1211                    printk("Calling %s to load policy. Please wait.\n", ccs_loader);
1212                    argv[0] = (char *) ccs_loader;
1213                    argv[1] = NULL;
1214                    envp[0] = "HOME=/";
1215                    envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
1216                    envp[2] = NULL;
1217    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1218                    call_usermodehelper(argv[0], argv, envp, 1);
1219    #else
1220                    call_usermodehelper(argv[0], argv, envp);
1221    #endif
1222                    while (!profile_loaded) {
1223                            set_current_state(TASK_INTERRUPTIBLE);
1224                            schedule_timeout(HZ / 10);
1225                    }
1226            }
1227  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1228          printk("SAKURA: 1.3.3-pre5   2007/03/09\n");          printk("SAKURA: 1.5.3-pre   2007/12/18\n");
1229  #endif  #endif
1230  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1231          printk("TOMOYO: 1.3.3-pre5   2007/03/09\n");          printk("TOMOYO: 1.5.3-pre   2007/12/17\n");
1232  #endif  #endif
1233          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");
1234          printk("Mandatory Access Control activated.\n");          printk("Mandatory Access Control activated.\n");
1235          sbin_init_started = 1;          sbin_init_started = 1;
1236          ccs_log_level = KERN_WARNING;          ccs_log_level = KERN_WARNING;
1237          { /* Check all profiles currently assigned to domains are defined. */          { /* Check all profiles currently assigned to domains are defined. */
1238                  struct domain_info *domain;                  struct domain_info *domain;
1239                  for (domain = &KERNEL_DOMAIN; domain; domain = domain->next) {                  list1_for_each_entry(domain, &domain_list, list) {
1240                          const u8 profile = domain->profile;                          const u8 profile = domain->profile;
1241                          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);
1242                  }                  }
1243          }          }
1244  }  }
# Line 1203  static DECLARE_WAIT_QUEUE_HEAD(query_wai Line 1250  static DECLARE_WAIT_QUEUE_HEAD(query_wai
1250    
1251  static spinlock_t query_lock = SPIN_LOCK_UNLOCKED;  static spinlock_t query_lock = SPIN_LOCK_UNLOCKED;
1252    
1253  typedef struct query_entry {  struct query_entry {
1254          struct list_head list;          struct list_head list;
1255          char *query;          char *query;
1256          int query_len;          int query_len;
1257          unsigned int serial;          unsigned int serial;
1258          int timer;          int timer;
1259          int answer;          int answer;
1260  } QUERY_ENTRY;  };
1261    
1262  static LIST_HEAD(query_list);  static LIST_HEAD(query_list);
1263  static atomic_t queryd_watcher = ATOMIC_INIT(0);  static atomic_t queryd_watcher = ATOMIC_INIT(0);
# Line 1221  int CheckSupervisor(const char *fmt, ... Line 1268  int CheckSupervisor(const char *fmt, ...
1268          int error = -EPERM;          int error = -EPERM;
1269          int pos, len;          int pos, len;
1270          static unsigned int serial = 0;          static unsigned int serial = 0;
1271          QUERY_ENTRY *query_entry;          struct query_entry *query_entry;
1272          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE)) return -EPERM;          if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) {
1273          if (!atomic_read(&queryd_watcher)) return -EPERM;  #ifdef ALT_EXEC
1274                    if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) {
1275                            int i;
1276                            for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) {
1277                                    set_current_state(TASK_INTERRUPTIBLE);
1278                                    schedule_timeout(HZ / 10);
1279                            }
1280                    }
1281    #endif
1282                    return -EPERM;
1283            }
1284          va_start(args, fmt);          va_start(args, fmt);
1285          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
1286          va_end(args);          va_end(args);
1287          if ((query_entry = (QUERY_ENTRY *) ccs_alloc(sizeof(QUERY_ENTRY))) == NULL ||          if ((query_entry = ccs_alloc(sizeof(*query_entry))) == NULL ||
1288                  (query_entry->query = ccs_alloc(len)) == NULL) goto out;                  (query_entry->query = ccs_alloc(len)) == NULL) goto out;
1289          INIT_LIST_HEAD(&query_entry->list);          INIT_LIST_HEAD(&query_entry->list);
1290          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
# Line 1296  static int PollQuery(struct file *file, Line 1353  static int PollQuery(struct file *file,
1353          return 0;          return 0;
1354  }  }
1355    
1356  static int ReadQuery(IO_BUFFER *head)  static int ReadQuery(struct io_buffer *head)
1357  {  {
1358          struct list_head *tmp;          struct list_head *tmp;
1359          int pos = 0, len = 0;          int pos = 0, len = 0;
# Line 1309  static int ReadQuery(IO_BUFFER *head) Line 1366  static int ReadQuery(IO_BUFFER *head)
1366          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1367          spin_lock(&query_lock);          spin_lock(&query_lock);
1368          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1369                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1370                  if (pos++ == head->read_step) {                  if (pos++ == head->read_step) {
1371                          len = ptr->query_len;                          len = ptr->query_len;
1372                          break;                          break;
# Line 1321  static int ReadQuery(IO_BUFFER *head) Line 1378  static int ReadQuery(IO_BUFFER *head)
1378                  head->read_step = 0;                  head->read_step = 0;
1379                  return 0;                  return 0;
1380          }          }
1381          if ((buf = (char *) ccs_alloc(len)) != NULL) {          if ((buf = ccs_alloc(len)) != NULL) {
1382                  pos = 0;                  pos = 0;
1383                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
1384                  spin_lock(&query_lock);                  spin_lock(&query_lock);
1385                  list_for_each(tmp, &query_list) {                  list_for_each(tmp, &query_list) {
1386                          QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                          struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1387                          if (pos++ == head->read_step) {                          if (pos++ == head->read_step) {
1388                                  /* 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. */
1389                                  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 1403  static int ReadQuery(IO_BUFFER *head)
1403          return 0;          return 0;
1404  }  }
1405    
1406  static int WriteAnswer(IO_BUFFER *head)  static int WriteAnswer(struct io_buffer *head)
1407  {  {
1408          char *data = head->write_buf;          char *data = head->write_buf;
1409          struct list_head *tmp;          struct list_head *tmp;
# Line 1354  static int WriteAnswer(IO_BUFFER *head) Line 1411  static int WriteAnswer(IO_BUFFER *head)
1411          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1412          spin_lock(&query_lock);          spin_lock(&query_lock);
1413          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1414                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1415                  ptr->timer = 0;                  ptr->timer = 0;
1416          }          }
1417          spin_unlock(&query_lock);          spin_unlock(&query_lock);
# Line 1363  static int WriteAnswer(IO_BUFFER *head) Line 1420  static int WriteAnswer(IO_BUFFER *head)
1420          /***** CRITICAL SECTION START *****/          /***** CRITICAL SECTION START *****/
1421          spin_lock(&query_lock);          spin_lock(&query_lock);
1422          list_for_each(tmp, &query_list) {          list_for_each(tmp, &query_list) {
1423                  QUERY_ENTRY *ptr = list_entry(tmp, QUERY_ENTRY, list);                  struct query_entry *ptr = list_entry(tmp, struct query_entry, list);
1424                  if (ptr->serial != serial) continue;                  if (ptr->serial != serial) continue;
1425                  if (!ptr->answer) ptr->answer = answer;                  if (!ptr->answer) ptr->answer = answer;
1426                  break;                  break;
# Line 1388  void UpdateCounter(const unsigned char i Line 1445  void UpdateCounter(const unsigned char i
1445          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
1446  }  }
1447    
1448  static int ReadUpdatesCounter(IO_BUFFER *head)  static int ReadUpdatesCounter(struct io_buffer *head)
1449  {  {
1450          if (!head->read_eof) {          if (!head->read_eof) {
1451                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];                  unsigned int counter[MAX_CCS_UPDATES_COUNTER];
# Line 1399  static int ReadUpdatesCounter(IO_BUFFER Line 1456  static int ReadUpdatesCounter(IO_BUFFER
1456                  spin_unlock(&updates_counter_lock);                  spin_unlock(&updates_counter_lock);
1457                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
1458                  io_printf(head,                  io_printf(head,
1459                                    "/proc/ccs/policy/system_policy:    %10u\n"                                    "/proc/ccs/system_policy:    %10u\n"
1460                                    "/proc/ccs/policy/domain_policy:    %10u\n"                                    "/proc/ccs/domain_policy:    %10u\n"
1461                                    "/proc/ccs/policy/exception_policy: %10u\n"                                    "/proc/ccs/exception_policy: %10u\n"
1462                                    "/proc/ccs/status:                  %10u\n"                                    "/proc/ccs/profile:          %10u\n"
1463                                    "/proc/ccs/policy/query:            %10u\n"                                    "/proc/ccs/query:            %10u\n"
1464                                    "/proc/ccs/policy/manager:          %10u\n"                                    "/proc/ccs/manager:          %10u\n"
1465                                    "/proc/ccs/info/grant_log:          %10u\n"                                    "/proc/ccs/grant_log:        %10u\n"
1466                                    "/proc/ccs/info/reject_log:         %10u\n",                                    "/proc/ccs/reject_log:       %10u\n",
1467                                    counter[CCS_UPDATES_COUNTER_SYSTEM_POLICY],                                    counter[CCS_UPDATES_COUNTER_SYSTEM_POLICY],
1468                                    counter[CCS_UPDATES_COUNTER_DOMAIN_POLICY],                                    counter[CCS_UPDATES_COUNTER_DOMAIN_POLICY],
1469                                    counter[CCS_UPDATES_COUNTER_EXCEPTION_POLICY],                                    counter[CCS_UPDATES_COUNTER_EXCEPTION_POLICY],
1470                                    counter[CCS_UPDATES_COUNTER_STATUS],                                    counter[CCS_UPDATES_COUNTER_PROFILE],
1471                                    counter[CCS_UPDATES_COUNTER_QUERY],                                    counter[CCS_UPDATES_COUNTER_QUERY],
1472                                    counter[CCS_UPDATES_COUNTER_MANAGER],                                    counter[CCS_UPDATES_COUNTER_MANAGER],
1473                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],                                    counter[CCS_UPDATES_COUNTER_GRANT_LOG],
# Line 1420  static int ReadUpdatesCounter(IO_BUFFER Line 1477  static int ReadUpdatesCounter(IO_BUFFER
1477          return 0;          return 0;
1478  }  }
1479    
1480  static int ReadMemoryCounter(IO_BUFFER *head)  static int ReadVersion(struct io_buffer *head)
1481    {
1482            if (!head->read_eof) {
1483                    if (io_printf(head, "1.5.3-pre") == 0) head->read_eof = 1;
1484            }
1485            return 0;
1486    }
1487    
1488    static int ReadMemoryCounter(struct io_buffer *head)
1489  {  {
1490          if (!head->read_eof) {          if (!head->read_eof) {
1491                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();                  const int shared = GetMemoryUsedForSaveName(), private = GetMemoryUsedForElements(), dynamic = GetMemoryUsedForDynamic();
# Line 1429  static int ReadMemoryCounter(IO_BUFFER * Line 1494  static int ReadMemoryCounter(IO_BUFFER *
1494          return 0;          return 0;
1495  }  }
1496    
1497    static int ReadSelfDomain(struct io_buffer *head)
1498    {
1499            if (!head->read_eof) {
1500                    io_printf(head, "%s", current->domain_info->domainname->name);
1501                    head->read_eof = 1;
1502            }
1503            return 0;
1504    }
1505    
1506  int CCS_OpenControl(const int type, struct file *file)  int CCS_OpenControl(const int type, struct file *file)
1507  {  {
1508          IO_BUFFER *head = (IO_BUFFER *) ccs_alloc(sizeof(IO_BUFFER));          struct io_buffer *head = ccs_alloc(sizeof(*head));
1509          if (!head) return -ENOMEM;          if (!head) return -ENOMEM;
1510          init_MUTEX(&head->read_sem);          mutex_init(&head->read_sem);
1511          init_MUTEX(&head->write_sem);          mutex_init(&head->write_sem);
1512          switch (type) {          switch (type) {
1513    #ifdef CONFIG_SAKURA
1514            case CCS_SYSTEMPOLICY:
1515                    head->write = AddSystemPolicy;
1516                    head->read = ReadSystemPolicy;
1517                    break;
1518    #endif
1519  #ifdef CONFIG_TOMOYO  #ifdef CONFIG_TOMOYO
1520          case CCS_POLICY_DOMAINPOLICY:          case CCS_DOMAINPOLICY:
1521                  head->write = AddDomainPolicy;                  head->write = AddDomainPolicy;
1522                  head->read = ReadDomainPolicy;                  head->read = ReadDomainPolicy;
1523                  break;                  break;
1524          case CCS_POLICY_EXCEPTIONPOLICY:          case CCS_EXCEPTIONPOLICY:
1525                  head->write = AddExceptionPolicy;                  head->write = AddExceptionPolicy;
1526                  head->read = ReadExceptionPolicy;                  head->read = ReadExceptionPolicy;
1527                  break;                  break;
1528          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:  
1529                  head->poll = PollGrantLog;                  head->poll = PollGrantLog;
1530                  head->read = ReadGrantLog;                  head->read = ReadGrantLog;
1531                  break;                  break;
1532          case CCS_INFO_REJECTLOG:          case CCS_REJECTLOG:
1533                  head->poll = PollRejectLog;                  head->poll = PollRejectLog;
1534                  head->read = ReadRejectLog;                  head->read = ReadRejectLog;
1535                  break;                  break;
1536  #endif  #endif
1537          case CCS_INFO_SELFDOMAIN:          case CCS_SELFDOMAIN:
1538                  head->read = ReadSelfDomain;                  head->read = ReadSelfDomain;
1539                  break;                  break;
1540  #ifdef CONFIG_TOMOYO_MAC_FOR_FILE          case CCS_DOMAIN_STATUS:
1541          case CCS_INFO_MAPPING:                  head->write = UpdateDomainProfile;
1542                  if (!sbin_init_started) head->write = SetPermissionMapping;                  head->read = ReadDomainProfile;
                 head->read = ReadPermissionMapping;  
1543                  break;                  break;
1544  #endif          case CCS_PROCESS_STATUS:
1545  #endif                  head->write = WritePID;
1546  #ifdef CONFIG_SAKURA                  head->read = ReadPID;
         case CCS_POLICY_SYSTEMPOLICY:  
                 head->write = AddSystemPolicy;  
                 head->read = ReadSystemPolicy;  
1547                  break;                  break;
1548  #endif          case CCS_VERSION:
1549          case CCS_INFO_MEMINFO:                  head->read = ReadVersion;
1550                    head->readbuf_size = 128;
1551                    break;
1552            case CCS_MEMINFO:
1553                  head->read = ReadMemoryCounter;                  head->read = ReadMemoryCounter;
1554                  head->readbuf_size = 128;                  head->readbuf_size = 128;
1555                  break;                  break;
1556          case CCS_STATUS:          case CCS_PROFILE:
1557                  head->write = SetStatus;                  head->write = SetProfile;
1558                  head->read = ReadStatus;                  head->read = ReadProfile;
1559                  break;                  break;
1560          case CCS_POLICY_QUERY:          case CCS_QUERY:
1561                  head->poll = PollQuery;                  head->poll = PollQuery;
1562                  head->write = WriteAnswer;                  head->write = WriteAnswer;
1563                  head->read = ReadQuery;                  head->read = ReadQuery;
1564                  break;                  break;
1565          case CCS_POLICY_MANAGER:          case CCS_MANAGER:
1566                  head->write = AddManagerPolicy;                  head->write = AddManagerPolicy;
1567                  head->read = ReadManagerPolicy;                  head->read = ReadManagerPolicy;
1568                  break;                  break;
1569          case CCS_INFO_UPDATESCOUNTER:          case CCS_UPDATESCOUNTER:
1570                  head->read = ReadUpdatesCounter;                  head->read = ReadUpdatesCounter;
1571                  break;                  break;
1572          }          }
1573          if (type != CCS_INFO_GRANTLOG && type != CCS_INFO_REJECTLOG && type != CCS_POLICY_QUERY) {          if (type != CCS_GRANTLOG && type != CCS_REJECTLOG && type != CCS_QUERY) {
1574                  if (!head->readbuf_size) head->readbuf_size = PAGE_SIZE * 2;                  if (!head->readbuf_size) head->readbuf_size = PAGE_SIZE * 2;
1575                  if ((head->read_buf = ccs_alloc(head->readbuf_size)) == NULL) {                  if ((head->read_buf = ccs_alloc(head->readbuf_size)) == NULL) {
1576                          ccs_free(head);                          ccs_free(head);
# Line 1516  int CCS_OpenControl(const int type, stru Line 1586  int CCS_OpenControl(const int type, stru
1586                  }                  }
1587          }          }
1588          file->private_data = head;          file->private_data = head;
1589          if (type == CCS_INFO_SELFDOMAIN) CCS_ReadControl(file, NULL, 0);          if (type == CCS_SELFDOMAIN) CCS_ReadControl(file, NULL, 0);
1590          else if (head->write == WriteAnswer) atomic_inc(&queryd_watcher);          else if (head->write == WriteAnswer) atomic_inc(&queryd_watcher);
1591          return 0;          return 0;
1592  }  }
1593    
1594  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)
1595  {  {
1596          int len = head->read_avail;          int len = head->read_avail;
1597          char *cp = head->read_buf;          char *cp = head->read_buf;
# Line 1536  static int CopyToUser(IO_BUFFER *head, c Line 1606  static int CopyToUser(IO_BUFFER *head, c
1606    
1607  int CCS_PollControl(struct file *file, poll_table *wait)  int CCS_PollControl(struct file *file, poll_table *wait)
1608  {  {
1609          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1610          if (!head->poll) return -ENOSYS;          if (!head->poll) return -ENOSYS;
1611          return head->poll(file, wait);          return head->poll(file, wait);
1612  }  }
# Line 1544  int CCS_PollControl(struct file *file, p Line 1614  int CCS_PollControl(struct file *file, p
1614  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)
1615  {  {
1616          int len = 0;          int len = 0;
1617          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1618          if (!head->read) return -ENOSYS;          if (!head->read) return -ENOSYS;
1619          if (!access_ok(VERIFY_WRITE, buffer, buffer_len)) return -EFAULT;          if (!access_ok(VERIFY_WRITE, buffer, buffer_len)) return -EFAULT;
1620          if (down_interruptible(&head->read_sem)) return -EINTR;          if (mutex_lock_interruptible(&head->read_sem)) return -EINTR;
1621          len = head->read(head);          len = head->read(head);
1622          if (len >= 0) len = CopyToUser(head, buffer, buffer_len);          if (len >= 0) len = CopyToUser(head, buffer, buffer_len);
1623          up(&head->read_sem);          mutex_unlock(&head->read_sem);
1624          return len;          return len;
1625  }  }
1626    
1627  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)
1628  {  {
1629          IO_BUFFER *head = (IO_BUFFER *) file->private_data;          struct io_buffer *head = file->private_data;
1630          int error = buffer_len;          int error = buffer_len;
1631          int avail_len = buffer_len;          int avail_len = buffer_len;
1632          char *cp0 = head->write_buf;          char *cp0 = head->write_buf;
# Line 1566  int CCS_WriteControl(struct file *file, Line 1636  int CCS_WriteControl(struct file *file,
1636          if (head->write != WritePID && !IsPolicyManager()) {          if (head->write != WritePID && !IsPolicyManager()) {
1637                  return -EPERM; /* Forbid updating policies for non manager programs. */                  return -EPERM; /* Forbid updating policies for non manager programs. */
1638          }          }
1639          if (down_interruptible(&head->write_sem)) return -EINTR;          if (mutex_lock_interruptible(&head->write_sem)) return -EINTR;
1640          while (avail_len > 0) {          while (avail_len > 0) {
1641                  char c;                  char c;
1642                  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 1654  int CCS_WriteControl(struct file *file,
1654                  NormalizeLine(cp0);                  NormalizeLine(cp0);
1655                  head->write(head);                  head->write(head);
1656          }          }
1657          up(&head->write_sem);          mutex_unlock(&head->write_sem);
1658          return error;          return error;
1659  }  }
1660    
1661    
1662  int CCS_CloseControl(struct file *file)  int CCS_CloseControl(struct file *file)
1663  {  {
1664          IO_BUFFER *head = file->private_data;          struct io_buffer *head = file->private_data;
1665          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);          if (head->write == WriteAnswer) atomic_dec(&queryd_watcher);
1666            else if (head->read == ReadMemoryCounter) profile_loaded = 1;
1667          ccs_free(head->read_buf); head->read_buf = NULL;          ccs_free(head->read_buf); head->read_buf = NULL;
1668          ccs_free(head->write_buf); head->write_buf = NULL;          ccs_free(head->write_buf); head->write_buf = NULL;
1669          ccs_free(head); head = NULL;          ccs_free(head); head = NULL;
1670          file->private_data = NULL;          file->private_data = NULL;
1671          return 0;          return 0;
1672  }  }
   
 EXPORT_SYMBOL(CheckCCSFlags);  
 EXPORT_SYMBOL(CheckCCSEnforce);  
 EXPORT_SYMBOL(CheckCCSAccept);  

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

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