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

Subversion リポジトリの参照

Diff of /trunk/1.8.x/ccs-patch/security/ccsecurity/domain.c

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

revision 329 by kumaneko, Wed Aug 8 11:15:09 2007 UTC revision 621 by kumaneko, Sat Oct 27 08:11:13 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.5.0-pre   2007/08/06   * Version: 1.5.2-pre   2007/10/19
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 44  struct domain_initializer_entry { Line 44  struct domain_initializer_entry {
44          struct domain_initializer_entry *next;          struct domain_initializer_entry *next;
45          const struct path_info *domainname;    /* This may be NULL */          const struct path_info *domainname;    /* This may be NULL */
46          const struct path_info *program;          const struct path_info *program;
47          u8 is_deleted;          bool is_deleted;
48          u8 is_not;          bool is_not;
49          u8 is_last_name;          bool is_last_name;
         u8 is_oldstyle;  
50  };  };
51    
52  /***** The structure for domains to not to transit domains. *****/  /***** The structure for domains to not to transit domains. *****/
# Line 56  struct domain_keeper_entry { Line 55  struct domain_keeper_entry {
55          struct domain_keeper_entry *next;          struct domain_keeper_entry *next;
56          const struct path_info *domainname;          const struct path_info *domainname;
57          const struct path_info *program;       /* This may be NULL */          const struct path_info *program;       /* This may be NULL */
58          u8 is_deleted;          bool is_deleted;
59          u8 is_not;          bool is_not;
60          u8 is_last_name;          bool is_last_name;
61  };  };
62    
63  /***** The structure for program files that should be aggregated. *****/  /***** The structure for program files that should be aggregated. *****/
# Line 67  struct aggregator_entry { Line 66  struct aggregator_entry {
66          struct aggregator_entry *next;          struct aggregator_entry *next;
67          const struct path_info *original_name;          const struct path_info *original_name;
68          const struct path_info *aggregated_name;          const struct path_info *aggregated_name;
69          int is_deleted;          bool is_deleted;
70  };  };
71    
72  /***** The structure for program files that should be aliased. *****/  /***** The structure for program files that should be aliased. *****/
# Line 76  struct alias_entry { Line 75  struct alias_entry {
75          struct alias_entry *next;          struct alias_entry *next;
76          const struct path_info *original_name;          const struct path_info *original_name;
77          const struct path_info *aliased_name;          const struct path_info *aliased_name;
78          int is_deleted;          bool is_deleted;
79  };  };
80    
81  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
# Line 86  static DECLARE_MUTEX(new_domain_assign_l Line 85  static DECLARE_MUTEX(new_domain_assign_l
85    
86  /*************************  UTILITY FUNCTIONS  *************************/  /*************************  UTILITY FUNCTIONS  *************************/
87    
 int IsDomainDef(const unsigned char *buffer)  
 {  
         /* while (*buffer && (*buffer <= ' ' || *buffer >= 127)) buffer++; */  
         return strncmp(buffer, ROOT_NAME, ROOT_NAME_LEN) == 0;  
 }  
   
88  const char *GetLastName(const struct domain_info *domain)  const char *GetLastName(const struct domain_info *domain)
89  {  {
90          const char *cp0 = domain->domainname->name, *cp1;          const char *cp0 = domain->domainname->name, *cp1;
# Line 99  const char *GetLastName(const struct dom Line 92  const char *GetLastName(const struct dom
92          return cp0;          return cp0;
93  }  }
94    
 int ReadSelfDomain(struct io_buffer *head)  
 {  
         if (!head->read_eof) {  
                 io_printf(head, "%s", current->domain_info->domainname->name);  
                 head->read_eof = 1;  
         }  
         return 0;  
 }  
   
