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

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 2703 by kumaneko, Tue Jun 30 04:43:11 2009 UTC revision 2738 by kumaneko, Tue Jul 7 01:28:46 2009 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.8   2009/05/28   * Version: 1.7.0-pre   2009/07/03
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 70  int ccs_add_domain_acl(struct ccs_domain Line 70  int ccs_add_domain_acl(struct ccs_domain
70          } else {          } else {
71                  acl->type &= ~ACL_DELETED;                  acl->type &= ~ACL_DELETED;
72          }          }
         ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
73          return 0;          return 0;
74  }  }
75    
# Line 85  int ccs_del_domain_acl(struct ccs_acl_in Line 84  int ccs_del_domain_acl(struct ccs_acl_in
84  {  {
85          if (acl)          if (acl)
86                  acl->type |= ACL_DELETED;                  acl->type |= ACL_DELETED;
         ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);  
87          return 0;          return 0;
88  }  }
89    
# Line 177  static int ccs_update_domain_initializer Line 175  static int ccs_update_domain_initializer
175                  error = 0;                  error = 0;
176                  break;                  break;
177          }          }
178          if (!is_delete && error && ccs_memory_ok(entry)) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
179                  entry->domainname = saved_domainname;                  entry->domainname = saved_domainname;
180                  saved_domainname = NULL;                  saved_domainname = NULL;
181                  entry->program = saved_program;                  entry->program = saved_program;
# Line 192  static int ccs_update_domain_initializer Line 190  static int ccs_update_domain_initializer
190          ccs_put_name(saved_domainname);          ccs_put_name(saved_domainname);
191          ccs_put_name(saved_program);          ccs_put_name(saved_program);
192          kfree(entry);          kfree(entry);
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
193          return error;          return error;
194  }  }
195    
# Line 349  static int ccs_update_domain_keeper_entr Line 346  static int ccs_update_domain_keeper_entr
346                  error = 0;                  error = 0;
347                  break;                  break;
348          }          }
349          if (!is_delete && error && ccs_memory_ok(entry)) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
350                  entry->domainname = saved_domainname;                  entry->domainname = saved_domainname;
351                  saved_domainname = NULL;                  saved_domainname = NULL;
352                  entry->program = saved_program;                  entry->program = saved_program;
# Line 364  static int ccs_update_domain_keeper_entr Line 361  static int ccs_update_domain_keeper_entr
361          ccs_put_name(saved_domainname);          ccs_put_name(saved_domainname);
362          ccs_put_name(saved_program);          ccs_put_name(saved_program);
363          kfree(entry);          kfree(entry);
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
364          return error;          return error;
365  }  }
366    
# Line 463  static bool ccs_is_domain_keeper(const s Line 459  static bool ccs_is_domain_keeper(const s
459          return flag;          return flag;
460  }  }
461    
 /* The list for "struct ccs_alias_entry". */  
 LIST_HEAD(ccs_alias_list);  
   
 /**  
  * ccs_update_alias_entry - Update "struct ccs_alias_entry" list.  
  *  
  * @original_name: The original program's real name.  
  * @aliased_name:  The symbolic program's symbolic link's name.  
  * @is_delete:     True if it is a delete request.  
  *  
  * Returns 0 on success, negative value otherwise.  
  */  
 static int ccs_update_alias_entry(const char *original_name,  
                                   const char *aliased_name,  
                                   const bool is_delete)  
 {  
         struct ccs_alias_entry *entry = NULL;  
         struct ccs_alias_entry *ptr;  
         const struct ccs_path_info *saved_original_name;  
         const struct ccs_path_info *saved_aliased_name;  
         int error = is_delete ? -ENOENT : -ENOMEM;  
         if (!ccs_is_correct_path(original_name, 1, -1, -1) ||  
             !ccs_is_correct_path(aliased_name, 1, -1, -1))  
                 return -EINVAL; /* No patterns allowed. */  
         saved_original_name = ccs_get_name(original_name);  
         saved_aliased_name = ccs_get_name(aliased_name);  
         if (!saved_original_name || !saved_aliased_name) {  
                 ccs_put_name(saved_original_name);  
                 ccs_put_name(saved_aliased_name);  
                 return -ENOMEM;  
         }  
         if (!is_delete)  
                 entry = kzalloc(sizeof(*entry), GFP_KERNEL);  
         mutex_lock(&ccs_policy_lock);  
         list_for_each_entry_rcu(ptr, &ccs_alias_list, list) {  
                 if (ptr->original_name != saved_original_name ||  
                     ptr->aliased_name != saved_aliased_name)  
                         continue;  
                 ptr->is_deleted = is_delete;  
                 error = 0;  
                 break;  
         }  
         if (!is_delete && error && ccs_memory_ok(entry)) {  
                 entry->original_name = saved_original_name;  
                 saved_original_name = NULL;  
                 entry->aliased_name = saved_aliased_name;  
                 saved_aliased_name = NULL;  
                 list_add_tail_rcu(&entry->list, &ccs_alias_list);  
                 entry = NULL;  
                 error = 0;  
         }  
         mutex_unlock(&ccs_policy_lock);  
         ccs_put_name(saved_original_name);  
         ccs_put_name(saved_aliased_name);  
         kfree(entry);  
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
         return error;  
 }  
   
 /**  
  * ccs_read_alias_policy - Read "struct ccs_alias_entry" list.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  *  
  * Returns true on success, false otherwise.  
  *  
  * Caller holds srcu_read_lock(&ccs_ss).  
  */  
 bool ccs_read_alias_policy(struct ccs_io_buffer *head)  
 {  
         struct list_head *pos;  
         bool done = true;  
         list_for_each_cookie(pos, head->read_var2, &ccs_alias_list) {  
                 struct ccs_alias_entry *ptr;  
                 ptr = list_entry(pos, struct ccs_alias_entry, list);  
                 if (ptr->is_deleted)  
                         continue;  
                 done = ccs_io_printf(head, KEYWORD_ALIAS "%s %s\n",  
                                      ptr->original_name->name,  
                                      ptr->aliased_name->name);  
                 if (!done)  
                         break;  
         }  
         return done;  
 }  
   
 /**  
  * ccs_write_alias_policy - Write "struct ccs_alias_entry" list.  
  *  
  * @data:      String to parse.  
  * @is_delete: True if it is a delete request.  
  *  
  * Returns 0 on success, negative value otherwise.  
  */  
 int ccs_write_alias_policy(char *data, const bool is_delete)  
 {  
         char *cp = strchr(data, ' ');  
         if (!cp)  
                 return -EINVAL;  
         *cp++ = '\0';  
         return ccs_update_alias_entry(data, cp, is_delete);  
 }  
   
