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

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 1561 by kumaneko, Tue Sep 9 04:29:07 2008 UTC revision 1657 by kumaneko, Tue Oct 7 02:21:32 2008 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2008  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.5-pre   2008/09/09   * Version: 1.6.5-pre   2008/10/07
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 160  static int audit_execute_handler_log(con Line 160  static int audit_execute_handler_log(con
160                                       const char *handler,                                       const char *handler,
161                                       struct linux_binprm *bprm)                                       struct linux_binprm *bprm)
162  {  {
163          char *buf;          struct ccs_request_info r;
164          int len;          ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_FILE);
165          int len2;          r.bprm = bprm;
166          u8 profile;          return ccs_write_audit_log(true, &r, "%s %s\n",
167          u8 mode;                                     is_default ? KEYWORD_EXECUTE_HANDLER :
168          if (ccs_can_save_audit_log(true) < 0)                                     KEYWORD_DENIED_EXECUTE_HANDLER, handler);
                 return -ENOMEM;  
         len = strlen(handler) + 32;  
         profile = current->domain_info->profile;  
         mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_FILE);  
         buf = ccs_init_audit_log(&len, profile, mode, bprm);  
         if (!buf)  
                 return -ENOMEM;  
         len2 = strlen(buf);  
         snprintf(buf + len2, len - len2 - 1, "%s %s\n",  
                  is_default ? KEYWORD_EXECUTE_HANDLER :  
                  KEYWORD_DENIED_EXECUTE_HANDLER, handler);  
         return ccs_write_audit_log(buf, true);  
169  }  }
170    
171  /**  /**
172   * audit_domain_creation_log - Audit domain creation log.   * audit_domain_creation_log - Audit domain creation log.
173   *   *
174   * @domainname: The name of newly created domain.   * @domain:  Pointer to "struct domain_info".
  * @mode:       Access control mode used.  
  * @profile:    Profile number used.  
175   *   *
176   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
177   */   */
178  static int audit_domain_creation_log(const char *domainname, const u8 mode,  static int audit_domain_creation_log(struct domain_info *domain)
                                      const u8 profile)  
179  {  {
180          char *buf;          struct ccs_request_info r;
181          char *cp;          ccs_init_request_info(&r, domain, CCS_TOMOYO_MAC_FOR_FILE);
182          int len;          return ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);
         int len2;  
         if (ccs_can_save_audit_log(false) < 0)  
                 return -ENOMEM;  
         len = strlen(domainname) + 32;  
         buf = ccs_init_audit_log(&len, profile, mode, NULL);  
         if (!buf)  
                 return -ENOMEM;  
         cp = strchr(buf, '\n');  
         if (!cp) {  
                 ccs_free(buf);  
                 return -ENOMEM;  
         }  
         *++cp = '\0';  
         len2 = strlen(buf);  
         snprintf(buf + len2, len - len2 - 1, "%s\nuse_profile %u\n",  
                  domainname, profile);  
         return ccs_write_audit_log(buf, false);  
183  }  }
184    
185  /* The list for "struct domain_initializer_entry". */  /* The list for "struct domain_initializer_entry". */
# Line 985  static bool get_argv0(struct linux_binpr Line 953  static bool get_argv0(struct linux_binpr
953  /**  /**
954   * find_next_domain - Find a domain.   * find_next_domain - Find a domain.
955   *   *
956   * @bprm:           Pointer to "struct linux_binprm".   * @r:       Pointer to "struct ccs_request_info".
957   * @next_domain:    Pointer to pointer to "struct domain_info".   * @handler: Pathname to verify. May be NULL.
  * @path_to_verify: Pathname to verify. May be NULL.  
  * @tmp:            Buffer for temporal use.  
958   *   *
959   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
960   */   */
961  static int find_next_domain(struct linux_binprm *bprm,  static int find_next_domain(struct ccs_request_info *r,
962                              struct domain_info **next_domain,                              const struct path_info *handler)
                             const struct path_info *path_to_verify,  
                             struct ccs_page_buffer *tmp)  
