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

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 652 by kumaneko, Mon Nov 5 07:48:31 2007 UTC revision 708 by kumaneko, Mon Nov 19 08:44: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.5.2-pre   2007/10/19   * Version: 1.5.2-pre   2007/11/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 26  Line 26 
26  /*************************  VARIABLES  *************************/  /*************************  VARIABLES  *************************/
27    
28  /* The initial domain. */  /* The initial domain. */
29  struct domain_info KERNEL_DOMAIN = { NULL, NULL, NULL, 0, 0, 0 };  struct domain_info KERNEL_DOMAIN;
30    
31    /* List of domains. */
32    LIST_HEAD(domain_list);
33    
34  /* /sbin/init started? */  /* /sbin/init started? */
35  extern int sbin_init_started;  extern int sbin_init_started;
# Line 41  DEFINE_MUTEX(domain_acl_lock); Line 44  DEFINE_MUTEX(domain_acl_lock);
44  /***** The structure for program files to force domain reconstruction. *****/  /***** The structure for program files to force domain reconstruction. *****/
45    
46  struct domain_initializer_entry {  struct domain_initializer_entry {
47          struct domain_initializer_entry *next;          struct list_head list;
48          const struct path_info *domainname;    /* This may be NULL */          const struct path_info *domainname;    /* This may be NULL */
49          const struct path_info *program;          const struct path_info *program;
50          bool is_deleted;          bool is_deleted;
# Line 52  struct domain_initializer_entry { Line 55  struct domain_initializer_entry {
55  /***** The structure for domains to not to transit domains. *****/  /***** The structure for domains to not to transit domains. *****/
56    
57  struct domain_keeper_entry {  struct domain_keeper_entry {
58          struct domain_keeper_entry *next;          struct list_head list;
59          const struct path_info *domainname;          const struct path_info *domainname;
60          const struct path_info *program;       /* This may be NULL */          const struct path_info *program;       /* This may be NULL */
61          bool is_deleted;          bool is_deleted;
# Line 63  struct domain_keeper_entry { Line 66  struct domain_keeper_entry {
66  /***** The structure for program files that should be aggregated. *****/  /***** The structure for program files that should be aggregated. *****/
67    
68  struct aggregator_entry {  struct aggregator_entry {
69          struct aggregator_entry *next;          struct list_head list;
70          const struct path_info *original_name;          const struct path_info *original_name;
71          const struct path_info *aggregated_name;          const struct path_info *aggregated_name;
72          bool is_deleted;          bool is_deleted;
# Line 72  struct aggregator_entry { Line 75  struct aggregator_entry {
75  /***** The structure for program files that should be aliased. *****/  /***** The structure for program files that should be aliased. *****/
76    
77  struct alias_entry {  struct alias_entry {
78          struct alias_entry *next;          struct list_head list;
79          const struct path_info *original_name;          const struct path_info *original_name;
80          const struct path_info *aliased_name;          const struct path_info *aliased_name;
81          bool is_deleted;          bool is_deleted;
# Line 92  const char *GetLastName(const struct dom Line 95  const char *GetLastName(const struct dom
95          return cp0;          return cp0;
96  }  }
97    
98  int AddDomainACL(struct acl_info *ptr, struct domain_info *domain, struct acl_info *new_ptr)  int AddDomainACL(struct domain_info *domain, struct acl_info *acl)
99  {  {
100          mb(); /* Instead of using spinlock. */          list_add_tail_mb(&acl->list, &domain->acl_info_list);
         if (!ptr) domain->first_acl_ptr = (struct acl_info *) new_ptr;  
         else ptr->next = (struct acl_info *) new_ptr;  
101          UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);          UpdateCounter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
102          return 0;          return 0;
103  }  }
# Line 110  int DelDomainACL(struct acl_info *ptr) Line 111  int DelDomainACL(struct acl_info *ptr)
111    
112  /*************************  DOMAIN INITIALIZER HANDLER  *************************/  /*************************  DOMAIN INITIALIZER HANDLER  *************************/
113    
114  static struct domain_initializer_entry *domain_initializer_list = NULL;  static LIST_HEAD(domain_initializer_list);
115    
116  static int AddDomainInitializerEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)  static int AddDomainInitializerEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)
117  {  {
# Line 130  static int AddDomainInitializerEntry(con Line 131  static int AddDomainInitializerEntry(con
131          }          }
132          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;          if ((saved_program = SaveName(program)) == NULL) return -ENOMEM;
133          mutex_lock(&lock);          mutex_lock(&lock);
134          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr, &domain_initializer_list, list) {
135                  if (ptr->is_not == is_not && ptr->domainname == saved_domainname && ptr->program == saved_program) {                  if (ptr->is_not == is_not && ptr->domainname == saved_domainname && ptr->program == saved_program) {
136                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
137                          error = 0;                          error = 0;
# Line 146  static int AddDomainInitializerEntry(con Line 147  static int AddDomainInitializerEntry(con
147          new_entry->program = saved_program;          new_entry->program = saved_program;
148          new_entry->is_not = is_not;          new_entry->is_not = is_not;
149          new_entry->is_last_name = is_last_name;          new_entry->is_last_name = is_last_name;
150          mb(); /* Instead of using spinlock. */          list_add_tail_mb(&new_entry->list, &domain_initializer_list);
         if ((ptr = domain_initializer_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 domain_initializer_list = new_entry;  
         }  
151          error = 0;          error = 0;
152   out:   out:
153          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 160  static int AddDomainInitializerEntry(con Line 156  static int AddDomainInitializerEntry(con
156    
157  int ReadDomainInitializerPolicy(struct io_buffer *head)  int ReadDomainInitializerPolicy(struct io_buffer *head)
158  {  {
159          struct domain_initializer_entry *ptr = head->read_var2;          struct list_head *pos;
160          if (!ptr) ptr = domain_initializer_list;          list_for_each_cookie(pos, head->read_var2, &domain_initializer_list) {
161          while (ptr) {                  struct domain_initializer_entry *ptr;
162                  head->read_var2 = ptr;                  ptr = list_entry(pos, struct domain_initializer_entry, list);
163                  if (!ptr->is_deleted) {                  if (ptr->is_deleted) continue;
164                          if (ptr->domainname) {                  if (ptr->domainname) {
165                                  if (io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN "%s from %s\n", ptr->is_not ? "no_" : "", 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)) return -ENOMEM;
166                          } else {                  } else {
167                                  if (io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN "%s\n", ptr->is_not ? "no_" : "", ptr->program->name)) break;                          if (io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN "%s\n", ptr->is_not ? "no_" : "", ptr->program->name)) return -ENOMEM;
                         }  
168                  }                  }
                 ptr = ptr->next;  
169          }          }
170          return ptr ? -ENOMEM : 0;          return 0;
171  }  }
172    
173  int AddDomainInitializerPolicy(char *data, const bool is_not, const bool is_delete)  int AddDomainInitializerPolicy(char *data, const bool is_not, const bool is_delete)
# Line 187  int AddDomainInitializerPolicy(char *dat Line 181  int AddDomainInitializerPolicy(char *dat
181          }          }
182  }  }
183    
184  static int IsDomainInitializer(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)  static bool IsDomainInitializer(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)
185  {  {
186          struct domain_initializer_entry *ptr;          struct domain_initializer_entry *ptr;
187          int flag = 0;          bool flag = 0;
188          for (ptr = domain_initializer_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr,  &domain_initializer_list, list) {
189                  if (ptr->is_deleted ) continue;                  if (ptr->is_deleted) continue;
190                  if (ptr->domainname) {                  if (ptr->domainname) {
191                          if (!ptr->is_last_name) {                          if (!ptr->is_last_name) {
192                                  if (ptr->domainname != domainname) continue;                                  if (ptr->domainname != domainname) continue;
# Line 209  static int IsDomainInitializer(const str Line 203  static int IsDomainInitializer(const str
203    
204  /*************************  DOMAIN KEEPER HANDLER  *************************/  /*************************  DOMAIN KEEPER HANDLER  *************************/
205    
206  static struct domain_keeper_entry *domain_keeper_list = NULL;  static LIST_HEAD(domain_keeper_list);
207    
208  static int AddDomainKeeperEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)  static int AddDomainKeeperEntry(const char *domainname, const char *program, const bool is_not, const bool is_delete)
209  {  {
# Line 229  static int AddDomainKeeperEntry(const ch Line 223  static int AddDomainKeeperEntry(const ch
223          }          }
224          if ((saved_domainname = SaveName(domainname)) == NULL) return -ENOMEM;          if ((saved_domainname = SaveName(domainname)) == NULL) return -ENOMEM;
225          mutex_lock(&lock);          mutex_lock(&lock);
226          for (ptr = domain_keeper_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr, &domain_keeper_list, list) {
227                  if (ptr->is_not == is_not && ptr->domainname == saved_domainname && ptr->program == saved_program) {                  if (ptr->is_not == is_not && ptr->domainname == saved_domainname && ptr->program == saved_program) {
228                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
229                          error = 0;                          error = 0;
# Line 245  static int AddDomainKeeperEntry(const ch Line 239  static int AddDomainKeeperEntry(const ch
239          new_entry->program = saved_program;          new_entry->program = saved_program;
240          new_entry->is_not = is_not;          new_entry->is_not = is_not;
241          new_entry->is_last_name = is_last_name;          new_entry->is_last_name = is_last_name;
242          mb(); /* Instead of using spinlock. */          list_add_tail_mb(&new_entry->list, &domain_keeper_list);
         if ((ptr = domain_keeper_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 domain_keeper_list = new_entry;  
         }  
243          error = 0;          error = 0;
244   out:   out:
245          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 270  int AddDomainKeeperPolicy(char *data, co Line 259  int AddDomainKeeperPolicy(char *data, co
259    
260  int ReadDomainKeeperPolicy(struct io_buffer *head)  int ReadDomainKeeperPolicy(struct io_buffer *head)
261  {  {
262          struct domain_keeper_entry *ptr = head->read_var2;          struct list_head *pos;
263          if (!ptr) ptr = domain_keeper_list;          list_for_each_cookie(pos, head->read_var2, &domain_keeper_list) {
264          while (ptr) {                  struct domain_keeper_entry *ptr;
265                  head->read_var2 = ptr;                  ptr = list_entry(pos, struct domain_keeper_entry, list);
266                  if (!ptr->is_deleted) {                  if (ptr->is_deleted) continue;
267                          if (ptr->program) {                  if (ptr->program) {
268                                  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)) return -ENOMEM;
269                          } else {                  } else {
270                                  if (io_printf(head, "%s" KEYWORD_KEEP_DOMAIN "%s\n", ptr->is_not ? "no_" : "", ptr->domainname->name)) break;                          if (io_printf(head, "%s" KEYWORD_KEEP_DOMAIN "%s\n", ptr->is_not ? "no_" : "", ptr->domainname->name)) return -ENOMEM;
                         }  
271                  }                  }
                 ptr = ptr->next;  
272          }          }
273          return ptr ? -ENOMEM : 0;          return 0;
274  }  }
275    
276  static int IsDomainKeeper(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)  static bool IsDomainKeeper(const struct path_info *domainname, const struct path_info *program, const struct path_info *last_name)
277  {  {
278          struct domain_keeper_entry *ptr;          struct domain_keeper_entry *ptr;
279          int flag = 0;          bool flag = 0;
280          for (ptr = domain_keeper_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr, &domain_keeper_list, list) {
281                  if (ptr->is_deleted) continue;                  if (ptr->is_deleted) continue;
282                  if (!ptr->is_last_name) {                  if (!ptr->is_last_name) {
283                          if (ptr->domainname != domainname) continue;                          if (ptr->domainname != domainname) continue;
284                  } else {                  } else {
285                          if (pathcmp(ptr->domainname, last_name)) continue;                          if (pathcmp(ptr->domainname, last_name)) continue;
286                  }                  }
287                  if (ptr->program && pathcmp(ptr->program, program)) continue;                  if (ptr->program && pathcmp(ptr->program, program)) continue;
288                  if (ptr->is_not) return 0;                  if (ptr->is_not) return 0;
# Line 306  static int IsDomainKeeper(const struct p Line 293  static int IsDomainKeeper(const struct p
293    
294  /*************************  SYMBOLIC LINKED PROGRAM HANDLER  *************************/  /*************************  SYMBOLIC LINKED PROGRAM HANDLER  *************************/
295    
296  static struct alias_entry *alias_list = NULL;  static LIST_HEAD(alias_list);
297    
298  static int AddAliasEntry(const char *original_name, const char *aliased_name, const bool is_delete)  static int AddAliasEntry(const char *original_name, const char *aliased_name, const bool is_delete)
299  {  {
# Line 317  static int AddAliasEntry(const char *ori Line 304  static int AddAliasEntry(const char *ori
304          if (!IsCorrectPath(original_name, 1, -1, -1, __FUNCTION__) || !IsCorrectPath(aliased_name, 1, -1, -1, __FUNCTION__)) return -EINVAL; /* No patterns allowed. */          if (!IsCorrectPath(original_name, 1, -1, -1, __FUNCTION__) || !IsCorrectPath(aliased_name, 1, -1, -1, __FUNCTION__)) return -EINVAL; /* No patterns allowed. */
305          if ((saved_original_name = SaveName(original_name)) == NULL || (saved_aliased_name = SaveName(aliased_name)) == NULL) return -ENOMEM;          if ((saved_original_name = SaveName(original_name)) == NULL || (saved_aliased_name = SaveName(aliased_name)) == NULL) return -ENOMEM;
306          mutex_lock(&lock);          mutex_lock(&lock);
307          for (ptr = alias_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr, &alias_list, list) {
308                  if (ptr->original_name == saved_original_name && ptr->aliased_name == saved_aliased_name) {                  if (ptr->original_name == saved_original_name && ptr->aliased_name == saved_aliased_name) {
309                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
310                          error = 0;                          error = 0;
# Line 331  static int AddAliasEntry(const char *ori Line 318  static int AddAliasEntry(const char *ori
318          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
319          new_entry->original_name = saved_original_name;          new_entry->original_name = saved_original_name;
320          new_entry->aliased_name = saved_aliased_name;          new_entry->aliased_name = saved_aliased_name;
321          mb(); /* Instead of using spinlock. */          list_add_tail_mb(&new_entry->list, &alias_list);
         if ((ptr = alias_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 alias_list = new_entry;  
         }  
322          error = 0;          error = 0;
323   out:   out:
324          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 345  static int AddAliasEntry(const char *ori Line 327  static int AddAliasEntry(const char *ori
327    
328  int ReadAliasPolicy(struct io_buffer *head)  int ReadAliasPolicy(struct io_buffer *head)
329  {  {
330          struct alias_entry *ptr = head->read_var2;          struct list_head *pos;
331          if (!ptr) ptr = alias_list;          list_for_each_cookie(pos, head->read_var2, &alias_list) {
332          while (ptr) {                  struct alias_entry *ptr;
333                  head->read_var2 = ptr;                  ptr = list_entry(pos, struct alias_entry, list);
334                  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) continue;
335                  ptr = ptr->next;                  if (io_printf(head, KEYWORD_ALIAS "%s %s\n", ptr->original_name->name, ptr->aliased_name->name)) return -ENOMEM;
336          }          }
337          return ptr ? -ENOMEM : 0;          return 0;
338  }  }
339    
340  int AddAliasPolicy(char *data, const bool is_delete)  int AddAliasPolicy(char *data, const bool is_delete)
# Line 365  int AddAliasPolicy(char *data, const boo Line 347  int AddAliasPolicy(char *data, const boo
347    
348  /*************************  DOMAIN AGGREGATOR HANDLER  *************************/  /*************************  DOMAIN AGGREGATOR HANDLER  *************************/
349    
350  static struct aggregator_entry *aggregator_list = NULL;  static LIST_HEAD(aggregator_list);
351    
352  static int AddAggregatorEntry(const char *original_name, const char *aggregated_name, const bool is_delete)  static int AddAggregatorEntry(const char *original_name, const char *aggregated_name, const bool is_delete)
353  {  {
# Line 376  static int AddAggregatorEntry(const char Line 358  static int AddAggregatorEntry(const char
358          if (!IsCorrectPath(original_name, 1, 0, -1, __FUNCTION__) || !IsCorrectPath(aggregated_name, 1, -1, -1, __FUNCTION__)) return -EINVAL;          if (!IsCorrectPath(original_name, 1, 0, -1, __FUNCTION__) || !IsCorrectPath(aggregated_name, 1, -1, -1, __FUNCTION__)) return -EINVAL;
359          if ((saved_original_name = SaveName(original_name)) == NULL || (saved_aggregated_name = SaveName(aggregated_name)) == NULL) return -ENOMEM;          if ((saved_original_name = SaveName(original_name)) == NULL || (saved_aggregated_name = SaveName(aggregated_name)) == NULL) return -ENOMEM;
360          mutex_lock(&lock);          mutex_lock(&lock);
361          for (ptr = aggregator_list; ptr; ptr = ptr->next) {          list_for_each_entry(ptr, &aggregator_list, list) {
362                  if (ptr->original_name == saved_original_name && ptr->aggregated_name == saved_aggregated_name) {                  if (ptr->original_name == saved_original_name && ptr->aggregated_name == saved_aggregated_name) {
363                          ptr->is_deleted = is_delete;                          ptr->is_deleted = is_delete;
364                          error = 0;                          error = 0;
# Line 390  static int AddAggregatorEntry(const char Line 372  static int AddAggregatorEntry(const char
372          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;          if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out;
373          new_entry->original_name = saved_original_name;          new_entry->original_name = saved_original_name;
374          new_entry->aggregated_name = saved_aggregated_name;          new_entry->aggregated_name = saved_aggregated_name;
375          mb(); /* Instead of using spinlock. */          list_add_tail_mb(&new_entry->list, &aggregator_list);
         if ((ptr = aggregator_list) != NULL) {  
                 while (ptr->next) ptr = ptr->next; ptr->next = new_entry;  
         } else {  
                 aggregator_list = new_entry;  
         }  
376          error = 0;          error = 0;
377   out:   out:
378          mutex_unlock(&lock);          mutex_unlock(&lock);
# Line 404  static int AddAggregatorEntry(const char Line 381  static int AddAggregatorEntry(const char
381    
382  int ReadAggregatorPolicy(struct io_buffer *head)  int ReadAggregatorPolicy(struct io_buffer *head)
383  {  {
384          struct aggregator_entry *ptr = head->read_var2;          struct list_head *pos;
385          if (!ptr) ptr = aggregator_list;          list_for_each_cookie(pos, head->read_var2, &aggregator_list) {
386          while (ptr) {                  struct aggregator_entry *ptr;
387                  head->read_var2 = ptr;                  ptr = list_entry(pos, struct aggregator_entry, list);
388                  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) continue;
389                  ptr = ptr->next;                  if (io_printf(head, KEYWORD_AGGREGATOR "%s %s\n", ptr->original_name->name, ptr->aggregated_name->name)) return -ENOMEM;
390          }          }
391          return ptr ? -ENOMEM : 0;          return 0;
392  }  }
393    
394  int AddAggregatorPolicy(char *data, const bool is_delete)  int AddAggregatorPolicy(char *data, const bool is_delete)
# Line 435  int DeleteDomain(char *domainname0) Line 412  int DeleteDomain(char *domainname0)
412          mutex_lock(&new_domain_assign_lock);          mutex_lock(&new_domain_assign_lock);
413  #ifdef DEBUG_DOMAIN_UNDELETE  #ifdef DEBUG_DOMAIN_UNDELETE
414          printk("DeleteDomain %s\n", domainname0);          printk("DeleteDomain %s\n", domainname0);
415          for (domain = KERNEL_DOMAIN.next; domain; domain = domain->next) {          list_for_each_entry(domain, &domain_list, list) {
416                  if (pathcmp(domain->domainname, &domainname)) continue;                  if (pathcmp(domain->domainname, &domainname)) continue;
417                  printk("List: %p %u\n", domain, domain->is_deleted);                  printk("List: %p %u\n", domain, domain->is_deleted);
418          }          }
419  #endif  #endif
420          /* Is there an active domain? */          /* Is there an active domain? */
421          for (domain = KERNEL_DOMAIN.next; domain; domain = domain->next) { /* Never delete KERNEL_DOMAIN */          list_for_each_entry(domain, &domain_list, list) {
                 if (domain->is_deleted || pathcmp(domain->domainname, &domainname)) continue;  
                 break;  
         }  
         if (domain) {  
422                  struct domain_info *domain2;                  struct domain_info *domain2;
423                    /* Never delete KERNEL_DOMAIN */
424                    if (domain == &KERNEL_DOMAIN || domain->is_deleted || pathcmp(domain->domainname, &domainname)) continue;
425                  /* Mark already deleted domains as non undeletable. */                  /* Mark already deleted domains as non undeletable. */
426                  for (domain2 = KERNEL_DOMAIN.next; domain2; domain2 = domain2->next) {                  list_for_each_entry(domain2, &domain_list, list) {
427                          if (!domain2->is_deleted || pathcmp(domain2->domainname, &domainname)) continue;                          if (!domain2->is_deleted || pathcmp(domain2->domainname, &domainname)) continue;
428  #ifdef DEBUG_DOMAIN_UNDELETE  #ifdef DEBUG_DOMAIN_UNDELETE
429                          if (domain2->is_deleted != 255) printk("Marked %p as non undeletable\n", domain2);                          if (domain2->is_deleted != 255) printk("Marked %p as non undeletable\n", domain2);
# Line 460  int DeleteDomain(char *domainname0) Line 435  int DeleteDomain(char *domainname0)
435  #ifdef DEBUG_DOMAIN_UNDELETE  #ifdef DEBUG_DOMAIN_UNDELETE
436                  printk("Marked %p as undeletable\n", domain);                  printk("Marked %p as undeletable\n", domain);
437  #endif  #endif
438                    break;
439          }          }
440          mutex_unlock(&new_domain_assign_lock);          mutex_unlock(&new_domain_assign_lock);
441          return 0;          return 0;
# Line 474  struct domain_info *UndeleteDomain(const Line 450  struct domain_info *UndeleteDomain(const
450          mutex_lock(&new_domain_assign_lock);          mutex_lock(&new_domain_assign_lock);
451  #ifdef DEBUG_DOMAIN_UNDELETE  #ifdef DEBUG_DOMAIN_UNDELETE
452          printk("UndeleteDomain %s\n", domainname0);          printk("UndeleteDomain %s\n", domainname0);
453          for (domain = KERNEL_DOMAIN.next; domain; domain = domain->next) {          list_for_each_entry(domain, &domain_list, list) {
454                  if (pathcmp(domain->domainname, &domainname)) continue;                  if (pathcmp(domain->domainname, &domainname)) continue;
455                  printk("List: %p %u\n", domain, domain->is_deleted);                  printk("List: %p %u\n", domain, domain->is_deleted);
456          }          }
457  #endif  #endif
458          for (domain = KERNEL_DOMAIN.next; domain; domain = domain->next) {          list_for_each_entry(domain, &domain_list, list) {
459                  if (pathcmp(&domainname, domain->domainname)) continue;                  if (pathcmp(&domainname, domain->domainname)) continue;
460                  if (!domain->is_deleted) {                  if (!domain->is_deleted) {
461                          /* This domain is active. I can't undelete. */                          /* This domain is active. I can't undelete. */
# Line 513  struct domain_info *FindOrAssignNewDomai Line 489  struct domain_info *FindOrAssignNewDomai
489          if (!IsCorrectDomain(domainname, __FUNCTION__)) goto out;          if (!IsCorrectDomain(domainname, __FUNCTION__)) goto out;
490          if ((saved_domainname = SaveName(domainname)) == NULL) goto out;          if ((saved_domainname = SaveName(domainname)) == NULL) goto out;
491          /* Can I reuse memory of deleted domain? */          /* Can I reuse memory of deleted domain? */
492          for (domain = KERNEL_DOMAIN.next; domain; domain = domain->next) {          list_for_each_entry(domain, &domain_list, list) {
493                  struct task_struct *p;                  struct task_struct *p;
494                  struct acl_info *ptr;                  struct acl_info *ptr;
495                  int flag;                  int flag;
# Line 530  struct domain_info *FindOrAssignNewDomai Line 506  struct domain_info *FindOrAssignNewDomai
506  #ifdef DEBUG_DOMAIN_UNDELETE  #ifdef DEBUG_DOMAIN_UNDELETE
507                  printk("Reusing %p %s\n", domain, domain->domainname->name);                  printk("Reusing %p %s\n", domain, domain->domainname->name);
508  #endif  #endif
509                  for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) ptr->is_deleted = 1;                  list_for_each_entry(ptr, &domain->acl_info_list, list) ptr->is_deleted = 1;
510                  domain->profile = profile;                  domain->profile = profile;
511                  domain->quota_warned = 0;                  domain->quota_warned = 0;
512                  mb(); /* Instead of using spinlock. */                  mb(); /* Avoid out-of-order execution. */
513                  domain->is_deleted = 0;                  domain->is_deleted = 0;
514                  goto out;                  goto out;
515          }          }
516          /* No memory reusable. Create using new memory. */          /* No memory reusable. Create using new memory. */
517          if ((domain = alloc_element(sizeof(*domain))) != NULL) {          if ((domain = alloc_element(sizeof(*domain))) != NULL) {
518                  struct domain_info *ptr = &KERNEL_DOMAIN;                  INIT_LIST_HEAD(&domain->acl_info_list);
519                  domain->domainname = saved_domainname;                  domain->domainname = saved_domainname;
520                  domain->profile = profile;                  domain->profile = profile;
521                  mb(); /* Instead of using spinlock. */                  list_add_tail_mb(&domain->list, &domain_list);
                 while (ptr->next) ptr = ptr->next; ptr->next = domain;  
522          }          }
523   out: ;   out: ;
524          mutex_unlock(&new_domain_assign_lock);          mutex_unlock(&new_domain_assign_lock);
# Line 626  static char *get_argv0(struct linux_binp Line 601  static char *get_argv0(struct linux_binp
601          return NULL;          return NULL;
602  }  }
603    
604  static int FindNextDomain(struct linux_binprm *bprm, struct domain_info **next_domain)  static int FindNextDomain(struct linux_binprm *bprm, struct domain_info **next_domain, const u8 do_perm_check)
605  {  {
606          /* This function assumes that the size of buffer returned by realpath() = CCS_MAX_PATHNAME_LEN. */          /* This function assumes that the size of buffer returned by realpath() = CCS_MAX_PATHNAME_LEN. */
607          struct domain_info *old_domain = current->domain_info, *domain = NULL;          struct domain_info *old_domain = current->domain_info, *domain = NULL;
# Line 665  static int FindNextDomain(struct linux_b Line 640  static int FindNextDomain(struct linux_b
640          else l.name = old_domain_name;          else l.name = old_domain_name;
641          fill_path_info(&l);          fill_path_info(&l);
642    
643            if (!do_perm_check) goto ok;
644    
645          /* Check 'alias' directive. */          /* Check 'alias' directive. */
646          if (pathcmp(&r, &s)) {          if (pathcmp(&r, &s)) {
647                  struct alias_entry *ptr;                  struct alias_entry *ptr;
648                  /* Is this program allowed to be called via symbolic links? */                  /* Is this program allowed to be called via symbolic links? */
649                  for (ptr = alias_list; ptr; ptr = ptr->next) {                  list_for_each_entry(ptr, &alias_list, list) {
650                          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;
651                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
652                          strncpy(real_program_name, ptr->aliased_name->name, CCS_MAX_PATHNAME_LEN - 1);                          strncpy(real_program_name, ptr->aliased_name->name, CCS_MAX_PATHNAME_LEN - 1);
# Line 702  static int FindNextDomain(struct linux_b Line 679  static int FindNextDomain(struct linux_b
679          {          {
680                  struct aggregator_entry *ptr;                  struct aggregator_entry *ptr;
681                  /* Is this program allowed to be aggregated? */                  /* Is this program allowed to be aggregated? */
682                  for (ptr = aggregator_list; ptr; ptr = ptr->next) {                  list_for_each_entry(ptr, &aggregator_list, list) {
683                          if (ptr->is_deleted || !PathMatchesToPattern(&r, ptr->original_name)) continue;                          if (ptr->is_deleted || !PathMatchesToPattern(&r, ptr->original_name)) continue;
684                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
685                          strncpy(real_program_name, ptr->aggregated_name->name, CCS_MAX_PATHNAME_LEN - 1);                          strncpy(real_program_name, ptr->aggregated_name->name, CCS_MAX_PATHNAME_LEN - 1);
# Line 714  static int FindNextDomain(struct linux_b Line 691  static int FindNextDomain(struct linux_b
691          /* Check execute permission. */          /* Check execute permission. */
692          if ((retval = CheckExecPerm(&r, filp)) < 0) goto out;          if ((retval = CheckExecPerm(&r, filp)) < 0) goto out;
693    
694     ok: ;
695          /* Allocate memory for calcurating domain name. */          /* Allocate memory for calcurating domain name. */
696          retval = -ENOMEM;          retval = -ENOMEM;
697          if ((new_domain_name = ccs_alloc(CCS_MAX_PATHNAME_LEN + 16)) == NULL) goto out;          if ((new_domain_name = ccs_alloc(CCS_MAX_PATHNAME_LEN + 16)) == NULL) goto out;
# Line 838  static int CheckEnviron(struct linux_bin Line 816  static int CheckEnviron(struct linux_bin
816          return error;          return error;
817  }  }
818    
819    static void UnEscape(unsigned char *dest)
820    {
821            unsigned char *src = dest;
822            unsigned char c, d, e;
823            while ((c = *src++) != '\0') {
824                    if (c != '\\') {
825                            *dest++ = c;
826                            continue;
827                    }
828                    c = *src++;
829                    if (c == '\\') {
830                            *dest++ = c;
831                    } else if (c >= '0' && c <= '3' &&
832                               (d = *src++) >= '0' && d <= '7' &&
833                               (e = *src++) >= '0' && e <= '7') {
834                            *dest++ = ((c - '0') << 6) | ((d - '0') << 3) | (e - '0');
835                    } else {
836                            break;
837                    }
838            }
839            *dest = '\0';
840    }
841    
842    static int try_alt_exec(struct linux_binprm *bprm, char **alt_exec0)
843    {
844            struct file *filp;
845            int retval;
846            /* domainname must not be modified. */
847            char *domainname = (char *) current->domain_info->domainname->name;
848            char *alt_exec;
849            const char *alt_exec1 = GetAltExec();
850            if (!alt_exec1 || *alt_exec1 != '/') return -EINVAL;
851            retval = strlen(alt_exec1) + 1;
852            *alt_exec0 = alt_exec = ccs_alloc(retval);
853            if (!alt_exec) return -ENOMEM;
854            memmove(alt_exec, alt_exec1, retval);
855            UnEscape(alt_exec);
856            allow_write_access(bprm->file);
857            fput(bprm->file);
858            bprm->file = NULL;
859    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
860            retval = remove_arg_zero(bprm);
861            if (retval) return retval;
862    #else
863            remove_arg_zero(bprm);
864    #endif
865    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
866            retval = copy_strings_kernel(1, &bprm->interp, bprm);
867    #else
868            retval = copy_strings_kernel(1, &bprm->filename, bprm);
869    #endif
870            if (retval < 0) return retval;
871            bprm->argc++;
872            retval = copy_strings_kernel(1, &domainname, bprm);
873            if (retval < 0) return retval;
874            bprm->argc++;
875            retval = copy_strings_kernel(1, &alt_exec, bprm);
876            if (retval < 0) return retval;
877            bprm->argc++;
878    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
879            bprm->interp = alt_exec;
880    #endif
881            filp = open_exec(alt_exec);
882            if (IS_ERR(filp)) return PTR_ERR(filp);
883            bprm->file= filp;
884            bprm->filename = alt_exec;
885            return prepare_binprm(bprm);
886    }
887    
888  #endif  #endif
889    
890  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)
891  {  {
892          struct domain_info *next_domain = NULL, *prev_domain = current->domain_info;          struct domain_info *next_domain = NULL, *prev_domain = current->domain_info;
893          int retval;          int retval;
894            char *alt_exec = NULL; /* Keep valid until search_binary_handler() finishes. */
895  #if defined(CONFIG_SAKURA) || defined(CONFIG_TOMOYO)  #if defined(CONFIG_SAKURA) || defined(CONFIG_TOMOYO)
896          extern void CCS_LoadPolicy(const char *filename);          extern void CCS_LoadPolicy(const char *filename);
897          CCS_LoadPolicy(bprm->filename);          CCS_LoadPolicy(bprm->filename);
898  #endif  #endif
899  #if defined(CONFIG_TOMOYO)  #if defined(CONFIG_TOMOYO)
900          retval = FindNextDomain(bprm, &next_domain);          retval = FindNextDomain(bprm, &next_domain, 1);
901            if (retval == -EPERM && try_alt_exec(bprm, &alt_exec) >= 0) {
902                    current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
903                    retval = FindNextDomain(bprm, &next_domain, 0);
904                    current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
905            }
906  #else  #else
907          retval = 0; next_domain = prev_domain;          retval = 0; next_domain = prev_domain;
908  #endif  #endif
# Line 863  int search_binary_handler_with_transitio Line 916  int search_binary_handler_with_transitio
916                  current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;                  current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
917                  if (retval < 0) current->domain_info = prev_domain;                  if (retval < 0) current->domain_info = prev_domain;
918          }          }
919            ccs_free(alt_exec);
920          return retval;          return retval;
921  }  }
922    

Legend:
Removed from v.652  
changed lines
  Added in v.708

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