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

Subversion リポジトリの参照

Diff of /trunk/1.6.x/ccs-patch/fs/tomoyo_domain.c

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

revision 1058 by kumaneko, Wed Mar 26 08:49:28 2008 UTC revision 1064 by kumaneko, Fri Mar 28 05:06:28 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.0-rc   2008/03/26   * Version: 1.6.0-rc   2008/03/28
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 117  const char *ccs_get_last_name(const stru Line 117  const char *ccs_get_last_name(const stru
117  /**  /**
118   * ccs_add_domain_acl - Add the given ACL to the given domain.   * ccs_add_domain_acl - Add the given ACL to the given domain.
119   *   *
120   * @domain: Pointer to "struct domain_info".   * @domain: Pointer to "struct domain_info". May be NULL.
121   * @acl:    Pointer to "struct acl_info".   * @acl:    Pointer to "struct acl_info".
122   *   *
123   * Returns 0.   * Returns 0.
# Line 135  int ccs_add_domain_acl(struct domain_inf Line 135  int ccs_add_domain_acl(struct domain_inf
135  /**  /**
136   * ccs_del_domain_acl - Delete the given ACL from the domain.   * ccs_del_domain_acl - Delete the given ACL from the domain.
137   *   *
138   * @acl: Pointer to "struct acl_info".   * @acl: Pointer to "struct acl_info". May be NULL.
139   *   *
140   * Returns 0.   * Returns 0.
141   */   */
# Line 150  int ccs_del_domain_acl(struct acl_info * Line 150  int ccs_del_domain_acl(struct acl_info *
150  /**  /**
151   * audit_execute_handler_log - Audit execute_handler log.   * audit_execute_handler_log - Audit execute_handler log.
152   *   *
153   * @is_preferred: True if it is "preffered_execute_handler" log.   * @is_default: True if it is "execute_handler" log.
154   * @handler:      The realpath of the handler.   * @handler:    The realpath of the handler.
155   * @bprm:         Pointer to "struct linux_binprm".   * @bprm:       Pointer to "struct linux_binprm".
156   *   *
157   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
158   */   */
159  static int audit_execute_handler_log(const bool is_preferred,  static int audit_execute_handler_log(const bool is_default,
160                                       const char *handler,                                       const char *handler,
161                                       struct linux_binprm *bprm)                                       struct linux_binprm *bprm)
162  {  {
# Line 175  static int audit_execute_handler_log(con Line 175  static int audit_execute_handler_log(con
175                  return -ENOMEM;                  return -ENOMEM;
176          len2 = strlen(buf);          len2 = strlen(buf);
177          snprintf(buf + len2, len - len2 - 1, "%s %s\n",          snprintf(buf + len2, len - len2 - 1, "%s %s\n",
178                   is_preferred ?                   is_default ? KEYWORD_EXECUTE_HANDLER :
179                   KEYWORD_PREFERRED_EXECUTE_HANDLER :                   KEYWORD_DENIED_EXECUTE_HANDLER, handler);
                  KEYWORD_DEFAULT_EXECUTE_HANDLER,  
                  handler);  
180          return ccs_write_audit_log(buf, true);          return ccs_write_audit_log(buf, true);
181  }  }
182    
# Line 186  static int audit_execute_handler_log(con Line 184  static int audit_execute_handler_log(con
184   * audit_domain_creation_log - Audit domain creation log.   * audit_domain_creation_log - Audit domain creation log.
185   *   *
186   * @domainname: The name of newly created domain.   * @domainname: The name of newly created domain.
187   * @mode:       Access control mode.   * @mode:       Access control mode used.
188   * @profile:    Profile number.   * @profile:    Profile number used.
189   *   *
190   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
191   */   */
# Line 234  static int update_domain_initializer_ent Line 232  static int update_domain_initializer_ent
232                                             const bool is_not,                                             const bool is_not,
233                                             const bool is_delete)                                             const bool is_delete)
234  {  {
235          struct domain_initializer_entry *new_entry, *ptr;          struct domain_initializer_entry *new_entry;
236            struct domain_initializer_entry *ptr;
237          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
238          const struct path_info *saved_program, *saved_domainname = NULL;          const struct path_info *saved_program;
239            const struct path_info *saved_domainname = NULL;
240          int error = -ENOMEM;          int error = -ENOMEM;
241          bool is_last_name = false;          bool is_last_name = false;
242          if (!ccs_is_correct_path(program, 1, -1, -1, __func__))          if (!ccs_is_correct_path(program, 1, -1, -1, __func__))
# Line 279  static int update_domain_initializer_ent Line 279  static int update_domain_initializer_ent
279          error = 0;          error = 0;
280   out:   out:
281          mutex_unlock(&lock);          mutex_unlock(&lock);
282            ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
283          return error;          return error;
284  }  }
285    
# Line 293  bool ccs_read_domain_initializer_policy( Line 294  bool ccs_read_domain_initializer_policy(
294  {  {
295          struct list1_head *pos;          struct list1_head *pos;
296          list1_for_each_cookie(pos, head->read_var2, &domain_initializer_list) {          list1_for_each_cookie(pos, head->read_var2, &domain_initializer_list) {
297                    const char *no;
298                    const char *from = "";
299                    const char *domain = "";
300                  struct domain_initializer_entry *ptr;                  struct domain_initializer_entry *ptr;
301                  ptr = list1_entry(pos, struct domain_initializer_entry, list);                  ptr = list1_entry(pos, struct domain_initializer_entry, list);
302                  if (ptr->is_deleted)                  if (ptr->is_deleted)
303                          continue;                          continue;
304                    no = ptr->is_not ? "no_" : "";
305                  if (ptr->domainname) {                  if (ptr->domainname) {
306                          if (!ccs_io_printf(head, "%s" KEYWORD_INITIALIZE_DOMAIN                          from = " from ";
307                                             "%s from %s\n",                          domain = ptr->domainname->name;
                                            ptr->is_not ? "no_" : "",  
                                            ptr->program->name,  
                                            ptr->domainname->name))  
                                 goto out;  
                 } else {  
                         if (!ccs_io_printf(head, "%s"  
                                            KEYWORD_INITIALIZE_DOMAIN "%s\n",  
                                            ptr->is_not ? "no_" : "",  
                                            ptr->program->name))  
                                 goto out;  
308                  }                  }
309                    if (!ccs_io_printf(head,
310                                       "%s" KEYWORD_INITIALIZE_DOMAIN "%s%s%s\n",
311                                       no, ptr->program->name, from, domain))
312                                    goto out;
313          }          }
314          return true;          return true;
315   out:   out:
# Line 334  int ccs_write_domain_initializer_policy( Line 333  int ccs_write_domain_initializer_policy(
333                  *cp = '\0';                  *cp = '\0';
334                  return update_domain_initializer_entry(cp + 6, data, is_not,                  return update_domain_initializer_entry(cp + 6, data, is_not,
335                                                         is_delete);                                                         is_delete);
         } else {  
                 return update_domain_initializer_entry(NULL, data, is_not,  
                                                        is_delete);  
336          }          }
337            return update_domain_initializer_entry(NULL, data, is_not, is_delete);
338  }  }
339    
340  /**  /**
# Line 394  static int update_domain_keeper_entry(co Line 391  static int update_domain_keeper_entry(co
391                                        const char *program,                                        const char *program,
392                                        const bool is_not, const bool is_delete)                                        const bool is_not, const bool is_delete)
393  {  {
394          struct domain_keeper_entry *new_entry, *ptr;          struct domain_keeper_entry *new_entry;
395          const struct path_info *saved_domainname, *saved_program = NULL;          struct domain_keeper_entry *ptr;
396            const struct path_info *saved_domainname;
397            const struct path_info *saved_program = NULL;
398          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
399          int error = -ENOMEM;          int error = -ENOMEM;
400          bool is_last_name = false;          bool is_last_name = false;
# Line 439  static int update_domain_keeper_entry(co Line 438  static int update_domain_keeper_entry(co
438          error = 0;          error = 0;
439   out:   out:
440          mutex_unlock(&lock);          mutex_unlock(&lock);
441            ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
442          return error;          return error;
443  }  }
444    
# Line 458  int ccs_write_domain_keeper_policy(char Line 458  int ccs_write_domain_keeper_policy(char
458                  *cp = '\0';                  *cp = '\0';
459                  return update_domain_keeper_entry(cp + 6, data,                  return update_domain_keeper_entry(cp + 6, data,
460                                                    is_not, is_delete);                                                    is_not, is_delete);
         } else {  
                 return update_domain_keeper_entry(data, NULL,  
                                                   is_not, is_delete);  
461          }          }
462            return update_domain_keeper_entry(data, NULL, is_not, is_delete);
463  }  }
464    
465  /**  /**
# Line 476  bool ccs_read_domain_keeper_policy(struc Line 474  bool ccs_read_domain_keeper_policy(struc
474          struct list1_head *pos;          struct list1_head *pos;
475          list1_for_each_cookie(pos, head->read_var2, &domain_keeper_list) {          list1_for_each_cookie(pos, head->read_var2, &domain_keeper_list) {
476                  struct domain_keeper_entry *ptr;                  struct domain_keeper_entry *ptr;
477                  const char *is_not;                  const char *no;
478                    const char *from = "";
479                    const char *program = "";
480                  ptr = list1_entry(pos, struct domain_keeper_entry, list);                  ptr = list1_entry(pos, struct domain_keeper_entry, list);
481                  if (ptr->is_deleted)                  if (ptr->is_deleted)
482                          continue;                          continue;
483                  is_not = ptr->is_not ? "no_" : "";                  no = ptr->is_not ? "no_" : "";
484                  if (ptr->program) {                  if (ptr->program) {
485                          if (!ccs_io_printf(head,                          from = " from ";
486                                             "%s" KEYWORD_KEEP_DOMAIN "%s "                          program = ptr->program->name;
                                            "from %s\n",  
                                            is_not, ptr->program->name,  
                                            ptr->domainname->name))  
                                 goto out;  
                 } else {  
                         if (!ccs_io_printf(head,  
                                            "%s" KEYWORD_KEEP_DOMAIN "%s\n",  
                                            is_not, ptr->domainname->name))  
                                 goto out;  
487                  }                  }
488                    if (!ccs_io_printf(head,
489                                       "%s" KEYWORD_KEEP_DOMAIN "%s%s%s\n", no,
490                                       program, from, ptr->domainname->name))
491                                    goto out;
492          }          }
493          return true;          return true;
494   out:   out:
# Line 551  static int update_alias_entry(const char Line 546  static int update_alias_entry(const char
546                                const char *aliased_name,                                const char *aliased_name,
547                                const bool is_delete)                                const bool is_delete)
548  {  {
549          struct alias_entry *new_entry, *ptr;          struct alias_entry *new_entry;
550            struct alias_entry *ptr;
551          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
552          const struct path_info *saved_original_name, *saved_aliased_name;          const struct path_info *saved_original_name;
553            const struct path_info *saved_aliased_name;
554          int error = -ENOMEM;          int error = -ENOMEM;
555          if (!ccs_is_correct_path(original_name, 1, -1, -1, __func__) ||          if (!ccs_is_correct_path(original_name, 1, -1, -1, __func__) ||
556              !ccs_is_correct_path(aliased_name, 1, -1, -1, __func__))              !ccs_is_correct_path(aliased_name, 1, -1, -1, __func__))
# Line 584  static int update_alias_entry(const char Line 581  static int update_alias_entry(const char
581          error = 0;          error = 0;
582   out:   out:
583          mutex_unlock(&lock);          mutex_unlock(&lock);
584            ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
585          return error;          return error;
586  }  }
587    
# Line 645  static int update_aggregator_entry(const Line 643  static int update_aggregator_entry(const
643                                     const char *aggregated_name,                                     const char *aggregated_name,
644                                     const bool is_delete)                                     const bool is_delete)
645  {  {
646          struct aggregator_entry *new_entry, *ptr;          struct aggregator_entry *new_entry;
647            struct aggregator_entry *ptr;
648          static DEFINE_MUTEX(lock);          static DEFINE_MUTEX(lock);
649          const struct path_info *saved_original_name, *saved_aggregated_name;          const struct path_info *saved_original_name;
650            const struct path_info *saved_aggregated_name;
651          int error = -ENOMEM;          int error = -ENOMEM;
652          if (!ccs_is_correct_path(original_name, 1, 0, -1, __func__) ||          if (!ccs_is_correct_path(original_name, 1, 0, -1, __func__) ||
653              !ccs_is_correct_path(aggregated_name, 1, -1, -1, __func__))              !ccs_is_correct_path(aggregated_name, 1, -1, -1, __func__))
# Line 678  static int update_aggregator_entry(const Line 678  static int update_aggregator_entry(const
678          error = 0;          error = 0;
679   out:   out:
680          mutex_unlock(&lock);          mutex_unlock(&lock);
681            ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
682          return error;          return error;
683  }  }
684    
# Line 791  int ccs_delete_domain(char *domainname) Line 792  int ccs_delete_domain(char *domainname)
792   */   */
793  struct domain_info *ccs_undelete_domain(const char *domainname)  struct domain_info *ccs_undelete_domain(const char *domainname)
794  {  {
795          struct domain_info *domain, *candidate_domain = NULL;          struct domain_info *domain;
796            struct domain_info *candidate_domain = NULL;
797          struct path_info name;          struct path_info name;
798          name.name = domainname;          name.name = domainname;
799          ccs_fill_path_info(&name);          ccs_fill_path_info(&name);
# Line 864  struct domain_info *ccs_find_or_assign_n Line 866  struct domain_info *ccs_find_or_assign_n
866                  /***** CRITICAL SECTION START *****/                  /***** CRITICAL SECTION START *****/
867                  read_lock(&tasklist_lock);                  read_lock(&tasklist_lock);
868                  for_each_process(p) {                  for_each_process(p) {
869                          if (p->domain_info == domain) {                          if (p->domain_info != domain)
870                                  flag = true;                                  continue;
871                                  break;                          flag = true;
872                          }                          break;
873                  }                  }
874                  read_unlock(&tasklist_lock);                  read_unlock(&tasklist_lock);
875                  /***** CRITICAL SECTION END *****/                  /***** CRITICAL SECTION END *****/
# Line 1009  static int find_next_domain(struct linux Line 1011  static int find_next_domain(struct linux
1011          const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_FILE);          const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_FILE);
1012          const bool is_enforce = (mode == 3);          const bool is_enforce = (mode == 3);
1013          int retval;          int retval;
1014          struct path_info r, s, l;          struct path_info r; /* real name */
1015            struct path_info s; /* symlink name */
1016            struct path_info l; /* last name */
1017    
1018          {          {
1019                  /*                  /*
1020                   * Built-in initializers. This is needed because policies are                   * Built-in initializers. This is needed because policies are
1021                   * not loaded until starting /sbin/init .                   * not loaded until starting /sbin/init.
1022                   */                   */
1023                  static bool first = true;                  static bool first = true;
1024                  if (first) {                  if (first) {
# Line 1045  static int find_next_domain(struct linux Line 1049  static int find_next_domain(struct linux
1049    
1050          if (path_to_verify) {          if (path_to_verify) {
1051                  if (ccs_pathcmp(&r, path_to_verify)) {                  if (ccs_pathcmp(&r, path_to_verify)) {
1052                            /* Failed to verify execute handler. */
1053                          static u8 counter = 20;                          static u8 counter = 20;
1054                          if (counter) {                          if (counter) {
1055                                  counter--;                                  counter--;
# Line 1122  static int find_next_domain(struct linux Line 1127  static int find_next_domain(struct linux
1127          } else if (old_domain == &KERNEL_DOMAIN && !sbin_init_started) {          } else if (old_domain == &KERNEL_DOMAIN && !sbin_init_started) {
1128                  /*                  /*
1129                   * Needn't to transit from kernel domain before starting                   * Needn't to transit from kernel domain before starting
1130                   * /sbin/init . But transit from kernel domain if executing                   * /sbin/init. But transit from kernel domain if executing
1131                   * initializers because they might start before /sbin/init .                   * initializers because they might start before /sbin/init.
1132                   */                   */
1133                  domain = old_domain;                  domain = old_domain;
1134          } else if (is_domain_keeper(old_domain->domainname, &r, &l)) {          } else if (is_domain_keeper(old_domain->domainname, &r, &l)) {
# Line 1139  static int find_next_domain(struct linux Line 1144  static int find_next_domain(struct linux
1144          domain = ccs_find_domain(new_domain_name);          domain = ccs_find_domain(new_domain_name);
1145          if (domain)          if (domain)
1146                  goto done;                  goto done;
1147          if (is_enforce) {          if (is_enforce && ccs_check_supervisor("#Need to create domain\n%s\n",
1148                  if (ccs_check_supervisor("#Need to create domain\n%s\n",                                                 new_domain_name))
                                          new_domain_name))  
1149                          goto done;                          goto done;
         }  
1150          domain = ccs_find_or_assign_new_domain(new_domain_name,          domain = ccs_find_or_assign_new_domain(new_domain_name,
1151                                                 old_domain->profile);                                                 old_domain->profile);
1152          if (domain)          if (domain)
# Line 1180  static int check_environ(struct linux_bi Line 1183  static int check_environ(struct linux_bi
1183          char *arg_ptr = tmp->buffer;          char *arg_ptr = tmp->buffer;
1184          int arg_len = 0;          int arg_len = 0;
1185          unsigned long pos = bprm->p;          unsigned long pos = bprm->p;
1186          int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;          int i = pos / PAGE_SIZE;
1187            int offset = pos % PAGE_SIZE;
1188          int argv_count = bprm->argc;          int argv_count = bprm->argc;
1189          int envp_count = bprm->envc;          int envp_count = bprm->envc;
1190          /* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */          /* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */
# Line 1270  static int check_environ(struct linux_bi Line 1274  static int check_environ(struct linux_bi
1274  static void unescape(unsigned char *dest)  static void unescape(unsigned char *dest)
1275  {  {
1276          unsigned char *src = dest;          unsigned char *src = dest;
1277          unsigned char c, d, e;          unsigned char c;
1278            unsigned char d;
1279            unsigned char e;
1280          while ((c = *src++) != '\0') {          while ((c = *src++) != '\0') {
1281                  if (c != '\\') {                  if (c != '\\') {
1282                          *dest++ = c;                          *dest++ = c;
# Line 1386  static int try_alt_exec(struct linux_bin Line 1392  static int try_alt_exec(struct linux_bin
1392           * Contents of modified bprm.           * Contents of modified bprm.
1393           * The envp[] in original bprm is moved to argv[] so that           * The envp[] in original bprm is moved to argv[] so that
1394           * the alternatively executed program won't be affected by           * the alternatively executed program won't be affected by
1395           * some dangerous environment variables like LD_PRELOAD .           * some dangerous environment variables like LD_PRELOAD.
1396           *           *
1397           * modified bprm->argc           * modified bprm->argc
1398           *    = original bprm->argc + original bprm->envc + 7           *    = original bprm->argc + original bprm->envc + 7
# Line 1570  static int try_alt_exec(struct linux_bin Line 1576  static int try_alt_exec(struct linux_bin
1576   */   */
1577  static const struct path_info *find_execute_handler(const u8 type)  static const struct path_info *find_execute_handler(const u8 type)
1578  {  {
1579          const struct domain_info *domain = current->domain_info;          struct task_struct *task = current;
1580            const struct domain_info *domain = task->domain_info;
1581          struct acl_info *ptr;          struct acl_info *ptr;
1582            /*
1583             * Don't use execute handler if the current process is
1584             * marked as execute handler to avoid infinite execute handler loop.
1585             */
1586            if (task->tomoyo_flags & TOMOYO_TASK_IS_EXECUTE_HANDLER)
1587                    return NULL;
1588          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
1589                  struct execute_handler_record *acl;                  struct execute_handler_record *acl;
1590                  if (ptr->type != type)                  if (ptr->type != type)
# Line 1609  int search_binary_handler_with_transitio Line 1622  int search_binary_handler_with_transitio
1622          if (!buf)          if (!buf)
1623                  return -ENOMEM;                  return -ENOMEM;
1624          /* printk(KERN_DEBUG "rootdepth=%d\n", get_root_depth()); */          /* printk(KERN_DEBUG "rootdepth=%d\n", get_root_depth()); */
1625          handler = find_execute_handler(TYPE_PREFERRED_EXECUTE_HANDLER);          handler = find_execute_handler(TYPE_EXECUTE_HANDLER);
1626          if (handler) {          if (handler) {
1627                  retval = try_alt_exec(bprm, handler, &work, &next_domain, buf);                  retval = try_alt_exec(bprm, handler, &work, &next_domain, buf);
1628                  if (!retval)                  if (!retval)
# Line 1619  int search_binary_handler_with_transitio Line 1632  int search_binary_handler_with_transitio
1632          retval = find_next_domain(bprm, &next_domain, NULL, buf);          retval = find_next_domain(bprm, &next_domain, NULL, buf);
1633          if (retval != -EPERM)          if (retval != -EPERM)
1634                  goto ok;                  goto ok;
1635          handler = find_execute_handler(TYPE_DEFAULT_EXECUTE_HANDLER);          handler = find_execute_handler(TYPE_DENIED_EXECUTE_HANDLER);
1636          if (handler) {          if (handler) {
1637                  retval = try_alt_exec(bprm, handler, &work, &next_domain, buf);                  retval = try_alt_exec(bprm, handler, &work, &next_domain, buf);
1638                  if (!retval)                  if (!retval)
# Line 1636  int search_binary_handler_with_transitio Line 1649  int search_binary_handler_with_transitio
1649          retval = search_binary_handler(bprm, regs);          retval = search_binary_handler(bprm, regs);
1650          task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;          task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
1651   out:   out:
1652            /* Return to previous domain if execution failed. */
1653          if (retval < 0)          if (retval < 0)
1654                  task->domain_info = prev_domain;                  task->domain_info = prev_domain;
1655            /* Mark the current process as execute handler. */
1656            else if (handler)
1657                    task->tomoyo_flags |= TOMOYO_TASK_IS_EXECUTE_HANDLER;
1658            /* Mark the current process as normal process. */
1659            else
1660                    task->tomoyo_flags &= ~TOMOYO_TASK_IS_EXECUTE_HANDLER;
1661          ccs_free(work);          ccs_free(work);
1662          ccs_free(buf);          ccs_free(buf);
1663          return retval;          return retval;

Legend:
Removed from v.1058  
changed lines
  Added in v.1064

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