963  {  {
964          /*          /*
965           * This function assumes that the size of buffer returned by           * This function assumes that the size of buffer returned by
966           * ccs_realpath() = CCS_MAX_PATHNAME_LEN.           * ccs_realpath() = CCS_MAX_PATHNAME_LEN.
967           */           */
         struct domain_info *old_domain = current->domain_info;  
968          struct domain_info *domain = NULL;          struct domain_info *domain = NULL;
969          const char *old_domain_name = old_domain->domainname->name;          const char *old_domain_name = r->domain->domainname->name;
970            struct linux_binprm *bprm = r->bprm;
971            struct ccs_page_buffer *tmp = r->obj->tmp;
972          const char *original_name = bprm->filename;          const char *original_name = bprm->filename;
973            const u8 mode = r->mode;
974            const bool is_enforce = (mode == 3);
975            const u32 tomoyo_flags = r->tomoyo_flags;
976          char *new_domain_name = NULL;          char *new_domain_name = NULL;
977          char *real_program_name = NULL;          char *real_program_name = NULL;
978          char *symlink_program_name = NULL;          char *symlink_program_name = NULL;
979          const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_FILE);          struct path_info rn; /* real name */
980          const bool is_enforce = (mode == 3);          struct path_info sn; /* symlink name */
981            struct path_info ln; /* last name */
982          int retval;          int retval;
         struct path_info r; /* real name */  
         struct path_info s; /* symlink name */  
         struct path_info l; /* last name */  
         const u32 tomoyo_flags = current->tomoyo_flags;  
983    
984          {          {
985                  /*                  /*
# Line 1033  static int find_next_domain(struct linux Line 998  static int find_next_domain(struct linux
998    
999   retry:   retry:
1000          current->tomoyo_flags = tomoyo_flags;          current->tomoyo_flags = tomoyo_flags;
1001            r->tomoyo_flags = tomoyo_flags;
1002          /* Get ccs_realpath of program. */          /* Get ccs_realpath of program. */
1003          retval = -ENOENT; /* I hope ccs_realpath() won't fail with -ENOMEM. */          retval = -ENOENT; /* I hope ccs_realpath() won't fail with -ENOMEM. */
1004          ccs_free(real_program_name);          ccs_free(real_program_name);
# Line 1045  static int find_next_domain(struct linux Line 1011  static int find_next_domain(struct linux
1011          if (!symlink_program_name)          if (!symlink_program_name)
1012                  goto out;                  goto out;
1013    
1014          r.name = real_program_name;          rn.name = real_program_name;
1015          ccs_fill_path_info(&r);          ccs_fill_path_info(&rn);
1016          s.name = symlink_program_name;          sn.name = symlink_program_name;
1017          ccs_fill_path_info(&s);          ccs_fill_path_info(&sn);
1018          l.name = ccs_get_last_name(old_domain);          ln.name = ccs_get_last_name(r->domain);
1019          ccs_fill_path_info(&l);          ccs_fill_path_info(&ln);
1020    
1021          if (path_to_verify) {          if (handler) {
1022                  if (ccs_pathcmp(&r, path_to_verify)) {                  if (ccs_pathcmp(&rn, handler)) {
1023                          /* Failed to verify execute handler. */                          /* Failed to verify execute handler. */
1024                          static u8 counter = 20;                          static u8 counter = 20;
1025                          if (counter) {                          if (counter) {
1026                                  counter--;                                  counter--;
1027                                  printk(KERN_WARNING "Failed to verify: %s\n",                                  printk(KERN_WARNING "Failed to verify: %s\n",
1028                                         path_to_verify->name);                                         handler->name);
1029                          }                          }
1030                          goto out;                          goto out;
1031                  }                  }
# Line 1067  static int find_next_domain(struct linux Line 1033  static int find_next_domain(struct linux
1033          }          }
1034    
1035          /* Check 'alias' directive. */          /* Check 'alias' directive. */
1036          if (ccs_pathcmp(&r, &s)) {          if (ccs_pathcmp(&rn, &sn)) {
1037                  struct alias_entry *ptr;                  struct alias_entry *ptr;
1038                  /* Is this program allowed to be called via symbolic links? */                  /* Is this program allowed to be called via symbolic links? */
1039                  list1_for_each_entry(ptr, &alias_list, list) {                  list1_for_each_entry(ptr, &alias_list, list) {
1040                          if (ptr->is_deleted ||                          if (ptr->is_deleted ||
1041                              ccs_pathcmp(&r, ptr->original_name) ||                              ccs_pathcmp(&rn, ptr->original_name) ||
1042                              ccs_pathcmp(&s, ptr->aliased_name))                              ccs_pathcmp(&sn, ptr->aliased_name))
1043                                  continue;                                  continue;
1044                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
1045                          strncpy(real_program_name, ptr->aliased_name->name,                          strncpy(real_program_name, ptr->aliased_name->name,
1046                                  CCS_MAX_PATHNAME_LEN - 1);                                  CCS_MAX_PATHNAME_LEN - 1);
1047                          ccs_fill_path_info(&r);                          ccs_fill_path_info(&rn);
1048                          break;                          break;
1049                  }                  }
1050          }          }
1051    
1052          /* Compare basename of real_program_name and argv[0] */          /* Compare basename of real_program_name and argv[0] */
1053          if (bprm->argc > 0 && ccs_check_flags(CCS_TOMOYO_MAC_FOR_ARGV0)) {          r->mode = ccs_check_flags(r->domain, CCS_TOMOYO_MAC_FOR_ARGV0);
1054            if (bprm->argc > 0 && r->mode) {
1055                  char *base_argv0 = tmp->buffer;                  char *base_argv0 = tmp->buffer;
1056                  const char *base_filename;                  const char *base_filename;
1057                  retval = -ENOMEM;                  retval = -ENOMEM;
# Line 1096  static int find_next_domain(struct linux Line 1063  static int find_next_domain(struct linux
1063                  else                  else
1064                          base_filename++;                          base_filename++;
1065                  if (strcmp(base_argv0, base_filename)) {                  if (strcmp(base_argv0, base_filename)) {
1066                          retval = ccs_check_argv0_perm(&r, base_argv0);                          retval = ccs_check_argv0_perm(r, &rn, base_argv0);
1067                          if (retval == 1)                          if (retval == 1) {
1068                                    r->retry++;
1069                                  goto retry;                                  goto retry;
1070                            }
1071                            r->retry = 0;
1072                            r->tomoyo_flags = current->tomoyo_flags;
1073                          if (retval < 0)                          if (retval < 0)
1074                                  goto out;                                  goto out;
1075                  }                  }
# Line 1110  static int find_next_domain(struct linux Line 1081  static int find_next_domain(struct linux
1081                  /* Is this program allowed to be aggregated? */                  /* Is this program allowed to be aggregated? */
1082                  list1_for_each_entry(ptr, &aggregator_list, list) {                  list1_for_each_entry(ptr, &aggregator_list, list) {
1083                          if (ptr->is_deleted ||                          if (ptr->is_deleted ||
1084                              !ccs_path_matches_pattern(&r, ptr->original_name))                              !ccs_path_matches_pattern(&rn, ptr->original_name))
1085                                  continue;                                  continue;
1086                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);                          memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
1087                          strncpy(real_program_name, ptr->aggregated_name->name,                          strncpy(real_program_name, ptr->aggregated_name->name,
1088                                  CCS_MAX_PATHNAME_LEN - 1);                                  CCS_MAX_PATHNAME_LEN - 1);
1089                          ccs_fill_path_info(&r);                          ccs_fill_path_info(&rn);
1090                          break;                          break;
1091                  }                  }
1092          }          }
1093    
1094          /* Check execute permission. */          /* Check execute permission. */
1095          retval = ccs_check_exec_perm(&r, bprm, tmp);          r->mode = mode;
1096          if (retval == 1)          retval = ccs_check_exec_perm(r, &rn);
1097            if (retval == 1) {
1098                    r->retry++;
1099                  goto retry;                  goto retry;
1100            }
1101            r->retry = 0;
1102            r->tomoyo_flags = current->tomoyo_flags;
1103          if (retval < 0)          if (retval < 0)
1104                  goto out;                  goto out;
1105    
1106   calculate_domain:   calculate_domain:
1107          new_domain_name = tmp->buffer;          new_domain_name = tmp->buffer;
1108          if (is_domain_initializer(old_domain->domainname, &r, &l)) {          if (is_domain_initializer(r->domain->domainname, &rn, &ln)) {
1109                  /* Transit to the child of KERNEL_DOMAIN domain. */                  /* Transit to the child of KERNEL_DOMAIN domain. */
1110                  snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,                  snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,
1111                           ROOT_NAME " " "%s", real_program_name);                           ROOT_NAME " " "%s", real_program_name);
1112          } else if (old_domain == &KERNEL_DOMAIN && !sbin_init_started) {          } else if (r->domain == &KERNEL_DOMAIN && !sbin_init_started) {
1113                  /*                  /*
1114                   * Needn't to transit from kernel domain before starting                   * Needn't to transit from kernel domain before starting
1115                   * /sbin/init. But transit from kernel domain if executing                   * /sbin/init. But transit from kernel domain if executing
1116                   * initializers because they might start before /sbin/init.                   * initializers because they might start before /sbin/init.
1117                   */                   */
1118                  domain = old_domain;                  domain = r->domain;
1119          } else if (is_domain_keeper(old_domain->domainname, &r, &l)) {          } else if (is_domain_keeper(r->domain->domainname, &rn, &ln)) {
1120                  /* Keep current domain. */                  /* Keep current domain. */
1121                  domain = old_domain;                  domain = r->domain;
1122          } else {          } else {
1123                  /* Normal domain transition. */                  /* Normal domain transition. */
1124                  snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,                  snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,
# Line 1154  static int find_next_domain(struct linux Line 1130  static int find_next_domain(struct linux
1130          if (domain)          if (domain)
1131                  goto done;                  goto done;
1132          if (is_enforce) {          if (is_enforce) {
1133                  int error = ccs_check_supervisor(NULL,                  int error = ccs_check_supervisor(r,
1134                                                   "# wants to create domain\n"                                                   "# wants to create domain\n"
1135                                                   "%s\n", new_domain_name);                                                   "%s\n", new_domain_name);
1136                  if (error == 1)                  if (error == 1) {
1137                            r->retry++;
1138                          goto retry;                          goto retry;
1139                    }
1140                    r->retry = 0;
1141                  if (error < 0)                  if (error < 0)
1142                          goto done;                          goto done;
1143          }          }
1144          domain = ccs_find_or_assign_new_domain(new_domain_name,          domain = ccs_find_or_assign_new_domain(new_domain_name, r->profile);
                                                old_domain->profile);  
1145          if (domain)          if (domain)
1146                  audit_domain_creation_log(new_domain_name, mode,                  audit_domain_creation_log(domain);
                                           domain->profile);  
1147   done:   done:
1148          if (!domain) {          if (!domain) {
1149                  printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",                  printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
# Line 1175  static int find_next_domain(struct linux Line 1152  static int find_next_domain(struct linux
1152                          retval = -EPERM;                          retval = -EPERM;
1153                  else {                  else {
1154                          retval = 0;                          retval = 0;
1155                          ccs_set_domain_flag(old_domain, false,                          ccs_set_domain_flag(r->domain, false,
1156                                              DOMAIN_FLAGS_TRANSITION_FAILED);                                              DOMAIN_FLAGS_TRANSITION_FAILED);
1157                  }                  }
1158          } else {          } else {
# Line 1184  static int find_next_domain(struct linux Line 1161  static int find_next_domain(struct linux
1161   out:   out:
1162          ccs_free(real_program_name);          ccs_free(real_program_name);
1163          ccs_free(symlink_program_name);          ccs_free(symlink_program_name);
1164          *next_domain = domain ? domain : old_domain;          if (domain)
1165                    r->domain = domain;
1166          return retval;          return retval;
1167  }  }
1168    
1169  /**  /**
1170   * check_environ - Check permission for environment variable names.   * check_environ - Check permission for environment variable names.
1171   *   *
1172   * @bprm: Pointer to "struct linux_binprm".   * @r: Pointer to "struct ccs_request_info".
  * @tmp:  Buffer for temporal use.  
1173   *   *
1174   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1175   */   */
1176  static int check_environ(struct linux_binprm *bprm, struct ccs_page_buffer *tmp)  static int check_environ(struct ccs_request_info *r)
1177  {  {
1178          const u8 profile = current->domain_info->profile;          struct linux_binprm *bprm = r->bprm;
1179          const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_ENV);          struct ccs_page_buffer *tmp = r->obj->tmp;
1180          char *arg_ptr = tmp->buffer;          char *arg_ptr = tmp->buffer;
1181          int arg_len = 0;          int arg_len = 0;
1182          unsigned long pos = bprm->p;          unsigned long pos = bprm->p;
# Line 1209  static int check_environ(struct linux_bi Line 1186  static int check_environ(struct linux_bi
1186          int envp_count = bprm->envc;          int envp_count = bprm->envc;
1187          /* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */          /* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */
1188          int error = -ENOMEM;          int error = -ENOMEM;
1189          if (!mode || !envp_count)          if (!r->mode || !envp_count)
1190                  return 0;                  return 0;
1191          while (error == -ENOMEM) {          while (error == -ENOMEM) {
1192                  struct page *page;                  struct page *page;
# Line 1259  static int check_environ(struct linux_bi Line 1236  static int check_environ(struct linux_bi
1236                          }                          }
1237                          if (c)                          if (c)
1238                                  continue;                                  continue;
1239                          if (ccs_check_env_perm(arg_ptr, profile, mode)) {                          if (ccs_check_env_perm(r, arg_ptr)) {
1240                                  error = -EPERM;                                  error = -EPERM;
1241                                  break;                                  break;
1242                          }                          }
# Line 1279  static int check_environ(struct linux_bi Line 1256  static int check_environ(struct linux_bi
1256                  offset = 0;                  offset = 0;
1257          }          }
1258   out:   out:
1259          if (error && mode != 3)          if (r->mode != 3)
1260                  error = 0;                  error = 0;
1261          return error;          return error;
1262  }  }
# Line 1389  static int get_root_depth(void) Line 1366  static int get_root_depth(void)
1366  /**  /**
1367   * try_alt_exec - Try to start execute handler.   * try_alt_exec - Try to start execute handler.
1368   *   *
1369   * @bprm:        Pointer to "struct linux_binprm".   * @r:           Pointer to "struct ccs_request_info".
1370   * @handler:     Pointer to the name of execute handler.   * @handler:     Pointer to the name of execute handler.
1371   * @eh_path:     Pointer to pointer to the name of execute handler.   * @eh_path:     Pointer to pointer to the name of execute handler.
  * @next_domain: Pointer to pointer to "struct domain_info".  
  * @tmp:         Buffer for temporal use.  
1372   *   *
1373   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1374   */   */
1375  static int try_alt_exec(struct linux_binprm *bprm,  static int try_alt_exec(struct ccs_request_info *r,
1376                          const struct path_info *handler, char **eh_path,                          const struct path_info *handler, char **eh_path)
                         struct domain_info **next_domain,  
                         struct ccs_page_buffer *tmp)  