462  /* The list for "struct ccs_aggregator_entry". */  /* The list for "struct ccs_aggregator_entry". */
463  LIST_HEAD(ccs_aggregator_list);  LIST_HEAD(ccs_aggregator_list);
464    
# Line 608  static int ccs_update_aggregator_entry(c Line 501  static int ccs_update_aggregator_entry(c
501                  error = 0;                  error = 0;
502                  break;                  break;
503          }          }
504          if (!is_delete && error && ccs_memory_ok(entry)) {          if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
505                  entry->original_name = saved_original_name;                  entry->original_name = saved_original_name;
506                  saved_original_name = NULL;                  saved_original_name = NULL;
507                  entry->aggregated_name = saved_aggregated_name;                  entry->aggregated_name = saved_aggregated_name;
# Line 621  static int ccs_update_aggregator_entry(c Line 514  static int ccs_update_aggregator_entry(c
514          ccs_put_name(saved_original_name);          ccs_put_name(saved_original_name);
515          ccs_put_name(saved_aggregated_name);          ccs_put_name(saved_aggregated_name);
516          kfree(entry);          kfree(entry);
         ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);  
517          return error;          return error;
518  }  }
519    
# Line 730  struct ccs_domain_info *ccs_find_or_assi Line 622  struct ccs_domain_info *ccs_find_or_assi
622                  found = true;                  found = true;
623                  break;                  break;
624          }          }
625          if (!found && ccs_memory_ok(entry)) {          if (!found && ccs_memory_ok(entry, sizeof(*entry))) {
626                  INIT_LIST_HEAD(&entry->acl_info_list);                  INIT_LIST_HEAD(&entry->acl_info_list);
627                  entry->domainname = saved_domainname;                  entry->domainname = saved_domainname;
628                  saved_domainname = NULL;                  saved_domainname = NULL;
# Line 822  static int ccs_find_next_domain(struct c Line 714  static int ccs_find_next_domain(struct c
714          const u32 ccs_flags = current->ccs_flags;          const u32 ccs_flags = current->ccs_flags;
715          char *new_domain_name = NULL;          char *new_domain_name = NULL;
716          struct ccs_path_info rn; /* real name */          struct ccs_path_info rn; /* real name */
         struct ccs_path_info sn; /* symlink name */  
717          struct ccs_path_info ln; /* last name */          struct ccs_path_info ln; /* last name */
718          int retval;          int retval;
719   retry:   retry:
720          current->ccs_flags = ccs_flags;          current->ccs_flags = ccs_flags;
721          r->cond = NULL;          r->cond = NULL;
722          /* Get realpath of program and symbolic link. */          /* Get symlink's pathname of program. */
723          retval = ccs_realpath_both(bprm->filename, ee);          retval = ccs_symlink_path(bprm->filename, ee);
724          if (retval < 0)          if (retval < 0)
725                  goto out;                  goto out;
726    
727          rn.name = ee->program_path;          rn.name = ee->program_path;
728          ccs_fill_path_info(&rn);          ccs_fill_path_info(&rn);
         sn.name = ee->tmp;  
         ccs_fill_path_info(&sn);  
729          ln.name = ccs_get_last_name(r->domain);          ln.name = ccs_get_last_name(r->domain);
730          ccs_fill_path_info(&ln);          ccs_fill_path_info(&ln);
731    
# Line 854  static int ccs_find_next_domain(struct c Line 743  static int ccs_find_next_domain(struct c
743                  goto calculate_domain;                  goto calculate_domain;
744          }          }
745    
         /* Check 'alias' directive. */  
         if (ccs_pathcmp(&rn, &sn)) {  
                 struct ccs_alias_entry *ptr;  
                 /* Is this program allowed to be called via symbolic links? */  
                 list_for_each_entry_rcu(ptr, &ccs_alias_list, list) {  
                         if (ptr->is_deleted ||  
                             ccs_pathcmp(&rn, ptr->original_name) ||  
                             ccs_pathcmp(&sn, ptr->aliased_name))  
                                 continue;  
                         strncpy(ee->program_path, ptr->aliased_name->name,  
                                 CCS_MAX_PATHNAME_LEN - 1);  
                         ccs_fill_path_info(&rn);  
                         break;  
                 }  
         }  
         /* sn will be overwritten after here. */  
   
