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

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 3535 by kumaneko, Thu Mar 25 08:53:03 2010 UTC branches/ccs-patch/security/ccsecurity/policy_io.c revision 3731 by kumaneko, Fri Jun 4 01:42:54 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-pre   2010/03/21   * Version: 1.7.2+   2010/06/04
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 246  bool ccs_io_printf(struct ccs_io_buffer Line 246  bool ccs_io_printf(struct ccs_io_buffer
246  }  }
247    
248  /**  /**
249   * ccs_find_or_assign_new_profile - Create a new profile.   * ccs_assign_profile - Create a new profile.
250   *   *
251   * @profile: Profile number to create.   * @profile: Profile number to create.
252   *   *
253   * Returns pointer to "struct ccs_profile" on success, NULL otherwise.   * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
254   */   */
255  static struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int  static struct ccs_profile *ccs_assign_profile(const unsigned int profile)
                                                           profile)  
256  {  {
257          struct ccs_profile *ptr;          struct ccs_profile *ptr;
258          struct ccs_profile *entry;          struct ccs_profile *entry;
# Line 305  static void ccs_check_profile(void) Line 304  static void ccs_check_profile(void)
304          if (ccs_profile_version != 20090903)          if (ccs_profile_version != 20090903)
305                  panic("Profile version %u is not supported.\n",                  panic("Profile version %u is not supported.\n",
306                        ccs_profile_version);                        ccs_profile_version);
307          printk(KERN_INFO "CCSecurity: 1.7.2-pre   2010/03/21\n");          printk(KERN_INFO "CCSecurity: 1.7.2+   2010/06/04\n");
308          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
309  }  }
310    
# Line 351  static int ccs_write_profile(struct ccs_ Line 350  static int ccs_write_profile(struct ccs_
350                  if (*cp != '-')                  if (*cp != '-')
351                          return -EINVAL;                          return -EINVAL;
352                  data = cp + 1;                  data = cp + 1;
353                  profile = ccs_find_or_assign_new_profile(i);                  profile = ccs_assign_profile(i);
354                  if (!profile)                  if (!profile)
355                          return -EINVAL;                          return -EINVAL;
356          }          }
# Line 367  static int ccs_write_profile(struct ccs_ Line 366  static int ccs_write_profile(struct ccs_
366                  value = 0;                  value = 0;
367          else          else
368                  value = -1;                  value = -1;
369          if (!strcmp(data, "PREFERENCE::audit")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_AUDIT)) {
370  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
371                  char *cp2;                  char *cp2;
372  #endif  #endif
# Line 396  static int ccs_write_profile(struct ccs_ Line 395  static int ccs_write_profile(struct ccs_
395                          profile->preference.audit_path_info = false;                          profile->preference.audit_path_info = false;
396                  return 0;                  return 0;
397          }          }
398          if (!strcmp(data, "PREFERENCE::enforcing")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_ENFORCING)) {
399                  char *cp2;                  char *cp2;
400                  if (use_default) {                  if (use_default) {
401                          profile->enforcing = &ccs_default_profile.preference;                          profile->enforcing = &ccs_default_profile.preference;
# Line 411  static int ccs_write_profile(struct ccs_ Line 410  static int ccs_write_profile(struct ccs_
410                                 &profile->preference.enforcing_penalty);                                 &profile->preference.enforcing_penalty);
411                  return 0;                  return 0;
412          }          }
413          if (!strcmp(data, "PREFERENCE::permissive")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_PERMISSIVE)) {
414                  if (use_default) {                  if (use_default) {
415                          profile->permissive = &ccs_default_profile.preference;                          profile->permissive = &ccs_default_profile.preference;
416                          return 0;                          return 0;
# Line 421  static int ccs_write_profile(struct ccs_ Line 420  static int ccs_write_profile(struct ccs_
420                          profile->preference.permissive_verbose = value;                          profile->preference.permissive_verbose = value;
421                  return 0;                  return 0;
422          }          }
423          if (!strcmp(data, "PREFERENCE::learning")) {          if (!strcmp(data, CCS_KEYWORD_PREFERENCE_LEARNING)) {
424                  char *cp2;                  char *cp2;
425                  if (use_default) {                  if (use_default) {
426                          profile->learning = &ccs_default_profile.preference;                          profile->learning = &ccs_default_profile.preference;
# Line 506  static int ccs_write_profile(struct ccs_ Line 505  static int ccs_write_profile(struct ccs_
505          return 0;          return 0;
506  }  }
507    
508    static bool ccs_print_preference(struct ccs_io_buffer *head, const int idx)
509    {
510            struct ccs_preference *pref = &ccs_default_profile.preference;
511            const struct ccs_profile *profile = idx >= 0 ?
512                    ccs_profile_ptr[idx] : NULL;
513            char buffer[16] = "";
514            if (profile) {
515                    buffer[sizeof(buffer) - 1] = '\0';
516                    snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
517            }
518            if (profile) {
519                    pref = profile->audit;
520                    if (pref == &ccs_default_profile.preference)
521                            pref = NULL;
522            }
523            if (pref && !ccs_io_printf(head, "%s%s={ "
524    #ifdef CONFIG_CCSECURITY_AUDIT
525                                       "max_grant_log=%u max_reject_log=%u "
526    #endif
527                                       "task_info=%s path_info=%s }\n", buffer,
528                                       CCS_KEYWORD_PREFERENCE_AUDIT,
529    #ifdef CONFIG_CCSECURITY_AUDIT
530                                       pref->audit_max_grant_log,
531                                       pref->audit_max_reject_log,
532    #endif
533                                       ccs_yesno(pref->audit_task_info),
534                                       ccs_yesno(pref->audit_path_info)))
535                    return false;
536            if (profile) {
537                    pref = profile->learning;
538                    if (pref == &ccs_default_profile.preference)
539                            pref = NULL;
540            }
541            if (pref && !ccs_io_printf(head, "%s%s={ "
542                                       "verbose=%s max_entry=%u exec.realpath=%s "
543                                       "exec.argv0=%s symlink.target=%s }\n",
544                                       buffer, CCS_KEYWORD_PREFERENCE_LEARNING,
545                                       ccs_yesno(pref->learning_verbose),
546                                       pref->learning_max_entry,
547                                       ccs_yesno(pref->learning_exec_realpath),
548                                       ccs_yesno(pref->learning_exec_argv0),
549                                       ccs_yesno(pref->learning_symlink_target)))
550                    return false;
551            if (profile) {
552                    pref = profile->permissive;
553                    if (pref == &ccs_default_profile.preference)
554                            pref = NULL;
555            }
556            if (pref && !ccs_io_printf(head, "%s%s={ verbose=%s }\n", buffer,
557                                       CCS_KEYWORD_PREFERENCE_PERMISSIVE,
558                                       ccs_yesno(pref->permissive_verbose)))
559                    return false;
560            if (profile) {
561                    pref = profile->enforcing;
562                    if (pref == &ccs_default_profile.preference)
563                            pref = NULL;
564            }
565            return !pref || ccs_io_printf(head, "%s%s={ verbose=%s penalty=%u }\n",
566                                          buffer, CCS_KEYWORD_PREFERENCE_ENFORCING,
567                                          ccs_yesno(pref->enforcing_verbose),
568                                          pref->enforcing_penalty);
569    }
570    
571  /**  /**
572   * ccs_read_profile - Read profile table.   * ccs_read_profile - Read profile table.
573   *   *
# Line 519  static void ccs_read_profile(struct ccs_ Line 581  static void ccs_read_profile(struct ccs_
581          if (head->read_bit)          if (head->read_bit)
582                  goto body;                  goto body;
583          ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");          ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
584          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);  
585          head->read_bit = 1;          head->read_bit = 1;
586   body:   body:
587          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 602  static void ccs_read_profile(struct ccs_
602                          goto out;                          goto out;
603                  config = profile->default_config;                  config = profile->default_config;
604  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
605                  if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s grant_log=%s "                  if (!ccs_io_printf(head, "%u-%s%s={ mode=%s "
606                                     "reject_log=%s }\n", index,                                     "grant_log=%s reject_log=%s }\n", index,
607                                     ccs_mode_4[config & 3],                                     "CONFIG", "", ccs_mode_4[config & 3],
608                                     ccs_yesno(config &                                     ccs_yesno(config &
609                                               CCS_CONFIG_WANT_GRANT_LOG),                                               CCS_CONFIG_WANT_GRANT_LOG),
610                                     ccs_yesno(config &                                     ccs_yesno(config &
611                                               CCS_CONFIG_WANT_REJECT_LOG)))                                               CCS_CONFIG_WANT_REJECT_LOG)))
612                          goto out;                          goto out;
613  #else  #else
614                  if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,                  if (!ccs_io_printf(head, "%u-%s%s={ mode=%s }\n", index,
615                                     ccs_mode_4[config & 3]))                                     "CONFIG", "", ccs_mode_4[config & 3]))
616                          goto out;                          goto out;
617  #endif  #endif
618                  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 627  static void ccs_read_profile(struct ccs_
627  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
628                          g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);                          g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);
629                          r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);                          r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);
630                          if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s "                          if (!ccs_io_printf(head, "%u-%s%s={ mode=%s "
631                                             "grant_log=%s reject_log=%s }\n",                                             "grant_log=%s reject_log=%s }\n",
632                                             index, ccs_mac_keywords[i],                                             index, "CONFIG::",
633                                               ccs_mac_keywords[i],
634                                             ccs_mode_4[config & 3], g, r))                                             ccs_mode_4[config & 3], g, r))
635                                  goto out;                                  goto out;
636  #else  #else
637                          if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s }\n",                          if (!ccs_io_printf(head, "%u-%s%s={ mode=%s }\n",
638                                             index, ccs_mac_keywords[i],                                             index, "CONFIG::",
639                                               ccs_mac_keywords[i],
640                                             ccs_mode_4[config & 3]))                                             ccs_mode_4[config & 3]))
641                                  goto out;                                  goto out;
642  #endif  #endif
643                  }                  }
644                  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))  
645                          goto out;                          goto out;
646                  continue;                  continue;
647   out:   out:
# Line 660  static void ccs_read_profile(struct ccs_ Line 652  static void ccs_read_profile(struct ccs_
652                  head->read_eof = true;                  head->read_eof = true;
653  }  }
654    
655  /* The list for "struct ccs_policy_manager_entry". */  static bool ccs_same_manager_entry(const struct ccs_acl_head *a,
656  LIST_HEAD(ccs_policy_manager_list);                                     const struct ccs_acl_head *b)
657    {
658            return container_of(a, struct ccs_manager, head)->manager
659                    == container_of(b, struct ccs_manager, head)->manager;
660    }
661    
662  /**  /**
663   * 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 669  LIST_HEAD(ccs_policy_manager_list);
669   */   */
670  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)
671  {  {
672          struct ccs_policy_manager_entry *ptr;          struct ccs_manager e = { };
         struct ccs_policy_manager_entry e = { };  
673          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
674          if (ccs_is_domain_def(manager)) {          if (ccs_domain_def(manager)) {
675                  if (!ccs_is_correct_domain(manager))                  if (!ccs_correct_domain(manager))
676                          return -EINVAL;                          return -EINVAL;
677                  e.is_domain = true;                  e.is_domain = true;
678          } else {          } else {
679                  if (!ccs_is_correct_path(manager, 1, -1, -1))                  if (!ccs_correct_path(manager))
680                          return -EINVAL;                          return -EINVAL;
681          }          }
682          e.manager = ccs_get_name(manager);          e.manager = ccs_get_name(manager);
683          if (!e.manager)          if (!e.manager)
684                  return -ENOMEM;                  return error;
685          if (mutex_lock_interruptible(&ccs_policy_lock))          error = ccs_update_policy(&e.head, sizeof(e), is_delete,
686                  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:  
687          ccs_put_name(e.manager);          ccs_put_name(e.manager);
688          return error;          return error;
689  }  }
690    
691  /**  /**
692   * ccs_write_manager_policy - Write manager policy.   * ccs_write_manager - Write manager policy.
693   *   *
694   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
695   *   *
696   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
697   */   */
698  static int ccs_write_manager_policy(struct ccs_io_buffer *head)  static int ccs_write_manager(struct ccs_io_buffer *head)
699  {  {
700          char *data = head->write_buf;          char *data = head->write_buf;
701          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 707  static int ccs_write_manager_policy(stru
707  }  }
708    
709  /**  /**
710   * ccs_read_manager_policy - Read manager policy.   * ccs_read_manager - Read manager policy.
711   *   *
712   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
713   *   *
714   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
715   */   */
716  static void ccs_read_manager_policy(struct ccs_io_buffer *head)  static void ccs_read_manager(struct ccs_io_buffer *head)
717  {  {
718          struct list_head *pos;          struct list_head *pos;
719          if (head->read_eof)          if (head->read_eof)
720                  return;                  return;
721          list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {          list_for_each_cookie(pos, head->read_var2,
722                  struct ccs_policy_manager_entry *ptr;                               &ccs_policy_list[CCS_ID_MANAGER]) {
723                  ptr = list_entry(pos, struct ccs_policy_manager_entry, list);                  struct ccs_manager *ptr
724                  if (ptr->is_deleted)                          = list_entry(pos, typeof(*ptr), head.list);
725                    if (ptr->head.is_deleted)
726                          continue;                          continue;
727                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
728                          return;                          return;
# Line 753  static void ccs_read_manager_policy(stru Line 731  static void ccs_read_manager_policy(stru
731  }  }
732    
733  /**  /**
734   * ccs_is_policy_manager - Check whether the current process is a policy manager.   * ccs_manager - Check whether the current process is a policy manager.
735   *   *
736   * Returns true if the current process is permitted to modify policy   * Returns true if the current process is permitted to modify policy
737   * via /proc/ccs/ interface.   * via /proc/ccs/ interface.
738   *   *
739   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
740   */   */
741  static bool ccs_is_policy_manager(void)  static bool ccs_manager(void)
742  {  {
743          struct ccs_policy_manager_entry *ptr;          struct ccs_manager *ptr;
744          const char *exe;          const char *exe;
745          struct task_struct *task = current;          struct task_struct *task = current;
746          const struct ccs_path_info *domainname          const struct ccs_path_info *domainname
# Line 770  static bool ccs_is_policy_manager(void) Line 748  static bool ccs_is_policy_manager(void)
748          bool found = false;          bool found = false;
749          if (!ccs_policy_loaded)          if (!ccs_policy_loaded)
750                  return true;                  return true;
751          if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)          if (task->ccs_flags & CCS_TASK_IS_MANAGER)
752                  return true;                  return true;
753          if (!ccs_manage_by_non_root && (current_uid() || current_euid()))          if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
754                  return false;                  return false;
         list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {  
                 if (!ptr->is_deleted && ptr->is_domain  
                     && !ccs_pathcmp(domainname, ptr->manager)) {  
                         /* Set manager flag. */  
                         task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;  
                         return true;  
                 }  
         }  
755          exe = ccs_get_exe();          exe = ccs_get_exe();
756          if (!exe)          list_for_each_entry_rcu(ptr, &ccs_policy_list[CCS_ID_MANAGER],
757                  return false;                                  head.list) {
758          list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {                  if (ptr->head.is_deleted)
759                  if (!ptr->is_deleted && !ptr->is_domain                          continue;
760                      && !strcmp(exe, ptr->manager->name)) {                  if (ptr->is_domain) {
761                          found = true;                          if (ccs_pathcmp(domainname, ptr->manager))
762                          /* Set manager flag. */                                  continue;
763                          task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;                  } else {
764                          break;                          if (!exe || strcmp(exe, ptr->manager->name))
765                                    continue;
766                  }                  }
767                    /* Set manager flag. */
768                    task->ccs_flags |= CCS_TASK_IS_MANAGER;
769                    found = true;
770                    break;
771          }          }
772          if (!found) { /* Reduce error messages. */          if (!found) { /* Reduce error messages. */
773                  static pid_t ccs_last_pid;                  static pid_t ccs_last_pid;
# Line 818  static bool ccs_is_policy_manager(void) Line 793  static bool ccs_is_policy_manager(void)
793  static char *ccs_find_condition_part(char *data)  static char *ccs_find_condition_part(char *data)
794  {  {
795          char *cp = strstr(data, " if ");          char *cp = strstr(data, " if ");
796          if (cp) {          if (!cp)
                 while (1) {  
                         char *cp2 = strstr(cp + 3, " if ");  
                         if (!cp2)  
                                 break;  
                         cp = cp2;  
                 }  
                 *cp++ = '\0';  
         } else {  
797                  cp = strstr(data, " ; set ");                  cp = strstr(data, " ; set ");
798                  if (cp)          if (cp)
799                          *cp++ = '\0';                  *cp++ = '\0';
         }  
800          return cp;          return cp;
801  }  }
802    
803  /**  /**
804   * ccs_is_select_one - Parse select command.   * ccs_select_one - Parse select command.
805   *   *
806   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
807   * @data: String to parse.   * @data: String to parse.
# Line 844  static char *ccs_find_condition_part(cha Line 810  static char *ccs_find_condition_part(cha
810   *   *
811   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
812   */   */
813  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)
814  {  {
815          unsigned int pid;          unsigned int pid;
816          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
# Line 870  static bool ccs_is_select_one(struct ccs Line 836  static bool ccs_is_select_one(struct ccs
836                          domain = ccs_task_domain(p);                          domain = ccs_task_domain(p);
837                  ccs_tasklist_unlock();                  ccs_tasklist_unlock();
838          } else if (!strncmp(data, "domain=", 7)) {          } else if (!strncmp(data, "domain=", 7)) {
839                  if (ccs_is_domain_def(data + 7))                  if (ccs_domain_def(data + 7))
840                          domain = ccs_find_domain(data + 7);                          domain = ccs_find_domain(data + 7);
841          } else          } else
842                  return false;                  return false;
# Line 899  static bool ccs_is_select_one(struct ccs Line 865  static bool ccs_is_select_one(struct ccs
865          return true;          return true;
866  }  }
867    
868  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,
869                                      struct ccs_condition *cond,                               struct ccs_condition *cond, const bool is_delete)
870                                      const bool is_delete)  {
871  {          u8 i;
872          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CAPABILITY))          static const struct {
873                  return ccs_write_capability_policy(data, domain, cond,                  const char *keyword;
874                                                     is_delete);                  int (*write) (char *, struct ccs_domain_info *,
875          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_NETWORK))                                struct ccs_condition *, const bool);
876                  return ccs_write_network_policy(data, domain, cond, is_delete);          } ccs_callback[5] = {
877          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_SIGNAL))                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },
878                  return ccs_write_signal_policy(data, domain, cond, is_delete);                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },
879          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },
880                  return ccs_write_env_policy(data, domain, cond, is_delete);                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },
881          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))                  { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }
882                  return ccs_write_mount_policy(data, domain, cond, is_delete);          };
883          return ccs_write_file_policy(data, domain, cond, is_delete);          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
884                          const bool) = ccs_write_file;
885            for (i = 0; i < 5; i++) {
886                    if (!ccs_str_starts(&data, ccs_callback[i].keyword))
887                            continue;
888                    write = ccs_callback[i].write;
889                    break;
890            }
891            return write(data, domain, cond, is_delete);
892  }  }
893    
894  /**  /**
895   * ccs_write_domain_policy - Write domain policy.   * ccs_write_domain - Write domain policy.
896   *   *
897   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
898   *   *
899   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
900   */   */
901  static int ccs_write_domain_policy(struct ccs_io_buffer *head)  static int ccs_write_domain(struct ccs_io_buffer *head)
902  {  {
903          char *data = head->write_buf;          char *data = head->write_buf;
904          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 912  static int ccs_write_domain_policy(struc
912                  is_delete = true;                  is_delete = true;
913          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))
914                  is_select = true;                  is_select = true;
915          if (is_select && ccs_is_select_one(head, data))          if (is_select && ccs_select_one(head, data))
916                  return 0;                  return 0;
917          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
918          if (!ccs_is_policy_manager())          if (!ccs_manager())
919                  return -EPERM;                  return -EPERM;
920          if (ccs_is_domain_def(data)) {          if (ccs_domain_def(data)) {
921                  domain = NULL;                  domain = NULL;
922                  if (is_delete)                  if (is_delete)
923                          ccs_delete_domain(data);                          ccs_delete_domain(data);
924                  else if (is_select)                  else if (is_select)
925                          domain = ccs_find_domain(data);                          domain = ccs_find_domain(data);
926                  else                  else
927                          domain = ccs_find_or_assign_new_domain(data, 0);                          domain = ccs_assign_domain(data, 0);
928                  head->write_var1 = domain;                  head->write_var1 = domain;
929                  return 0;                  return 0;
930          }          }
# Line 963  static int ccs_write_domain_policy(struc Line 937  static int ccs_write_domain_policy(struc
937                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
938                  return 0;                  return 0;
939          }          }
940            if (!strcmp(data, CCS_KEYWORD_IGNORE_GLOBAL)) {
941                    domain->ignore_global = !is_delete;
942                    return 0;
943            }
944          if (!strcmp(data, CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {          if (!strcmp(data, CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
945                  domain->ignore_global_allow_read = !is_delete;                  domain->ignore_global_allow_read = !is_delete;
946                  return 0;                  return 0;
# Line 985  static int ccs_write_domain_policy(struc Line 963  static int ccs_write_domain_policy(struc
963                  if (!cond)                  if (!cond)
964                          return -EINVAL;                          return -EINVAL;
965          }          }
966          error = ccs_write_domain_policy2(data, domain, cond, is_delete);          error = ccs_write_domain2(data, domain, cond, is_delete);
967          if (cond)          if (cond)
968                  ccs_put_condition(cond);                  ccs_put_condition(cond);
969          return error;          return error;
# Line 1028  static bool ccs_print_name_union_quoted( Line 1006  static bool ccs_print_name_union_quoted(
1006          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);
1007  }  }
1008    
1009    static void ccs_print_number(char *buffer, int buffer_len,
1010                                 const struct ccs_number_union *ptr)
1011    {
1012            int i;
1013            unsigned long min = ptr->values[0];
1014            const unsigned long max = ptr->values[1];
1015            u8 min_type = ptr->value_type[0];
1016            const u8 max_type = ptr->value_type[1];
1017            memset(buffer, 0, buffer_len);
1018            buffer_len -= 2;
1019            for (i = 0; i < 2; i++) {
1020                    int len;
1021                    switch (min_type) {
1022                    case CCS_VALUE_TYPE_HEXADECIMAL:
1023                            snprintf(buffer, buffer_len, "0x%lX", min);
1024                            break;
1025                    case CCS_VALUE_TYPE_OCTAL:
1026                            snprintf(buffer, buffer_len, "0%lo", min);
1027                            break;
1028                    default:
1029                            snprintf(buffer, buffer_len, "%lu", min);
1030                            break;
1031                    }
1032                    if (min == max && min_type == max_type)
1033                            break;
1034                    len = strlen(buffer);
1035                    buffer[len++] = '-';
1036                    buffer += len;
1037                    buffer_len -= len;
1038                    min_type = max_type;
1039                    min = max;
1040            }
1041    }
1042    
1043  /**  /**
1044   * ccs_print_number_union_common - Print a ccs_number_union.   * ccs_print_number_union_common - Print a ccs_number_union.
1045   *   *
# Line 1041  static bool ccs_print_number_union_commo Line 1053  static bool ccs_print_number_union_commo
1053                                            const struct ccs_number_union *ptr,                                            const struct ccs_number_union *ptr,
1054                                            const bool need_space)                                            const bool need_space)
1055  {  {
1056          unsigned long min;          char buffer[128];
         unsigned long max;  
         u8 min_type;  
         u8 max_type;  
1057          if (need_space && !ccs_io_printf(head, " "))          if (need_space && !ccs_io_printf(head, " "))
1058                  return false;                  return false;
1059          if (ptr->is_group)          if (ptr->is_group)
1060                  return ccs_io_printf(head, "@%s",                  return ccs_io_printf(head, "@%s",
1061                                       ptr->group->group_name->name);                                       ptr->group->group_name->name);
1062          min_type = ptr->min_type;          ccs_print_number(buffer, sizeof(buffer), ptr);
1063          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);  
         }  
1064  }  }
1065    
1066  /**  /**
# Line 1088  static bool ccs_print_number_union_commo Line 1071  static bool ccs_print_number_union_commo
1071   *   *
1072   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1073   */   */
1074  bool ccs_print_number_union(struct ccs_io_buffer *head,  static bool ccs_print_number_union(struct ccs_io_buffer *head,
1075                              const struct ccs_number_union *ptr)                                     const struct ccs_number_union *ptr)
1076  {  {
1077          return ccs_print_number_union_common(head, ptr, true);          return ccs_print_number_union_common(head, ptr, true);
1078  }  }
# Line 1122  static bool ccs_print_condition(struct c Line 1105  static bool ccs_print_condition(struct c
1105          const struct ccs_condition_element *condp;          const struct ccs_condition_element *condp;
1106          const struct ccs_number_union *numbers_p;          const struct ccs_number_union *numbers_p;
1107          const struct ccs_name_union *names_p;          const struct ccs_name_union *names_p;
1108          const struct ccs_argv_entry *argv;          const struct ccs_argv *argv;
1109          const struct ccs_envp_entry *envp;          const struct ccs_envp *envp;
1110          u16 condc;          u16 condc;
1111          u16 i;          u16 i;
1112          u16 j;          u16 j;
# Line 1135  static bool ccs_print_condition(struct c Line 1118  static bool ccs_print_condition(struct c
1118          numbers_p = (const struct ccs_number_union *) (condp + condc);          numbers_p = (const struct ccs_number_union *) (condp + condc);
1119          names_p = (const struct ccs_name_union *)          names_p = (const struct ccs_name_union *)
1120                  (numbers_p + cond->numbers_count);                  (numbers_p + cond->numbers_count);
1121          argv = (const struct ccs_argv_entry *) (names_p + cond->names_count);          argv = (const struct ccs_argv *) (names_p + cond->names_count);
1122          envp = (const struct ccs_envp_entry *) (argv + cond->argc);          envp = (const struct ccs_envp *) (argv + cond->argc);
1123          memset(buffer, 0, sizeof(buffer));          memset(buffer, 0, sizeof(buffer));
1124          if (condc && !ccs_io_printf(head, "%s", " if"))          if (condc && !ccs_io_printf(head, "%s", " if"))
1125                  goto out;                  goto out;
# Line 1212  static bool ccs_print_condition(struct c Line 1195  static bool ccs_print_condition(struct c
1195                                     cond->post_state[j]))                                     cond->post_state[j]))
1196                          goto out;                          goto out;
1197          }          }
1198            if (i & (1 << 4)) {
1199                    if (!ccs_io_printf(head, " audit=%s",
1200                                       ccs_yesno(cond->post_state[4])))
1201                            goto out;
1202            }
1203   no_condition:   no_condition:
1204          if (ccs_io_printf(head, "\n"))          if (ccs_io_printf(head, "\n"))
1205                  return true;                  return true;
# Line 1410  static bool ccs_print_capability_acl(str Line 1398  static bool ccs_print_capability_acl(str
1398  }  }
1399    
1400  /**  /**
  * 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;  
 }  
   
 /**  
1401   * ccs_print_network_acl - Print a network ACL entry.   * ccs_print_network_acl - Print a network ACL entry.
1402   *   *
1403   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 1470  static bool ccs_print_network_acl(struct Line 1412  static bool ccs_print_network_acl(struct
1412  {  {
1413          int pos;          int pos;
1414          u8 bit;          u8 bit;
1415          const u16 perm = ptr->perm;          const u8 perm = ptr->perm;
1416            char buf[128];
1417          for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {          for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
1418                    const char *w[2] = { "", "" };
1419                  if (!(perm & (1 << bit)))                  if (!(perm & (1 << bit)))
1420                          continue;                          continue;
1421                  pos = head->read_avail;                  pos = head->read_avail;
                 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",  
                                    ccs_net2keyword(bit)))  
                         goto out;  
1422                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1423                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
1424                          if (!ccs_io_printf(head, "@%s", ptr->address.group->                          w[0] = "@";
1425                                             group_name->name))                          w[1] = ptr->address.group->group_name->name;
                                 goto out;  
1426                          break;                          break;
1427                  case CCS_IP_ADDRESS_TYPE_IPv4:                  case CCS_IP_ADDRESS_TYPE_IPv4:
1428                          if (!ccs_print_ipv4_entry(head, ptr))                          ccs_print_ipv4(buf, sizeof(buf), ptr->address.ipv4.min,
1429                                  goto out;                                         ptr->address.ipv4.max);
1430                            w[0] = buf;
1431                          break;                          break;
1432                  case CCS_IP_ADDRESS_TYPE_IPv6:                  case CCS_IP_ADDRESS_TYPE_IPv6:
1433                          if (!ccs_print_ipv6_entry(head, ptr))                          ccs_print_ipv6(buf, sizeof(buf), ptr->address.ipv6.min,
1434                                  goto out;                                         ptr->address.ipv6.max);
1435                            w[0] = buf;
1436                          break;                          break;
1437                  }                  }
1438                  if (!ccs_print_number_union(head, &ptr->port) ||                  if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s %s%s",
1439                                       ccs_net2keyword(bit), w[0], w[1]) ||
1440                        !ccs_print_number_union(head, &ptr->port) ||
1441                      !ccs_print_condition(head, cond))                      !ccs_print_condition(head, cond))
1442                          goto out;                          goto out;
1443          }          }
# Line 1529  static bool ccs_print_signal_acl(struct Line 1473  static bool ccs_print_signal_acl(struct
1473  }  }
1474    
1475  /**  /**
1476   * ccs_print_execute_handler_record - Print an execute handler ACL entry.   * ccs_print_execute_handler - Print an execute handler ACL entry.
1477   *   *
1478   * @head:    Pointer to "struct ccs_io_buffer".   * @head:    Pointer to "struct ccs_io_buffer".
1479   * @keyword: Name of the keyword.   * @keyword: Name of the keyword.
1480   * @ptr:     Pointer to "struct ccs_execute_handler_record".   * @ptr:     Pointer to "struct ccs_execute_handler".
1481   *   *
1482   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1483   */   */
1484  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,  static bool ccs_print_execute_handler(struct ccs_io_buffer *head,
1485                                               const char *keyword,                                        const char *keyword,
1486                                               struct ccs_execute_handler_record *                                        struct ccs_execute_handler *ptr)
                                              ptr)  
