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

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 3131 by kumaneko, Tue Nov 3 03:51:07 2009 UTC revision 3626 by kumaneko, Wed May 5 02:06:14 2010 UTC
# Line 1  Line 1 
1  /*  /*
2   * security/ccsecurity/domain.c   * security/ccsecurity/domain.c
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.1-pre   2009/11/03   * Version: 1.7.2+   2010/05/05
7   *   *
8   * 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.
9   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 41  LIST_HEAD(ccs_domain_list); Line 41  LIST_HEAD(ccs_domain_list);
41  static int ccs_audit_execute_handler_log(struct ccs_execve_entry *ee,  static int ccs_audit_execute_handler_log(struct ccs_execve_entry *ee,
42                                           const bool is_default)                                           const bool is_default)
43  {  {
44            int error;
45          struct ccs_request_info *r = &ee->r;          struct ccs_request_info *r = &ee->r;
46            struct ccs_domain_info *domain = r->domain;
47          const char *handler = ee->handler->name;          const char *handler = ee->handler->name;
48            r->type = CCS_MAC_FILE_EXECUTE;
49          r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE);          r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE);
50          return ccs_write_audit_log(true, r, "%s %s\n",          r->domain = ee->previous_domain;
51                                     is_default ? CCS_KEYWORD_EXECUTE_HANDLER :          error = ccs_write_audit_log(true, r, "%s %s\n",
52                                     CCS_KEYWORD_DENIED_EXECUTE_HANDLER, handler);                                      is_default ? CCS_KEYWORD_EXECUTE_HANDLER :
53                                        CCS_KEYWORD_DENIED_EXECUTE_HANDLER,
54                                        handler);
55            r->domain = domain;
56            return error;
57  }  }
58    
59  /**  /**
# Line 58  static int ccs_audit_execute_handler_log Line 65  static int ccs_audit_execute_handler_log
65   */   */
66  static int ccs_audit_domain_creation_log(struct ccs_domain_info *domain)  static int ccs_audit_domain_creation_log(struct ccs_domain_info *domain)
67  {  {
         int error;  
68          struct ccs_request_info r;          struct ccs_request_info r;
69          ccs_init_request_info(&r, domain, CCS_MAC_FILE_EXECUTE);          ccs_init_request_info(&r, domain, CCS_MAC_FILE_EXECUTE);
70          error = ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);          return ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);
         return error;  
71  }  }
72    
73  /* The list for "struct ccs_domain_initializer_entry". */  /* The list for "struct ccs_domain_initializer_entry". */
# Line 83  static int ccs_update_domain_initializer Line 88  static int ccs_update_domain_initializer
88                                                 const bool is_not,                                                 const bool is_not,
89                                                 const bool is_delete)                                                 const bool is_delete)
90  {  {
         struct ccs_domain_initializer_entry *entry = NULL;  
91          struct ccs_domain_initializer_entry *ptr;          struct ccs_domain_initializer_entry *ptr;
92          struct ccs_domain_initializer_entry e = { .is_not = is_not };          struct ccs_domain_initializer_entry e = { .is_not = is_not };
93          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
# Line 102  static int ccs_update_domain_initializer Line 106  static int ccs_update_domain_initializer
106          e.program = ccs_get_name(program);          e.program = ccs_get_name(program);
107          if (!e.program)          if (!e.program)
108                  goto out;                  goto out;
109          if (!is_delete)          if (mutex_lock_interruptible(&ccs_policy_lock))
110                  entry = kmalloc(sizeof(e), GFP_KERNEL);                  goto out;
         mutex_lock(&ccs_policy_lock);  
111          list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) {          list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) {
112                  if (ccs_memcmp(ptr, &e, offsetof(typeof(e), is_not),                  if (!ccs_is_same_domain_initializer_entry(ptr, &e))
                                sizeof(e)))  
113                          continue;                          continue;
114                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
115                  error = 0;                  error = 0;
116                  break;                  break;
117          }          }
118          if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {          if (!is_delete && error) {
119                  list_add_tail_rcu(&entry->list, &ccs_domain_initializer_list);                  struct ccs_domain_initializer_entry *entry =
120                  entry = NULL;                          ccs_commit_ok(&e, sizeof(e));
121                  error = 0;                  if (entry) {
122                            list_add_tail_rcu(&entry->list,
123                                              &ccs_domain_initializer_list);
124                            error = 0;
125                    }
126          }          }
127          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
128   out:   out:
129          ccs_put_name(e.domainname);          ccs_put_name(e.domainname);
130          ccs_put_name(e.program);          ccs_put_name(e.program);
         kfree(entry);  
