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

Subversion リポジトリの参照

Diff of /branches/ccs-patch/security/ccsecurity/policy_io.c

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

revision 3069 by kumaneko, Mon Sep 28 02:07:38 2009 UTC revision 3561 by kumaneko, Thu Apr 1 05:04:44 2010 UTC
# Line 1  Line 1 
1  /*  /*
2   * security/ccsecurity/policy_io.c   * security/ccsecurity/policy_io.c
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0   2009/09/04   * Version: 1.7.2   2010/04/01
7   *   *
8   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
9   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 33  static struct ccs_profile ccs_default_pr Line 33  static struct ccs_profile ccs_default_pr
33          .preference.permissive_verbose = true          .preference.permissive_verbose = true
34  };  };
35    
36    /* Profile version. Currently only 20090903 is defined. */
37    static unsigned int ccs_profile_version;
38    
39  /* Profile table. Memory is allocated as needed. */  /* Profile table. Memory is allocated as needed. */
40  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
41    
 /* Lock for protecting "struct ccs_profile"->comment  */  
 static DEFINE_SPINLOCK(ccs_profile_comment_lock);  
   
42  /* String table for functionality that takes 4 modes. */  /* String table for functionality that takes 4 modes. */
43  static const char *ccs_mode_4[4] = {  static const char *ccs_mode_4[4] = {
44          "disabled", "learning", "permissive", "enforcing"          "disabled", "learning", "permissive", "enforcing"
# Line 94  static const char *ccs_mac_keywords[CCS_ Line 94  static const char *ccs_mac_keywords[CCS_
94          = "file::umount",          = "file::umount",
95          [CCS_MAC_FILE_PIVOT_ROOT]          [CCS_MAC_FILE_PIVOT_ROOT]
96          = "file::pivot_root",          = "file::pivot_root",
97            [CCS_MAC_FILE_TRANSIT]
98            = "file::transit",
99          [CCS_MAC_ENVIRON]          [CCS_MAC_ENVIRON]
100          = "misc::env",          = "misc::env",
101          [CCS_MAC_NETWORK_UDP_BIND]          [CCS_MAC_NETWORK_UDP_BIND]
# Line 260  static struct ccs_profile *ccs_find_or_a Line 262  static struct ccs_profile *ccs_find_or_a
262          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
263          if (ptr)          if (ptr)
264                  return ptr;                  return ptr;
265          entry = kzalloc(sizeof(*entry), GFP_KERNEL);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
266          mutex_lock(&ccs_policy_lock);          if (mutex_lock_interruptible(&ccs_policy_lock))
267                    goto out;
268          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
269          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
270                  ptr = entry;                  ptr = entry;
# Line 278  static struct ccs_profile *ccs_find_or_a Line 281  static struct ccs_profile *ccs_find_or_a
281                  entry = NULL;                  entry = NULL;
282          }          }
283          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
284     out:
285          kfree(entry);          kfree(entry);
286          return ptr;          return ptr;
287  }  }
# Line 285  static struct ccs_profile *ccs_find_or_a Line 289  static struct ccs_profile *ccs_find_or_a
289  /**  /**
290   * ccs_check_profile - Check all profiles currently assigned to domains are defined.   * ccs_check_profile - Check all profiles currently assigned to domains are defined.
291   */   */
292  void ccs_check_profile(void)  static void ccs_check_profile(void)
293  {  {
294          struct ccs_domain_info *domain;          struct ccs_domain_info *domain;
295            const int idx = ccs_read_lock();
296          ccs_policy_loaded = true;          ccs_policy_loaded = true;
297          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {          list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
298                  const u8 profile = domain->profile;                  const u8 profile = domain->profile;
# Line 296  void ccs_check_profile(void) Line 301  void ccs_check_profile(void)
301                  panic("Profile %u (used by '%s') not defined.\n",                  panic("Profile %u (used by '%s') not defined.\n",
302                        profile, domain->domainname->name);                        profile, domain->domainname->name);
303          }          }
304            ccs_read_unlock(idx);
305            if (ccs_profile_version != 20090903)
306                    panic("Profile version %u is not supported.\n",
307                          ccs_profile_version);
308            printk(KERN_INFO "CCSecurity: 1.7.2   2010/04/01\n");
309            printk(KERN_INFO "Mandatory Access Control activated.\n");
310  }  }
311    
312  /**  /**
# Line 331  static int ccs_write_profile(struct ccs_ Line 342  static int ccs_write_profile(struct ccs_
342          bool use_default = false;          bool use_default = false;
343          char *cp;          char *cp;
344          struct ccs_profile *profile;          struct ccs_profile *profile;
345            if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
346                    return 0;
347          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
348          if (data == cp) {          if (data == cp) {
349                  profile = &ccs_default_profile;                  profile = &ccs_default_profile;
# Line 438  static int ccs_write_profile(struct ccs_ Line 451  static int ccs_write_profile(struct ccs_
451          if (profile == &ccs_default_profile)          if (profile == &ccs_default_profile)
452                  return -EINVAL;                  return -EINVAL;
453          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
454                  const struct ccs_path_info *new_comment = ccs_get_name(cp);                  const struct ccs_path_info *old_comment = profile->comment;
455                  const struct ccs_path_info *old_comment;                  profile->comment = ccs_get_name(cp);
                 /* Protect reader from ccs_put_name(). */  
                 spin_lock(&ccs_profile_comment_lock);  
                 old_comment = profile->comment;  
                 profile->comment = new_comment;  
                 spin_unlock(&ccs_profile_comment_lock);  