1487  {  {
1488          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1489  }  }
# Line 1591  static bool ccs_print_entry(struct ccs_i Line 1534  static bool ccs_print_entry(struct ccs_i
1534                          = container_of(ptr, struct ccs_path_acl, head);                          = container_of(ptr, struct ccs_path_acl, head);
1535                  return ccs_print_path_acl(head, acl, cond);                  return ccs_print_path_acl(head, acl, cond);
1536          }          }
1537          if (acl_type == CCS_TYPE_EXECUTE_HANDLER) {          if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||
1538                  struct ccs_execute_handler_record *acl              acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1539                          = container_of(ptr, struct ccs_execute_handler_record,                  struct ccs_execute_handler *acl
1540                                         head);                          = container_of(ptr, struct ccs_execute_handler, head);
1541                  const char *keyword = CCS_KEYWORD_EXECUTE_HANDLER;                  const char *keyword = acl_type == CCS_TYPE_EXECUTE_HANDLER ?
1542                  return ccs_print_execute_handler_record(head, keyword, acl);                          CCS_KEYWORD_EXECUTE_HANDLER :
1543          }                          CCS_KEYWORD_DENIED_EXECUTE_HANDLER;
1544          if (acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {                  return ccs_print_execute_handler(head, keyword, acl);
                 struct ccs_execute_handler_record *acl  
                         = container_of(ptr, struct ccs_execute_handler_record,  
                                        head);  
                 const char *keyword = CCS_KEYWORD_DENIED_EXECUTE_HANDLER;  
                 return ccs_print_execute_handler_record(head, keyword, acl);  
1545          }          }
1546          if (head->read_execute_only)          if (head->read_execute_only)
1547                  return true;                  return true;
# Line 1652  static bool ccs_print_entry(struct ccs_i Line 1590  static bool ccs_print_entry(struct ccs_i
1590  }  }
1591    
1592  /**  /**
1593   * ccs_read_domain_policy - Read domain policy.   * ccs_read_domain2 - Read domain policy.
1594     *
1595     * @head:   Pointer to "struct ccs_io_buffer".
1596     * @domain: Pointer to "struct ccs_domain_info".
1597     *
1598     * Caller holds ccs_read_lock().
1599     *
1600     * Returns true on success, false otherwise.
1601     */
1602    static bool ccs_read_domain2(struct ccs_io_buffer *head,
1603                                 struct ccs_domain_info *domain)
1604    {
1605            struct list_head *pos;
1606            /* Print ACL entries in the domain. */
1607            list_for_each_cookie(pos, head->read_var2, &domain->acl_info_list) {
1608                    struct ccs_acl_info *ptr
1609                            = list_entry(pos, struct ccs_acl_info, list);
1610                    if (!ccs_print_entry(head, ptr))
1611                            return false;
1612            }
1613            return true;
1614    }
1615    
1616    /**
1617     * ccs_read_domain - Read domain policy.
1618   *   *
1619   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1620   *   *
1621   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1622   */   */
1623  static void ccs_read_domain_policy(struct ccs_io_buffer *head)  static void ccs_read_domain(struct ccs_io_buffer *head)
1624  {  {
1625          struct list_head *dpos;          struct list_head *pos;
         struct list_head *apos;  
1626          if (head->read_eof)          if (head->read_eof)
1627                  return;                  return;
1628          if (head->read_step == 0)          list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
1629                  head->read_step = 1;                  struct ccs_domain_info *domain =
1630          list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {                          list_entry(pos, struct ccs_domain_info, list);
1631                  struct ccs_domain_info *domain;                  const char *w[5] = { "", "", "", "", "" };
1632                  const char *quota_exceeded = "";                  switch (head->read_step) {
1633                  const char *transition_failed = "";                  case 0:
1634                  const char *ignore_global_allow_read = "";                          if (domain->is_deleted && !head->read_single_domain)
1635                  const char *ignore_global_allow_env = "";                                  continue;
1636                  domain = list_entry(dpos, struct ccs_domain_info, list);                          /* Print domainname and flags. */
1637                  if (head->read_step != 1)                          if (domain->quota_warned)
1638                          goto acl_loop;                                  w[0] = CCS_KEYWORD_QUOTA_EXCEEDED "\n";
1639                  if (domain->is_deleted && !head->read_single_domain)                          if (domain->domain_transition_failed)
1640                          continue;                                  w[1] = CCS_KEYWORD_TRANSITION_FAILED "\n";
1641                  /* Print domainname and flags. */                          if (domain->ignore_global)
1642                  if (domain->quota_warned)                                  w[2] = CCS_KEYWORD_IGNORE_GLOBAL "\n";
1643                          quota_exceeded = CCS_KEYWORD_QUOTA_EXCEEDED "\n";                          if (domain->ignore_global_allow_read)
1644                  if (domain->domain_transition_failed)                                  w[3] = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
1645                          transition_failed = CCS_KEYWORD_TRANSITION_FAILED "\n";                                          "\n";
1646                  if (domain->ignore_global_allow_read)                          if (domain->ignore_global_allow_env)
1647                          ignore_global_allow_read                                  w[4] = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV
1648                                  = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";                                          "\n";
1649                  if (domain->ignore_global_allow_env)                          if (!ccs_io_printf(head, "%s\n" CCS_KEYWORD_USE_PROFILE
1650                          ignore_global_allow_env                                             "%u\n%s%s%s%s%s\n",
1651                                  = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";                                             domain->domainname->name,
1652                  if (!ccs_io_printf(head, "%s\n" CCS_KEYWORD_USE_PROFILE "%u\n"                                             domain->profile, w[0], w[1], w[2],
1653                                     "%s%s%s%s\n", domain->domainname->name,                                             w[3], w[4]))
                                    domain->profile, quota_exceeded,  
                                    transition_failed,  
                                    ignore_global_allow_read,  
                                    ignore_global_allow_env))  
                         return;  
                 head->read_step = 2;  
  acl_loop:  
                 if (head->read_step == 3)  
                         goto tail_mark;  
                 /* Print ACL entries in the domain. */  
                 list_for_each_cookie(apos, head->read_var2,  
                                      &domain->acl_info_list) {  
                         struct ccs_acl_info *ptr  
                                 = list_entry(apos, struct ccs_acl_info, list);  
                         if (!ccs_print_entry(head, ptr))  
1654                                  return;                                  return;
1655                            head->read_step++;
1656                            /* fall through */
1657                    case 1:
1658                            if (!ccs_read_domain2(head, domain))
1659                                    return;
1660                            head->read_step++;
1661                            /* fall through */
1662                    case 2:
1663                            if (!ccs_io_printf(head, "\n"))
1664                                    return;
1665                            head->read_step = 0;
1666                            if (head->read_single_domain)
1667                                    goto out;
1668                  }                  }
                 head->read_step = 3;  
  tail_mark:  
                 if (!ccs_io_printf(head, "\n"))  
                         return;  
                 head->read_step = 1;  
                 if (head->read_single_domain)  
                         break;  
1669          }          }
1670     out:
1671          head->read_eof = true;          head->read_eof = true;
1672  }  }
1673    
# Line 1850  static void ccs_read_pid(struct ccs_io_b Line 1803  static void ccs_read_pid(struct ccs_io_b
1803                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1804                                "state[0]=%u state[1]=%u state[2]=%u", pid,                                "state[0]=%u state[1]=%u state[2]=%u", pid,
1805                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1806                                          CCS_TASK_IS_POLICY_MANAGER),                                          CCS_TASK_IS_MANAGER),
1807                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1808                                          CCS_TASK_IS_EXECUTE_HANDLER),                                          CCS_TASK_IS_EXECUTE_HANDLER),
1809                                (u8) (ccs_flags >> 24),                                (u8) (ccs_flags >> 24),
# Line 1859  static void ccs_read_pid(struct ccs_io_b Line 1812  static void ccs_read_pid(struct ccs_io_b
1812  }  }
1813    
1814  /**  /**
1815   * ccs_write_exception_policy - Write exception policy.   * ccs_write_exception - Write exception policy.
1816   *   *
1817   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1818   *   *
1819   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
1820   */   */
1821  static int ccs_write_exception_policy(struct ccs_io_buffer *head)  static int ccs_write_exception(struct ccs_io_buffer *head)
1822  {  {
1823          char *data = head->write_buf;          char *data = head->write_buf;
1824          bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);          const bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
1825          if (ccs_str_starts(&data, CCS_KEYWORD_KEEP_DOMAIN))          u8 i;
1826                  return ccs_write_domain_keeper_policy(data, false, is_delete);          static const struct {
1827          if (ccs_str_starts(&data, CCS_KEYWORD_NO_KEEP_DOMAIN))                  const char *keyword;
1828                  return ccs_write_domain_keeper_policy(data, true, is_delete);                  int (*write) (char *, const bool, const u8);
1829          if (ccs_str_starts(&data, CCS_KEYWORD_INITIALIZE_DOMAIN))          } ccs_callback[8] = {
1830                  return ccs_write_domain_initializer_policy(data, false,                  { CCS_KEYWORD_NO_KEEP_DOMAIN, ccs_write_domain_keeper },
1831                                                             is_delete);                  { CCS_KEYWORD_NO_INITIALIZE_DOMAIN,
1832          if (ccs_str_starts(&data, CCS_KEYWORD_NO_INITIALIZE_DOMAIN))                    ccs_write_domain_initializer },
1833                  return ccs_write_domain_initializer_policy(data, true,                  { CCS_KEYWORD_KEEP_DOMAIN, ccs_write_domain_keeper },
1834                                                             is_delete);                  { CCS_KEYWORD_INITIALIZE_DOMAIN,
1835          if (ccs_str_starts(&data, CCS_KEYWORD_AGGREGATOR))                    ccs_write_domain_initializer },
1836                  return ccs_write_aggregator_policy(data, is_delete);                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1837          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_READ))                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
1838                  return ccs_write_globally_readable_policy(data, is_delete);                  { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },
1839          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1840                  return ccs_write_globally_usable_env_policy(data, is_delete);          };
1841          if (ccs_str_starts(&data, CCS_KEYWORD_FILE_PATTERN))          static const char *ccs_name[CCS_MAX_GROUP] = {
1842                  return ccs_write_pattern_policy(data, is_delete);                  [CCS_PATH_GROUP] = CCS_KEYWORD_PATH_GROUP,
1843          if (ccs_str_starts(&data, CCS_KEYWORD_PATH_GROUP))                  [CCS_NUMBER_GROUP] = CCS_KEYWORD_NUMBER_GROUP,
1844                  return ccs_write_path_group_policy(data, is_delete);                  [CCS_ADDRESS_GROUP] = CCS_KEYWORD_ADDRESS_GROUP
1845          if (ccs_str_starts(&data, CCS_KEYWORD_NUMBER_GROUP))          };
1846                  return ccs_write_number_group_policy(data, is_delete);          for (i = 0; i < 8; i++) {
1847          if (ccs_str_starts(&data, CCS_KEYWORD_DENY_REWRITE))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1848                  return ccs_write_no_rewrite_policy(data, is_delete);                          return ccs_callback[i].write(data, is_delete, i < 2);
1849          if (ccs_str_starts(&data, CCS_KEYWORD_ADDRESS_GROUP))          }
1850                  return ccs_write_address_group_policy(data, is_delete);          for (i = 0; i < CCS_MAX_GROUP; i++) {
1851          if (ccs_str_starts(&data, CCS_KEYWORD_DENY_AUTOBIND))                  if (ccs_str_starts(&data, ccs_name[i]))
1852                  return ccs_write_reserved_port_policy(data, is_delete);                          return ccs_write_group(data, is_delete, i);
1853          return -EINVAL;          }
1854            {
1855                    int error;
1856                    struct ccs_condition *cond = NULL;
1857                    char *cp = ccs_find_condition_part(data);
1858                    if (cp) {
1859                            cond = ccs_get_condition(cp);
1860                            if (!cond)
1861                                    return -EINVAL;
1862                    }
1863                    error = ccs_write_domain2(data, &ccs_global_domain, cond,
1864                                              is_delete);
1865                    if (cond)
1866                            ccs_put_condition(cond);
1867                    return error;
1868            }
1869  }  }
1870    
1871  /**  /**
1872   * ccs_read_exception_policy - Read exception policy.   * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
1873   *   *
1874   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1875     * @idx:  Index number.
1876     *
1877     * Returns true on success, false otherwise.
1878   *   *
1879   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1880   */   */
1881  static void ccs_read_exception_policy(struct ccs_io_buffer *head)  static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
1882  {  {
1883          if (head->read_eof)          struct list_head *gpos;
1884                  return;          struct list_head *mpos;
1885          switch (head->read_step) {          const char *w[3] = { "", "", "" };
1886          case 0:          if (idx == CCS_PATH_GROUP)
1887                  head->read_var2 = NULL;                  w[0] = CCS_KEYWORD_PATH_GROUP;
1888                  head->read_step = 1;          else if (idx == CCS_NUMBER_GROUP)
1889          case 1:                  w[0] = CCS_KEYWORD_NUMBER_GROUP;
1890                  if (!ccs_read_domain_keeper_policy(head))          else if (idx == CCS_ADDRESS_GROUP)
1891                          break;                  w[0] = CCS_KEYWORD_ADDRESS_GROUP;
1892                  head->read_var2 = NULL;          list_for_each_cookie(gpos, head->read_var1, &ccs_group_list[idx]) {
1893                  head->read_step = 2;                  struct ccs_group *group =
1894          case 2:                          list_entry(gpos, struct ccs_group, head.list);
1895                  if (!ccs_read_globally_readable_policy(head))                  w[1] = group->group_name->name;
1896                          break;                  list_for_each_cookie(mpos, head->read_var2,
1897                  head->read_var2 = NULL;                                       &group->member_list) {
1898                  head->read_step = 3;                          char buffer[128];
1899          case 3:                          struct ccs_acl_head *ptr =
1900                  if (!ccs_read_globally_usable_env_policy(head))                                  list_entry(mpos, struct ccs_acl_head, list);
1901                          break;                          if (ptr->is_deleted)
1902                  head->read_var2 = NULL;                                  continue;
1903                  head->read_step = 4;                          if (idx == CCS_PATH_GROUP) {
1904          case 4:                                  w[2] = container_of(ptr, struct ccs_path_group,
1905                  if (!ccs_read_domain_initializer_policy(head))                                                      head)->member_name->name;
1906                          break;                          } else if (idx == CCS_NUMBER_GROUP) {
1907                  head->read_var2 = NULL;                                  w[2] = buffer;
1908                  head->read_step = 6;                                  ccs_print_number(buffer, sizeof(buffer),
1909          case 6:                                                   &container_of
1910                  if (!ccs_read_aggregator_policy(head))                                                   (ptr, struct ccs_number_group,
1911                          break;                                                    head)->number);
1912                  head->read_var2 = NULL;                          } else if (idx == CCS_ADDRESS_GROUP) {
1913                  head->read_step = 7;                                  struct ccs_address_group *member =
1914          case 7:                                          container_of(ptr, typeof(*member),
1915                  if (!ccs_read_file_pattern(head))                                                       head);
1916                                    w[2] = buffer;
1917                                    if (member->is_ipv6)
1918                                            ccs_print_ipv6(buffer, sizeof(buffer),
1919                                                           member->min.ipv6,
1920                                                           member->max.ipv6);
1921                                    else
1922                                            ccs_print_ipv4(buffer, sizeof(buffer),
1923                                                           member->min.ipv4,
1924                                                           member->max.ipv4);
1925                            }
1926                            if (!ccs_io_printf(head, "%s%s %s\n", w[0], w[1],
1927                                               w[2]))
1928                                    return false;
1929                    }
1930            }
1931            return true;
1932    }
1933    
1934    /**
1935     * ccs_read_policy - Read "struct ccs_..._entry" list.
1936     *
1937     * @head: Pointer to "struct ccs_io_buffer".
1938     * @idx:  Index number.
1939     *
1940     * Returns true on success, false otherwise.
1941     *
1942     * Caller holds ccs_read_lock().
1943     */
1944    static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
1945    {
1946            struct list_head *pos;
1947            list_for_each_cookie(pos, head->read_var2, &ccs_policy_list[idx]) {
1948                    const char *w[4] = { "", "", "", "" };
1949                    char buffer[16];
1950                    struct ccs_acl_head *acl = container_of(pos, typeof(*acl),
1951                                                            list);
1952                    if (acl->is_deleted)
1953                            continue;
1954                    switch (idx) {
1955                    case CCS_ID_DOMAIN_KEEPER:
1956                            {
1957                                    struct ccs_domain_keeper *ptr =
1958                                            container_of(acl, typeof(*ptr), head);
1959                                    w[0] = ptr->is_not ?
1960                                            CCS_KEYWORD_NO_KEEP_DOMAIN :
1961                                            CCS_KEYWORD_KEEP_DOMAIN;
1962                                    if (ptr->program) {
1963                                            w[1] = ptr->program->name;
1964                                            w[2] = " from ";
1965                                    }
1966                                    w[3] = ptr->domainname->name;
1967                            }
1968                          break;                          break;
1969                  head->read_var2 = NULL;                  case CCS_ID_DOMAIN_INITIALIZER:
1970                  head->read_step = 8;                          {
1971          case 8:                                  struct ccs_domain_initializer *ptr =
1972                  if (!ccs_read_no_rewrite_policy(head))                                          container_of(acl, typeof(*ptr), head);
1973                                    w[0] = ptr->is_not ?
1974                                            CCS_KEYWORD_NO_INITIALIZE_DOMAIN :
1975                                            CCS_KEYWORD_INITIALIZE_DOMAIN;
1976                                    w[1] = ptr->program->name;
1977                                    if (ptr->domainname) {
1978                                            w[2] = " from ";
1979                                            w[3] = ptr->domainname->name;
1980                                    }
1981                            }
1982                          break;                          break;
1983                  head->read_var2 = NULL;                  case CCS_ID_AGGREGATOR:
1984                  head->read_step = 9;                          {
1985          case 9:                                  struct ccs_aggregator *ptr =
1986                  if (!ccs_read_path_group_policy(head))                                          container_of(acl, typeof(*ptr), head);
1987                                    w[0] = CCS_KEYWORD_AGGREGATOR;
1988                                    w[1] = ptr->original_name->name;
1989                                    w[2] = " ";
1990                                    w[3] = ptr->aggregated_name->name;
1991                            }
1992                          break;                          break;
1993                  head->read_var1 = NULL;                  case CCS_ID_PATTERN:
1994                  head->read_var2 = NULL;                          {
1995                  head->read_step = 10;                                  struct ccs_pattern *ptr =
1996          case 10:                                          container_of(acl, typeof(*ptr), head);
1997                  if (!ccs_read_number_group_policy(head))                                  w[0] = CCS_KEYWORD_FILE_PATTERN;
1998                                    w[1] = ptr->pattern->name;
1999                            }
2000                          break;                          break;
2001                  head->read_var1 = NULL;                  case CCS_ID_NO_REWRITE:
2002                  head->read_var2 = NULL;                          {
2003                  head->read_step = 11;                                  struct ccs_no_rewrite *ptr =
2004          case 11:                                          container_of(acl, typeof(*ptr), head);
2005                  if (!ccs_read_address_group_policy(head))                                  w[0] = CCS_KEYWORD_DENY_REWRITE;
2006                                    w[1] = ptr->pattern->name;
2007                            }
2008                          break;                          break;
2009                  head->read_var2 = NULL;                  case CCS_ID_RESERVEDPORT:
2010                  head->read_step = 12;                          {
2011          case 12:                                  struct ccs_reserved *ptr =
2012                  if (!ccs_read_reserved_port_policy(head))                                          container_of(acl, typeof(*ptr), head);
2013                                    const u16 min_port = ptr->min_port;
2014                                    const u16 max_port = ptr->max_port;
2015                                    w[0] = CCS_KEYWORD_DENY_AUTOBIND;
2016                                    snprintf(buffer, sizeof(buffer) - 1, "%u%c%u",
2017                                             min_port, min_port != max_port ?
2018                                             '-' : '\0', max_port);
2019                                    buffer[sizeof(buffer) - 1] = '\0';
2020                                    w[1] = buffer;
2021                            }
2022                          break;                          break;
2023                  head->read_eof = true;                  default:
2024                            continue;
2025                    }
2026                    if (!ccs_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2], w[3]))
2027                            return false;
2028          }          }
2029            return true;
2030    }
2031    
2032    static void ccs_read_global_domain(struct ccs_io_buffer *head)
2033    {
2034            if (!head->read_eof)
2035                    head->read_eof = ccs_read_domain2(head, &ccs_global_domain);
2036    }
2037    
2038    /**
2039     * ccs_read_exception - Read exception policy.
2040     *
2041     * @head: Pointer to "struct ccs_io_buffer".
2042     *
2043     * Caller holds ccs_read_lock().
2044     */
2045    static void ccs_read_exception(struct ccs_io_buffer *head)
2046    {
2047            if (head->read_eof)
2048                    return;
2049            while (head->read_step < CCS_MAX_POLICY &&
2050                   ccs_read_policy(head, head->read_step))
2051                    head->read_step++;
2052            if (head->read_step < CCS_MAX_POLICY)
2053                    return;
2054            while (head->read_step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
2055                   ccs_read_group(head, head->read_step - CCS_MAX_POLICY))
2056                    head->read_step++;
2057            if (head->read_step < CCS_MAX_POLICY + CCS_MAX_GROUP)
2058                    return;
2059            head->read = ccs_read_global_domain;
2060  }  }
2061    
2062  /**  /**
2063   * ccs_get_argv0 - Get argv[0].   * ccs_get_argv0 - Get argv[0].
2064   *   *
2065   * @ee: Pointer to "struct ccs_execve_entry".   * @ee: Pointer to "struct ccs_execve".
2066   *   *
2067   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
2068   */   */
2069  static bool ccs_get_argv0(struct ccs_execve_entry *ee)  static bool ccs_get_argv0(struct ccs_execve *ee)
2070  {  {
2071          struct linux_binprm *bprm = ee->bprm;          struct linux_binprm *bprm = ee->bprm;
2072          char *arg_ptr = ee->tmp;          char *arg_ptr = ee->tmp;
# Line 2030  static bool ccs_get_argv0(struct ccs_exe Line 2115  static bool ccs_get_argv0(struct ccs_exe
2115  /**  /**
2116   * ccs_get_execute_condition - Get condition part for execute requests.   * ccs_get_execute_condition - Get condition part for execute requests.
2117   *   *
2118   * @ee: Pointer to "struct ccs_execve_entry".   * @ee: Pointer to "struct ccs_execve".
2119   *   *
2120   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2121   */   */
2122  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve *ee)
                                                        *ee)  