1377  {  {
1378          /*          /*
1379           * Contents of modified bprm.           * Contents of modified bprm.
# Line 1438  static int try_alt_exec(struct linux_bin Line 1411  static int try_alt_exec(struct linux_bin
1411           * modified bprm->argv[bprm->envc + bprm->argc + 6]           * modified bprm->argv[bprm->envc + bprm->argc + 6]
1412           *     = original bprm->envp[bprm->envc - 1]           *     = original bprm->envp[bprm->envc - 1]
1413           */           */
1414            struct linux_binprm *bprm = r->bprm;
1415          struct file *filp;          struct file *filp;
1416          int retval;          int retval;
1417          const int original_argc = bprm->argc;          const int original_argc = bprm->argc;
1418          const int original_envc = bprm->envc;          const int original_envc = bprm->envc;
1419          struct task_struct *task = current;          struct task_struct *task = current;
1420          char *buffer = tmp->buffer;          char *buffer = r->obj->tmp->buffer;
1421          /* Allocate memory for execute handler's pathname. */          /* Allocate memory for execute handler's pathname. */
1422          char *execute_handler = ccs_alloc(sizeof(struct ccs_page_buffer));          char *execute_handler = ccs_alloc(sizeof(struct ccs_page_buffer));
1423          *eh_path = execute_handler;          *eh_path = execute_handler;
# Line 1575  static int try_alt_exec(struct linux_bin Line 1549  static int try_alt_exec(struct linux_bin
1549          if (retval < 0)          if (retval < 0)
1550                  goto out;                  goto out;
1551          task->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          task->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1552          retval = find_next_domain(bprm, next_domain, handler, tmp);          retval = find_next_domain(r, handler);
1553          task->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          task->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1554   out:   out:
1555          return retval;          return retval;
# Line 1609  static const struct path_info *find_exec Line 1583  static const struct path_info *find_exec
1583          return NULL;          return NULL;
1584  }  }
1585    
1586    /* List of next_domain which is used for checking interpreter's permissions. */
1587    struct execve_entry {
1588            struct list_head list;
1589            struct task_struct *task;
1590            struct domain_info *next_domain;
1591    };
1592    
1593    static LIST_HEAD(execve_list);
1594    static DEFINE_SPINLOCK(execve_list_lock);
1595    
1596    /**
1597     * ccs_register_next_domain - Remember next_domain.
1598     *
1599     * @next_domain: Pointer to "struct domain_info".
1600     *
1601     * Returns 0 on success, -ENOMEM otherwise.
1602     */
1603    static int ccs_register_next_domain(struct domain_info *next_domain)
1604    {
1605            struct execve_entry *ee = kmalloc(sizeof(*ee), GFP_KERNEL);
1606            if (!ee)
1607                    return -ENOMEM;
1608            ee->task = current;
1609            ee->next_domain = next_domain;
1610            /***** CRITICAL SECTION START *****/
1611            spin_lock(&execve_list_lock);
1612            list_add(&ee->list, &execve_list);
1613            spin_unlock(&execve_list_lock);
1614            /***** CRITICAL SECTION END *****/
1615            return 0;
1616    }
1617    
1618    /**
1619     * ccs_fetch_next_domain - Fetch next_domain from the list.
1620     *
1621     * Returns pointer to "struct domain_info" which will be used if execve()
1622     * succeeds. This function does not return NULL.
1623     */
1624    struct domain_info *ccs_fetch_next_domain(void)
1625    {
1626            struct task_struct *task = current;
1627            struct domain_info *next_domain = task->domain_info;
1628            struct execve_entry *p;
1629            /***** CRITICAL SECTION START *****/
1630            spin_lock(&execve_list_lock);
1631            list_for_each_entry(p, &execve_list, list) {
1632                    if (p->task != task)
1633                            continue;
1634                    next_domain = p->next_domain;
1635                    break;
1636            }
1637            spin_unlock(&execve_list_lock);
1638            /***** CRITICAL SECTION END *****/
1639            return next_domain;
1640    }
1641    
1642    /**
1643     * ccs_unregister_next_domain - Forget next_domain.
1644     */
1645    static void ccs_unregister_next_domain(void)
1646    {
1647            struct task_struct *task = current;
1648            struct execve_entry *p;
1649            struct execve_entry *ee = NULL;
1650            /***** CRITICAL SECTION START *****/
1651            spin_lock(&execve_list_lock);
1652            list_for_each_entry(p, &execve_list, list) {
1653                    if (p->task != task)
1654                            continue;
1655                    list_del(&p->list);
1656                    ee = p;
1657                    break;
1658            }
1659            spin_unlock(&execve_list_lock);
1660            /***** CRITICAL SECTION END *****/
1661            kfree(ee);
1662    }
1663    
1664  /**  /**
1665   * search_binary_handler_with_transition - Perform domain transition.   * search_binary_handler_with_transition - Perform domain transition.
1666   *   *
# Line 1621  static const struct path_info *find_exec Line 1673  static const struct path_info *find_exec
1673  int search_binary_handler_with_transition(struct linux_binprm *bprm,  int search_binary_handler_with_transition(struct linux_binprm *bprm,
1674                                            struct pt_regs *regs)                                            struct pt_regs *regs)
1675  {  {
1676            int retval;
1677          struct task_struct *task = current;          struct task_struct *task = current;
         struct domain_info *next_domain = NULL;  
         struct domain_info *prev_domain = task->domain_info;  
1678          const struct path_info *handler;          const struct path_info *handler;
1679          int retval;          struct ccs_request_info r;
1680            struct obj_info obj;
1681          /*          /*
1682           * "eh_path" holds path to execute handler program.           * "eh_path" holds path to execute handler program.
1683           * Thus, keep valid until search_binary_handler() finishes.           * Thus, keep valid until search_binary_handler() finishes.
1684           */           */
1685          char *eh_path = NULL;          char *eh_path = NULL;
1686          struct ccs_page_buffer *tmp = ccs_alloc(sizeof(struct ccs_page_buffer));          struct ccs_page_buffer *tmp = ccs_alloc(sizeof(struct ccs_page_buffer));
1687          ccs_load_policy(bprm->filename);          memset(&obj, 0, sizeof(obj));
1688            if (!sbin_init_started)
1689                    ccs_load_policy(bprm->filename);
1690          if (!tmp)          if (!tmp)
1691                  return -ENOMEM;                  return -ENOMEM;
1692          /* printk(KERN_DEBUG "rootdepth=%d\n", get_root_depth()); */  
1693            ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_FILE);
1694            r.bprm = bprm;
1695            r.obj = &obj;
1696            obj.path1_dentry = bprm->file->f_dentry;
1697            obj.path1_vfsmnt = bprm->file->f_vfsmnt;
1698            obj.tmp = tmp;
1699    
1700            /* Clear manager flag. */
1701            task->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1702          handler = find_execute_handler(TYPE_EXECUTE_HANDLER);          handler = find_execute_handler(TYPE_EXECUTE_HANDLER);
1703          if (handler) {          if (handler) {
1704                  retval = try_alt_exec(bprm, handler, &eh_path, &next_domain,                  retval = try_alt_exec(&r, handler, &eh_path);
                                       tmp);  
1705                  if (!retval)                  if (!retval)
1706                          audit_execute_handler_log(true, handler->name, bprm);                          audit_execute_handler_log(true, handler->name, bprm);
1707                  goto ok;                  goto ok;
1708          }          }
1709          retval = find_next_domain(bprm, &next_domain, NULL, tmp);          retval = find_next_domain(&r, NULL);
1710          if (retval != -EPERM)          if (retval != -EPERM)
1711                  goto ok;                  goto ok;
1712          handler = find_execute_handler(TYPE_DENIED_EXECUTE_HANDLER);          handler = find_execute_handler(TYPE_DENIED_EXECUTE_HANDLER);
1713          if (handler) {          if (handler) {
1714                  retval = try_alt_exec(bprm, handler, &eh_path, &next_domain,                  retval = try_alt_exec(&r, handler, &eh_path);
                                       tmp);  
1715                  if (!retval)                  if (!retval)
1716                          audit_execute_handler_log(false, handler->name, bprm);                          audit_execute_handler_log(false, handler->name, bprm);
1717          }          }
1718   ok:   ok:
1719          if (retval < 0)          if (retval < 0)
1720                  goto out;                  goto out;
1721          task->domain_info = next_domain;          r.mode = ccs_check_flags(r.domain, CCS_TOMOYO_MAC_FOR_ENV);
1722          retval = check_environ(bprm, tmp);          retval = check_environ(&r);
1723            if (retval < 0)
1724                    goto out;
1725            retval = ccs_register_next_domain(r.domain);
1726          if (retval < 0)          if (retval < 0)
1727                  goto out;                  goto out;
1728          task->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;          task->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
1729          retval = search_binary_handler(bprm, regs);          retval = search_binary_handler(bprm, regs);
1730          task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;          task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
  out:  
         /* Return to previous domain if execution failed. */  
