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

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

revision 3079 by kumaneko, Fri Oct 2 06:23:24 2009 UTC revision 3627 by kumaneko, Wed May 5 04:55:52 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/10/01   * 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 961  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 1202  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 1220  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 1520  static bool ccs_print_signal_acl(struct Line 1539  static bool ccs_print_signal_acl(struct
1539   */   */
1540  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,  static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1541                                               const char *keyword,                                               const char *keyword,
1542                                               struct ccs_execute_handler_record *                                               struct ccs_execute_handler_record
1543                                               ptr)                                               *ptr)
1544  {  {
1545          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);          return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1546  }  }
# Line 1595  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 1612  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 1664  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 1800  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 1810  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 1823  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 2025  static struct ccs_condition *ccs_get_exe Line 2042  static struct ccs_condition *ccs_get_exe
2042          int len = 256;          int len = 256;
2043          char *realpath = NULL;          char *realpath = NULL;
2044          char *argv0 = NULL;          char *argv0 = NULL;
2045          const struct ccs_profile *profile = ccs_profile(ee->r.domain->profile);          const struct ccs_profile *profile = ccs_profile(ccs_current_domain()->
2046                                                            profile);
2047          if (profile->learning->learning_exec_realpath) {          if (profile->learning->learning_exec_realpath) {
2048                  struct file *file = ee->bprm->file;                  struct file *file = ee->bprm->file;
2049  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
# Line 2043  static struct ccs_condition *ccs_get_exe Line 2061  static struct ccs_condition *ccs_get_exe
2061                          len += strlen(argv0) + 16;                          len += strlen(argv0) + 16;
2062                  }                  }
2063          }          }
2064          buf = kmalloc(len, GFP_KERNEL);          buf = kmalloc(len, CCS_GFP_FLAGS);
2065          if (!buf) {          if (!buf) {
2066                  kfree(realpath);                  kfree(realpath);
2067                  return NULL;                  return NULL;
# Line 2089  static struct ccs_condition *ccs_get_sym Line 2107  static struct ccs_condition *ccs_get_sym
2107                  symlink = r->obj->symlink_target->name;                  symlink = r->obj->symlink_target->name;
2108                  len += strlen(symlink) + 18;                  len += strlen(symlink) + 18;
2109          }          }
2110          buf = kmalloc(len, GFP_KERNEL);          buf = kmalloc(len, CCS_GFP_FLAGS);
2111          if (!buf)          if (!buf)
2112                  return NULL;                  return NULL;
2113          snprintf(buf, len - 1, "if");          snprintf(buf, len - 1, "if");
# Line 2137  static atomic_t ccs_query_observers = AT Line 2155  static atomic_t ccs_query_observers = AT
2155   * @fmt:     The printf()'s format string, followed by parameters.   * @fmt:     The printf()'s format string, followed by parameters.
2156   *   *
2157   * Returns 0 if the supervisor decided to permit the access request which   * Returns 0 if the supervisor decided to permit the access request which
2158   * violated the policy in enforcing mode, 1 if the supervisor decided to   * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
2159   * retry the access request which violated the policy in enforcing mode,   * decided to retry the access request which violated the policy in enforcing
2160   * 0 if it is not in enforcing mode, -EPERM otherwise.   * mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2161   */   */
2162  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
2163  {  {
# Line 2151  int ccs_supervisor(struct ccs_request_in Line 2169  int ccs_supervisor(struct ccs_request_in
2169          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query_entry *ccs_query_entry = NULL;
2170          bool quota_exceeded = false;          bool quota_exceeded = false;
2171          char *header;          char *header;
2172          if (!r->domain)          struct ccs_domain_info * const domain = ccs_current_domain();
                 r->domain = ccs_current_domain();  
2173          switch (r->mode) {          switch (r->mode) {
2174                  char *buffer;                  char *buffer;
2175                  struct ccs_condition *cond;                  struct ccs_condition *cond;
# Line 2162  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 2178  int ccs_supervisor(struct ccs_request_in Line 2195  int ccs_supervisor(struct ccs_request_in
2195                          cond = ccs_get_condition(str);                          cond = ccs_get_condition(str);
2196                  } else                  } else
2197                          cond = NULL;                          cond = NULL;
2198                  ccs_write_domain_policy2(buffer, r->domain, cond, false);                  ccs_write_domain_policy2(buffer, domain, cond, false);
2199                  ccs_put_condition(cond);                  ccs_put_condition(cond);
2200                  kfree(buffer);                  kfree(buffer);
2201                  /* fall through */                  /* fall through */
# Line 2189  int ccs_supervisor(struct ccs_request_in Line 2206  int ccs_supervisor(struct ccs_request_in
2206                  int i;                  int i;
2207                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2208                          return -EPERM;                          return -EPERM;
2209                  for (i = 0; i < ccs_profile(r->domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->
2210                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
2211                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2212                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2202  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 2248  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 2288  static int ccs_poll_query(struct file *f Line 2305  static int ccs_poll_query(struct file *f
2305          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2306                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2307                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2308                          struct ccs_query_entry *ptr                          struct ccs_query_entry *ptr =
2309                                  = list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, struct ccs_query_entry, list);
2310                          if (ptr->answer)                          if (ptr->answer)
2311                                  continue;                                  continue;
2312                          found = true;                          found = true;
# Line 2339  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 2415  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 2446  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 2462  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 2522  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 2536  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 2545  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 2598  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 2612  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 2634  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 2654  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 2695  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 2718  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 2731  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.3079  
changed lines
  Added in v.3627

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