746          /* Compare basename of program_path and argv[0] */          /* Compare basename of program_path and argv[0] */
747          r->mode = ccs_check_flags(r->domain, CCS_MAC_FOR_ARGV0);          r->mode = ccs_check_flags(r->domain, CCS_MAC_FOR_ARGV0);
748          if (bprm->argc > 0 && r->mode) {          if (bprm->argc > 0 && r->mode) {
# Line 1164  static DEFINE_SPINLOCK(ccs_execve_list_l Line 1036  static DEFINE_SPINLOCK(ccs_execve_list_l
1036   */   */
1037  static struct ccs_execve_entry *ccs_allocate_execve_entry(void)  static struct ccs_execve_entry *ccs_allocate_execve_entry(void)
1038  {  {
1039          struct ccs_execve_entry *ee = ccs_alloc(sizeof(*ee), false);          struct ccs_execve_entry *ee = kzalloc(sizeof(*ee), GFP_KERNEL);
1040          if (!ee)          if (!ee)
1041                  return NULL;                  return NULL;
1042          memset(ee, 0, sizeof(*ee));          ee->program_path = kzalloc(CCS_MAX_PATHNAME_LEN, GFP_KERNEL);
1043          ee->program_path = ccs_alloc(CCS_MAX_PATHNAME_LEN, false);          ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);
         ee->tmp = ccs_alloc(CCS_MAX_PATHNAME_LEN, false);  
1044          if (!ee->program_path || !ee->tmp) {          if (!ee->program_path || !ee->tmp) {
1045                  ccs_free(ee->program_path);                  kfree(ee->program_path);
1046                  ccs_free(ee->tmp);                  kfree(ee->tmp);
1047                  ccs_free(ee);                  kfree(ee);
1048                  return NULL;                  return NULL;
1049          }          }
1050          ee->srcu_idx = srcu_read_lock(&ccs_ss);          ee->srcu_idx = srcu_read_lock(&ccs_ss);
# Line 1224  static void ccs_free_execve_entry(struct Line 1095  static void ccs_free_execve_entry(struct
1095          list_del(&ee->list);          list_del(&ee->list);
1096          spin_unlock(&ccs_execve_list_lock);          spin_unlock(&ccs_execve_list_lock);
1097          /***** CRITICAL SECTION END *****/          /***** CRITICAL SECTION END *****/
1098          ccs_free(ee->program_path);          kfree(ee->program_path);
1099          ccs_free(ee->tmp);          kfree(ee->tmp);
1100          kfree(ee->dump.data);          kfree(ee->dump.data);
1101          srcu_read_unlock(&ccs_ss, ee->srcu_idx);          srcu_read_unlock(&ccs_ss, ee->srcu_idx);
1102          ccs_free(ee);          kfree(ee);
1103  }  }
1104    
1105  /**  /**
# Line 1347  static int ccs_try_alt_exec(struct ccs_e Line 1218  static int ccs_try_alt_exec(struct ccs_e
1218                  char *exe = (char *) ccs_get_exe();                  char *exe = (char *) ccs_get_exe();
1219                  if (exe) {                  if (exe) {
1220                          retval = copy_strings_kernel(1, &exe, bprm);                          retval = copy_strings_kernel(1, &exe, bprm);
1221                          ccs_free(exe);                          kfree(exe);
1222                  } else {                  } else {
1223                          exe = ee->tmp;                          exe = ee->tmp;
1224                          strncpy(ee->tmp, "<unknown>", CCS_EXEC_TMPSIZE - 1);                          strncpy(ee->tmp, "<unknown>", CCS_EXEC_TMPSIZE - 1);
# Line 1418  static int ccs_try_alt_exec(struct ccs_e Line 1289  static int ccs_try_alt_exec(struct ccs_e
1289                   * overwrite ee->program_path and ee->tmp.                   * overwrite ee->program_path and ee->tmp.
1290                   */                   */
1291                  const int len = strlen(ee->program_path) + 1;                  const int len = strlen(ee->program_path) + 1;
1292                  char *cp = kmalloc(len, GFP_KERNEL);                  char *cp = kzalloc(len, GFP_KERNEL);
1293                  if (!cp) {                  if (!cp) {
1294                          retval = -ENOMEM;                          retval = -ENOMEM;
1295                          goto out;                          goto out;
# Line 1494  bool ccs_dump_page(struct linux_binprm * Line 1365  bool ccs_dump_page(struct linux_binprm *
1365          struct page *page;          struct page *page;
1366          /* dump->data is released by ccs_free_execve_entry(). */          /* dump->data is released by ccs_free_execve_entry(). */
1367          if (!dump->data) {          if (!dump->data) {
1368                  dump->data = kmalloc(PAGE_SIZE, GFP_KERNEL);                  dump->data = kzalloc(PAGE_SIZE, GFP_KERNEL);
1369                  if (!dump->data)                  if (!dump->data)
1370                          return false;                          return false;
1371          }          }

Legend:
Removed from v.2703  
changed lines
  Added in v.2738

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