456                  ccs_put_name(old_comment);                  ccs_put_name(old_comment);
457                  return 0;                  return 0;
458          }          }
# Line 551  static void ccs_read_profile(struct ccs_ Line 559  static void ccs_read_profile(struct ccs_
559                  int i;                  int i;
560                  int pos;                  int pos;
561                  const struct ccs_profile *profile = ccs_profile_ptr[index];                  const struct ccs_profile *profile = ccs_profile_ptr[index];
562                    const struct ccs_path_info *comment;
563                  head->read_step = index;                  head->read_step = index;
564                  if (!profile)                  if (!profile)
565                          continue;                          continue;
566                  pos = head->read_avail;                  pos = head->read_avail;
567                  spin_lock(&ccs_profile_comment_lock);                  comment = profile->comment;
568                  done = ccs_io_printf(head, "%u-COMMENT=%s\n", index,                  done = ccs_io_printf(head, "%u-COMMENT=%s\n", index,
569                                       profile->comment ? profile->comment->name                                       comment ? comment->name : "");
                                      : "");  
                 spin_unlock(&ccs_profile_comment_lock);  
570                  if (!done)                  if (!done)
571                          goto out;                          goto out;
572                  config = profile->default_config;                  config = profile->default_config;
# Line 666  LIST_HEAD(ccs_policy_manager_list); Line 673  LIST_HEAD(ccs_policy_manager_list);
673   */   */
674  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)
675  {  {
         struct ccs_policy_manager_entry *entry = NULL;  
676          struct ccs_policy_manager_entry *ptr;          struct ccs_policy_manager_entry *ptr;
677          struct ccs_policy_manager_entry e = { };          struct ccs_policy_manager_entry e = { };
678          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
# Line 681  static int ccs_update_manager_entry(cons Line 687  static int ccs_update_manager_entry(cons
687          e.manager = ccs_get_name(manager);          e.manager = ccs_get_name(manager);
688          if (!e.manager)          if (!e.manager)
689                  return -ENOMEM;                  return -ENOMEM;
690          if (!is_delete)          if (mutex_lock_interruptible(&ccs_policy_lock))
691                  entry = kmalloc(sizeof(e), GFP_KERNEL);                  goto out;
         mutex_lock(&ccs_policy_lock);  
692          list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {          list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
693                  if (ptr->manager != e.manager)                  if (ptr->manager != e.manager)
694                          continue;                          continue;
# Line 691  static int ccs_update_manager_entry(cons Line 696  static int ccs_update_manager_entry(cons
696                  error = 0;                  error = 0;
697                  break;                  break;
698          }          }
699          if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {          if (!is_delete && error) {
700                  list_add_tail_rcu(&entry->list, &ccs_policy_manager_list);                  struct ccs_policy_manager_entry *entry =
701                  entry = NULL;                          ccs_commit_ok(&e, sizeof(e));
702                  error = 0;                  if (entry) {
703                            list_add_tail_rcu(&entry->list,
704                                              &ccs_policy_manager_list);
705                            error = 0;
706                    }
707          }          }
708          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
709     out:
710          ccs_put_name(e.manager);          ccs_put_name(e.manager);
         kfree(entry);  
711          return error;          return error;
712  }  }
713    
# Line 847  static bool ccs_is_select_one(struct ccs Line 856  static bool ccs_is_select_one(struct ccs
856          if (sscanf(data, "pid=%u", &pid) == 1 ||          if (sscanf(data, "pid=%u", &pid) == 1 ||
857              (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {              (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
858                  struct task_struct *p;                  struct task_struct *p;
859                  read_lock(&tasklist_lock);                  ccs_tasklist_lock();
860  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
861                  if (global_pid)                  if (global_pid)
862                          p = find_task_by_pid_ns(pid, &init_pid_ns);                          p = ccsecurity_exports.find_task_by_pid_ns(pid,
863                                                                   &init_pid_ns);
864                  else                  else
865                          p = find_task_by_vpid(pid);                          p = ccsecurity_exports.find_task_by_vpid(pid);
866  #else  #else
867                  p = find_task_by_pid(pid);                  p = find_task_by_pid(pid);
868  #endif  #endif
869                  if (p)                  if (p)
870                          domain = ccs_task_domain(p);                          domain = ccs_task_domain(p);
871                  read_unlock(&tasklist_lock);                  ccs_tasklist_unlock();
872          } else if (!strncmp(data, "domain=", 7)) {          } else if (!strncmp(data, "domain=", 7)) {
873                  if (ccs_is_domain_def(data + 7))                  if (ccs_is_domain_def(data + 7))
874                          domain = ccs_find_domain(data + 7);                          domain = ccs_find_domain(data + 7);
# Line 904  static int ccs_write_domain_policy2(char Line 914  static int ccs_write_domain_policy2(char
914                  return ccs_write_env_policy(data, domain, cond, is_delete);                  return ccs_write_env_policy(data, domain, cond, is_delete);
915          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))
916                  return ccs_write_mount_policy(data, domain, cond, is_delete);                  return ccs_write_mount_policy(data, domain, cond, is_delete);
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_UNMOUNT))  
                 return ccs_write_umount_policy(data, domain, cond, is_delete);  
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CHROOT))  
                 return ccs_write_chroot_policy(data, domain, cond, is_delete);  
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_PIVOT_ROOT))  
                 return ccs_write_pivot_root_policy(data, domain, cond,  
                                                    is_delete);  