2123  {  {
2124          struct ccs_condition *cond;          struct ccs_condition *cond;
2125          char *buf;          char *buf;
2126          int len = 256;          int len = 256;
2127          char *realpath = NULL;          char *realpath = NULL;
2128          char *argv0 = NULL;          char *argv0 = NULL;
2129          const struct ccs_profile *profile = ccs_profile(ee->r.domain->profile);          const struct ccs_profile *profile = ccs_profile(ccs_current_domain()->
2130                                                            profile);
2131          if (profile->learning->learning_exec_realpath) {          if (profile->learning->learning_exec_realpath) {
2132                  struct file *file = ee->bprm->file;                  struct file *file = ee->bprm->file;
2133  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
# Line 2094  static struct ccs_condition *ccs_get_exe Line 2179  static struct ccs_condition *ccs_get_exe
2179   *   *
2180   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.   * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2181   */   */
2182  static struct ccs_condition *ccs_get_symlink_condition(struct ccs_request_info  static struct ccs_condition *ccs_get_symlink_condition
2183                                                         *r)  (const struct ccs_request_info *r)
2184  {  {
2185          struct ccs_condition *cond;          struct ccs_condition *cond;
2186          char *buf;          char *buf;
# Line 2150  static atomic_t ccs_query_observers = AT Line 2235  static atomic_t ccs_query_observers = AT
2235  /**  /**
2236   * ccs_supervisor - Ask for the supervisor's decision.   * ccs_supervisor - Ask for the supervisor's decision.
2237   *   *
2238   * @r:       Pointer to "struct ccs_request_info".   * @r:   Pointer to "struct ccs_request_info".
2239   * @fmt:     The printf()'s format string, followed by parameters.   * @fmt: The printf()'s format string, followed by parameters.
2240   *   *
2241   * Returns 0 if the supervisor decided to permit the access request which   * Returns 0 if the supervisor decided to permit the access request which
2242   * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor   * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
# Line 2168  int ccs_supervisor(struct ccs_request_in Line 2253  int ccs_supervisor(struct ccs_request_in
2253          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query_entry *ccs_query_entry = NULL;
2254          bool quota_exceeded = false;          bool quota_exceeded = false;
2255          char *header;          char *header;
2256          if (!r->domain)          struct ccs_domain_info * const domain = ccs_current_domain();
                 r->domain = ccs_current_domain();  
2257          switch (r->mode) {          switch (r->mode) {
2258                  char *buffer;                  char *buffer;
2259                  struct ccs_condition *cond;                  struct ccs_condition *cond;
# Line 2186  int ccs_supervisor(struct ccs_request_in Line 2270  int ccs_supervisor(struct ccs_request_in
2270                  vsnprintf(buffer, len - 1, fmt, args);                  vsnprintf(buffer, len - 1, fmt, args);
2271                  va_end(args);                  va_end(args);
2272                  ccs_normalize_line(buffer);                  ccs_normalize_line(buffer);
2273                  if (r->ee && !strncmp(buffer, "allow_execute ", 14))                  if (r->param_type == CCS_TYPE_PATH_ACL &&
2274                        r->param.path.operation == CCS_TYPE_EXECUTE)
2275                          cond = ccs_get_execute_condition(r->ee);                          cond = ccs_get_execute_condition(r->ee);
2276                  else if (r->obj && r->obj->symlink_target)                  else if (r->param_type == CCS_TYPE_PATH_ACL &&
2277                             r->param.path.operation == CCS_TYPE_SYMLINK)
2278                          cond = ccs_get_symlink_condition(r);                          cond = ccs_get_symlink_condition(r);
2279                  else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {                  else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
2280                          char str[] = "if task.type=execute_handler";                          char str[] = "if task.type=execute_handler";
2281                          cond = ccs_get_condition(str);                          cond = ccs_get_condition(str);
2282                  } else                  } else
2283                          cond = NULL;                          cond = NULL;
2284                  ccs_write_domain_policy2(buffer, r->domain, cond, false);                  ccs_write_domain2(buffer, domain, cond, false);
2285                  ccs_put_condition(cond);                  ccs_put_condition(cond);
2286                  kfree(buffer);                  kfree(buffer);
2287                  /* fall through */                  /* fall through */
# Line 2206  int ccs_supervisor(struct ccs_request_in Line 2292  int ccs_supervisor(struct ccs_request_in
2292                  int i;                  int i;
2293                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2294                          return -EPERM;                          return -EPERM;
2295                  for (i = 0; i < ccs_profile(r->domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->
2296                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
2297                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2298                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2216  int ccs_supervisor(struct ccs_request_in Line 2302  int ccs_supervisor(struct ccs_request_in
2302          va_start(args, fmt);          va_start(args, fmt);
2303          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2304          va_end(args);          va_end(args);
2305          header = ccs_init_audit_log(&len, r);          header = ccs_init_log(&len, r);
2306          if (!header)          if (!header)
2307                  goto out;                  goto out;
2308          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);
# Line 2305  static int ccs_poll_query(struct file *f Line 2391  static int ccs_poll_query(struct file *f
2391          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2392                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2393                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2394                          struct ccs_query_entry *ptr                          struct ccs_query_entry *ptr =
2395                                  = list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, struct ccs_query_entry, list);
2396                          if (ptr->answer)                          if (ptr->answer)
2397                                  continue;                                  continue;
2398                          found = true;                          found = true;
# Line 2432  static void ccs_read_version(struct ccs_ Line 2518  static void ccs_read_version(struct ccs_
2518  {  {
2519          if (head->read_eof)          if (head->read_eof)
2520                  return;                  return;
2521          ccs_io_printf(head, "1.7.1");          ccs_io_printf(head, "1.7.2");
2522          head->read_eof = true;          head->read_eof = true;
2523  }  }
2524    
# Line 2470  int ccs_open_control(const u8 type, stru Line 2556  int ccs_open_control(const u8 type, stru
2556          head->type = type;          head->type = type;
2557          switch (type) {          switch (type) {
2558          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */          case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
2559                  head->write = ccs_write_domain_policy;                  head->write = ccs_write_domain;
2560                  head->read = ccs_read_domain_policy;                  head->read = ccs_read_domain;
2561                  break;                  break;
2562          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */          case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
2563                  head->write = ccs_write_exception_policy;                  head->write = ccs_write_exception;
2564                  head->read = ccs_read_exception_policy;                  head->read = ccs_read_exception;
2565                  break;                  break;
2566  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
2567          case CCS_GRANTLOG: /* /proc/ccs/grant_log */          case CCS_GRANTLOG: /* /proc/ccs/grant_log */
2568          case CCS_REJECTLOG: /* /proc/ccs/reject_log */          case CCS_REJECTLOG: /* /proc/ccs/reject_log */
2569                  head->poll = ccs_poll_audit_log;                  head->poll = ccs_poll_log;
2570                  head->read = ccs_read_audit_log;                  head->read = ccs_read_log;
2571                  break;                  break;
2572  #endif  #endif
2573          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
# Line 2521  int ccs_open_control(const u8 type, stru Line 2607  int ccs_open_control(const u8 type, stru
2607                  head->read = ccs_read_query;                  head->read = ccs_read_query;
2608                  break;                  break;
2609          case CCS_MANAGER: /* /proc/ccs/manager */          case CCS_MANAGER: /* /proc/ccs/manager */
2610                  head->write = ccs_write_manager_policy;                  head->write = ccs_write_manager;
2611                  head->read = ccs_read_manager_policy;                  head->read = ccs_read_manager;
2612                  break;                  break;
2613          }          }
2614          if (!(file->f_mode & FMODE_READ)) {          if (!(file->f_mode & FMODE_READ)) {
# Line 2558  int ccs_open_control(const u8 type, stru Line 2644  int ccs_open_control(const u8 type, stru
2644                  }                  }
2645          }          }
2646          if (type != CCS_QUERY &&          if (type != CCS_QUERY &&
2647              type != CCS_GRANTLOG && type != CCS_REJECTLOG) {              type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2648                  spin_lock(&ccs_io_buffer_list_lock);                  head->reader_idx = ccs_lock();
                 list_add(&head->list, &ccs_io_buffer_list);  
                 spin_unlock(&ccs_io_buffer_list_lock);  
         }  
2649          file->private_data = head;          file->private_data = head;
2650          /*          /*
2651           * Call the handler now if the file is /proc/ccs/self_domain           * Call the handler now if the file is /proc/ccs/self_domain
# Line 2683  int ccs_write_control(struct file *file, Line 2766  int ccs_write_control(struct file *file,
2766                  return -EINTR;                  return -EINTR;
2767          idx = ccs_read_lock();          idx = ccs_read_lock();
2768          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
2769          if (head->write != ccs_write_pid &&          if (head->write != ccs_write_pid && head->write != ccs_write_domain &&
2770              head->write != ccs_write_domain_policy &&              !ccs_manager()) {
             !ccs_is_policy_manager()) {  
2771                  ccs_read_unlock(idx);                  ccs_read_unlock(idx);
2772                    mutex_unlock(&head->io_sem);
2773                  return -EPERM;                  return -EPERM;
2774          }          }
2775          /* Read a line and dispatch it to the policy handler. */          /* Read a line and dispatch it to the policy handler. */
# Line 2742  int ccs_close_control(struct file *file) Line 2825  int ccs_close_control(struct file *file)
2825          if (type == CCS_QUERY)          if (type == CCS_QUERY)
2826                  atomic_dec(&ccs_query_observers);                  atomic_dec(&ccs_query_observers);
2827          if (type != CCS_QUERY &&          if (type != CCS_QUERY &&
2828              type != CCS_GRANTLOG && type != CCS_REJECTLOG) {              type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2829                  spin_lock(&ccs_io_buffer_list_lock);                  ccs_unlock(head->reader_idx);
                 list_del(&head->list);  
                 spin_unlock(&ccs_io_buffer_list_lock);  
         }  
2830          /* Release memory used for policy I/O. */          /* Release memory used for policy I/O. */
2831          kfree(head->read_buf);          kfree(head->read_buf);
2832          head->read_buf = NULL;          head->read_buf = NULL;

Legend:
Removed from v.3535  
changed lines
  Added in v.3731

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