95  int AddDomainACL(struct acl_info *ptr, struct domain_info *domain, struct acl_info *new_ptr)  int AddDomainACL(struct acl_info *ptr, struct domain_info *domain, struct acl_info *new_ptr)
96  {  {
97          mb(); /* Instead of using spinlock. */          mb(); /* Instead of using spinlock. */
# Line 124  int DelDomainACL(struct acl_info *ptr) Line 108  int DelDomainACL(struct acl_info *ptr)
108          return 0;          return 0;
109  }  }
110    
 int TooManyDomainACL(struct domain_info * const domain) {  
         unsigned int count = 0;  
         struct acl_info *ptr;  
         for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {  
                 if (!ptr->is_deleted) count++;  
         }  
         /* If there are so many entries, don't append if learning mode. */  
         if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 0;  
         if (!domain->quota_warned) {  
                 printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);  
                 domain->quota_warned = 1;  
         }  
         return 1;  
 }  
   
   
111  /*************************  DOMAIN INITIALIZER HANDLER  *************************/  /*************************  DOMAIN INITIALIZER HANDLER  *************************/
112    
113  static struct domain_initializer_entry *domain_initializer_list = NULL;  static struct domain_initializer_entry *domain_initializer_list = NULL;
114    
115  static int AddDomainInitializerEntry(const char *domainname, const char *program, const int is_not, const int is_delete, const int is_oldstyle)  static int AddDomainInitializerEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)
116  {  {
117          struct domain_initializer_entry *new_entry, *ptr;          struct domain_initializer_entry *new_entry, *ptr;
118          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
119          const struct path_info *saved_program, *saved_domainname = NULL;          const struct path_info *saved_program, *saved_domainname = NULL;
120          int error = -ENOMEM;          int error = -ENOMEM;
121          int is_last_name = 0;          bool is_last_name = 0;
122          if (!IsCorrectPath(program, 1, -1, -1, __FUNCTION__)) return -EINVAL; /* No patterns allowed. */          if (!IsCorrectPath(program, 1, -1, -1, __FUNCTION__)) return -EINVAL; /* No patterns allowed. */
123          if (domainname) {          if (domainname) {
124                  if (!IsDomainDef(domainname) && IsCorrectPath(domainname, 1, -1, -1, __FUNCTION__)) {                  if (!IsDomainDef(domainname) && IsCorrectPath(domainname, 1, -1, -1, __FUNCTION__)) {
# Line 163  static int AddDomainInitializerEntry(con Line 131  static int AddDomainInitializerEntry(con
131          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;
132          down(&lock);          down(&lock);
133          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {
134                  if (ptr->is_not == is_not && ptr->is_oldstyle == is_oldstyle && ptr->domainname == saved_domainname && ptr->program == saved_program) {                  if (ptr->is_not == is_not && ptr->domainname == saved_domainname && ptr->program == saved_program) {
135                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
136                          error = 0;                          error = 0;
137                          goto out;                          goto out;
# Line 178  static int AddDomainInitializerEntry(con Line 146  static int AddDomainInitializerEntry(con
146          new_entry->program = saved_program;          new_entry->program = saved_program;
147          new_entry->is_not = is_not;          new_entry->is_not = is_not;
148          new_entry->is_last_name = is_last_name;          new_entry->is_last_name = is_last_name;
         new_entry->is_oldstyle = is_oldstyle;  
149          mb(); /* Instead of using spinlock. */          mb(); /* Instead of using spinlock. */
150          if ((ptr = domain_initializer_list) != NULL) {          if ((ptr = domain_initializer_list) != NULL) {
151                  while (ptr->next) ptr = ptr->next; ptr->next = new_entry;                  while (ptr->next) ptr = ptr->next; ptr->next = new_entry;
# Line 199  int ReadDomainInitializerPolicy(struct i Line 166  int ReadDomainInitializerPolicy(struct i
166                  head->read_var2 = ptr;                  head->read_var2 = ptr;
167                  if (!ptr->is_deleted) {                  if (!ptr->is_deleted) {
168                          if (ptr->domainname) {                          if (ptr->domainname) {
169                                  if (io_printf(head, "%s%s%s from %s\n", ptr->is_not ? "no_" : "", ptr->is_oldstyle ? KEYWORD_INITIALIZER : KEYWORD_INITIALIZE_DOMAIN, ptr->program->name, ptr->domainname->name)) break;                                  if (io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN "%s from %s\n", ptr->is_not ? "no_" : "", ptr->program->name, ptr->domainname->name)) break;
170                          } else {                          } else {
171                                  if (io_printf(head, "%s%s%s\n", ptr->is_not ? "no_" : "", ptr->is_oldstyle ? KEYWORD_INITIALIZER : KEYWORD_INITIALIZE_DOMAIN, ptr->program->name)) break;                                  if (io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN "%s\n", ptr->is_not ? "no_" : "", ptr->program->name)) break;
172                          }                          }
173                  }                  }
174                  ptr = ptr->next;                  ptr = ptr->next;
# Line 209  int ReadDomainInitializerPolicy(struct i Line 176  int ReadDomainInitializerPolicy(struct i
176          return ptr ? -ENOMEM : 0;          return ptr ? -ENOMEM : 0;
177  }  }
178    
179  int AddDomainInitializerPolicy(char *data, const int is_not, const int is_delete, const int is_oldstyle)  int AddDomainInitializerPolicy(char *data, const bool is_not, const bool is_delete)
180  {  {
181          char *cp = strstr(data, " from ");          char *cp = strstr(data, " from ");
182          if (cp) {          if (cp) {
183                  *cp = '\0';                  *cp = '\0';
184                  return AddDomainInitializerEntry(cp + 6, data, is_not, is_delete, is_oldstyle);                  return AddDomainInitializerEntry(cp + 6, data, is_not, is_delete);
185          } else {          } else {
186                  return AddDomainInitializerEntry(NULL, data, is_not, is_delete, is_oldstyle);                  return AddDomainInitializerEntry(NULL, data, is_not, is_delete);
187          }          }
188  }  }
189    
# Line 244  static int IsDomainInitializer(const str Line 211  static int IsDomainInitializer(const str
211    
212  static struct domain_keeper_entry *domain_keeper_list = NULL;  static struct domain_keeper_entry *domain_keeper_list = NULL;
213    
214  static int AddDomainKeeperEntry(const char *domainname, const char *program, const int is_not, const int is_delete)  static int AddDomainKeeperEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)
215  {  {
216          struct domain_keeper_entry *new_entry, *ptr;          struct domain_keeper_entry *new_entry, *ptr;
217          const struct path_info *saved_domainname, *saved_program = NULL;          const struct path_info *saved_domainname, *saved_program = NULL;
218          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
219          int error = -ENOMEM;          int error = -ENOMEM;
220          int is_last_name = 0;          bool is_last_name = 0;
221          if (!IsDomainDef(domainname) && IsCorrectPath(domainname, 1, -1, -1, __FUNCTION__)) {          if (!IsDomainDef(domainname) && IsCorrectPath(domainname, 1, -1, -1, __FUNCTION__)) {
222                  is_last_name = 1;                  is_last_name = 1;
223          } else if (!IsCorrectDomain(domainname, __FUNCTION__)) {          } else if (!IsCorrectDomain(domainname, __FUNCTION__)) {
# Line 290  static int AddDomainKeeperEntry(const ch Line 257  static int AddDomainKeeperEntry(const ch
257          return error;          return error;
258  }  }
259    
260  int AddDomainKeeperPolicy(char *data, const int is_not, const int is_delete)  int AddDomainKeeperPolicy(char *data, const bool is_not, const bool is_delete)
261  {  {
262          char *cp = strstr(data, " from ");          char *cp = strstr(data, " from ");
263          if (cp) {          if (cp) {
# Line 341  static int IsDomainKeeper(const struct p Line 308  static int IsDomainKeeper(const struct p
308    
309  static struct alias_entry *alias_list = NULL;  static struct alias_entry *alias_list = NULL;
310    
311  static int AddAliasEntry(const char *original_name, const char *aliased_name, const int is_delete)  static int AddAliasEntry(const char *original_name, const char *aliased_name, const bool is_delete)
312  {  {
313          struct alias_entry *new_entry, *ptr;          struct alias_entry *new_entry, *ptr;
314          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
# Line 388  int ReadAliasPolicy(struct io_buffer *he Line 355  int ReadAliasPolicy(struct io_buffer *he
355          return ptr ? -ENOMEM : 0;          return ptr ? -ENOMEM : 0;
356  }  }
357    
358  int AddAliasPolicy(char *data, const int is_delete)  int AddAliasPolicy(char *data, const bool is_delete)
359  {  {
360          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
361          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
# Line 400  int AddAliasPolicy(char *data, const int Line 367  int AddAliasPolicy(char *data, const int
367    
368  static struct aggregator_entry *aggregator_list = NULL;  static struct aggregator_entry *aggregator_list = NULL;
369    
370  static int AddAggregatorEntry(const char *original_name, const char *aggregated_name, const int is_delete)  static int AddAggregatorEntry(const char *original_name, const char *aggregated_name, const bool is_delete)
371  {  {
372          struct aggregator_entry *new_entry, *ptr;          struct aggregator_entry *new_entry, *ptr;
373          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
# Line 447  int ReadAggregatorPolicy(struct io_buffe Line 414  int ReadAggregatorPolicy(struct io_buffe
414          return ptr ? -ENOMEM : 0;          return ptr ? -ENOMEM : 0;
415  }  }
416    
417  int AddAggregatorPolicy(char *data, const int is_delete)  int AddAggregatorPolicy(char *data, const bool is_delete)
418  {  {
419          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
420          if (!cp) return -EINVAL;          if (!cp) return -EINVAL;
# Line 537  struct domain_info *UndeleteDomain(const Line 504  struct domain_info *UndeleteDomain(const
504    
505  /*************************  DOMAIN TRANSITION HANDLER  *************************/  /*************************  DOMAIN TRANSITION HANDLER  *************************/
506    
 struct domain_info *FindDomain(const char *domainname0)  
 {  
         struct domain_info *domain;  
         static int first = 1;  
         struct path_info domainname;  
         domainname.name = domainname0;  
         fill_path_info(&domainname);  
         if (first) {  
                 KERNEL_DOMAIN.domainname = SaveName(ROOT_NAME);  
                 first = 0;  
         }  
         for (domain = &KERNEL_DOMAIN; domain; domain = domain->next) {  
                 if (!domain->is_deleted && !pathcmp(&domainname, domain->domainname)) return domain;  
         }  
         return NULL;  
 }  
   
507  struct domain_info *FindOrAssignNewDomain(const char *domainname, const u8 profile)  struct domain_info *FindOrAssignNewDomain(const char *domainname, const u8 profile)
508  {  {
509          struct domain_info *domain = NULL;          struct domain_info *domain = NULL;
# Line 685  static int FindNextDomain(struct linux_b Line 635  static int FindNextDomain(struct linux_b
635          struct file *filp = bprm->file;          struct file *filp = bprm->file;
636          char *new_domain_name = NULL;          char *new_domain_name = NULL;
637          char *real_program_name = NULL, *symlink_program_name = NULL;          char *real_program_name = NULL, *symlink_program_name = NULL;
638          const int is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_FILE);          const bool is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_FILE);
639          int retval;          int retval;
640          struct path_info r, s, l;          struct path_info r, s, l;
641    
# Line 695  static int FindNextDomain(struct linux_b Line 645  static int FindNextDomain(struct linux_b
645                   */                   */
646                  static int first = 1;                  static int first = 1;
647                  if (first) {                  if (first) {
648                          AddDomainInitializerEntry(NULL, "/sbin/hotplug", 0, 0, 0);                          AddDomainInitializerEntry(NULL, "/sbin/hotplug", 0, 0);
649                          AddDomainInitializerEntry(NULL, "/sbin/modprobe", 0, 0, 0);                          AddDomainInitializerEntry(NULL, "/sbin/modprobe", 0, 0);
650                          first = 0;                          first = 0;
651                  }                  }
652          }          }
# Line 806  static int FindNextDomain(struct linux_b Line 756  static int FindNextDomain(struct linux_b
756          return retval;          return retval;
757  }  }
758    
759    static int CheckEnviron(struct linux_binprm *bprm)
760    {
761            char *arg_ptr = ccs_alloc(CCS_MAX_PATHNAME_LEN);
762            int arg_len = 0;
763            unsigned long pos = bprm->p;
764            int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;
765            int argv_count = bprm->argc;
766            int envp_count = bprm->envc;
767            //printk("start %d %d\n", argv_count, envp_count);
768            int error = -ENOMEM;
769            if (!arg_ptr) goto out;
770            if (!envp_count) {
771                    error = 0;
772                    goto out;
773            }
774            while (error == -ENOMEM) {
775                    struct page *page;
776                    const char *kaddr;
777    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
778                    if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) goto out;
779    #else
780                    page = bprm->page[i];
781    #endif
782                    /* Map */
783                    kaddr = kmap(page);
784                    if (!kaddr) { /* Mapping failed. */
785    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
786                            put_page(page);
787    #endif
788                            goto out;
789                    }
790                    /* Read. */
791                    while (argv_count && offset < PAGE_SIZE) {
792                            if (!kaddr[offset++]) argv_count--;
793                    }
794                    if (argv_count) goto unmap_page;
795                    while (offset < PAGE_SIZE) {
796                            const unsigned char c = kaddr[offset++];
797                            if (arg_len < CCS_MAX_PATHNAME_LEN - 10) {
798                                    if (c == '=') {
799                                            arg_ptr[arg_len++] = '\0';
800                                    } else if (c == '\\') {
801                                            arg_ptr[arg_len++] = '\\';
802                                            arg_ptr[arg_len++] = '\\';
803                                    } else if (c > ' ' && c < 127) {
804                                            arg_ptr[arg_len++] = c;
805                                    } else {
806                                            arg_ptr[arg_len++] = '\\';
807                                            arg_ptr[arg_len++] = (c >> 6) + '0';
808                                            arg_ptr[arg_len++] = ((c >> 3) & 7) + '0';
809                                            arg_ptr[arg_len++] = (c & 7) + '0';
810                                    }
811                            } else {
812                                    arg_ptr[arg_len] = '\0';
813                            }
814                            if (c) continue;
815                            if (CheckEnvPerm(arg_ptr)) {
816                                    error = -EPERM;
817                                    break;
818                            }
819                            if (!--envp_count) {
820                                    error = 0;
821                                    break;
822                            }
823                            arg_len = 0;
824                    }
825            unmap_page:
826                    /* Unmap. */
827                    kunmap(page);
828    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
829                    put_page(page);
830                    pos += PAGE_SIZE - offset;
831    #endif
832                    i++;
833                    offset = 0;
834            }
835     out:
836            ccs_free(arg_ptr);
837            if (error && !CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_ENV)) error = 0;
838            return error;
839    }
840    
841  #endif  #endif
842    
843  int search_binary_handler_with_transition(struct linux_binprm *bprm, struct pt_regs *regs)  int search_binary_handler_with_transition(struct linux_binprm *bprm, struct pt_regs *regs)
# Line 822  int search_binary_handler_with_transitio Line 854  int search_binary_handler_with_transitio
854          retval = 0; next_domain = prev_domain;          retval = 0; next_domain = prev_domain;
855  #endif  #endif
856          if (retval == 0) {          if (retval == 0) {
                 current->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;  
857                  current->domain_info = next_domain;                  current->domain_info = next_domain;
858                  retval = search_binary_handler(bprm, regs);  #if defined(CONFIG_TOMOYO)
859                  if (retval < 0) current->domain_info = prev_domain;                  if (CheckCCSFlags(CCS_TOMOYO_MAC_FOR_ENV)) retval = CheckEnviron(bprm);
860    #endif
861                    current->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
862                    if (!retval) retval = search_binary_handler(bprm, regs);
863                  current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;                  current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
864                    if (retval < 0) current->domain_info = prev_domain;
865          }          }
866          return retval;          return retval;
867  }  }

Legend:
Removed from v.329  
changed lines
  Added in v.621

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