131          return error;          return error;
132  }  }
133    
# Line 244  static int ccs_update_domain_keeper_entr Line 249  static int ccs_update_domain_keeper_entr
249                                            const bool is_not,                                            const bool is_not,
250                                            const bool is_delete)                                            const bool is_delete)
251  {  {
         struct ccs_domain_keeper_entry *entry = NULL;  
252          struct ccs_domain_keeper_entry *ptr;          struct ccs_domain_keeper_entry *ptr;
253          struct ccs_domain_keeper_entry e = { .is_not = is_not };          struct ccs_domain_keeper_entry e = { .is_not = is_not };
254          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
# Line 263  static int ccs_update_domain_keeper_entr Line 267  static int ccs_update_domain_keeper_entr
267          e.domainname = ccs_get_name(domainname);          e.domainname = ccs_get_name(domainname);
268          if (!e.domainname)          if (!e.domainname)
269                  goto out;                  goto out;
270          if (!is_delete)          if (mutex_lock_interruptible(&ccs_policy_lock))
271                  entry = kmalloc(sizeof(e), GFP_KERNEL);                  goto out;
         mutex_lock(&ccs_policy_lock);  
272          list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) {          list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) {
273                  if (ccs_memcmp(ptr, &e, offsetof(typeof(e), is_not),                  if (!ccs_is_same_domain_keeper_entry(ptr, &e))
                                sizeof(e)))  
274                          continue;                          continue;
275                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
276                  error = 0;                  error = 0;
277                  break;                  break;
278          }          }
279          if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {          if (!is_delete && error) {
280                  list_add_tail_rcu(&entry->list, &ccs_domain_keeper_list);                  struct ccs_domain_keeper_entry *entry =
281                  entry = NULL;                          ccs_commit_ok(&e, sizeof(e));
282                  error = 0;                  if (entry) {
283                            list_add_tail_rcu(&entry->list,
284                                              &ccs_domain_keeper_list);
285                            error = 0;
286                    }
287          }          }
288          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
289   out:   out:
290          ccs_put_name(e.domainname);          ccs_put_name(e.domainname);
291          ccs_put_name(e.program);          ccs_put_name(e.program);
         kfree(entry);  
292          return error;          return error;
293  }  }
294    
# Line 398  static int ccs_update_aggregator_entry(c Line 403  static int ccs_update_aggregator_entry(c
403                                         const char *aggregated_name,                                         const char *aggregated_name,
404                                         const bool is_delete)                                         const bool is_delete)
405  {  {
         struct ccs_aggregator_entry *entry = NULL;  
406          struct ccs_aggregator_entry *ptr;          struct ccs_aggregator_entry *ptr;
407          struct ccs_aggregator_entry e = { };          struct ccs_aggregator_entry e = { };
408          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
# Line 409  static int ccs_update_aggregator_entry(c Line 413  static int ccs_update_aggregator_entry(c
413          e.aggregated_name = ccs_get_name(aggregated_name);          e.aggregated_name = ccs_get_name(aggregated_name);
414          if (!e.original_name || !e.aggregated_name)          if (!e.original_name || !e.aggregated_name)
415                  goto out;                  goto out;
416          if (!is_delete)          if (mutex_lock_interruptible(&ccs_policy_lock))
417                  entry = kmalloc(sizeof(e), GFP_KERNEL);                  goto out;
         mutex_lock(&ccs_policy_lock);  
418          list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) {          list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) {
419                  if (ccs_memcmp(ptr, &e, offsetof(typeof(e), original_name),                  if (!ccs_is_same_aggregator_entry(ptr, &e))
                                sizeof(e)))  
420                          continue;                          continue;
421                  ptr->is_deleted = is_delete;                  ptr->is_deleted = is_delete;
422                  error = 0;                  error = 0;
423                  break;                  break;
424          }          }
425          if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {          if (!is_delete && error) {
426                  list_add_tail_rcu(&entry->list, &ccs_aggregator_list);                  struct ccs_aggregator_entry *entry =
427                  entry = NULL;                          ccs_commit_ok(&e, sizeof(e));
428                  error = 0;                  if (entry) {
429                            list_add_tail_rcu(&entry->list, &ccs_aggregator_list);
430                            error = 0;
431                    }
432          }          }
433          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
434   out:   out:
435          ccs_put_name(e.original_name);          ccs_put_name(e.original_name);
436          ccs_put_name(e.aggregated_name);          ccs_put_name(e.aggregated_name);
         kfree(entry);  
