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

Subversion リポジトリの参照

Diff of /trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c

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

trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c revision 3560 by kumaneko, Wed Mar 31 13:13:57 2010 UTC branches/ccs-patch/security/ccsecurity/policy_io.c revision 3693 by kumaneko, Sun May 23 08:05:44 2010 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2010  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.2-rc   2010/03/31   * Version: 1.7.2   2010/04/01
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 305  static void ccs_check_profile(void) Line 305  static void ccs_check_profile(void)
305          if (ccs_profile_version != 20090903)          if (ccs_profile_version != 20090903)
306                  panic("Profile version %u is not supported.\n",                  panic("Profile version %u is not supported.\n",
307                        ccs_profile_version);                        ccs_profile_version);
308          printk(KERN_INFO "CCSecurity: 1.7.2-rc   2010/03/31\n");          printk(KERN_INFO "CCSecurity: 1.7.2   2010/04/01\n");
309          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
310  }  }
311    
# Line 367  static int ccs_write_profile(struct ccs_ Line 367  static int ccs_write_profile(struct ccs_
367                  value = 0;                  value = 0;
368          else          else
369                  value = -1;                  value = -1;
370          if (!strcmp(data, "PREFERENCE::audit")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_AUDIT)) {
371  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
372                  char *cp2;                  char *cp2;
373  #endif  #endif
# Line 396  static int ccs_write_profile(struct ccs_ Line 396  static int ccs_write_profile(struct ccs_
396                          profile->preference.audit_path_info = false;                          profile->preference.audit_path_info = false;
397                  return 0;                  return 0;
398          }          }
399          if (!strcmp(data, "PREFERENCE::enforcing")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_ENFORCING)) {
400                  char *cp2;                  char *cp2;
401                  if (use_default) {                  if (use_default) {
402                          profile->enforcing = &ccs_default_profile.preference;                          profile->enforcing = &ccs_default_profile.preference;
# Line 411  static int ccs_write_profile(struct ccs_ Line 411  static int ccs_write_profile(struct ccs_
411                                 &profile->preference.enforcing_penalty);                                 &profile->preference.enforcing_penalty);
412                  return 0;                  return 0;
413          }          }
414          if (!strcmp(data, "PREFERENCE::permissive")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_PERMISSIVE)) {
415                  if (use_default) {                  if (use_default) {
416                          profile->permissive = &ccs_default_profile.preference;                          profile->permissive = &ccs_default_profile.preference;
417                          return 0;                          return 0;
# Line 421  static int ccs_write_profile(struct ccs_ Line 421  static int ccs_write_profile(struct ccs_
421                          profile->preference.permissive_verbose = value;                          profile->preference.permissive_verbose = value;
422                  return 0;                  return 0;
423          }          }
424          if (!strcmp(data, "PREFERENCE::learning")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_LEARNING)) {
425                  char *cp2;                  char *cp2;
426                  if (use_default) {                  if (use_default) {
427                          profile->learning = &ccs_default_profile.preference;                          profile->learning = &ccs_default_profile.preference;
# Line 506  static int ccs_write_profile(struct ccs_ Line 506  static int ccs_write_profile(struct ccs_
506          return 0;          return 0;
507  }  }
508    
509    static bool ccs_print_preference(struct ccs_io_buffer *head, const int idx)
510    {
511            struct ccs_preference *pref = &ccs_default_profile.preference;
512            const struct ccs_profile *profile = idx >= 0 ?
513                    ccs_profile_ptr[idx] : NULL;
514            char buffer[16] = "";
515            if (profile) {
516                    buffer[sizeof(buffer) - 1] = '\0';
517                    snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
518            }
519            if (profile) {
520                    pref = profile->audit;
521                    if (pref == &ccs_default_profile.preference)
522                            pref = NULL;
523            }
524            if (pref && !ccs_io_printf(head, "%s%s={ "
525    #ifdef CONFIG_CCSECURITY_AUDIT
526                                       "max_grant_log=%u max_reject_log=%u "
527    #endif
528                                       "task_info=%s path_info=%s }\n", buffer,
529                                       CCS_KEYWORD_PREFERENCE_AUDIT,
530    #ifdef CONFIG_CCSECURITY_AUDIT
531                                       pref->audit_max_grant_log,
532                                       pref->audit_max_reject_log,
533    #endif
534                                       ccs_yesno(pref->audit_task_info),
535                                       ccs_yesno(pref->audit_path_info)))
536                    return false;
537            if (profile) {
538                    pref = profile->learning;
539                    if (pref == &ccs_default_profile.preference)
540                            pref = NULL;
541            }
542            if (pref && !ccs_io_printf(head, "%s%s={ "
543                                       "verbose=%s max_entry=%u exec.realpath=%s "
544                                       "exec.argv0=%s symlink.target=%s }\n",
545                                       buffer, CCS_KEYWORD_PREFERENCE_LEARNING,
546                                       ccs_yesno(pref->learning_verbose),
547                                       pref->learning_max_entry,
548                                       ccs_yesno(pref->learning_exec_realpath),
549                                       ccs_yesno(pref->learning_exec_argv0),
550                                       ccs_yesno(pref->learning_symlink_target)))
551                    return false;
552            if (profile) {
553                    pref = profile->permissive;
554                    if (pref == &ccs_default_profile.preference)
555                            pref = NULL;
556            }
557            if (pref && !ccs_io_printf(head, "%s%s={ verbose=%s }\n", buffer,
558                                       CCS_KEYWORD_PREFERENCE_PERMISSIVE,
559                                       ccs_yesno(pref->permissive_verbose)))
560                    return false;
561            if (profile) {
562                    pref = profile->enforcing;
563                    if (pref == &ccs_default_profile.preference)
564                            pref = NULL;
565            }
566            return !pref || ccs_io_printf(head, "%s%s={ verbose=%s penalty=%u }\n",
567                                          buffer, CCS_KEYWORD_PREFERENCE_ENFORCING,
568                                          ccs_yesno(pref->enforcing_verbose),
569                                          pref->enforcing_penalty);
570    }
571    
572  /**  /**
573   * ccs_read_profile - Read profile table.   * ccs_read_profile - Read profile table.
574   *   *
# Line 519  static void ccs_read_profile(struct ccs_ Line 582  static void ccs_read_profile(struct ccs_
582          if (head->read_bit)          if (head->read_bit)
583                  goto body;                  goto body;
584          ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");          ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
585          ccs_io_printf(head, "PREFERENCE::audit={ "          ccs_print_preference(head, -1);
 #ifdef CONFIG_CCSECURITY_AUDIT  
                       "max_grant_log=%u max_reject_log=%u "  
 #endif  
                       "task_info=%s path_info=%s }\n",  
 #ifdef CONFIG_CCSECURITY_AUDIT  
                       ccs_default_profile.preference.audit_max_grant_log,  
                       ccs_default_profile.preference.audit_max_reject_log,  
 #endif  
                       ccs_yesno(ccs_default_profile.preference.  
                                 audit_task_info),  
                       ccs_yesno(ccs_default_profile.preference.  
                                 audit_path_info));  
         ccs_io_printf(head, "PREFERENCE::learning={ verbose=%s max_entry=%u "  
                       "exec.realpath=%s exec.argv0=%s symlink.target=%s }\n",  
                       ccs_yesno(ccs_default_profile.preference.  
                                 learning_verbose),  
                       ccs_default_profile.preference.learning_max_entry,  
                       ccs_yesno(ccs_default_profile.preference.  
                                 learning_exec_realpath),  
                       ccs_yesno(ccs_default_profile.preference.  
                                 learning_exec_argv0),  
                       ccs_yesno(ccs_default_profile.preference.  
                                 learning_symlink_target));  
         ccs_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n",  
                       ccs_yesno(ccs_default_profile.preference.  
                                 permissive_verbose));  
         ccs_io_printf(head, "PREFERENCE::enforcing={ verbose=%s penalty=%u "  
                       "}\n",  
                       ccs_yesno(ccs_default_profile.preference.  
                                 enforcing_verbose),  
                       ccs_default_profile.preference.enforcing_penalty);  
586          head->read_bit = 1;          head->read_bit = 1;
587   body:   body:
588          for (index = head->read_step; index < CCS_MAX_PROFILES; index++) {          for (index = head->read_step; index < CCS_MAX_PROFILES; index++) {
# Line 571  static void ccs_read_profile(struct ccs_ Line 603  static void ccs_read_profile(struct ccs_
603                          goto out;                          goto out;
604                  config = profile->default_config;                  config = profile->default_config;
605  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
606                  if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s grant_log=%s "                  if (!ccs_io_printf(head, "%u-%s%s={ mode=%s "
607                                     "reject_log=%s }\n", index,                                     "grant_log=%s reject_log=%s }\n", index,
608                                     ccs_mode_4[config & 3],                                     "CONFIG", "", ccs_mode_4[config & 3],
609                                     ccs_yesno(config &                                     ccs_yesno(config &
610                                               CCS_CONFIG_WANT_GRANT_LOG),                                               CCS_CONFIG_WANT_GRANT_LOG),
611                                     ccs_yesno(config &                                     ccs_yesno(config &
612                                               CCS_CONFIG_WANT_REJECT_LOG)))                                               CCS_CONFIG_WANT_REJECT_LOG)))
613                          goto out;                          goto out;
614  #else  #else
615                  if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,                  if (!ccs_io_printf(head, "%u-%s%s={ mode=%s }\n", index,
616                                     ccs_mode_4[config & 3]))                                     "CONFIG", "", ccs_mode_4[config & 3]))
617                          goto out;                          goto out;
618  #endif  #endif
619                  for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX                  for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
# Line 596  static void ccs_read_profile(struct ccs_ Line 628  static void ccs_read_profile(struct ccs_
628  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
629                          g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);                          g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);
630                          r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);                          r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);
631                          if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s "                          if (!ccs_io_printf(head, "%u-%s%s={ mode=%s "
632                                             "grant_log=%s reject_log=%s }\n",                                             "grant_log=%s reject_log=%s }\n",
633                                             index, ccs_mac_keywords[i],                                             index, "CONFIG::",
634                                               ccs_mac_keywords[i],
635                                             ccs_mode_4[config & 3], g, r))                                             ccs_mode_4[config & 3], g, r))
636                                  goto out;                                  goto out;
637  #else  #else
638                          if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s }\n",                          if (!ccs_io_printf(head, "%u-%s%s={ mode=%s }\n",
639                                             index, ccs_mac_keywords[i],                                             index, "CONFIG::",
640                                               ccs_mac_keywords[i],
641                                             ccs_mode_4[config & 3]))                                             ccs_mode_4[config & 3]))
642                                  goto out;                                  goto out;
643  #endif  #endif
644                  }                  }
645                  if (profile->audit != &ccs_default_profile.preference &&                  if (!ccs_print_preference(head, index))
                     !ccs_io_printf(head, "%u-PREFERENCE::audit={ "  
 #ifdef CONFIG_CCSECURITY_AUDIT  
                                    "max_grant_log=%u max_reject_log=%u "  
 #endif  
                                    "task_info=%s path_info=%s }\n", index,  
 #ifdef CONFIG_CCSECURITY_AUDIT  
                                    profile->preference.audit_max_grant_log,  
                                    profile->preference.audit_max_reject_log,  
 #endif  
                                    ccs_yesno(profile->preference.  
                                              audit_task_info),  
                                    ccs_yesno(profile->preference.  
                                              audit_path_info)))  
                         goto out;  
                 if (profile->learning != &ccs_default_profile.preference &&  
                     !ccs_io_printf(head, "%u-PREFERENCE::learning={ "  
                                    "verbose=%s max_entry=%u exec.realpath=%s "  
                                    "exec.argv0=%s symlink.target=%s }\n",  
                                    index,  
                                    ccs_yesno(profile->preference.  
                                              learning_verbose),  
                                    profile->preference.learning_max_entry,  
                                    ccs_yesno(profile->preference.  
                                              learning_exec_realpath),  
                                    ccs_yesno(profile->preference.  
                                              learning_exec_argv0),  
                                    ccs_yesno(profile->preference.  
                                              learning_symlink_target)))  
                         goto out;  
                 if (profile->permissive != &ccs_default_profile.preference &&  
                     !ccs_io_printf(head, "%u-PREFERENCE::permissive={ "  
                                    "verbose=%s }\n", index,  
                                    ccs_yesno(profile->preference.  
                                              permissive_verbose)))  
                         goto out;  
                 if (profile->enforcing != &ccs_default_profile.preference &&  
                     !ccs_io_printf(head, "%u-PREFERENCE::enforcing={ "  
                                    "verbose=%s penalty=%u }\n", index,  
                                    ccs_yesno(profile->preference.  
                                              enforcing_verbose),  
                                    profile->preference.enforcing_penalty))  
646                          goto out;                          goto out;
647                  continue;                  continue;
648   out:   out:
# Line 660  static void ccs_read_profile(struct ccs_ Line 653  static void ccs_read_profile(struct ccs_
653                  head->read_eof = true;                  head->read_eof = true;
654  }  }
655    
656  /* The list for "struct ccs_policy_manager_entry". */  static bool ccs_same_manager_entry(const struct ccs_acl_head *a,
657  LIST_HEAD(ccs_policy_manager_list);                                        const struct ccs_acl_head *b)
658    {
659            return container_of(a, struct ccs_manager, head)->manager
660                    == container_of(b, struct ccs_manager, head)->manager;
661    }
662    
663  /**  /**
664   * ccs_update_manager_entry - Add a manager entry.   * ccs_update_manager_entry - Add a manager entry.
# Line 673  LIST_HEAD(ccs_policy_manager_list); Line 670  LIST_HEAD(ccs_policy_manager_list);
670   */   */
671  static int ccs_update_manager_entry(const char *manager, const bool is_delete)  static int ccs_update_manager_entry(const char *manager, const bool is_delete)
672  {  {
673          struct ccs_policy_manager_entry *ptr;          struct ccs_manager e = { };
         struct ccs_policy_manager_entry e = { };  
674          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
675          if (ccs_is_domain_def(manager)) {          if (ccs_domain_def(manager)) {
676                  if (!ccs_is_correct_domain(manager))                  if (!ccs_correct_domain(manager))
677                          return -EINVAL;                          return -EINVAL;
678                  e.is_domain = true;                  e.is_domain = true;
679          } else {          } else {
680                  if (!ccs_is_correct_path(manager, 1, -1, -1))                  if (!ccs_correct_path(manager, 1, -1, -1))
681                          return -EINVAL;                          return -EINVAL;
682          }          }
683          e.manager = ccs_get_name(manager);          e.manager = ccs_get_name(manager);
684          if (!e.manager)          if (!e.manager)
685                  return -ENOMEM;                  return error;
686          if (mutex_lock_interruptible(&ccs_policy_lock))          error = ccs_update_policy(&e.head, sizeof(e), is_delete,
687                  goto out;                                    CCS_ID_MANAGER, ccs_same_manager_entry);
         list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {  
                 if (ptr->manager != e.manager)  
                         continue;  
                 ptr->is_deleted = is_delete;  
                 error = 0;  
                 break;  
         }  
         if (!is_delete && error) {  
                 struct ccs_policy_manager_entry *entry =  
                         ccs_commit_ok(&e, sizeof(e));  
                 if (entry) {  
                         list_add_tail_rcu(&entry->list,  
                                           &ccs_policy_manager_list);  
                         error = 0;  
                 }  
         }  
         mutex_unlock(&ccs_policy_lock);  
  out:  
688          ccs_put_name(e.manager);          ccs_put_name(e.manager);
689          return error;          return error;
690  }  }
691    
692  /**  /**
693   * ccs_write_manager_policy - Write manager policy.   * ccs_write_manager - Write manager policy.
694   *   *
695   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
696   *   *
697   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
698   */   */
699  static int ccs_write_manager_policy(struct ccs_io_buffer *head)  static int ccs_write_manager(struct ccs_io_buffer *head)
700  {  {
701          char *data = head->write_buf;          char *data = head->write_buf;
702          bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);          bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
# Line 730  static int ccs_write_manager_policy(stru Line 708  static int ccs_write_manager_policy(stru
708  }  }
709    
710  /**  /**
711   * ccs_read_manager_policy - Read manager policy.   * ccs_read_manager - Read manager policy.
712   *   *
713   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
714   *   *
715   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
716   */   */
717  static void ccs_read_manager_policy(struct ccs_io_buffer *head)  static void ccs_read_manager(struct ccs_io_buffer *head)
718  {  {
719          struct list_head *pos;          struct list_head *pos;
720          if (head->read_eof)          if (head->read_eof)
721                  return;                  return;
722          list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {          list_for_each_cookie(pos, head->read_var2,
723                  struct ccs_policy_manager_entry *ptr;                               &ccs_policy_list[CCS_ID_MANAGER]) {
724                  ptr = list_entry(pos, struct ccs_policy_manager_entry, list);                  struct ccs_manager *ptr
725                  if (ptr->is_deleted)                          = list_entry(pos, typeof(*ptr), head.list);
726                    if (ptr->head.is_deleted)
727                          continue;                          continue;
728                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
729                          return;                          return;
# Line 753  static void ccs_read_manager_policy(stru Line 732  static void ccs_read_manager_policy(stru
732  }  }
733    
734  /**  /**
735   * ccs_is_policy_manager - Check whether the current process is a policy manager.   * ccs_manager - Check whether the current process is a policy manager.
736   *   *
737   * Returns true if the current process is permitted to modify policy   * Returns true if the current process is permitted to modify policy
738   * via /proc/ccs/ interface.   * via /proc/ccs/ interface.
739   *   *
740   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
741   */   */
742  static bool ccs_is_policy_manager(void)  static bool ccs_manager(void)
743  {  {
744          struct ccs_policy_manager_entry *ptr;          struct ccs_manager *ptr;
745          const char *exe;          const char *exe;
746          struct task_struct *task = current;          struct task_struct *task = current;
747          const struct ccs_path_info *domainname          const struct ccs_path_info *domainname
# Line 770  static bool ccs_is_policy_manager(void) Line 749  static bool ccs_is_policy_manager(void)
749          bool found = false;          bool found = false;
750          if (!ccs_policy_loaded)          if (!ccs_policy_loaded)
751                  return true;                  return true;
752          if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)          if (task->ccs_flags & CCS_TASK_IS_MANAGER)
753                  return true;                  return true;
754          if (!ccs_manage_by_non_root && (current_uid() || current_euid()))          if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
755                  return false;                  return false;
756          list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {          list_for_each_entry_rcu(ptr, &ccs_policy_list[CCS_ID_MANAGER],
757                  if (!ptr->is_deleted && ptr->is_domain                                  head.list) {
758                    if (!ptr->head.is_deleted && ptr->is_domain
759                      && !ccs_pathcmp(domainname, ptr->manager)) {                      && !ccs_pathcmp(domainname, ptr->manager)) {
760                          /* Set manager flag. */                          /* Set manager flag. */
761                          task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;                          task->ccs_flags |= CCS_TASK_IS_MANAGER;
762                          return true;                          return true;
763                  }                  }
764          }          }
765          exe = ccs_get_exe();          exe = ccs_get_exe();
766          if (!exe)          if (!exe)
767                  return false;                  return false;
768          list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {          list_for_each_entry_rcu(ptr, &ccs_policy_list[CCS_ID_MANAGER],
769                  if (!ptr->is_deleted && !ptr->is_domain                                  head.list) {
770                    if (!ptr->head.is_deleted && !ptr->is_domain
771                      && !strcmp(exe, ptr->manager->name)) {                      && !strcmp(exe, ptr->manager->name)) {
772                          found = true;                          found = true;
773                          /* Set manager flag. */                          /* Set manager flag. */
774                          task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;                          task->ccs_flags |= CCS_TASK_IS_MANAGER;
775                          break;                          break;
776                  }                  }
777          }          }
# Line 835  static char *ccs_find_condition_part(cha Line 816  static char *ccs_find_condition_part(cha
816  }  }
817    
818  /**  /**
819   * ccs_is_select_one - Parse select command.   * ccs_select_one - Parse select command.
820   *   *
821   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
822   * @data: String to parse.   * @data: String to parse.
# Line 844  static char *ccs_find_condition_part(cha Line 825  static char *ccs_find_condition_part(cha
825   *   *
826   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
827   */   */
828  static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)  static bool ccs_select_one(struct ccs_io_buffer *head, const char *data)
829  {  {
830          unsigned int pid;          unsigned int pid;
831          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
# Line 870  static bool ccs_is_select_one(struct ccs Line 851  static bool ccs_is_select_one(struct ccs
851                          domain = ccs_task_domain(p);                          domain = ccs_task_domain(p);
852                  ccs_tasklist_unlock();                  ccs_tasklist_unlock();
853          } else if (!strncmp(data, "domain=", 7)) {          } else if (!strncmp(data, "domain=", 7)) {
854                  if (ccs_is_domain_def(data + 7))                  if (ccs_domain_def(data + 7))
855                          domain = ccs_find_domain(data + 7);                          domain = ccs_find_domain(data + 7);
856          } else          } else
857                  return false;                  return false;
# Line 899  static bool ccs_is_select_one(struct ccs Line 880  static bool ccs_is_select_one(struct ccs
880          return true;          return true;
881  }  }
882    
883  static int ccs_write_domain_policy2(char *data, struct ccs_domain_info *domain,  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,
884                                      struct ccs_condition *cond,                               struct ccs_condition *cond, const bool is_delete)
885                                      const bool is_delete)  {
886  {          u8 i;
887          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CAPABILITY))          static const struct {
888                  return ccs_write_capability_policy(data, domain, cond,                  const char *keyword;
889                                                     is_delete);                  int (*write) (char *, struct ccs_domain_info *,
890          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_NETWORK))                                struct ccs_condition *, const bool);
891                  return ccs_write_network_policy(data, domain, cond, is_delete);          } ccs_callback[5] = {
892          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_SIGNAL))                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },
893                  return ccs_write_signal_policy(data, domain, cond, is_delete);                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },
894          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },
895                  return ccs_write_env_policy(data, domain, cond, is_delete);                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },
896          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))                  { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }
897                  return ccs_write_mount_policy(data, domain, cond, is_delete);          };
898          return ccs_write_file_policy(data, domain, cond, is_delete);          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
899                          const bool) = ccs_write_file;
900            for (i = 0; i < 5; i++) {
901                    if (!ccs_str_starts(&data, ccs_callback[i].keyword))
902                            continue;
903                    write = ccs_callback[i].write;
904                    break;
905            }
906            return write(data, domain, cond, is_delete);
907  }  }
908    
909  /**  /**
910   * ccs_write_domain_policy - Write domain policy.   * ccs_write_domain - Write domain policy.
911   *   *
912   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
913   *   *
914   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
915   */   */
916  static int ccs_write_domain_policy(struct ccs_io_buffer *head)  static int ccs_write_domain(struct ccs_io_buffer *head)
917  {  {
918          char *data = head->write_buf;          char *data = head->write_buf;
919          struct ccs_domain_info *domain = head->write_var1;          struct ccs_domain_info *domain = head->write_var1;
# Line 938  static int ccs_write_domain_policy(struc Line 927  static int ccs_write_domain_policy(struc
927                  is_delete = true;                  is_delete = true;
928          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))
929                  is_select = true;                  is_select = true;
930          if (is_select && ccs_is_select_one(head, data))          if (is_select && ccs_select_one(head, data))
931                  return 0;                  return 0;
932          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
933          if (!ccs_is_policy_manager())          if (!ccs_manager())
934                  return -EPERM;                  return -EPERM;
935          if (ccs_is_domain_def(data)) {          if (ccs_domain_def(data)) {
936                  domain = NULL;                  domain = NULL;
937                  if (is_delete)                  if (is_delete)
938                          ccs_delete_domain(data);                          ccs_delete_domain(data);
# Line 985  static int ccs_write_domain_policy(struc Line 974  static int ccs_write_domain_policy(struc
974                  if (!cond)                  if (!cond)
975                          return -EINVAL;                          return -EINVAL;
976          }          }
977          error = ccs_write_domain_policy2(data, domain, cond, is_delete);          error = ccs_write_domain2(data, domain, cond, is_delete);
978          if (cond)          if (cond)
979                  ccs_put_condition(cond);                  ccs_put_condition(cond);
980          return error;          return error;
# Line 1028  static bool ccs_print_name_union_quoted( Line 1017  static bool ccs_print_name_union_quoted(
1017          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);
1018  }  }
1019    
1020    static void ccs_print_number(char *buffer, int buffer_len,
1021                                 const struct ccs_number_union *ptr)
1022    {
1023            int i;
1024            unsigned long min = ptr->values[0];
1025            const unsigned long max = ptr->values[1];
1026            u8 min_type = ptr->value_type[0];
1027            const u8 max_type = ptr->value_type[1];
1028            memset(buffer, 0, buffer_len);
1029            buffer_len -= 2;
1030            for (i = 0; i < 2; i++) {
1031                    int len;
1032                    switch (min_type) {
1033                    case CCS_VALUE_TYPE_HEXADECIMAL:
1034                            snprintf(buffer, buffer_len, "0x%lX", min);
1035                            break;
1036                    case CCS_VALUE_TYPE_OCTAL:
1037                            snprintf(buffer, buffer_len, "0%lo", min);
1038                            break;
1039                    default:
1040                            snprintf(buffer, buffer_len, "%lu", min);
1041                            break;
1042                    }
1043                    if (min == max && min_type == max_type)
1044                            break;
1045                    len = strlen(buffer);
1046                    buffer[len++] = '-';
1047                    buffer += len;
1048                    buffer_len -= len;
1049                    min_type = max_type;
1050                    min = max;
1051            }
1052    }
1053    
1054  /**  /**
1055   * ccs_print_number_union_common - Print a ccs_number_union.   * ccs_print_number_union_common - Print a ccs_number_union.
1056   *   *
# Line 1041  static bool ccs_print_number_union_commo Line 1064  static bool ccs_print_number_union_commo
1064                                            const struct ccs_number_union *ptr,                                            const struct ccs_number_union *ptr,
1065                                            const bool need_space)                                            const bool need_space)
1066  {  {
1067          unsigned long min;          char buffer[128];
         unsigned long max;  
         u8 min_type;  
         u8 max_type;  
1068          if (need_space && !ccs_io_printf(head, " "))          if (need_space && !ccs_io_printf(head, " "))
1069                  return false;                  return false;
1070          if (ptr->is_group)          if (ptr->is_group)
1071                  return ccs_io_printf(head, "@%s",                  return ccs_io_printf(head, "@%s",
1072                                       ptr->group->group_name->name);                                       ptr->group->group_name->name);
1073          min_type = ptr->min_type;          ccs_print_number(buffer, sizeof(buffer), ptr);
1074          max_type = ptr->max_type;          return ccs_io_printf(head, "%s", buffer);
         min = ptr->values[0];  
         max = ptr->values[1];  
         switch (min_type) {  
         case CCS_VALUE_TYPE_HEXADECIMAL:  
                 if (!ccs_io_printf(head, "0x%lX", min))  
                         return false;  
                 break;  
         case CCS_VALUE_TYPE_OCTAL:  
                 if (!ccs_io_printf(head, "0%lo", min))  
                         return false;  
                 break;  
         default:  
                 if (!ccs_io_printf(head, "%lu", min))  
                         return false;  
                 break;  
         }  
         if (min == max && min_type == max_type)  
                 return true;  
         switch (max_type) {  
         case CCS_VALUE_TYPE_HEXADECIMAL:  
                 return ccs_io_printf(head, "-0x%lX", max);  
         case CCS_VALUE_TYPE_OCTAL:  
                 return ccs_io_printf(head, "-0%lo", max);  
         default:  
                 return ccs_io_printf(head, "-%lu", max);  
         }  
1075  }  }
1076    
1077  /**  /**
# Line 1122  static bool ccs_print_condition(struct c Line 1116  static bool ccs_print_condition(struct c
1116          const struct ccs_condition_element *condp;          const struct ccs_condition_element *condp;
1117          const struct ccs_number_union *numbers_p;          const struct ccs_number_union *numbers_p;
1118          const struct ccs_name_union *names_p;          const struct ccs_name_union *names_p;
1119          const struct ccs_argv_entry *argv;          const struct ccs_argv *argv;
1120          const struct ccs_envp_entry *envp;          const struct ccs_envp *envp;
1121          u16 condc;          u16 condc;
1122          u16 i;          u16 i;
1123          u16 j;          u16 j;
# Line 1135  static bool ccs_print_condition(struct c Line 1129  static bool ccs_print_condition(struct c
1129          numbers_p = (const struct ccs_number_union *) (condp + condc);          numbers_p = (const struct ccs_number_union *) (condp + condc);
1130          names_p = (const struct ccs_name_union *)          names_p = (const struct ccs_name_union *)
1131                  (numbers_p + cond->numbers_count);                  (numbers_p + cond->numbers_count);
1132          argv = (const struct ccs_argv_entry *) (names_p + cond->names_count);          argv = (const struct ccs_argv *) (names_p + cond->names_count);
1133          envp = (const struct ccs_envp_entry *) (argv + cond->argc);          envp = (const struct ccs_envp *) (argv + cond->argc);
1134          memset(buffer, 0, sizeof(buffer));          memset(buffer, 0, sizeof(buffer));
1135          if (condc && !ccs_io_printf(head, "%s", " if"))          if (condc && !ccs_io_printf(head, "%s", " if"))
1136                  goto out;                  goto out;
# Line 1410  static bool ccs_print_capability_acl(str Line 1404  static bool ccs_print_capability_acl(str
1404  }  }
1405    
1406  /**  /**
  * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_ip_network_acl".  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,  
                                  struct ccs_ip_network_acl *ptr)  
 {  
         const u32 min_address = ptr->address.ipv4.min;  
         const u32 max_address = ptr->address.ipv4.max;  
         if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))  
                 return false;  
         if (min_address != max_address  
             && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))  
                 return false;  
         return true;  
 }  
   
 /**  
  * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_ip_network_acl".  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,  
                                  struct ccs_ip_network_acl *ptr)  
 {  
         char buf[64];  
         const struct in6_addr *min_address = ptr->address.ipv6.min;  
         const struct in6_addr *max_address = ptr->address.ipv6.max;  
         ccs_print_ipv6(buf, sizeof(buf), min_address);  
         if (!ccs_io_printf(head, "%s", buf))  
                 return false;  
         if (min_address != max_address) {  
                 ccs_print_ipv6(buf, sizeof(buf), max_address);  
                 if (!ccs_io_printf(head, "-%s", buf))  
                         return false;  
         }  
         return true;  
 }  
   
 /**  
1407   * ccs_print_network_acl - Print a network ACL entry.   * ccs_print_network_acl - Print a network ACL entry.
1408   *   *
1409   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 1471  static bool ccs_print_network_acl(struct Line 1419  static bool ccs_print_network_acl(struct
1419          int pos;          int pos;
1420          u8 bit;          u8 bit;
1421          const u16 perm = ptr->perm;          const u16 perm = ptr->perm;
1422            char buf[128];
1423          for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {          for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
1424                    const char *w[2] = { "", "" };
1425                  if (!(perm & (1 << bit)))                  if (!(perm & (1 << bit)))
1426                          continue;                          continue;
1427                  pos = head->read_avail;                  pos = head->read_avail;
                 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",  
                                    ccs_net2keyword(bit)))  
                         goto out;  
1428                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1429                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
1430                          if (!ccs_io_printf(head, "@%s", ptr->address.group->                          w[0] = "@";
1431                                             group_name->name))                          w[1] = ptr->address.group->group_name->name;
                                 goto out;  
1432                          break;                          break;
1433                  case CCS_IP_ADDRESS_TYPE_IPv4:                  case CCS_IP_ADDRESS_TYPE_IPv4:
1434                          if (!ccs_print_ipv4_entry(head, ptr))                          ccs_print_ipv4(buf, sizeof(buf), ptr->address.ipv4.min,
1435                                  goto out;                                         ptr->address.ipv4.max);
1436                            w[0] = buf;
1437                          break;                          break;
1438                  case CCS_IP_ADDRESS_TYPE_IPv6:                  case CCS_IP_ADDRESS_TYPE_IPv6:
1439                          if (!ccs_print_ipv6_entry(head, ptr))                          ccs_print_ipv6(buf, sizeof(buf), ptr->address.ipv6.min,
1440                                  goto out;                                         ptr->address.ipv6.max);
1441                            w[0] = buf;
1442                          break;                          break;
1443                  }                  }
1444                  if (!ccs_print_number_union(head, &ptr->port) ||                  if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s %s%s",
1445                                       ccs_net2keyword(bit), w[0], w[1]) ||
1446                        !ccs_print_number_union(head, &ptr->port) ||
1447                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond))
1448                          goto out;                          goto out;
1449          }          }
# Line 1539  static bool ccs_print_signal_acl(struct Line 1489  static bool ccs_print_signal_acl(struct
1489   */   */
1490  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1491                                               const char *keyword,                                               const char *keyword,
1492                                               struct ccs_execute_handler_record *                                               struct ccs_execute_handler_record
1493                                               ptr)                                               *ptr)
1494  {  {
1495          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1496  }  }
# Line 1652  static bool ccs_print_entry(struct ccs_i Line 1602  static bool ccs_print_entry(struct ccs_i
1602  }  }
1603    
1604  /**  /**
1605   * ccs_read_domain_policy - Read domain policy.   * ccs_read_domain - Read domain policy.
1606   *   *
1607   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1608   *   *
1609   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1610   */   */
1611  static void ccs_read_domain_policy(struct ccs_io_buffer *head)  static void ccs_read_domain(struct ccs_io_buffer *head)
1612  {  {
1613          struct list_head *dpos;          struct list_head *dpos;
1614          struct list_head *apos;          struct list_head *apos;
# Line 1850  static void ccs_read_pid(struct ccs_io_b Line 1800  static void ccs_read_pid(struct ccs_io_b
1800                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1801                                "state[0]=%u state[1]=%u state[2]=%u", pid,                                "state[0]=%u state[1]=%u state[2]=%u", pid,
1802                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1803                                          CCS_TASK_IS_POLICY_MANAGER),                                          CCS_TASK_IS_MANAGER),
1804                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1805                                          CCS_TASK_IS_EXECUTE_HANDLER),                                          CCS_TASK_IS_EXECUTE_HANDLER),
1806                                (u8) (ccs_flags >> 24),                                (u8) (ccs_flags >> 24),
# Line 1859  static void ccs_read_pid(struct ccs_io_b Line 1809  static void ccs_read_pid(struct ccs_io_b
1809  }  }
1810    
1811  /**  /**
1812   * ccs_write_exception_policy - Write exception policy.   * ccs_write_exception - Write exception policy.
1813   *   *
1814   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1815   *   *
1816   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1817   */   */
1818  static int ccs_write_exception_policy(struct ccs_io_buffer *head)  static int ccs_write_exception(struct ccs_io_buffer *head)
1819  {  {
1820          char *data = head->write_buf;          char *data = head->write_buf;
1821          bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);          const bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
1822          if (ccs_str_starts(&data, CCS_KEYWORD_KEEP_DOMAIN))          u8 i;
1823                  return ccs_write_domain_keeper_policy(data, false, is_delete);          static const struct {
1824          if (ccs_str_starts(&data, CCS_KEYWORD_NO_KEEP_DOMAIN))                  const char *keyword;
1825                  return ccs_write_domain_keeper_policy(data, true, is_delete);                  int (*write) (char *, const bool, const u8);
1826          if (ccs_str_starts(&data, CCS_KEYWORD_INITIALIZE_DOMAIN))          } ccs_callback[10] = {
1827                  return ccs_write_domain_initializer_policy(data, false,                  { CCS_KEYWORD_NO_KEEP_DOMAIN, ccs_write_domain_keeper },
1828                                                             is_delete);                  { CCS_KEYWORD_NO_INITIALIZE_DOMAIN,
1829          if (ccs_str_starts(&data, CCS_KEYWORD_NO_INITIALIZE_DOMAIN))                    ccs_write_domain_initializer },
1830                  return ccs_write_domain_initializer_policy(data, true,                  { CCS_KEYWORD_KEEP_DOMAIN, ccs_write_domain_keeper },
1831                                                             is_delete);                  { CCS_KEYWORD_INITIALIZE_DOMAIN,
1832          if (ccs_str_starts(&data, CCS_KEYWORD_AGGREGATOR))                    ccs_write_domain_initializer },
1833                  return ccs_write_aggregator_policy(data, is_delete);                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1834          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_READ))                  { CCS_KEYWORD_ALLOW_READ, ccs_write_global_read },
1835                  return ccs_write_globally_readable_policy(data, is_delete);                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_global_env },
1836          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
1837                  return ccs_write_globally_usable_env_policy(data, is_delete);                  { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },
1838          if (ccs_str_starts(&data, CCS_KEYWORD_FILE_PATTERN))                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1839                  return ccs_write_pattern_policy(data, is_delete);          };
1840          if (ccs_str_starts(&data, CCS_KEYWORD_PATH_GROUP))          static const char *ccs_name[CCS_MAX_GROUP] = {
1841                  return ccs_write_path_group_policy(data, is_delete);                  [CCS_PATH_GROUP] = CCS_KEYWORD_PATH_GROUP,
1842          if (ccs_str_starts(&data, CCS_KEYWORD_NUMBER_GROUP))                  [CCS_NUMBER_GROUP] = CCS_KEYWORD_NUMBER_GROUP,
1843                  return ccs_write_number_group_policy(data, is_delete);                  [CCS_ADDRESS_GROUP] = CCS_KEYWORD_ADDRESS_GROUP
1844          if (ccs_str_starts(&data, CCS_KEYWORD_DENY_REWRITE))          };
1845                  return ccs_write_no_rewrite_policy(data, is_delete);          for (i = 0; i < 10; i++) {
1846          if (ccs_str_starts(&data, CCS_KEYWORD_ADDRESS_GROUP))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1847                  return ccs_write_address_group_policy(data, is_delete);                          return ccs_callback[i].write(data, is_delete, i < 2);
1848          if (ccs_str_starts(&data, CCS_KEYWORD_DENY_AUTOBIND))          }
1849                  return ccs_write_reserved_port_policy(data, is_delete);          for (i = 0; i < CCS_MAX_GROUP; i++) {
1850                    if (ccs_str_starts(&data, ccs_name[i]))
1851                            return ccs_write_group(data, is_delete, i);
1852            }
1853          return -EINVAL;          return -EINVAL;
1854  }  }
1855    
1856  /**  /**
1857   * ccs_read_exception_policy - Read exception policy.   * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
1858   *   *
1859   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1860     * @idx:  Index number.
1861     *
1862     * Returns true on success, false otherwise.
1863   *   *
1864   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1865   */   */
1866  static void ccs_read_exception_policy(struct ccs_io_buffer *head)  static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
1867  {  {
1868          if (head->read_eof)          struct list_head *gpos;
1869                  return;          struct list_head *mpos;
1870          switch (head->read_step) {          const char *w[3] = { "", "", "" };
1871          case 0:          if (idx == CCS_PATH_GROUP)
1872                  head->read_var2 = NULL;                  w[0] = CCS_KEYWORD_PATH_GROUP;
1873                  head->read_step = 1;          else if (idx == CCS_NUMBER_GROUP)
1874          case 1:                  w[0] = CCS_KEYWORD_NUMBER_GROUP;
1875                  if (!ccs_read_domain_keeper_policy(head))          else if (idx == CCS_ADDRESS_GROUP)
1876                          break;                  w[0] = CCS_KEYWORD_ADDRESS_GROUP;
1877                  head->read_var2 = NULL;          list_for_each_cookie(gpos, head->read_var1, &ccs_group_list[idx]) {
1878                  head->read_step = 2;                  struct ccs_group *group =
1879          case 2:                          list_entry(gpos, struct ccs_group, head.list);
1880                  if (!ccs_read_globally_readable_policy(head))                  w[1] = group->group_name->name;
1881                          break;                  list_for_each_cookie(mpos, head->read_var2,
1882                  head->read_var2 = NULL;                                       &group->member_list) {
1883                  head->read_step = 3;                          char buffer[128];
1884          case 3:                          struct ccs_acl_head *ptr =
1885                  if (!ccs_read_globally_usable_env_policy(head))                                  list_entry(mpos, struct ccs_acl_head, list);
1886                          break;                          if (ptr->is_deleted)
1887                  head->read_var2 = NULL;                                  continue;
1888                  head->read_step = 4;                          if (idx == CCS_PATH_GROUP) {
1889          case 4:                                  w[2] = container_of(ptr, struct ccs_path_group,
1890                  if (!ccs_read_domain_initializer_policy(head))                                                      head)->member_name->name;
1891                            } else if (idx == CCS_NUMBER_GROUP) {
1892                                    w[2] = buffer;
1893                                    ccs_print_number(buffer, sizeof(buffer),
1894                                                     &container_of
1895                                                     (ptr, struct ccs_number_group,
1896                                                      head)->number);
1897                            } else if (idx == CCS_ADDRESS_GROUP) {
1898                                    struct ccs_address_group *member =
1899                                            container_of(ptr, typeof(*member),
1900                                                         head);
1901                                    w[2] = buffer;
1902                                    if (member->is_ipv6)
1903                                            ccs_print_ipv6(buffer, sizeof(buffer),
1904                                                           member->min.ipv6,
1905                                                           member->max.ipv6);
1906                                    else
1907                                            ccs_print_ipv4(buffer, sizeof(buffer),
1908                                                           member->min.ipv4,
1909                                                           member->max.ipv4);
1910                            }
1911                            if (!ccs_io_printf(head, "%s%s %s\n", w[0], w[1],
1912                                               w[2]))
1913                                    return false;
1914                    }
1915            }
1916            return true;
1917    }
1918    
1919    /**
1920     * ccs_read_policy - Read "struct ccs_..._entry" list.
1921     *
1922     * @head: Pointer to "struct ccs_io_buffer".
1923     * @idx:  Index number.
1924     *
1925     * Returns true on success, false otherwise.
1926     *
1927     * Caller holds ccs_read_lock().
1928     */
1929    static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
1930    {
1931            struct list_head *pos;
1932            list_for_each_cookie(pos, head->read_var2, &ccs_policy_list[idx]) {
1933                    const char *w[4] = { "", "", "", "" };
1934                    char buffer[16];
1935                    struct ccs_acl_head *acl = container_of(pos, typeof(*acl),
1936                                                            list);
1937                    if (acl->is_deleted)
1938                            continue;
1939                    switch (idx) {
1940                    case CCS_ID_DOMAIN_KEEPER:
1941                            {
1942                                    struct ccs_domain_keeper *ptr =
1943                                            container_of(acl, typeof(*ptr), head);
1944                                    w[0] = ptr->is_not ?
1945                                            CCS_KEYWORD_NO_KEEP_DOMAIN :
1946                                            CCS_KEYWORD_KEEP_DOMAIN;
1947                                    if (ptr->program) {
1948                                            w[1] = ptr->program->name;
1949                                            w[2] = " from ";
1950                                    }
1951                                    w[3] = ptr->domainname->name;
1952                            }
1953                          break;                          break;
1954                  head->read_var2 = NULL;                  case CCS_ID_DOMAIN_INITIALIZER:
1955                  head->read_step = 6;                          {
1956          case 6:                                  struct ccs_domain_initializer *ptr =
1957                  if (!ccs_read_aggregator_policy(head))                                          container_of(acl, typeof(*ptr), head);
1958                                    w[0] = ptr->is_not ?
1959                                            CCS_KEYWORD_NO_INITIALIZE_DOMAIN :
1960                                            CCS_KEYWORD_INITIALIZE_DOMAIN;
1961                                    w[1] = ptr->program->name;
1962                                    if (ptr->domainname) {
1963                                            w[2] = " from ";
1964                                            w[3] = ptr->domainname->name;
1965                                    }
1966                            }
1967                          break;                          break;
1968                  head->read_var2 = NULL;                  case CCS_ID_AGGREGATOR:
1969                  head->read_step = 7;                          {
1970          case 7:                                  struct ccs_aggregator *ptr =
1971                  if (!ccs_read_file_pattern(head))                                          container_of(acl, typeof(*ptr), head);
1972                                    w[0] = CCS_KEYWORD_AGGREGATOR;
1973                                    w[1] = ptr->original_name->name;
1974                                    w[2] = " ";
1975                                    w[3] = ptr->aggregated_name->name;
1976                            }
1977                          break;                          break;
1978                  head->read_var2 = NULL;                  case CCS_ID_GLOBAL_READ:
1979                  head->read_step = 8;                          {
1980          case 8:                                  struct ccs_global_read *ptr =
1981                  if (!ccs_read_no_rewrite_policy(head))                                          container_of(acl, typeof(*ptr), head);
1982                                    w[0] = CCS_KEYWORD_ALLOW_READ;
1983                                    w[1] = ptr->filename->name;
1984                            }
1985                          break;                          break;
1986                  head->read_var2 = NULL;                  case CCS_ID_PATTERN:
1987                  head->read_step = 9;                          {
1988          case 9:                                  struct ccs_pattern *ptr =
1989                  if (!ccs_read_path_group_policy(head))                                          container_of(acl, typeof(*ptr), head);
1990                                    w[0] = CCS_KEYWORD_FILE_PATTERN;
1991                                    w[1] = ptr->pattern->name;
1992                            }
1993                          break;                          break;
1994                  head->read_var1 = NULL;                  case CCS_ID_NO_REWRITE:
1995                  head->read_var2 = NULL;                          {
1996                  head->read_step = 10;                                  struct ccs_no_rewrite *ptr =
1997          case 10:                                          container_of(acl, typeof(*ptr), head);
1998                  if (!ccs_read_number_group_policy(head))                                  w[0] = CCS_KEYWORD_DENY_REWRITE;
1999                                    w[1] = ptr->pattern->name;
2000                            }
2001                          break;                          break;
2002                  head->read_var1 = NULL;                  case CCS_ID_GLOBAL_ENV:
2003                  head->read_var2 = NULL;                          {
2004                  head->read_step = 11;                                  struct ccs_global_env *ptr =
2005          case 11:                                          container_of(acl, typeof(*ptr), head);
2006                  if (!ccs_read_address_group_policy(head))                                  w[0] = CCS_KEYWORD_ALLOW_ENV;
2007                                    w[1] = ptr->env->name;
2008                            }
2009                          break;                          break;
2010                  head->read_var2 = NULL;                  case CCS_ID_RESERVEDPORT:
2011                  head->read_step = 12;                          {
2012          case 12:                                  struct ccs_reserved *ptr =
2013                  if (!ccs_read_reserved_port_policy(head))                                          container_of(acl, typeof(*ptr), head);
2014                                    const u16 min_port = ptr->min_port;
2015                                    const u16 max_port = ptr->max_port;
2016                                    w[0] = CCS_KEYWORD_DENY_AUTOBIND;
2017                                    snprintf(buffer, sizeof(buffer) - 1, "%u%c%u",
2018                                             min_port, min_port != max_port ?
2019                                             '-' : '\0', max_port);
2020                                    buffer[sizeof(buffer) - 1] = '\0';
2021                                    w[1] = buffer;
2022                            }
2023                          break;                          break;
2024                  head->read_eof = true;                  }
2025                    if (!ccs_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2], w[3]))
2026                            return false;
2027          }          }
2028            return true;
2029    }
2030    
2031    /**
2032     * ccs_read_exception - Read exception policy.
2033     *
2034     * @head: Pointer to "struct ccs_io_buffer".
2035     *
2036     * Caller holds ccs_read_lock().
2037     */
2038    static void ccs_read_exception(struct ccs_io_buffer *head)
2039    {
2040            if (head->read_eof)
2041                    return;
2042            while (head->read_step < CCS_MAX_POLICY &&
2043                   ccs_read_policy(head, head->read_step))
2044                    head->read_step++;
2045            if (head->read_step < CCS_MAX_POLICY)
2046                    return;
2047            while (head->read_step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
2048                   ccs_read_group(head, head->read_step - CCS_MAX_POLICY))
2049                    head->read_step++;
2050            head->read_eof = head->read_step == CCS_MAX_POLICY + CCS_MAX_GROUP;
2051  }  }
2052    
2053  /**  /**
2054   * ccs_get_argv0 - Get argv[0].   * ccs_get_argv0 - Get argv[0].
2055   *   *
2056   * @ee: Pointer to "struct ccs_execve_entry".   * @ee: Pointer to "struct ccs_execve".
2057   *   *
2058   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
2059   */   */
2060  static bool ccs_get_argv0(struct ccs_execve_entry *ee)  static bool ccs_get_argv0(struct ccs_execve *ee)
2061  {  {
2062          struct linux_binprm *bprm = ee->bprm;          struct linux_binprm *bprm = ee->bprm;
2063          char *arg_ptr = ee->tmp;          char *arg_ptr = ee->tmp;
# Line 2030  static bool ccs_get_argv0(struct ccs_exe Line 2106  static bool ccs_get_argv0(struct ccs_exe
2106  /**  /**
2107   * ccs_get_execute_condition - Get condition part for execute requests.   * ccs_get_execute_condition - Get condition part for execute requests.
2108   *   *
2109   * @ee: Pointer to "struct ccs_execve_entry".   * @ee: Pointer to "struct ccs_execve".
2110   *   *
2111   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2112   */   */
2113  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve
2114                                                         *ee)                                                         *ee)
2115  {  {
2116          struct ccs_condition *cond;          struct ccs_condition *cond;
# Line 2042  static struct ccs_condition *ccs_get_exe Line 2118  static struct ccs_condition *ccs_get_exe
2118          int len = 256;          int len = 256;
2119          char *realpath = NULL;          char *realpath = NULL;
2120          char *argv0 = NULL;          char *argv0 = NULL;
2121          const struct ccs_profile *profile = ccs_profile(ee->r.domain->profile);          const struct ccs_profile *profile = ccs_profile(ccs_current_domain()->
2122                                                            profile);
2123          if (profile->learning->learning_exec_realpath) {          if (profile->learning->learning_exec_realpath) {
2124                  struct file *file = ee->bprm->file;                  struct file *file = ee->bprm->file;
2125  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
# Line 2168  int ccs_supervisor(struct ccs_request_in Line 2245  int ccs_supervisor(struct ccs_request_in
2245          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query_entry *ccs_query_entry = NULL;
2246          bool quota_exceeded = false;          bool quota_exceeded = false;
2247          char *header;          char *header;
2248          if (!r->domain)          struct ccs_domain_info * const domain = ccs_current_domain();
                 r->domain = ccs_current_domain();  
2249          switch (r->mode) {          switch (r->mode) {
2250                  char *buffer;                  char *buffer;
2251                  struct ccs_condition *cond;                  struct ccs_condition *cond;
# Line 2195  int ccs_supervisor(struct ccs_request_in Line 2271  int ccs_supervisor(struct ccs_request_in
2271                          cond = ccs_get_condition(str);                          cond = ccs_get_condition(str);
2272                  } else                  } else
2273                          cond = NULL;                          cond = NULL;
2274                  ccs_write_domain_policy2(buffer, r->domain, cond, false);                  ccs_write_domain2(buffer, domain, cond, false);
2275                  ccs_put_condition(cond);                  ccs_put_condition(cond);
2276                  kfree(buffer);                  kfree(buffer);
2277                  /* fall through */                  /* fall through */
# Line 2206  int ccs_supervisor(struct ccs_request_in Line 2282  int ccs_supervisor(struct ccs_request_in
2282                  int i;                  int i;
2283                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2284                          return -EPERM;                          return -EPERM;
2285                  for (i = 0; i < ccs_profile(r->domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->
2286                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
2287                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2288                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2305  static int ccs_poll_query(struct file *f Line 2381  static int ccs_poll_query(struct file *f
2381          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2382                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2383                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2384                          struct ccs_query_entry *ptr                          struct ccs_query_entry *ptr =
2385                                  = list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, struct ccs_query_entry, list);
2386                          if (ptr->answer)                          if (ptr->answer)
2387                                  continue;                                  continue;
2388                          found = true;                          found = true;
# Line 2470  int ccs_open_control(const u8 type, stru Line 2546  int ccs_open_control(const u8 type, stru
2546          head->type = type;          head->type = type;
2547          switch (type) {          switch (type) {
2548          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
2549                  head->write = ccs_write_domain_policy;                  head->write = ccs_write_domain;
2550                  head->read = ccs_read_domain_policy;                  head->read = ccs_read_domain;
2551                  break;                  break;
2552          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
2553                  head->write = ccs_write_exception_policy;                  head->write = ccs_write_exception;
2554                  head->read = ccs_read_exception_policy;                  head->read = ccs_read_exception;
2555                  break;                  break;
2556  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
2557          case CCS_GRANTLOG: /* /proc/ccs/grant_log */          case CCS_GRANTLOG: /* /proc/ccs/grant_log */
# Line 2521  int ccs_open_control(const u8 type, stru Line 2597  int ccs_open_control(const u8 type, stru
2597                  head->read = ccs_read_query;                  head->read = ccs_read_query;
2598                  break;                  break;
2599          case CCS_MANAGER: /* /proc/ccs/manager */          case CCS_MANAGER: /* /proc/ccs/manager */
2600                  head->write = ccs_write_manager_policy;                  head->write = ccs_write_manager;
2601                  head->read = ccs_read_manager_policy;                  head->read = ccs_read_manager;
2602                  break;                  break;
2603          }          }
2604          if (!(file->f_mode & FMODE_READ)) {          if (!(file->f_mode & FMODE_READ)) {
# Line 2680  int ccs_write_control(struct file *file, Line 2756  int ccs_write_control(struct file *file,
2756                  return -EINTR;                  return -EINTR;
2757          idx = ccs_read_lock();          idx = ccs_read_lock();
2758          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
2759          if (head->write != ccs_write_pid &&          if (head->write != ccs_write_pid && head->write != ccs_write_domain &&
2760              head->write != ccs_write_domain_policy &&              !ccs_manager()) {
             !ccs_is_policy_manager()) {  
2761                  ccs_read_unlock(idx);                  ccs_read_unlock(idx);
2762                  mutex_unlock(&head->io_sem);                  mutex_unlock(&head->io_sem);
2763                  return -EPERM;                  return -EPERM;

Legend:
Removed from v.3560  
changed lines
  Added in v.3693

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