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

Subversion リポジトリの参照

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

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

trunk/ccs-patch/fs/tomoyo_domain.c revision 141 by kumaneko, Mon Mar 19 13:29:09 2007 UTC trunk/1.5.x/ccs-patch/fs/tomoyo_domain.c revision 502 by kumaneko, Tue Sep 25 13:33:45 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.3   2007/04/01   * Version: 1.5.0   2007/09/20
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 40  DECLARE_MUTEX(domain_acl_lock); Line 40  DECLARE_MUTEX(domain_acl_lock);
40    
41  /***** The structure for program files to force domain reconstruction. *****/  /***** The structure for program files to force domain reconstruction. *****/
42    
43  typedef struct domain_initializer_entry {  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;          u8 is_deleted;
48          u8 is_not;          u8 is_not;
49          u8 is_last_name;          u8 is_last_name;
50          u8 is_oldstyle;  };
 } DOMAIN_INITIALIZER_ENTRY;  
51    
52  /***** The structure for domains to not to transit domains. *****/  /***** The structure for domains to not to transit domains. *****/
53    
54  typedef struct domain_keeper_entry {  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;          u8 is_deleted;
59          u8 is_not;          u8 is_not;
60          u8 is_last_name;          u8 is_last_name;
61  } DOMAIN_KEEPER_ENTRY;  };
62    
63  /***** The structure for program files that should be aggregated. *****/  /***** The structure for program files that should be aggregated. *****/
64    
65  typedef struct aggregator_entry {  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;          int is_deleted;
70  } AGGREGATOR_ENTRY;  };
71    
72  /***** The structure for program files that should be aliased. *****/  /***** The structure for program files that should be aliased. *****/
73    
74  typedef struct alias_entry {  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;          int is_deleted;
79  } ALIAS_ENTRY;  };
80    
81  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
82    
# 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(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 130  int TooManyDomainACL(struct domain_info Line 114  int TooManyDomainACL(struct domain_info
114          for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {          for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
115                  if (!ptr->is_deleted) count++;                  if (!ptr->is_deleted) count++;
116          }          }
117          /* If there are so many entries, don't append if accept mode. */          /* If there are so many entries, don't append if learning mode. */
118          if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 0;          if (count < CheckCCSFlags(CCS_TOMOYO_MAX_ACCEPT_ENTRY)) return 0;
119          if (!domain->quota_warned) {          if (!domain->quota_warned) {
120                  printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped auto-append mode.\n", domain->domainname->name);                  printk("TOMOYO-WARNING: Domain '%s' has so many ACLs to hold. Stopped learning mode.\n", domain->domainname->name);
121                  domain->quota_warned = 1;                  domain->quota_warned = 1;
122          }          }
123          return 1;          return 1;
# Line 142  int TooManyDomainACL(struct domain_info Line 126  int TooManyDomainACL(struct domain_info
126    
127  /*************************  DOMAIN INITIALIZER HANDLER  *************************/  /*************************  DOMAIN INITIALIZER HANDLER  *************************/
128    
129  static DOMAIN_INITIALIZER_ENTRY *domain_initializer_list = NULL;  static struct domain_initializer_entry *domain_initializer_list = NULL;
130    
131  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 int is_not, const int is_delete)
132  {  {
133          DOMAIN_INITIALIZER_ENTRY *new_entry, *ptr;          struct domain_initializer_entry *new_entry, *ptr;
134          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
135          const struct path_info *saved_program, *saved_domainname = NULL;          const struct path_info *saved_program, *saved_domainname = NULL;
136          int error = -ENOMEM;          int error = -ENOMEM;
# Line 163  static int AddDomainInitializerEntry(con Line 147  static int AddDomainInitializerEntry(con
147          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;
148          down(&lock);          down(&lock);
149          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {
150                  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) {
151                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
152                          error = 0;                          error = 0;
153                          goto out;                          goto out;
# Line 173  static int AddDomainInitializerEntry(con Line 157  static int AddDomainInitializerEntry(con
157                  error = -ENOENT;                  error = -ENOENT;
158                  goto out;                  goto out;
159          }          }
160          if ((new_entry = (DOMAIN_INITIALIZER_ENTRY *) alloc_element(sizeof(DOMAIN_INITIALIZER_ENTRY))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
161          new_entry->domainname = saved_domainname;          new_entry->domainname = saved_domainname;
162          new_entry->program = saved_program;          new_entry->program = saved_program;
163          new_entry->is_not = is_not;          new_entry->is_not = is_not;
164          new_entry->is_last_name = is_last_name;          new_entry->is_last_name = is_last_name;
         new_entry->is_oldstyle = is_oldstyle;  
165          mb(); /* Instead of using spinlock. */          mb(); /* Instead of using spinlock. */
166          if ((ptr = domain_initializer_list) != NULL) {          if ((ptr = domain_initializer_list) != NULL) {
167                  while (ptr->next) ptr = ptr->next; ptr->next = new_entry;                  while (ptr->next) ptr = ptr->next; ptr->next = new_entry;
# Line 191  static int AddDomainInitializerEntry(con Line 174  static int AddDomainInitializerEntry(con
174          return error;          return error;
175  }  }
176    
177  int ReadDomainInitializerPolicy(IO_BUFFER *head)  int ReadDomainInitializerPolicy(struct io_buffer *head)
178  {  {
179          DOMAIN_INITIALIZER_ENTRY *ptr = (DOMAIN_INITIALIZER_ENTRY *) head->read_var2;          struct domain_initializer_entry *ptr = head->read_var2;
180          if (!ptr) ptr = domain_initializer_list;          if (!ptr) ptr = domain_initializer_list;
181          while (ptr) {          while (ptr) {
182                  head->read_var2 = (void *) ptr;                  head->read_var2 = ptr;
183                  if (!ptr->is_deleted) {                  if (!ptr->is_deleted) {
184                          if (ptr->domainname) {                          if (ptr->domainname) {
185                                  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;
186                          } else {                          } else {
187                                  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;
188                          }                          }
189                  }                  }
190                  ptr = ptr->next;                  ptr = ptr->next;
# Line 209  int ReadDomainInitializerPolicy(IO_BUFFE Line 192  int ReadDomainInitializerPolicy(IO_BUFFE
192          return ptr ? -ENOMEM : 0;          return ptr ? -ENOMEM : 0;
193  }  }
194    
195  int AddDomainInitializerPolicy(char *data, const int is_not, const int is_delete, const int is_oldstyle)  int AddDomainInitializerPolicy(char *data, const int is_not, const int is_delete)
196  {  {
197          char *cp = strstr(data, " from ");          char *cp = strstr(data, " from ");
198          if (cp) {          if (cp) {
199                  *cp = '\0';                  *cp = '\0';
200                  return AddDomainInitializerEntry(cp + 6, data, is_not, is_delete, is_oldstyle);                  return AddDomainInitializerEntry(cp + 6, data, is_not, is_delete);
201          } else {          } else {
202                  return AddDomainInitializerEntry(NULL, data, is_not, is_delete, is_oldstyle);                  return AddDomainInitializerEntry(NULL, data, is_not, is_delete);
203          }          }
204  }  }
205    
206  static int IsDomainInitializer(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)  static int IsDomainInitializer(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)
207  {  {
208          DOMAIN_INITIALIZER_ENTRY *ptr;          struct domain_initializer_entry *ptr;
209          int flag = 0;          int flag = 0;
210          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {
211                  if (ptr->is_deleted ) continue;                  if (ptr->is_deleted ) continue;
# Line 242  static int IsDomainInitializer(const str Line 225  static int IsDomainInitializer(const str
225    
226  /*************************  DOMAIN KEEPER HANDLER  *************************/  /*************************  DOMAIN KEEPER HANDLER  *************************/
227    
228  static DOMAIN_KEEPER_ENTRY *domain_keeper_list = NULL;  static struct domain_keeper_entry *domain_keeper_list = NULL;
229    
230  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 int is_not, const int is_delete)
231  {  {
232          DOMAIN_KEEPER_ENTRY *new_entry, *ptr;          struct domain_keeper_entry *new_entry, *ptr;
233          const struct path_info *saved_domainname, *saved_program = NULL;          const struct path_info *saved_domainname, *saved_program = NULL;
234          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
235          int error = -ENOMEM;          int error = -ENOMEM;
# Line 273  static int AddDomainKeeperEntry(const ch Line 256  static int AddDomainKeeperEntry(const ch
256                  error = -ENOENT;                  error = -ENOENT;
257                  goto out;                  goto out;
258          }          }
259          if ((new_entry = (DOMAIN_KEEPER_ENTRY *) alloc_element(sizeof(DOMAIN_KEEPER_ENTRY))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
260          new_entry->domainname = saved_domainname;          new_entry->domainname = saved_domainname;
261          new_entry->program = saved_program;          new_entry->program = saved_program;
262          new_entry->is_not = is_not;          new_entry->is_not = is_not;
# Line 301  int AddDomainKeeperPolicy(char *data, co Line 284  int AddDomainKeeperPolicy(char *data, co
284          }          }
285  }  }
286    
287  int ReadDomainKeeperPolicy(IO_BUFFER *head)  int ReadDomainKeeperPolicy(struct io_buffer *head)
288  {  {
289          DOMAIN_KEEPER_ENTRY *ptr = (DOMAIN_KEEPER_ENTRY *) head->read_var2;          struct domain_keeper_entry *ptr = head->read_var2;
290          if (!ptr) ptr = domain_keeper_list;          if (!ptr) ptr = domain_keeper_list;
291          while (ptr) {          while (ptr) {
292                  head->read_var2 = (void *) ptr;                  head->read_var2 = ptr;
293                  if (!ptr->is_deleted) {                  if (!ptr->is_deleted) {
294                          if (ptr->program) {                          if (ptr->program) {
295                                  if (io_printf(head, "%s" KEYWORD_KEEP_DOMAIN "%s from %s\n", ptr->is_not ? "no_" : "", ptr->program->name, ptr->domainname->name)) break;                                  if (io_printf(head, "%s" KEYWORD_KEEP_DOMAIN "%s from %s\n", ptr->is_not ? "no_" : "", ptr->program->name, ptr->domainname->name)) break;
# Line 321  int ReadDomainKeeperPolicy(IO_BUFFER *he Line 304  int ReadDomainKeeperPolicy(IO_BUFFER *he
304    
305  static int IsDomainKeeper(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)  static int IsDomainKeeper(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)
306  {  {
307          DOMAIN_KEEPER_ENTRY *ptr;          struct domain_keeper_entry *ptr;
308          int flag = 0;          int flag = 0;
309          for (ptr = domain_keeper_list; ptr; ptr = ptr->next) {          for (ptr = domain_keeper_list; ptr; ptr = ptr->next) {
310                  if (ptr->is_deleted) continue;                  if (ptr->is_deleted) continue;
# Line 339  static int IsDomainKeeper(const struct p Line 322  static int IsDomainKeeper(const struct p
322    
323  /*************************  SYMBOLIC LINKED PROGRAM HANDLER  *************************/  /*************************  SYMBOLIC LINKED PROGRAM HANDLER  *************************/
324    
325  static ALIAS_ENTRY *alias_list = NULL;  static struct alias_entry *alias_list = NULL;
326    
327  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 int is_delete)
328  {  {
329          ALIAS_ENTRY *new_entry, *ptr;          struct alias_entry *new_entry, *ptr;
330          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
331          const struct path_info *saved_original_name, *saved_aliased_name;          const struct path_info *saved_original_name, *saved_aliased_name;
332          int error = -ENOMEM;          int error = -ENOMEM;
# Line 361  static int AddAliasEntry(const char *ori Line 344  static int AddAliasEntry(const char *ori
344                  error = -ENOENT;                  error = -ENOENT;
345                  goto out;                  goto out;
346          }          }
347          if ((new_entry = (ALIAS_ENTRY *) alloc_element(sizeof(ALIAS_ENTRY))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
348          new_entry->original_name = saved_original_name;          new_entry->original_name = saved_original_name;
349          new_entry->aliased_name = saved_aliased_name;          new_entry->aliased_name = saved_aliased_name;
350          mb(); /* Instead of using spinlock. */          mb(); /* Instead of using spinlock. */
# Line 376  static int AddAliasEntry(const char *ori Line 359  static int AddAliasEntry(const char *ori
359          return error;          return error;
360  }  }
361    
362  int ReadAliasPolicy(IO_BUFFER *head)  int ReadAliasPolicy(struct io_buffer *head)
363  {  {
364          ALIAS_ENTRY *ptr = (ALIAS_ENTRY *) head->read_var2;          struct alias_entry *ptr = head->read_var2;
365          if (!ptr) ptr = alias_list;          if (!ptr) ptr = alias_list;
366          while (ptr) {          while (ptr) {
367                  head->read_var2 = (void *) ptr;                  head->read_var2 = ptr;
368                  if (!ptr->is_deleted && io_printf(head, KEYWORD_ALIAS "%s %s\n", ptr->original_name->name, ptr->aliased_name->name)) break;                  if (!ptr->is_deleted && io_printf(head, KEYWORD_ALIAS "%s %s\n", ptr->original_name->name, ptr->aliased_name->name)) break;
369                  ptr = ptr->next;                  ptr = ptr->next;
370          }          }
# Line 398  int AddAliasPolicy(char *data, const int Line 381  int AddAliasPolicy(char *data, const int
381    
382  /*************************  DOMAIN AGGREGATOR HANDLER  *************************/  /*************************  DOMAIN AGGREGATOR HANDLER  *************************/
383    
384  static AGGREGATOR_ENTRY *aggregator_list = NULL;  static struct aggregator_entry *aggregator_list = NULL;
385    
386  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 int is_delete)
387  {  {
388          AGGREGATOR_ENTRY *new_entry, *ptr;          struct aggregator_entry *new_entry, *ptr;
389          static DECLARE_MUTEX(lock);          static DECLARE_MUTEX(lock);
390          const struct path_info *saved_original_name, *saved_aggregated_name;          const struct path_info *saved_original_name, *saved_aggregated_name;
391          int error = -ENOMEM;          int error = -ENOMEM;
# Line 420  static int AddAggregatorEntry(const char Line 403  static int AddAggregatorEntry(const char
403                  error = -ENOENT;                  error = -ENOENT;
404                  goto out;                  goto out;
405          }          }
406          if ((new_entry = (AGGREGATOR_ENTRY *) alloc_element(sizeof(AGGREGATOR_ENTRY))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
407          new_entry->original_name = saved_original_name;          new_entry->original_name = saved_original_name;
408          new_entry->aggregated_name = saved_aggregated_name;          new_entry->aggregated_name = saved_aggregated_name;
409          mb(); /* Instead of using spinlock. */          mb(); /* Instead of using spinlock. */
# Line 435  static int AddAggregatorEntry(const char Line 418  static int AddAggregatorEntry(const char
418          return error;          return error;
419  }  }
420    
421  int ReadAggregatorPolicy(IO_BUFFER *head)  int ReadAggregatorPolicy(struct io_buffer *head)
422  {  {
423          AGGREGATOR_ENTRY *ptr = (AGGREGATOR_ENTRY *) head->read_var2;          struct aggregator_entry *ptr = head->read_var2;
424          if (!ptr) ptr = aggregator_list;          if (!ptr) ptr = aggregator_list;
425          while (ptr) {          while (ptr) {
426                  head->read_var2 = (void *) ptr;                  head->read_var2 = ptr;
427                  if (!ptr->is_deleted && io_printf(head, KEYWORD_AGGREGATOR "%s %s\n", ptr->original_name->name, ptr->aggregated_name->name)) break;                  if (!ptr->is_deleted && io_printf(head, KEYWORD_AGGREGATOR "%s %s\n", ptr->original_name->name, ptr->aggregated_name->name)) break;
428                  ptr = ptr->next;                  ptr = ptr->next;
429          }          }
# Line 457  int AddAggregatorPolicy(char *data, cons Line 440  int AddAggregatorPolicy(char *data, cons
440    
441  /*************************  DOMAIN DELETION HANDLER  *************************/  /*************************  DOMAIN DELETION HANDLER  *************************/
442    
443  // #define DEBUG_DOMAIN_UNDELETE  /* #define DEBUG_DOMAIN_UNDELETE */
444    
445  int DeleteDomain(char *domainname0)  int DeleteDomain(char *domainname0)
446  {  {
# Line 537  struct domain_info *UndeleteDomain(const Line 520  struct domain_info *UndeleteDomain(const
520    
521  /*************************  DOMAIN TRANSITION HANDLER  *************************/  /*************************  DOMAIN TRANSITION HANDLER  *************************/
522    
 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;  
 }  
   
523  struct domain_info *FindOrAssignNewDomain(const char *domainname, const u8 profile)  struct domain_info *FindOrAssignNewDomain(const char *domainname, const u8 profile)
524  {  {
525          struct domain_info *domain = NULL;          struct domain_info *domain = NULL;
# Line 588  struct domain_info *FindOrAssignNewDomai Line 554  struct domain_info *FindOrAssignNewDomai
554                  goto out;                  goto out;
555          }          }
556          /* No memory reusable. Create using new memory. */          /* No memory reusable. Create using new memory. */
557          if ((domain = (struct domain_info *) alloc_element(sizeof(struct domain_info))) != NULL) {          if ((domain = alloc_element(sizeof(*domain))) != NULL) {
558                  struct domain_info *ptr = &KERNEL_DOMAIN;                  struct domain_info *ptr = &KERNEL_DOMAIN;
559                  domain->domainname = saved_domainname;                  domain->domainname = saved_domainname;
560                  domain->profile = profile;                  domain->profile = profile;
# Line 631  static int Escape(char *dest, const char Line 597  static int Escape(char *dest, const char
597    
598  static char *get_argv0(struct linux_binprm *bprm)  static char *get_argv0(struct linux_binprm *bprm)
599  {  {
600          if (bprm->argc > 0) {          char *arg_ptr = ccs_alloc(PAGE_SIZE); /* Initial buffer. */
601                  char *arg_ptr = ccs_alloc(PAGE_SIZE);          int arg_len = 0;
602                  int arg_len = 0;          unsigned long pos = bprm->p;
603                  const unsigned long pos = bprm->p;          int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;
604                  int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;          if (!bprm->argc || !arg_ptr) goto out;
605                  if (!arg_ptr) goto out;          while (1) {
606                  while (1) {                  struct page *page;
607                          struct page *page = bprm->page[i];  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
608                    if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) goto out;
609    #else
610                    page = bprm->page[i];
611    #endif
612                    { /* Map and copy to kernel buffer and unmap. */
613                          const char *kaddr = kmap(page);                          const char *kaddr = kmap(page);
614                          if (!kaddr) goto out;                          if (!kaddr) { /* Mapping failed. */
615    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
616                                    put_page(page);
617    #endif
618                                    goto out;
619                            }
620                          memmove(arg_ptr + arg_len, kaddr + offset, PAGE_SIZE - offset);                          memmove(arg_ptr + arg_len, kaddr + offset, PAGE_SIZE - offset);
621                          kunmap(page);                          kunmap(page);
                         arg_len += PAGE_SIZE - offset;  
                         if (memchr(arg_ptr, '\0', arg_len)) break;  
                         {  
                                 char *tmp_arg_ptr = ccs_alloc(arg_len + PAGE_SIZE);  
                                 if (!tmp_arg_ptr) goto out;  
                                 memmove(tmp_arg_ptr, arg_ptr, arg_len);  
                                 ccs_free(arg_ptr);  
                                 arg_ptr = tmp_arg_ptr;  
                         }  
                         i++;  
                         offset = 0;  
622                  }                  }
623                  return arg_ptr;  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
624          out:                  put_page(page);
625                  ccs_free(arg_ptr);                  pos += PAGE_SIZE - offset;
626          }  #endif
627                    arg_len += PAGE_SIZE - offset;
628                    if (memchr(arg_ptr, '\0', arg_len)) break;
629                    { /* Initial buffer was too small for argv[0]. Retry after expanding buffer. */
630                            char *tmp_arg_ptr = ccs_alloc(arg_len + PAGE_SIZE);
631                            if (!tmp_arg_ptr) goto out;
632                            memmove(tmp_arg_ptr, arg_ptr, arg_len);
633                            ccs_free(arg_ptr);
634                            arg_ptr = tmp_arg_ptr;
635                    }
636                    i++;
637                    offset = 0;
638            }
639            return arg_ptr;
640     out: /* Release initial buffer. */
641            ccs_free(arg_ptr);
642          return NULL;          return NULL;
643  }  }
644    
# Line 681  static int FindNextDomain(struct linux_b Line 661  static int FindNextDomain(struct linux_b
661                   */                   */
662                  static int first = 1;                  static int first = 1;
663                  if (first) {                  if (first) {
664                          AddDomainInitializerEntry(NULL, "/sbin/hotplug", 0, 0, 0);                          AddDomainInitializerEntry(NULL, "/sbin/hotplug", 0, 0);
665                          AddDomainInitializerEntry(NULL, "/sbin/modprobe", 0, 0, 0);                          AddDomainInitializerEntry(NULL, "/sbin/modprobe", 0, 0);
666                          first = 0;                          first = 0;
667                  }                  }
668          }          }
# Line 703  static int FindNextDomain(struct linux_b Line 683  static int FindNextDomain(struct linux_b
683    
684          /* Check 'alias' directive. */          /* Check 'alias' directive. */
685          if (pathcmp(&r, &s)) {          if (pathcmp(&r, &s)) {
686                  ALIAS_ENTRY *ptr;                  struct alias_entry *ptr;
687                  /* Is this program allowed to be called via symbolic links? */                  /* Is this program allowed to be called via symbolic links? */
688                  for (ptr = alias_list; ptr; ptr = ptr->next) {                  for (ptr = alias_list; ptr; ptr = ptr->next) {
689                          if (ptr->is_deleted || pathcmp(&r, ptr->original_name) || pathcmp(&s, ptr->aliased_name)) continue;                          if (ptr->is_deleted || pathcmp(&r, ptr->original_name) || pathcmp(&s, ptr->aliased_name)) continue;
# Line 714  static int FindNextDomain(struct linux_b Line 694  static int FindNextDomain(struct linux_b
694                  }                  }
695          }          }
696                    
697          /* Check 'aggregator' directive. */          /* Compare basename of real_program_name and argv[0] */
         {  
                 AGGREGATOR_ENTRY *ptr;  
                 /* Is this program allowed to be aggregated? */  
                 for (ptr = aggregator_list; ptr; ptr = ptr->next) {  
                         if (ptr->is_deleted || !PathMatchesToPattern(&r, ptr->original_name)) continue;  
                         memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);  
                         strncpy(real_program_name, ptr->aggregated_name->name, CCS_MAX_PATHNAME_LEN - 1);  
                         fill_path_info(&r);  
                         break;  
                 }  
         }  
   
         /* Compare basename of symlink_program_name and argv[0] */  
698          if (bprm->argc > 0 && CheckCCSFlags(CCS_TOMOYO_MAC_FOR_ARGV0)) {          if (bprm->argc > 0 && CheckCCSFlags(CCS_TOMOYO_MAC_FOR_ARGV0)) {
699                  char *org_argv0 = get_argv0(bprm);                  char *org_argv0 = get_argv0(bprm);
700                  retval = -ENOMEM;                  retval = -ENOMEM;
# Line 737  static int FindNextDomain(struct linux_b Line 704  static int FindNextDomain(struct linux_b
704                          if (printable_argv0 && Escape(printable_argv0, org_argv0, len * 4 + 8) == 0) {                          if (printable_argv0 && Escape(printable_argv0, org_argv0, len * 4 + 8) == 0) {
705                                  const char *base_argv0, *base_filename;                                  const char *base_argv0, *base_filename;
706                                  if ((base_argv0 = strrchr(printable_argv0, '/')) == NULL) base_argv0 = printable_argv0; else base_argv0++;                                  if ((base_argv0 = strrchr(printable_argv0, '/')) == NULL) base_argv0 = printable_argv0; else base_argv0++;
707                                  if ((base_filename = strrchr(symlink_program_name, '/')) == NULL) base_filename = symlink_program_name; else base_filename++;                                  if ((base_filename = strrchr(real_program_name, '/')) == NULL) base_filename = real_program_name; else base_filename++;
708                                  if (strcmp(base_argv0, base_filename)) retval = CheckArgv0Perm(&s, base_argv0);                                  if (strcmp(base_argv0, base_filename)) retval = CheckArgv0Perm(&r, base_argv0);
709                                  else retval = 0;                                  else retval = 0;
710                          }                          }
711                          ccs_free(printable_argv0);                          ccs_free(printable_argv0);
# Line 747  static int FindNextDomain(struct linux_b Line 714  static int FindNextDomain(struct linux_b
714                  if (retval) goto out;                  if (retval) goto out;
715          }          }
716                    
717            /* Check 'aggregator' directive. */
718            {
719                    struct aggregator_entry *ptr;
720                    /* Is this program allowed to be aggregated? */
721                    for (ptr = aggregator_list; ptr; ptr = ptr->next) {
722                            if (ptr->is_deleted || !PathMatchesToPattern(&r, ptr->original_name)) continue;
723                            memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
724                            strncpy(real_program_name, ptr->aggregated_name->name, CCS_MAX_PATHNAME_LEN - 1);
725                            fill_path_info(&r);
726                            break;
727                    }
728            }
729    
730          /* Check execute permission. */          /* Check execute permission. */
731          if ((retval = CheckExecPerm(&r, filp)) < 0) goto out;          if ((retval = CheckExecPerm(&r, filp)) < 0) goto out;
732    

Legend:
Removed from v.141  
changed lines
  Added in v.502

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