917          return ccs_write_file_policy(data, domain, cond, is_delete);          return ccs_write_file_policy(data, domain, cond, is_delete);
918  }  }
919    
# Line 968  static int ccs_write_domain_policy(struc Line 971  static int ccs_write_domain_policy(struc
971                  domain->ignore_global_allow_env = !is_delete;                  domain->ignore_global_allow_env = !is_delete;
972                  return 0;                  return 0;
973          }          }
974            if (!strcmp(data, CCS_KEYWORD_QUOTA_EXCEEDED)) {
975                    domain->quota_warned = !is_delete;
976                    return 0;
977            }
978            if (!strcmp(data, CCS_KEYWORD_TRANSITION_FAILED)) {
979                    domain->domain_transition_failed = !is_delete;
980                    return 0;
981            }
982          cp = ccs_find_condition_part(data);          cp = ccs_find_condition_part(data);
983          if (cp) {          if (cp) {
984                  cond = ccs_get_condition(cp);                  cond = ccs_get_condition(cp);
# Line 1209  static bool ccs_print_condition(struct c Line 1220  static bool ccs_print_condition(struct c
1220  }  }
1221    
1222  /**  /**
1223   * ccs_print_path_acl - Print a single path ACL entry.   * ccs_print_path_acl - Print a path ACL entry.
1224   *   *
1225   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1226   * @ptr:  Pointer to "struct ccs_path_acl".   * @ptr:  Pointer to "struct ccs_path_acl".
# Line 1227  static bool ccs_print_path_acl(struct cc Line 1238  static bool ccs_print_path_acl(struct cc
1238          for (bit = head->read_bit; bit < CCS_MAX_PATH_OPERATION; bit++) {          for (bit = head->read_bit; bit < CCS_MAX_PATH_OPERATION; bit++) {
1239                  if (!(perm & (1 << bit)))                  if (!(perm & (1 << bit)))
1240                          continue;                          continue;
1241                  if (head->read_execute_only && bit != CCS_TYPE_EXECUTE)                  if (head->read_execute_only && bit != CCS_TYPE_EXECUTE
1242                        && bit != CCS_TYPE_TRANSIT)
1243                          continue;                          continue;
1244                  /* Print "read/write" instead of "read" and "write". */                  /* Print "read/write" instead of "read" and "write". */
1245                  if ((bit == CCS_TYPE_READ || bit == CCS_TYPE_WRITE)                  if ((bit == CCS_TYPE_READ || bit == CCS_TYPE_WRITE)
# Line 1560  static bool ccs_print_mount_acl(struct c Line 1572  static bool ccs_print_mount_acl(struct c
1572  }  }
1573    
1574  /**  /**
  * ccs_print_umount_acl - Print a mount ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_umount_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_umount_acl(struct ccs_io_buffer *head,  
                                  struct ccs_umount_acl *ptr,  
                                  const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT) ||  
             !ccs_print_name_union(head, &ptr->dir) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
  * ccs_print_chroot_acl - Print a chroot ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_chroot_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_chroot_acl(struct ccs_io_buffer *head,  
                                  struct ccs_chroot_acl *ptr,  
                                  const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT) ||  
             !ccs_print_name_union(head, &ptr->dir) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
  * ccs_print_pivot_root_acl - Print a pivot_root ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_pivot_root_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_pivot_root_acl(struct ccs_io_buffer *head,  
                                      struct ccs_pivot_root_acl *ptr,  
                                      const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT) ||  
             !ccs_print_name_union(head, &ptr->new_root) ||  
             !ccs_print_name_union(head, &ptr->old_root) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
1575   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1576   *   *
1577   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 1672  static bool ccs_print_entry(struct ccs_i Line 1614  static bool ccs_print_entry(struct ccs_i
1614          }          }
1615          if (acl_type == CCS_TYPE_PATH2_ACL) {          if (acl_type == CCS_TYPE_PATH2_ACL) {
1616                  struct ccs_path2_acl *acl                  struct ccs_path2_acl *acl
1617                          = container_of(ptr, struct ccs_path2_acl,                          = container_of(ptr, struct ccs_path2_acl, head);
                                        head);  
1618                  return ccs_print_path2_acl(head, acl, cond);                  return ccs_print_path2_acl(head, acl, cond);
1619          }          }
1620          if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {          if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
1621                  struct ccs_path_number_acl *acl                  struct ccs_path_number_acl *acl
1622                          = container_of(ptr, struct ccs_path_number_acl,                          = container_of(ptr, struct ccs_path_number_acl, head);
                                        head);  
1623                  return ccs_print_path_number_acl(head, acl, cond);                  return ccs_print_path_number_acl(head, acl, cond);
1624          }          }
1625          if (acl_type == CCS_TYPE_ENV_ACL) {          if (acl_type == CCS_TYPE_ENV_ACL) {
# Line 1689  static bool ccs_print_entry(struct ccs_i Line 1629  static bool ccs_print_entry(struct ccs_i
1629          }          }
1630          if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1631                  struct ccs_capability_acl *acl                  struct ccs_capability_acl *acl
1632                          = container_of(ptr, struct ccs_capability_acl,                          = container_of(ptr, struct ccs_capability_acl, head);
                                        head);  
1633                  return ccs_print_capability_acl(head, acl, cond);                  return ccs_print_capability_acl(head, acl, cond);
1634          }          }
1635          if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1636                  struct ccs_ip_network_acl *acl                  struct ccs_ip_network_acl *acl
1637                          = container_of(ptr, struct ccs_ip_network_acl,                          = container_of(ptr, struct ccs_ip_network_acl, head);
                                        head);  
1638                  return ccs_print_network_acl(head, acl, cond);                  return ccs_print_network_acl(head, acl, cond);
1639          }          }
1640          if (acl_type == CCS_TYPE_SIGNAL_ACL) {          if (acl_type == CCS_TYPE_SIGNAL_ACL) {
# Line 1709  static bool ccs_print_entry(struct ccs_i Line 1647  static bool ccs_print_entry(struct ccs_i
1647                          = container_of(ptr, struct ccs_mount_acl, head);                          = container_of(ptr, struct ccs_mount_acl, head);
1648                  return ccs_print_mount_acl(head, acl, cond);                  return ccs_print_mount_acl(head, acl, cond);
1649          }          }
         if (acl_type == CCS_TYPE_UMOUNT_ACL) {  
                 struct ccs_umount_acl *acl  
                         = container_of(ptr, struct ccs_umount_acl, head);  
                 return ccs_print_umount_acl(head, acl, cond);  
         }  
         if (acl_type == CCS_TYPE_CHROOT_ACL) {  
                 struct ccs_chroot_acl *acl  
                         = container_of(ptr, struct ccs_chroot_acl, head);  
                 return ccs_print_chroot_acl(head, acl, cond);  
         }  
         if (acl_type == CCS_TYPE_PIVOT_ROOT_ACL) {  
                 struct ccs_pivot_root_acl *acl  
                         = container_of(ptr, struct ccs_pivot_root_acl,  
                                        head);  
                 return ccs_print_pivot_root_acl(head, acl, cond);  
         }  
1650          BUG(); /* This must not happen. */          BUG(); /* This must not happen. */
1651          return false;          return false;
1652  }  }
# Line 1757  static void ccs_read_domain_policy(struc Line 1679  static void ccs_read_domain_policy(struc
1679                          continue;                          continue;
1680                  /* Print domainname and flags. */                  /* Print domainname and flags. */
1681                  if (domain->quota_warned)                  if (domain->quota_warned)
1682                          quota_exceeded = "quota_exceeded\n";                          quota_exceeded = CCS_KEYWORD_QUOTA_EXCEEDED "\n";
1683                  if (domain->domain_transition_failed)                  if (domain->domain_transition_failed)
1684                          transition_failed = "transition_failed\n";                          transition_failed = CCS_KEYWORD_TRANSITION_FAILED "\n";
1685                  if (domain->ignore_global_allow_read)                  if (domain->ignore_global_allow_read)
1686                          ignore_global_allow_read                          ignore_global_allow_read
1687                                  = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";                                  = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
# Line 1893  static void ccs_read_pid(struct ccs_io_b Line 1815  static void ccs_read_pid(struct ccs_io_b
1815          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
1816          u32 ccs_flags = 0;          u32 ccs_flags = 0;
1817          /* Accessing write_buf is safe because head->io_sem is held. */          /* Accessing write_buf is safe because head->io_sem is held. */
1818          if (!buf)          if (!buf) {
1819                    head->read_eof = true;
1820                  return; /* Do nothing if open(O_RDONLY). */                  return; /* Do nothing if open(O_RDONLY). */
1821            }
1822          if (head->read_avail || head->read_eof)          if (head->read_avail || head->read_eof)
1823                  return;                  return;
1824          head->read_eof = true;          head->read_eof = true;
# Line 1903  static void ccs_read_pid(struct ccs_io_b Line 1827  static void ccs_read_pid(struct ccs_io_b
1827          if (ccs_str_starts(&buf, "global-pid "))          if (ccs_str_starts(&buf, "global-pid "))
1828                  global_pid = true;                  global_pid = true;
1829          pid = (unsigned int) simple_strtoul(buf, NULL, 10);          pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1830          read_lock(&tasklist_lock);          ccs_tasklist_lock();
1831  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1832          if (global_pid)          if (global_pid)
1833                  p = find_task_by_pid_ns(pid, &init_pid_ns);                  p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns);
1834          else          else
1835                  p = find_task_by_vpid(pid);                  p = ccsecurity_exports.find_task_by_vpid(pid);
1836  #else  #else
1837          p = find_task_by_pid(pid);          p = find_task_by_pid(pid);
1838  #endif  #endif
# Line 1916  static void ccs_read_pid(struct ccs_io_b Line 1840  static void ccs_read_pid(struct ccs_io_b
1840                  domain = ccs_task_domain(p);                  domain = ccs_task_domain(p);
1841                  ccs_flags = p->ccs_flags;                  ccs_flags = p->ccs_flags;
1842          }          }
1843          read_unlock(&tasklist_lock);          ccs_tasklist_unlock();
1844          if (!domain)          if (!domain)
1845                  return;                  return;
1846          if (!task_info)          if (!task_info)
# Line 2136  static struct ccs_condition *ccs_get_exe Line 2060  static struct ccs_condition *ccs_get_exe
2060                          len += strlen(argv0) + 16;                          len += strlen(argv0) + 16;
2061                  }                  }
2062          }          }
2063          buf = kmalloc(len, GFP_KERNEL);          buf = kmalloc(len, CCS_GFP_FLAGS);
2064          if (!buf) {          if (!buf) {
2065                  kfree(realpath);                  kfree(realpath);
2066                  return NULL;                  return NULL;
# Line 2182  static struct ccs_condition *ccs_get_sym Line 2106  static struct ccs_condition *ccs_get_sym
2106                  symlink = r->obj->symlink_target->name;                  symlink = r->obj->symlink_target->name;
2107                  len += strlen(symlink) + 18;                  len += strlen(symlink) + 18;
2108          }          }
2109          buf = kmalloc(len, GFP_KERNEL);          buf = kmalloc(len, CCS_GFP_FLAGS);
2110          if (!buf)          if (!buf)
2111                  return NULL;                  return NULL;
2112          snprintf(buf, len - 1, "if");          snprintf(buf, len - 1, "if");
# Line 2230  static atomic_t ccs_query_observers = AT Line 2154  static atomic_t ccs_query_observers = AT
2154   * @fmt:     The printf()'s format string, followed by parameters.   * @fmt:     The printf()'s format string, followed by parameters.
2155   *   *
2156   * Returns 0 if the supervisor decided to permit the access request which   * Returns 0 if the supervisor decided to permit the access request which
2157   * violated the policy in enforcing mode, 1 if the supervisor decided to   * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
2158   * retry the access request which violated the policy in enforcing mode,   * decided to retry the access request which violated the policy in enforcing
2159   * 0 if it is not in enforcing mode, -EPERM otherwise.   * mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2160   */   */
2161  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
2162  {  {
# Line 2255  int ccs_supervisor(struct ccs_request_in Line 2179  int ccs_supervisor(struct ccs_request_in
2179                  va_start(args, fmt);                  va_start(args, fmt);
2180                  len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;                  len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
2181                  va_end(args);                  va_end(args);
2182                  buffer = kmalloc(len, GFP_KERNEL);                  buffer = kmalloc(len, CCS_GFP_FLAGS);
2183                  if (!buffer)                  if (!buffer)
2184                          return 0;                          return 0;
2185                  va_start(args, fmt);                  va_start(args, fmt);
# Line 2295  int ccs_supervisor(struct ccs_request_in Line 2219  int ccs_supervisor(struct ccs_request_in
2219          header = ccs_init_audit_log(&len, r);          header = ccs_init_audit_log(&len, r);
2220          if (!header)          if (!header)
2221                  goto out;                  goto out;
2222          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), GFP_KERNEL);          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);
2223          if (!ccs_query_entry)          if (!ccs_query_entry)
2224                  goto out;                  goto out;
2225          len = ccs_round2(len);          len = ccs_round2(len);
2226          ccs_query_entry->query = kzalloc(len, GFP_KERNEL);          ccs_query_entry->query = kzalloc(len, CCS_GFP_FLAGS);
2227          if (!ccs_query_entry->query)          if (!ccs_query_entry->query)
2228                  goto out;                  goto out;
2229          INIT_LIST_HEAD(&ccs_query_entry->list);          INIT_LIST_HEAD(&ccs_query_entry->list);
# Line 2341  int ccs_supervisor(struct ccs_request_in Line 2265  int ccs_supervisor(struct ccs_request_in
2265          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2266          switch (ccs_query_entry->answer) {          switch (ccs_query_entry->answer) {
2267          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
2268                  error = 1;                  error = CCS_RETRY_REQUEST;
2269                  r->retry++;                  r->retry++;
2270                  break;                  break;
2271          case 1:          case 1:
# Line 2432  static void ccs_read_query(struct ccs_io Line 2356  static void ccs_read_query(struct ccs_io
2356                  head->read_step = 0;                  head->read_step = 0;
2357                  return;                  return;
2358          }          }
2359          buf = kzalloc(len, GFP_KERNEL);          buf = kzalloc(len, CCS_GFP_FLAGS);
2360          if (!buf)          if (!buf)
2361                  return;                  return;
2362          pos = 0;          pos = 0;
# Line 2508  static void ccs_read_version(struct ccs_ Line 2432  static void ccs_read_version(struct ccs_
2432  {  {
2433          if (head->read_eof)          if (head->read_eof)
2434                  return;                  return;
2435          ccs_io_printf(head, "1.7.0");          ccs_io_printf(head, "1.7.2");
2436          head->read_eof = true;          head->read_eof = true;
2437  }  }
2438    
# Line 2539  static void ccs_read_self_domain(struct Line 2463  static void ccs_read_self_domain(struct
2463   */   */
2464  int ccs_open_control(const u8 type, struct file *file)  int ccs_open_control(const u8 type, struct file *file)
2465  {  {
2466          struct ccs_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);          struct ccs_io_buffer *head = kzalloc(sizeof(*head), CCS_GFP_FLAGS);
2467          if (!head)          if (!head)
2468                  return -ENOMEM;                  return -ENOMEM;
2469          mutex_init(&head->io_sem);          mutex_init(&head->io_sem);
# Line 2555  int ccs_open_control(const u8 type, stru Line 2479  int ccs_open_control(const u8 type, stru
2479                  break;                  break;
2480  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
2481          case CCS_GRANTLOG: /* /proc/ccs/grant_log */          case CCS_GRANTLOG: /* /proc/ccs/grant_log */
                 head->poll = ccs_poll_grant_log;  
                 head->read = ccs_read_grant_log;  
                 break;  
2482          case CCS_REJECTLOG: /* /proc/ccs/reject_log */          case CCS_REJECTLOG: /* /proc/ccs/reject_log */
2483                  head->poll = ccs_poll_reject_log;                  head->poll = ccs_poll_audit_log;
2484                  head->read = ccs_read_reject_log;                  head->read = ccs_read_audit_log;
2485                  break;                  break;
2486  #endif  #endif
2487          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */          case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
# Line 2615  int ccs_open_control(const u8 type, stru Line 2536  int ccs_open_control(const u8 type, stru
2536                  /* Don't allocate read_buf for poll() access. */                  /* Don't allocate read_buf for poll() access. */
2537                  if (!head->readbuf_size)                  if (!head->readbuf_size)
2538                          head->readbuf_size = 4096;                          head->readbuf_size = 4096;
2539                  head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);                  head->read_buf = kzalloc(head->readbuf_size, CCS_GFP_FLAGS);
2540                  if (!head->read_buf) {                  if (!head->read_buf) {
2541                          kfree(head);                          kfree(head);
2542                          return -ENOMEM;                          return -ENOMEM;
# Line 2629  int ccs_open_control(const u8 type, stru Line 2550  int ccs_open_control(const u8 type, stru
2550                  head->write = NULL;                  head->write = NULL;
2551          } else if (head->write) {          } else if (head->write) {
2552                  head->writebuf_size = 4096;                  head->writebuf_size = 4096;
2553                  head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);                  head->write_buf = kzalloc(head->writebuf_size, CCS_GFP_FLAGS);
2554                  if (!head->write_buf) {                  if (!head->write_buf) {
2555                          kfree(head->read_buf);                          kfree(head->read_buf);
2556                          kfree(head);                          kfree(head);
# Line 2638  int ccs_open_control(const u8 type, stru Line 2559  int ccs_open_control(const u8 type, stru
2559          }          }
2560          if (type != CCS_QUERY &&          if (type != CCS_QUERY &&
2561              type != CCS_GRANTLOG && type != CCS_REJECTLOG)              type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2562                  head->reader_idx = ccs_read_lock();                  head->reader_idx = ccs_lock();
2563          file->private_data = head;          file->private_data = head;
2564          /*          /*
2565           * 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 2691  int ccs_read_control(struct file *file, Line 2612  int ccs_read_control(struct file *file,
2612          int len = 0;          int len = 0;
2613          struct ccs_io_buffer *head = file->private_data;          struct ccs_io_buffer *head = file->private_data;
2614          char *cp;          char *cp;
2615            int idx;
2616          if (!head->read)          if (!head->read)
2617                  return -ENOSYS;                  return -ENOSYS;
2618          if (!access_ok(VERIFY_WRITE, buffer, buffer_len))          if (!access_ok(VERIFY_WRITE, buffer, buffer_len))
2619                  return -EFAULT;                  return -EFAULT;
2620          if (mutex_lock_interruptible(&head->io_sem))          if (mutex_lock_interruptible(&head->io_sem))
2621                  return -EINTR;                  return -EINTR;
2622            idx = ccs_read_lock();
2623          while (1) {          while (1) {
2624                  /* Call the policy handler. */                  /* Call the policy handler. */
2625                  head->read(head);                  head->read(head);
# Line 2705  int ccs_read_control(struct file *file, Line 2628  int ccs_read_control(struct file *file,
2628                  if (len || head->poll || head->read_eof)                  if (len || head->poll || head->read_eof)
2629                          break;                          break;
2630                  len = head->readbuf_size * 2;                  len = head->readbuf_size * 2;
2631                  cp = kzalloc(len, GFP_KERNEL);                  cp = kzalloc(len, CCS_GFP_FLAGS);
2632                  if (!cp) {                  if (!cp) {
2633                          len = -ENOMEM;                          len = -ENOMEM;
2634                          goto out;                          goto out;
# Line 2727  int ccs_read_control(struct file *file, Line 2650  int ccs_read_control(struct file *file,
2650          head->read_avail -= len;          head->read_avail -= len;
2651          memmove(cp, cp + len, head->read_avail);          memmove(cp, cp + len, head->read_avail);
2652   out:   out:
2653            ccs_read_unlock(idx);
2654          mutex_unlock(&head->io_sem);          mutex_unlock(&head->io_sem);
2655          return len;          return len;
2656  }  }
# Line 2747  int ccs_write_control(struct file *file, Line 2671  int ccs_write_control(struct file *file,
2671          int error = buffer_len;          int error = buffer_len;
2672          int avail_len = buffer_len;          int avail_len = buffer_len;
2673          char *cp0 = head->write_buf;          char *cp0 = head->write_buf;
2674            int idx;
2675          if (!head->write)          if (!head->write)
2676                  return -ENOSYS;                  return -ENOSYS;
2677          if (!access_ok(VERIFY_READ, buffer, buffer_len))          if (!access_ok(VERIFY_READ, buffer, buffer_len))
2678                  return -EFAULT;                  return -EFAULT;
2679            if (mutex_lock_interruptible(&head->io_sem))
2680                    return -EINTR;
2681            idx = ccs_read_lock();
2682          /* Don't allow updating policies by non manager programs. */          /* Don't allow updating policies by non manager programs. */
2683          if (head->write != ccs_write_pid &&          if (head->write != ccs_write_pid &&
2684              head->write != ccs_write_domain_policy &&              head->write != ccs_write_domain_policy &&
2685              !ccs_is_policy_manager())              !ccs_is_policy_manager()) {
2686                    ccs_read_unlock(idx);
2687                    mutex_unlock(&head->io_sem);
2688                  return -EPERM;                  return -EPERM;
2689          if (mutex_lock_interruptible(&head->io_sem))          }
                 return -EINTR;  
2690          /* Read a line and dispatch it to the policy handler. */          /* Read a line and dispatch it to the policy handler. */
2691          while (avail_len > 0) {          while (avail_len > 0) {
2692                  char c;                  char c;
2693                  if (head->write_avail >= head->writebuf_size - 1) {                  if (head->write_avail >= head->writebuf_size - 1) {
2694                          const int len = head->writebuf_size * 2;                          const int len = head->writebuf_size * 2;
2695                          char *cp = kzalloc(len, GFP_KERNEL);                          char *cp = kzalloc(len, CCS_GFP_FLAGS);
2696                          if (!cp) {                          if (!cp) {
2697                                  error = -ENOMEM;                                  error = -ENOMEM;
2698                                  break;                                  break;
# Line 2788  int ccs_write_control(struct file *file, Line 2717  int ccs_write_control(struct file *file,
2717                  ccs_normalize_line(cp0);                  ccs_normalize_line(cp0);
2718                  head->write(head);                  head->write(head);
2719          }          }
2720            ccs_read_unlock(idx);
2721          mutex_unlock(&head->io_sem);          mutex_unlock(&head->io_sem);
2722          return error;          return error;
2723  }  }
# Line 2811  int ccs_close_control(struct file *file) Line 2741  int ccs_close_control(struct file *file)
2741                  atomic_dec(&ccs_query_observers);                  atomic_dec(&ccs_query_observers);
2742          if (type != CCS_QUERY &&          if (type != CCS_QUERY &&
2743              type != CCS_GRANTLOG && type != CCS_REJECTLOG)              type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2744                  ccs_read_unlock(head->reader_idx);                  ccs_unlock(head->reader_idx);
2745          /* Release memory used for policy I/O. */          /* Release memory used for policy I/O. */
2746          kfree(head->read_buf);          kfree(head->read_buf);
2747          head->read_buf = NULL;          head->read_buf = NULL;
# Line 2824  int ccs_close_control(struct file *file) Line 2754  int ccs_close_control(struct file *file)
2754                  ccs_run_gc();                  ccs_run_gc();
2755          return 0;          return 0;
2756  }  }
2757    
2758    void __init ccs_policy_io_init(void)
2759    {
2760            ccsecurity_ops.check_profile = ccs_check_profile;
2761    }

Legend:
Removed from v.3069  
changed lines
  Added in v.3561

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