1731          if (retval < 0)          if (retval < 0)
1732                  task->domain_info = prev_domain;                  goto out;
1733            /* Proceed to next domain if execution suceeded. */
1734            task->domain_info = r.domain;
1735            mb(); /* Make domain transition visible to other CPUs. */
1736          /* Mark the current process as execute handler. */          /* Mark the current process as execute handler. */
1737          else if (handler)          if (handler)
1738                  task->tomoyo_flags |= TOMOYO_TASK_IS_EXECUTE_HANDLER;                  task->tomoyo_flags |= TOMOYO_TASK_IS_EXECUTE_HANDLER;
1739          /* Mark the current process as normal process. */          /* Mark the current process as normal process. */
1740          else          else
1741                  task->tomoyo_flags &= ~TOMOYO_TASK_IS_EXECUTE_HANDLER;                  task->tomoyo_flags &= ~TOMOYO_TASK_IS_EXECUTE_HANDLER;
1742     out:
1743            ccs_unregister_next_domain();
1744          ccs_free(eh_path);          ccs_free(eh_path);
1745          ccs_free(tmp);          ccs_free(tmp);
1746          return retval;          return retval;
# Line 1693  int search_binary_handler_with_transitio Line 1760  int search_binary_handler_with_transitio
1760                                            struct pt_regs *regs)                                            struct pt_regs *regs)
1761  {  {
1762  #ifdef CONFIG_SAKURA  #ifdef CONFIG_SAKURA
1763            /* Clear manager flag. */
1764            current->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1765          ccs_load_policy(bprm->filename);          ccs_load_policy(bprm->filename);
1766  #endif  #endif
1767          return search_binary_handler(bprm, regs);          return search_binary_handler(bprm, regs);

Legend:
Removed from v.1561  
changed lines
  Added in v.1657

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