437          return error;          return error;
438  }  }
439    
# Line 491  int ccs_delete_domain(char *domainname) Line 495  int ccs_delete_domain(char *domainname)
495          struct ccs_path_info name;          struct ccs_path_info name;
496          name.name = domainname;          name.name = domainname;
497          ccs_fill_path_info(&name);          ccs_fill_path_info(&name);
498          mutex_lock(&ccs_policy_lock);          if (mutex_lock_interruptible(&ccs_policy_lock))
499                    return 0;
500          /* Is there an active domain? */          /* Is there an active domain? */
501          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
502                  /* Never delete ccs_kernel_domain */                  /* Never delete ccs_kernel_domain */
# Line 519  struct ccs_domain_info *ccs_find_or_assi Line 524  struct ccs_domain_info *ccs_find_or_assi
524                                                        const u8 profile)                                                        const u8 profile)
525  {  {
526          struct ccs_domain_info *entry;          struct ccs_domain_info *entry;
527          struct ccs_domain_info *domain;          struct ccs_domain_info *domain = NULL;
528          const struct ccs_path_info *saved_domainname;          const struct ccs_path_info *saved_domainname;
529          bool found = false;          bool found = false;
530    
# Line 528  struct ccs_domain_info *ccs_find_or_assi Line 533  struct ccs_domain_info *ccs_find_or_assi
533          saved_domainname = ccs_get_name(domainname);          saved_domainname = ccs_get_name(domainname);
534          if (!saved_domainname)          if (!saved_domainname)
535                  return NULL;                  return NULL;
536          entry = kzalloc(sizeof(*entry), GFP_KERNEL);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
537          mutex_lock(&ccs_policy_lock);          if (mutex_lock_interruptible(&ccs_policy_lock))
538                    goto out;
539          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
540                  if (domain->is_deleted ||                  if (domain->is_deleted ||
541                      ccs_pathcmp(saved_domainname, domain->domainname))                      ccs_pathcmp(saved_domainname, domain->domainname))
# Line 548  struct ccs_domain_info *ccs_find_or_assi Line 554  struct ccs_domain_info *ccs_find_or_assi
554                  found = true;                  found = true;
555          }          }
556          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
557     out:
558          ccs_put_name(saved_domainname);          ccs_put_name(saved_domainname);
559          kfree(entry);          kfree(entry);
560          return found ? domain : NULL;          return found ? domain : NULL;
# Line 617  static int ccs_find_next_domain(struct c Line 624  static int ccs_find_next_domain(struct c
624    
625                  /* Check execute permission. */                  /* Check execute permission. */
626                  retval = ccs_exec_perm(r, &rn);                  retval = ccs_exec_perm(r, &rn);
627                  if (retval == 1)                  if (retval == CCS_RETRY_REQUEST)
628                          goto retry;                          goto retry;
629                  if (retval < 0)                  if (retval < 0)
630                          goto out;                          goto out;
# Line 651  static int ccs_find_next_domain(struct c Line 658  static int ccs_find_next_domain(struct c
658          if (r->mode == CCS_CONFIG_ENFORCING) {          if (r->mode == CCS_CONFIG_ENFORCING) {
659                  int error = ccs_supervisor(r, "# wants to create domain\n"                  int error = ccs_supervisor(r, "# wants to create domain\n"
660                                             "%s\n", ee->tmp);                                             "%s\n", ee->tmp);
661                  if (error == 1)                  if (error == CCS_RETRY_REQUEST)
662                          goto retry;                          goto retry;
663                  if (error < 0)                  if (error < 0)
664                          goto done;                          goto done;
665          }          }
666          domain = ccs_find_or_assign_new_domain(ee->tmp, r->profile);          domain = ccs_find_or_assign_new_domain(ee->tmp, r->profile);
667          if (domain)          if (domain)
668                  ccs_audit_domain_creation_log(r->domain);                  ccs_audit_domain_creation_log(domain);
669   done:   done:
670          if (!domain) {          if (!domain) {
671                  printk(KERN_WARNING "ERROR: Domain '%s' not defined.\n",                  retval = (r->mode == CCS_CONFIG_ENFORCING) ? -EPERM : 0;
672                         ee->tmp);                  if (!r->domain->domain_transition_failed) {
                 if (r->mode == CCS_CONFIG_ENFORCING)  
                         retval = -EPERM;  
                 else {  
                         retval = 0;  
673                          r->domain->domain_transition_failed = true;                          r->domain->domain_transition_failed = true;
674                            ccs_write_audit_log(false, r,
675                                                CCS_KEYWORD_TRANSITION_FAILED
676                                                "\n");
677                            printk(KERN_WARNING "ERROR: Domain '%s' not defined.\n",
678                                   ee->tmp);
679                  }                  }
680          } else {          } else {
681                  retval = 0;                  retval = 0;
# Line 703  static int ccs_environ(struct ccs_execve Line 711  static int ccs_environ(struct ccs_execve
711          int error = -ENOMEM;          int error = -ENOMEM;
712          if (!r->mode || !envp_count)          if (!r->mode || !envp_count)
713                  return 0;                  return 0;
714          arg_ptr = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);          arg_ptr = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
715          if (!arg_ptr)          if (!arg_ptr)
716                  goto out;                  goto out;
717          while (error == -ENOMEM) {          while (error == -ENOMEM) {
# Line 757  static int ccs_environ(struct ccs_execve Line 765  static int ccs_environ(struct ccs_execve
765          if (r->mode != 3)          if (r->mode != 3)
766                  error = 0;                  error = 0;
767          kfree(env_page.data);          kfree(env_page.data);
768            kfree(arg_ptr);
769          return error;          return error;
770  }  }
771    
# Line 807  static void ccs_unescape(unsigned char * Line 816  static void ccs_unescape(unsigned char *
816   *   *
817   * Returns number of directories to strip.   * Returns number of directories to strip.
818   */   */
819  static inline int ccs_root_depth(struct dentry *dentry, struct vfsmount *vfsmnt)  static int ccs_root_depth(struct dentry *dentry, struct vfsmount *vfsmnt)
820  {  {
821          int depth = 0;          int depth = 0;
822          ccs_realpath_lock();          ccs_realpath_lock();
# Line 964  static int ccs_try_alt_exec(struct ccs_e Line 973  static int ccs_try_alt_exec(struct ccs_e
973                           "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "                           "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
974                           "sgid=%d fsuid=%d fsgid=%d state[0]=%u "                           "sgid=%d fsuid=%d fsgid=%d state[0]=%u "
975                           "state[1]=%u state[2]=%u",                           "state[1]=%u state[2]=%u",
976                           (pid_t) sys_getpid(), current_uid(), current_gid(),                           (pid_t) ccsecurity_exports.sys_getpid(),
977                           current_euid(), current_egid(), current_suid(),                           current_uid(), current_gid(), current_euid(),
978                           current_sgid(), current_fsuid(), current_fsgid(),                           current_egid(), current_suid(), current_sgid(),
979                             current_fsuid(), current_fsgid(),
980                           (u8) (ccs_flags >> 24), (u8) (ccs_flags >> 16),                           (u8) (ccs_flags >> 24), (u8) (ccs_flags >> 16),
981                           (u8) (ccs_flags >> 8));                           (u8) (ccs_flags >> 8));
982                  retval = copy_strings_kernel(1, &cp, bprm);                  retval = copy_strings_kernel(1, &cp, bprm);
# Line 1006  static int ccs_try_alt_exec(struct ccs_e Line 1016  static int ccs_try_alt_exec(struct ccs_e
1016          {          {
1017                  int depth = ccs_get_root_depth();                  int depth = ccs_get_root_depth();
1018                  int len = ee->handler->total_len + 1;                  int len = ee->handler->total_len + 1;
1019                  char *cp = kmalloc(len, GFP_KERNEL);                  char *cp = kmalloc(len, CCS_GFP_FLAGS);
1020                  if (!cp) {                  if (!cp) {
1021                          retval = -ENOMEM;                          retval = -ENOMEM;
1022                          goto out;                          goto out;
# Line 1037  static int ccs_try_alt_exec(struct ccs_e Line 1047  static int ccs_try_alt_exec(struct ccs_e
1047  #endif  #endif
1048  #endif  #endif
1049    
1050          /* OK, now restart the process with execute handler program's dentry. */          /*
1051             * OK, now restart the process with execute handler program's dentry.
1052             */
1053          filp = open_exec(ee->handler_path);          filp = open_exec(ee->handler_path);
1054          if (IS_ERR(filp)) {          if (IS_ERR(filp)) {
1055                  retval = PTR_ERR(filp);                  retval = PTR_ERR(filp);
# Line 1111  bool ccs_dump_page(struct linux_binprm * Line 1123  bool ccs_dump_page(struct linux_binprm *
1123          struct page *page;          struct page *page;
1124          /* dump->data is released by ccs_finish_execve(). */          /* dump->data is released by ccs_finish_execve(). */
1125          if (!dump->data) {          if (!dump->data) {
1126                  dump->data = kzalloc(PAGE_SIZE, GFP_KERNEL);                  dump->data = kzalloc(PAGE_SIZE, CCS_GFP_FLAGS);
1127                  if (!dump->data)                  if (!dump->data)
1128                          return false;                          return false;
1129          }          }
# Line 1137  bool ccs_dump_page(struct linux_binprm * Line 1149  bool ccs_dump_page(struct linux_binprm *
1149                   */                   */
1150                  char *kaddr = kmap_atomic(page, KM_USER0);                  char *kaddr = kmap_atomic(page, KM_USER0);
1151                  dump->page = page;                  dump->page = page;
1152                  memcpy(dump->data + offset, kaddr + offset, PAGE_SIZE - offset);                  memcpy(dump->data + offset, kaddr + offset,
1153                           PAGE_SIZE - offset);
1154                  kunmap_atomic(kaddr, KM_USER0);                  kunmap_atomic(kaddr, KM_USER0);
1155          }          }
1156          /* Same with put_arg_page(page) in fs/exec.c */          /* Same with put_arg_page(page) in fs/exec.c */
# Line 1159  bool ccs_dump_page(struct linux_binprm * Line 1172  bool ccs_dump_page(struct linux_binprm *
1172   *   *
1173   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1174   */   */
1175  int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve_entry **eep)  static int ccs_start_execve(struct linux_binprm *bprm,
1176                                struct ccs_execve_entry **eep)
1177  {  {
1178          int retval;          int retval;
1179          struct task_struct *task = current;          struct task_struct *task = current;
1180          struct ccs_execve_entry *ee;          struct ccs_execve_entry *ee;
1181          *eep = NULL;          *eep = NULL;
1182          if (!ccs_policy_loaded)          ee = kzalloc(sizeof(*ee), CCS_GFP_FLAGS);
                 ccs_load_policy(bprm->filename);  
         ee = kzalloc(sizeof(*ee), GFP_KERNEL);  
1183          if (!ee)          if (!ee)
1184                  return -ENOMEM;                  return -ENOMEM;
1185          ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, GFP_KERNEL);          ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
1186          if (!ee->tmp) {          if (!ee->tmp) {
1187                  kfree(ee);                  kfree(ee);
1188                  return -ENOMEM;                  return -ENOMEM;
# Line 1180  int ccs_start_execve(struct linux_binprm Line 1192  int ccs_start_execve(struct linux_binprm
1192          ee->previous_domain = task->ccs_domain_info;          ee->previous_domain = task->ccs_domain_info;
1193          /* Clear manager flag. */          /* Clear manager flag. */
1194          task->ccs_flags &= ~CCS_TASK_IS_POLICY_MANAGER;          task->ccs_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
         /* Tell GC that I started execve(). */  
         task->ccs_flags |= CCS_TASK_IS_IN_EXECVE;  
         /*  
          * Make task->ccs_flags visible to GC before changing  
          * task->ccs_domain_info .  
          */  
         smp_mb();  
1195          *eep = ee;          *eep = ee;
1196          ccs_init_request_info(&ee->r, NULL, CCS_MAC_FILE_EXECUTE);          ccs_init_request_info(&ee->r, NULL, CCS_MAC_FILE_EXECUTE);
1197          ee->r.ee = ee;          ee->r.ee = ee;
# Line 1212  int ccs_start_execve(struct linux_binprm Line 1217  int ccs_start_execve(struct linux_binprm
1217          if (retval < 0)          if (retval < 0)
1218                  goto out;                  goto out;
1219          /*          /*
1220             * Tell GC that I started execve().
1221             * Also, tell open_exec() to check read permission.
1222             */
1223            task->ccs_flags |= CCS_TASK_IS_IN_EXECVE;
1224            /*
1225             * Make task->ccs_flags visible to GC before changing
1226             * task->ccs_domain_info .
1227             */
1228            smp_mb();
1229            /*
1230           * Proceed to the next domain in order to allow reaching via PID.           * Proceed to the next domain in order to allow reaching via PID.
1231           * It will be reverted if execve() failed. Reverting is not good.           * It will be reverted if execve() failed. Reverting is not good.
1232           * But it is better than being unable to reach via PID in interactive           * But it is better than being unable to reach via PID in interactive
1233           * enforcing mode.           * enforcing mode.
1234           */           */
1235          task->ccs_domain_info = ee->r.domain;          task->ccs_domain_info = ee->r.domain;
1236            ee->r.type = CCS_MAC_ENVIRON;
1237          ee->r.mode = ccs_get_mode(ee->r.domain->profile, CCS_MAC_ENVIRON);          ee->r.mode = ccs_get_mode(ee->r.domain->profile, CCS_MAC_ENVIRON);
1238          retval = ccs_environ(ee);          retval = ccs_environ(ee);
1239          if (retval < 0)          if (retval < 0)
# Line 1235  int ccs_start_execve(struct linux_binprm Line 1251  int ccs_start_execve(struct linux_binprm
1251   *   *
1252   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1253   */   */
1254  void ccs_finish_execve(int retval, struct ccs_execve_entry *ee)  static void ccs_finish_execve(int retval, struct ccs_execve_entry *ee)
1255  {  {
1256          struct task_struct *task = current;          struct task_struct *task = current;
1257          if (!ee)          if (!ee)
# Line 1263  void ccs_finish_execve(int retval, struc Line 1279  void ccs_finish_execve(int retval, struc
1279          kfree(ee->dump.data);          kfree(ee->dump.data);
1280          kfree(ee);          kfree(ee);
1281  }  }
1282    
1283    /**
1284     * ccs_may_transit - Check permission and do domain transition without execve().
1285     *
1286     * @domainname: Domainname to transit to.
1287     * @pathname: Pathname to check.
1288     *
1289     * Returns 0 on success, negative value otherwise.
1290     *
1291     * Caller holds ccs_read_lock().
1292     */
1293    int ccs_may_transit(const char *domainname, const char *pathname)
1294    {
1295            struct ccs_path_info name;
1296            struct ccs_request_info r;
1297            struct ccs_domain_info *domain;
1298            int error;
1299            name.name = pathname;
1300            ccs_fill_path_info(&name);
1301            /* Check allow_transit permission. */
1302            ccs_init_request_info(&r, NULL, CCS_MAC_FILE_TRANSIT);
1303            error = ccs_path_permission(&r, CCS_TYPE_TRANSIT, &name);
1304            if (error)
1305                    return error;
1306            /* Check destination domain. */
1307            domain = ccs_find_domain(domainname);
1308            if (!domain && r.mode != CCS_CONFIG_ENFORCING &&
1309                strlen(domainname) < CCS_EXEC_TMPSIZE - 10) {
1310                    domain = ccs_find_or_assign_new_domain(domainname, r.profile);
1311                    if (domain)
1312                            ccs_audit_domain_creation_log(domain);
1313            }
1314            if (domain) {
1315                    error = 0;
1316                    current->ccs_domain_info = domain;
1317            } else {
1318                    error = -ENOENT;
1319            }
1320            return error;
1321    }
1322    
1323    static int __ccs_search_binary_handler(struct linux_binprm *bprm,
1324                                           struct pt_regs *regs)
1325    {
1326            struct ccs_execve_entry *ee;
1327            int retval;
1328            if (!ccs_policy_loaded)
1329                    ccsecurity_exports.load_policy(bprm->filename);
1330            retval = ccs_start_execve(bprm, &ee);
1331            if (!retval)
1332                    retval = search_binary_handler(bprm, regs);
1333            ccs_finish_execve(retval, ee);
1334            return retval;
1335    }
1336    
1337    void __init ccs_domain_init(void)
1338    {
1339            ccsecurity_ops.search_binary_handler = __ccs_search_binary_handler;
1340    }

Legend:
Removed from v.3131  
changed lines
  Added in v.3626

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