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

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

branches/ccs-patch/security/ccsecurity/policy_io.c revision 3780 by kumaneko, Thu Jun 24 08:50:05 2010 UTC trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c revision 3892 by kumaneko, Tue Aug 10 10:42:21 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+   2010/06/04   * Version: 1.8.0-pre   2010/08/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 13  Line 13 
13  #include "internal.h"  #include "internal.h"
14    
15  static struct ccs_profile ccs_default_profile = {  static struct ccs_profile ccs_default_profile = {
         .learning = &ccs_default_profile.preference,  
         .permissive = &ccs_default_profile.preference,  
         .enforcing = &ccs_default_profile.preference,  
         .audit = &ccs_default_profile.preference,  
16  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
17          .preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,          .preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,
18          .preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,          .preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,
# Line 24  static struct ccs_profile ccs_default_pr Line 20  static struct ccs_profile ccs_default_pr
20          .preference.audit_task_info = true,          .preference.audit_task_info = true,
21          .preference.audit_path_info = true,          .preference.audit_path_info = true,
22          .preference.enforcing_penalty = 0,          .preference.enforcing_penalty = 0,
         .preference.enforcing_verbose = true,  
23          .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,          .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,
         .preference.learning_verbose = false,  
24          .preference.learning_exec_realpath = true,          .preference.learning_exec_realpath = true,
25          .preference.learning_exec_argv0 = true,          .preference.learning_exec_argv0 = true,
26          .preference.learning_symlink_target = true,          .preference.learning_symlink_target = true,
         .preference.permissive_verbose = true  
27  };  };
28    
29  /* Profile version. Currently only 20090903 is defined. */  /* Profile version. Currently only 20090903 is defined. */
# Line 40  static unsigned int ccs_profile_version; Line 33  static unsigned int ccs_profile_version;
33  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
34    
35  /* String table for functionality that takes 4 modes. */  /* String table for functionality that takes 4 modes. */
36  static const char *ccs_mode[CCS_CONFIG_MAX_MODE] = {  const char *ccs_mode[CCS_CONFIG_MAX_MODE] = {
37          [CCS_CONFIG_DISABLED] = "disabled",          [CCS_CONFIG_DISABLED] = "disabled",
38          [CCS_CONFIG_LEARNING] = "learning",          [CCS_CONFIG_LEARNING] = "learning",
39          [CCS_CONFIG_PERMISSIVE] = "permissive",          [CCS_CONFIG_PERMISSIVE] = "permissive",
# Line 71  static const char *ccs_mac_keywords[CCS_ Line 64  static const char *ccs_mac_keywords[CCS_
64          = "file::truncate",          = "file::truncate",
65          [CCS_MAC_FILE_SYMLINK]          [CCS_MAC_FILE_SYMLINK]
66          = "file::symlink",          = "file::symlink",
         [CCS_MAC_FILE_REWRITE]  
         = "file::rewrite",  
67          [CCS_MAC_FILE_MKBLOCK]          [CCS_MAC_FILE_MKBLOCK]
68          = "file::mkblock",          = "file::mkblock",
69          [CCS_MAC_FILE_MKCHAR]          [CCS_MAC_FILE_MKCHAR]
# Line 101  static const char *ccs_mac_keywords[CCS_ Line 92  static const char *ccs_mac_keywords[CCS_
92          = "file::transit",          = "file::transit",
93          [CCS_MAC_ENVIRON]          [CCS_MAC_ENVIRON]
94          = "misc::env",          = "misc::env",
         [CCS_MAC_NETWORK_UDP_BIND]  
         = "network::inet_udp_bind",  
         [CCS_MAC_NETWORK_UDP_CONNECT]  
         = "network::inet_udp_connect",  
95          [CCS_MAC_NETWORK_TCP_BIND]          [CCS_MAC_NETWORK_TCP_BIND]
96          = "network::inet_tcp_bind",          = "network::inet_tcp_bind",
97          [CCS_MAC_NETWORK_TCP_LISTEN]          [CCS_MAC_NETWORK_TCP_LISTEN]
# Line 113  static const char *ccs_mac_keywords[CCS_ Line 100  static const char *ccs_mac_keywords[CCS_
100          = "network::inet_tcp_connect",          = "network::inet_tcp_connect",
101          [CCS_MAC_NETWORK_TCP_ACCEPT]          [CCS_MAC_NETWORK_TCP_ACCEPT]
102          = "network::inet_tcp_accept",          = "network::inet_tcp_accept",
103            [CCS_MAC_NETWORK_UDP_BIND]
104            = "network::inet_udp_bind",
105            [CCS_MAC_NETWORK_UDP_SEND]
106            = "network::inet_udp_send",
107            [CCS_MAC_NETWORK_UDP_RECV]
108            = "network::inet_udp_recv",
109          [CCS_MAC_NETWORK_RAW_BIND]          [CCS_MAC_NETWORK_RAW_BIND]
110          = "network::inet_raw_bind",          = "network::inet_raw_bind",
111          [CCS_MAC_NETWORK_RAW_CONNECT]          [CCS_MAC_NETWORK_RAW_SEND]
112          = "network::inet_raw_connect",          = "network::inet_raw_send",
113            [CCS_MAC_NETWORK_RAW_RECV]
114            = "network::inet_raw_recv",
115          [CCS_MAC_SIGNAL]          [CCS_MAC_SIGNAL]
116          = "ipc::signal",          = "ipc::signal",
         [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE]  
         = "capability::inet_tcp_create",  
         [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN]  
         = "capability::inet_tcp_listen",  
         [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT]  
         = "capability::inet_tcp_connect",  
         [CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET]  
         = "capability::use_inet_udp",  
         [CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET]  
         = "capability::use_inet_ip",  
117          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
118          = "capability::use_route",          = "capability::use_route",
119          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
120          = "capability::use_packet",          = "capability::use_packet",
         [CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT]  
         = "capability::SYS_MOUNT",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT]  
         = "capability::SYS_UMOUNT",  
121          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
122          = "capability::SYS_REBOOT",          = "capability::SYS_REBOOT",
         [CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT]  
         = "capability::SYS_CHROOT",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_KILL]  
         = "capability::SYS_KILL",  
123          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
124          = "capability::SYS_VHANGUP",          = "capability::SYS_VHANGUP",
125          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
# Line 153  static const char *ccs_mac_keywords[CCS_ Line 130  static const char *ccs_mac_keywords[CCS_
130          = "capability::SYS_SETHOSTNAME",          = "capability::SYS_SETHOSTNAME",
131          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
132          = "capability::use_kernel_module",          = "capability::use_kernel_module",
         [CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO]  
         = "capability::create_fifo",  
         [CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV]  
         = "capability::create_block_dev",  
         [CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV]  
         = "capability::create_char_dev",  
         [CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET]  
         = "capability::create_unix_socket",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_LINK]  
         = "capability::SYS_LINK",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK]  
         = "capability::SYS_SYMLINK",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_RENAME]  
         = "capability::SYS_RENAME",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK]  
         = "capability::SYS_UNLINK",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD]  
         = "capability::SYS_CHMOD",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN]  
         = "capability::SYS_CHOWN",  
         [CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL]  
         = "capability::SYS_IOCTL",  
133          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
134          = "capability::SYS_KEXEC_LOAD",          = "capability::SYS_KEXEC_LOAD",
         [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]  
         = "capability::SYS_PIVOT_ROOT",  
135          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
136          = "capability::SYS_PTRACE",          = "capability::SYS_PTRACE",
         [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]  
         = "capability::conceal_mount",  
137          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
138           + CCS_MAC_CATEGORY_FILE] = "file",           + CCS_MAC_CATEGORY_FILE] = "file",
139          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
# Line 289  static void ccs_set_string(struct ccs_io Line 240  static void ccs_set_string(struct ccs_io
240                  head->r.w[head->r.w_pos++] = string;                  head->r.w[head->r.w_pos++] = string;
241                  ccs_flush(head);                  ccs_flush(head);
242          } else          } else
243                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
244  }  }
245    
246  /**  /**
# Line 310  void ccs_io_printf(struct ccs_io_buffer Line 261  void ccs_io_printf(struct ccs_io_buffer
261          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
262          va_end(args);          va_end(args);
263          if (pos + len >= head->readbuf_size) {          if (pos + len >= head->readbuf_size) {
264                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
265                  return;                  return;
266          }          }
267          head->r.avail += len;          head->r.avail += len;
# Line 350  static struct ccs_profile *ccs_assign_pr Line 301  static struct ccs_profile *ccs_assign_pr
301          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
302          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
303                  ptr = entry;                  ptr = entry;
                 ptr->audit = &ccs_default_profile.preference;  
                 ptr->learning = &ccs_default_profile.preference;  
                 ptr->permissive = &ccs_default_profile.preference;  
                 ptr->enforcing = &ccs_default_profile.preference;  
304                  ptr->default_config = CCS_CONFIG_DISABLED |                  ptr->default_config = CCS_CONFIG_DISABLED |
305                            CCS_CONFIG_VERBOSE |
306                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
307                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
308                         sizeof(ptr->config));                         sizeof(ptr->config));
# Line 387  static void ccs_check_profile(void) Line 335  static void ccs_check_profile(void)
335          if (ccs_profile_version != 20090903)          if (ccs_profile_version != 20090903)
336                  panic("Profile version %u is not supported.\n",                  panic("Profile version %u is not supported.\n",
337                        ccs_profile_version);                        ccs_profile_version);
338          printk(KERN_INFO "CCSecurity: 1.7.2+   2010/06/04\n");          printk(KERN_INFO "CCSecurity: 1.8.0-pre   2010/08/01\n");
339          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
340  }  }
341    
# Line 440  static void ccs_set_uint(unsigned int *i Line 388  static void ccs_set_uint(unsigned int *i
388  }  }
389    
390  static void ccs_set_pref(const char *name, const char *value,  static void ccs_set_pref(const char *name, const char *value,
391                           const bool use_default, struct ccs_profile *profile)                           struct ccs_profile *profile)
392  {  {
         struct ccs_preference **pref;  
         bool *verbose;  
393          if (!strcmp(name, "audit")) {          if (!strcmp(name, "audit")) {
                 if (use_default) {  
                         pref = &profile->audit;  
                         goto set_default;  
                 }  
                 profile->audit = &profile->preference;  
394  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
395                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,
396                               "max_grant_log");                               "max_grant_log");
# Line 463  static void ccs_set_pref(const char *nam Line 404  static void ccs_set_pref(const char *nam
404                  return;                  return;
405          }          }
406          if (!strcmp(name, "enforcing")) {          if (!strcmp(name, "enforcing")) {
                 if (use_default) {  
                         pref = &profile->enforcing;  
                         goto set_default;  
                 }  
                 profile->enforcing = &profile->preference;  
407                  ccs_set_uint(&profile->preference.enforcing_penalty, value,                  ccs_set_uint(&profile->preference.enforcing_penalty, value,
408                               "penalty");                               "penalty");
409                  verbose = &profile->preference.enforcing_verbose;                  return;
                 goto set_verbose;  
         }  
         if (!strcmp(name, "permissive")) {  
                 if (use_default) {  
                         pref = &profile->permissive;  
                         goto set_default;  
                 }  
                 profile->permissive = &profile->preference;  
                 verbose = &profile->preference.permissive_verbose;  
                 goto set_verbose;  
410          }          }
411          if (!strcmp(name, "learning")) {          if (!strcmp(name, "learning")) {
                 if (use_default) {  
                         pref = &profile->learning;  
                         goto set_default;  
                 }  
                 profile->learning = &profile->preference;  
412                  ccs_set_uint(&profile->preference.learning_max_entry, value,                  ccs_set_uint(&profile->preference.learning_max_entry, value,
413                               "max_entry");                               "max_entry");
414                  ccs_set_bool(&profile->preference.learning_exec_realpath,                  ccs_set_bool(&profile->preference.learning_exec_realpath,
# Line 496  static void ccs_set_pref(const char *nam Line 417  static void ccs_set_pref(const char *nam
417                               "exec.argv0");                               "exec.argv0");
418                  ccs_set_bool(&profile->preference.learning_symlink_target,                  ccs_set_bool(&profile->preference.learning_symlink_target,
419                               value, "symlink.target");                               value, "symlink.target");
420                  verbose = &profile->preference.learning_verbose;                  return;
                 goto set_verbose;  
421          }          }
         return;  
  set_default:  
         *pref = &ccs_default_profile.preference;  
         return;  
  set_verbose:  
         ccs_set_bool(verbose, value, "verbose");  
422  }  }
423    
424  static int ccs_set_mode(char *name, const char *value, const bool use_default,  static int ccs_set_mode(char *name, const char *value,
425                          struct ccs_profile *profile)                          struct ccs_profile *profile)
426  {  {
427          u8 i;          u8 i;
# Line 531  static int ccs_set_mode(char *name, cons Line 445  static int ccs_set_mode(char *name, cons
445          } else {          } else {
446                  return -EINVAL;                  return -EINVAL;
447          }          }
448          if (use_default) {          if (strstr(value, "use_default")) {
449                  config = CCS_CONFIG_USE_DEFAULT;                  config = CCS_CONFIG_USE_DEFAULT;
450          } else {          } else {
451                  u8 mode;                  u8 mode;
# Line 542  static int ccs_set_mode(char *name, cons Line 456  static int ccs_set_mode(char *name, cons
456                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
457                                   */                                   */
458                                  config = (config & ~7) | mode;                                  config = (config & ~7) | mode;
 #ifdef CONFIG_CCSECURITY_AUDIT  
459                  if (config != CCS_CONFIG_USE_DEFAULT) {                  if (config != CCS_CONFIG_USE_DEFAULT) {
460                            switch (ccs_find_yesno(value, "verbose")) {
461                            case 1:
462                                    config |= CCS_CONFIG_VERBOSE;
463                                    break;
464                            case 0:
465                                    config &= ~CCS_CONFIG_VERBOSE;
466                                    break;
467                            }
468    #ifdef CONFIG_CCSECURITY_AUDIT
469                          switch (ccs_find_yesno(value, "grant_log")) {                          switch (ccs_find_yesno(value, "grant_log")) {
470                          case 1:                          case 1:
471                                  config |= CCS_CONFIG_WANT_GRANT_LOG;                                  config |= CCS_CONFIG_WANT_GRANT_LOG;
# Line 560  static int ccs_set_mode(char *name, cons Line 482  static int ccs_set_mode(char *name, cons
482                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;
483                                  break;                                  break;
484                          }                          }
                 }  
485  #endif  #endif
486                    }
487          }          }
488          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
489              + CCS_MAX_MAC_CATEGORY_INDEX)              + CCS_MAX_MAC_CATEGORY_INDEX)
# Line 581  static int ccs_set_mode(char *name, cons Line 503  static int ccs_set_mode(char *name, cons
503  static int ccs_write_profile(struct ccs_io_buffer *head)  static int ccs_write_profile(struct ccs_io_buffer *head)
504  {  {
505          char *data = head->write_buf;          char *data = head->write_buf;
506          bool use_default = false;          unsigned int i;
507          char *cp;          char *cp;
         int i;  
508          struct ccs_profile *profile;          struct ccs_profile *profile;
509          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
510                  return 0;                  return 0;
511          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
512          if (data == cp) {          if (*cp != '-')
513                  profile = &ccs_default_profile;                  return -EINVAL;
514          } else {          data = cp + 1;
515                  if (*cp != '-')          profile = ccs_assign_profile(i);
516                          return -EINVAL;          if (!profile)
517                  data = cp + 1;                  return -EINVAL;
                 profile = ccs_assign_profile(i);  
                 if (!profile)  
                         return -EINVAL;  
         }  
518          cp = strchr(data, '=');          cp = strchr(data, '=');
519          if (!cp)          if (!cp)
520                  return -EINVAL;                  return -EINVAL;
521          *cp++ = '\0';          *cp++ = '\0';
         if (profile != &ccs_default_profile)  
                 use_default = strstr(cp, "use_default") != NULL;  
522          if (ccs_str_starts(&data, "PREFERENCE::")) {          if (ccs_str_starts(&data, "PREFERENCE::")) {
523                  ccs_set_pref(data, cp, use_default, profile);                  ccs_set_pref(data, cp, profile);
524                  return 0;                  return 0;
525          }          }
         if (profile == &ccs_default_profile)  
                 return -EINVAL;  
526          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
527                  const struct ccs_path_info *old_comment = profile->comment;                  const struct ccs_path_info *old_comment = profile->comment;
528                  profile->comment = ccs_get_name(cp);                  profile->comment = ccs_get_name(cp);
529                  ccs_put_name(old_comment);                  ccs_put_name(old_comment);
530                  return 0;                  return 0;
531          }          }
532          return ccs_set_mode(data, cp, use_default, profile);          return ccs_set_mode(data, cp, profile);
533  }  }
534    
535  static void ccs_print_preference(struct ccs_io_buffer *head, const int idx)  static void ccs_print_preference(struct ccs_io_buffer *head, const int index)
536  {  {
537          struct ccs_preference *pref = &ccs_default_profile.preference;          struct ccs_profile *profile = ccs_profile_ptr[index];
538          const struct ccs_profile *profile = idx >= 0 ?          struct ccs_preference *pref = &profile->preference;
539                  ccs_profile_ptr[idx] : NULL;          ccs_io_printf(head, "%u-PREFERENCE::%s={ "
         char buffer[16] = "";  
         if (profile) {  
                 buffer[sizeof(buffer) - 1] = '\0';  
                 snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);  
         }  
         if (profile) {  
                 pref = profile->audit;  
                 if (pref == &ccs_default_profile.preference)  
                         goto skip0;  
         }  
         ccs_io_printf(head, "%sPREFERENCE::%s={ "  
540  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
541                        "max_grant_log=%u max_reject_log=%u "                        "max_grant_log=%u max_reject_log=%u "
542  #endif  #endif
543                        "task_info=%s path_info=%s }\n", buffer,                        "task_info=%s path_info=%s }\n", index,
544                        "audit",                        "audit",
545  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
546                        pref->audit_max_grant_log,                        pref->audit_max_grant_log,
# Line 646  static void ccs_print_preference(struct Line 548  static void ccs_print_preference(struct
548  #endif  #endif
549                        ccs_yesno(pref->audit_task_info),                        ccs_yesno(pref->audit_task_info),
550                        ccs_yesno(pref->audit_path_info));                        ccs_yesno(pref->audit_path_info));
551   skip0:          ccs_io_printf(head, "%u-PREFERENCE::%s={ "
552          if (profile) {                        "max_entry=%u exec.realpath=%s "
                 pref = profile->learning;  
                 if (pref == &ccs_default_profile.preference)  
                         goto skip1;  
         }  
         ccs_io_printf(head, "%sPREFERENCE::%s={ "  
                       "verbose=%s max_entry=%u exec.realpath=%s "  
553                        "exec.argv0=%s symlink.target=%s }\n",                        "exec.argv0=%s symlink.target=%s }\n",
554                        buffer, "learning",                        index, "learning",
                       ccs_yesno(pref->learning_verbose),  
555                        pref->learning_max_entry,                        pref->learning_max_entry,
556                        ccs_yesno(pref->learning_exec_realpath),                        ccs_yesno(pref->learning_exec_realpath),
557                        ccs_yesno(pref->learning_exec_argv0),                        ccs_yesno(pref->learning_exec_argv0),
558                        ccs_yesno(pref->learning_symlink_target));                        ccs_yesno(pref->learning_symlink_target));
559   skip1:          ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index,
560          if (profile) {                        "enforcing", pref->enforcing_penalty);
                 pref = profile->permissive;  
                 if (pref == &ccs_default_profile.preference)  
                         goto skip2;  
         }  
         ccs_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",  
                       buffer, "permissive",  
                       ccs_yesno(pref->permissive_verbose));  
  skip2:  
         if (profile) {  
                 pref = profile->enforcing;  
                 if (pref == &ccs_default_profile.preference)  
                         return;  
         }  
         ccs_io_printf(head, "%sPREFERENCE::%s={ verbose=%s "  
                       "penalty=%u }\n", buffer, "enforcing",  
                       ccs_yesno(pref->enforcing_verbose),  
                       pref->enforcing_penalty);  
561  }  }
562    
563  static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)  static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)
564  {  {
565          ccs_io_printf(head, "={ mode=%s", ccs_mode[config & 3]);          ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3],
566                          ccs_yesno(config & CCS_CONFIG_VERBOSE));
567  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
568          ccs_io_printf(head, " grant_log=%s reject_log=%s",          ccs_io_printf(head, " grant_log=%s reject_log=%s",
569                        ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),                        ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
# Line 708  static void ccs_read_profile(struct ccs_ Line 587  static void ccs_read_profile(struct ccs_
587          switch (head->r.step) {          switch (head->r.step) {
588          case 0:          case 0:
589                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
                 ccs_print_preference(head, -1);  
590                  head->r.step++;                  head->r.step++;
591                  break;                  break;
592          case 1:          case 1:
# Line 764  static void ccs_read_profile(struct ccs_ Line 642  static void ccs_read_profile(struct ccs_
642                  goto next;                  goto next;
643  }  }
644    
645  static bool ccs_same_manager_entry(const struct ccs_acl_head *a,  static bool ccs_same_manager(const struct ccs_acl_head *a,
646                                     const struct ccs_acl_head *b)                               const struct ccs_acl_head *b)
647  {  {
648          return container_of(a, struct ccs_manager, head)->manager          return container_of(a, struct ccs_manager, head)->manager
649                  == container_of(b, struct ccs_manager, head)->manager;                  == container_of(b, struct ccs_manager, head)->manager;
# Line 796  static int ccs_update_manager_entry(cons Line 674  static int ccs_update_manager_entry(cons
674                  return error;                  return error;
675          error = ccs_update_policy(&e.head, sizeof(e), is_delete,          error = ccs_update_policy(&e.head, sizeof(e), is_delete,
676                                    &ccs_policy_list[CCS_ID_MANAGER],                                    &ccs_policy_list[CCS_ID_MANAGER],
677                                    ccs_same_manager_entry);                                    ccs_same_manager);
678          ccs_put_name(e.manager);          ccs_put_name(e.manager);
679          return error;          return error;
680  }  }
# Line 928  static bool ccs_select_one(struct ccs_io Line 806  static bool ccs_select_one(struct ccs_io
806          unsigned int pid;          unsigned int pid;
807          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
808          bool global_pid = false;          bool global_pid = false;
809          if (!strcmp(data, "allow_execute")) {          if (!strcmp(data, "execute")) {
810                  head->r.print_execute_only = true;                  head->r.print_execute_only = true;
811                  return true;                  return true;
812          }          }
# Line 959  static bool ccs_select_one(struct ccs_io Line 837  static bool ccs_select_one(struct ccs_io
837                  return true; /* Do nothing if open(O_WRONLY). */                  return true; /* Do nothing if open(O_WRONLY). */
838          memset(&head->r, 0, sizeof(head->r));          memset(&head->r, 0, sizeof(head->r));
839          head->r.print_this_domain_only = true;          head->r.print_this_domain_only = true;
840          head->r.eof = !domain;          if (domain)
841          head->r.domain = &domain->list;                  head->r.domain = &domain->list;
842            else
843                    head->r.eof = true;
844          ccs_io_printf(head, "# select %s\n", data);          ccs_io_printf(head, "# select %s\n", data);
845          if (domain && domain->is_deleted)          if (domain && domain->is_deleted)
846                  ccs_set_string(head, "# This is a deleted domain.\n");                  ccs_set_string(head, "# This is a deleted domain.\n");
# Line 974  static int ccs_write_domain2(char *data, Line 854  static int ccs_write_domain2(char *data,
854                  const char *keyword;                  const char *keyword;
855                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (char *, struct ccs_domain_info *,
856                                struct ccs_condition *, const bool);                                struct ccs_condition *, const bool);
857          } ccs_callback[5] = {          } ccs_callback[4] = {
858                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },                  { "network ", ccs_write_network },
859                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },                  { "misc ", ccs_write_misc },
860                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },                  { "capability ", ccs_write_capability },
861                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },                  { "ipc ", ccs_write_ipc },
                 { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }  
862          };          };
863          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
864                        const bool) = ccs_write_file;                        const bool) = ccs_write_file;
# Line 992  static int ccs_write_domain2(char *data, Line 871  static int ccs_write_domain2(char *data,
871                  if (!cond)                  if (!cond)
872                          return -EINVAL;                          return -EINVAL;
873          }          }
874          for (i = 0; i < 5; i++) {          for (i = 0; i < 4; i++) {
875                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))
876                          continue;                          continue;
877                  write = ccs_callback[i].write;                  write = ccs_callback[i].write;
# Line 1006  static int ccs_write_domain2(char *data, Line 885  static int ccs_write_domain2(char *data,
885    
886  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
887          [CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n",          [CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n",
         [CCS_DIF_IGNORE_GLOBAL] = CCS_KEYWORD_IGNORE_GLOBAL "\n",  
         [CCS_DIF_IGNORE_GLOBAL_ALLOW_READ]  
         = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n",  
         [CCS_DIF_IGNORE_GLOBAL_ALLOW_ENV]  
         = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n",  
888          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"
889  };  };
890                    
# Line 1044  static int ccs_write_domain(struct ccs_i Line 918  static int ccs_write_domain(struct ccs_i
918                  else if (is_select)                  else if (is_select)
919                          domain = ccs_find_domain(data);                          domain = ccs_find_domain(data);
920                  else                  else
921                          domain = ccs_assign_domain(data, 0);                          domain = ccs_assign_domain(data, 0, 0);
922                  head->w.domain = domain;                  head->w.domain = domain;
923                  return 0;                  return 0;
924          }          }
# Line 1057  static int ccs_write_domain(struct ccs_i Line 931  static int ccs_write_domain(struct ccs_i
931                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
932                  return 0;                  return 0;
933          }          }
934            if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1
935                && profile < CCS_MAX_ACL_GROUPS) {
936                    domain->group = (u8) profile;
937                    return 0;
938            }
939          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
940                  const char *cp = ccs_dif[profile];                  const char *cp = ccs_dif[profile];
941                  if (strncmp(data, cp, strlen(cp) - 1))                  if (strncmp(data, cp, strlen(cp) - 1))
# Line 1301  static u8 ccs_fns(const u8 perm, u8 bit) Line 1180  static u8 ccs_fns(const u8 perm, u8 bit)
1180          return bit;          return bit;
1181  }  }
1182    
1183    static void ccs_set_group(struct ccs_io_buffer *head)
1184    {
1185            if (head->type == CCS_EXCEPTIONPOLICY)
1186                    ccs_io_printf(head, "acl_group %u ", head->r.group_index);
1187    }
1188    
1189  /**  /**
1190   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1191   *   *
# Line 1332  static bool ccs_print_entry(struct ccs_i Line 1217  static bool ccs_print_entry(struct ccs_i
1217                          if (head->r.print_execute_only &&                          if (head->r.print_execute_only &&
1218                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)
1219                                  continue;                                  continue;
                         /* Print "read/write" instead of "read" and "write". */  
                         if ((bit == CCS_TYPE_READ || bit == CCS_TYPE_WRITE)  
                             && (perm & (1 << CCS_TYPE_READ_WRITE)))  
                                 continue;  
1220                          break;                          break;
1221                  }                  }
1222                  if (bit >= CCS_MAX_PATH_OPERATION)                  if (bit >= CCS_MAX_PATH_OPERATION)
1223                          goto done;                          goto done;
1224                  ccs_io_printf(head, "allow_%s", ccs_path_keyword[bit]);                  ccs_set_group(head);
1225                    ccs_set_string(head, "file ");
1226                    ccs_set_string(head, ccs_path_keyword[bit]);
1227                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1228          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||
1229                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1230                  struct ccs_execute_handler *ptr                  struct ccs_execute_handler *ptr
1231                          = container_of(acl, typeof(*ptr), head);                          = container_of(acl, typeof(*ptr), head);
1232                    ccs_set_group(head);
1233                  ccs_io_printf(head, "%s ",                  ccs_io_printf(head, "%s ",
1234                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?
1235                                CCS_KEYWORD_EXECUTE_HANDLER :                                CCS_KEYWORD_EXECUTE_HANDLER :
# Line 1359  static bool ccs_print_entry(struct ccs_i Line 1243  static bool ccs_print_entry(struct ccs_i
1243                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1244                  if (bit >= CCS_MAX_MKDEV_OPERATION)                  if (bit >= CCS_MAX_MKDEV_OPERATION)
1245                          goto done;                          goto done;
1246                  ccs_io_printf(head, "allow_%s", ccs_mkdev_keyword[bit]);                  ccs_set_group(head);
1247                    ccs_set_string(head, "file ");
1248                    ccs_set_string(head, ccs_mkdev_keyword[bit]);
1249                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1250                  ccs_print_number_union(head, &ptr->mode);                  ccs_print_number_union(head, &ptr->mode);
1251                  ccs_print_number_union(head, &ptr->major);                  ccs_print_number_union(head, &ptr->major);
# Line 1370  static bool ccs_print_entry(struct ccs_i Line 1256  static bool ccs_print_entry(struct ccs_i
1256                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1257                  if (bit >= CCS_MAX_PATH2_OPERATION)                  if (bit >= CCS_MAX_PATH2_OPERATION)
1258                          goto done;                          goto done;
1259                  ccs_io_printf(head, "allow_%s", ccs_path2_keyword[bit]);                  ccs_set_group(head);
1260                    ccs_set_string(head, "file ");
1261                    ccs_set_string(head, ccs_path2_keyword[bit]);
1262                  ccs_print_name_union(head, &ptr->name1);                  ccs_print_name_union(head, &ptr->name1);
1263                  ccs_print_name_union(head, &ptr->name2);                  ccs_print_name_union(head, &ptr->name2);
1264          } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {          } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
# Line 1379  static bool ccs_print_entry(struct ccs_i Line 1267  static bool ccs_print_entry(struct ccs_i
1267                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1268                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)
1269                          goto done;                          goto done;
1270                  ccs_io_printf(head, "allow_%s",                  ccs_set_group(head);
1271                                ccs_path_number_keyword[bit]);                  ccs_set_string(head, "file ");
1272                    ccs_set_string(head, ccs_path_number_keyword[bit]);
1273                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1274                  ccs_print_number_union(head, &ptr->number);                  ccs_print_number_union(head, &ptr->number);
1275          } else if (acl_type == CCS_TYPE_ENV_ACL) {          } else if (acl_type == CCS_TYPE_ENV_ACL) {
1276                  struct ccs_env_acl *ptr =                  struct ccs_env_acl *ptr =
1277                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1278                  ccs_set_string(head, CCS_KEYWORD_ALLOW_ENV);                  ccs_set_group(head);
1279                    ccs_set_string(head, "misc env ");
1280                  ccs_set_string(head, ptr->env->name);                  ccs_set_string(head, ptr->env->name);
1281          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1282                  struct ccs_capability_acl *ptr =                  struct ccs_capability_acl *ptr =
1283                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1284                  ccs_set_string(head, CCS_KEYWORD_ALLOW_CAPABILITY);                  ccs_set_group(head);
1285                    ccs_set_string(head, "capability ");
1286                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));
1287          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1288                  struct ccs_ip_network_acl *ptr =                  struct ccs_ip_network_acl *ptr =
# Line 1399  static bool ccs_print_entry(struct ccs_i Line 1290  static bool ccs_print_entry(struct ccs_i
1290                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1291                  if (bit >= CCS_MAX_NETWORK_OPERATION)                  if (bit >= CCS_MAX_NETWORK_OPERATION)
1292                          goto done;                          goto done;
1293                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",                  ccs_set_group(head);
1294                                ccs_net_keyword[bit]);                  ccs_set_string(head, "network ");
1295                    ccs_set_string(head, ccs_net_protocol_keyword[ptr->protocol]);
1296                    ccs_set_space(head);
1297                    ccs_set_string(head, ccs_net_keyword[bit]);
1298                    ccs_set_space(head);
1299                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1300                          char buf[128];                          char buf[128];
1301                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
# Line 1423  static bool ccs_print_entry(struct ccs_i Line 1318  static bool ccs_print_entry(struct ccs_i
1318          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1319                  struct ccs_signal_acl *ptr =                  struct ccs_signal_acl *ptr =
1320                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1321                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u ", ptr->sig);                  ccs_set_group(head);
1322                    ccs_set_string(head, "ipc signal ");
1323                    ccs_io_printf(head, "%u ", ptr->sig);
1324                  ccs_set_string(head, ptr->domainname->name);                  ccs_set_string(head, ptr->domainname->name);
1325          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
1326                  struct ccs_mount_acl *ptr =                  struct ccs_mount_acl *ptr =
1327                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1328                  ccs_io_printf(head, "allow_mount");                  ccs_set_group(head);
1329                    ccs_io_printf(head, "file mount");
1330                  ccs_print_name_union(head, &ptr->dev_name);                  ccs_print_name_union(head, &ptr->dev_name);
1331                  ccs_print_name_union(head, &ptr->dir_name);                  ccs_print_name_union(head, &ptr->dir_name);
1332                  ccs_print_name_union(head, &ptr->fs_type);                  ccs_print_name_union(head, &ptr->fs_type);
# Line 1508  static void ccs_read_domain(struct ccs_i Line 1406  static void ccs_read_domain(struct ccs_i
1406                          ccs_set_lf(head);                          ccs_set_lf(head);
1407                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",
1408                                        domain->profile);                                        domain->profile);
1409                            ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",
1410                                          domain->group);
1411                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1412                                  if (domain->flags[i])                                  if (domain->flags[i])
1413                                          ccs_set_string(head, ccs_dif[i]);                                          ccs_set_string(head, ccs_dif[i]);
# Line 1702  static int ccs_write_exception(struct cc Line 1602  static int ccs_write_exception(struct cc
1602          static const struct {          static const struct {
1603                  const char *keyword;                  const char *keyword;
1604                  int (*write) (char *, const bool);                  int (*write) (char *, const bool);
1605          } ccs_callback[4] = {          } ccs_callback[3] = {
1606                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1607                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
                 { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },  
1608                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1609          };          };
1610          for (i = 0; i < 4; i++) {          for (i = 0; i < 3; i++)
1611                  if (ccs_str_starts(&data, ccs_callback[i].keyword))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1612                          return ccs_callback[i].write(data, is_delete);                          return ccs_callback[i].write(data, is_delete);
1613          }          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) {  
1614                  if (ccs_str_starts(&data, ccs_transition_type[i]))                  if (ccs_str_starts(&data, ccs_transition_type[i]))
1615                          return ccs_write_transition_control(data, is_delete,                          return ccs_write_transition_control(data, is_delete,
1616                                                              i);                                                              i);
1617          }          for (i = 0; i < CCS_MAX_GROUP; i++)
         for (i = 0; i < CCS_MAX_GROUP; i++) {  
1618                  if (ccs_str_starts(&data, ccs_group_name[i]))                  if (ccs_str_starts(&data, ccs_group_name[i]))
1619                          return ccs_write_group(data, is_delete, i);                          return ccs_write_group(data, is_delete, i);
1620            if (ccs_str_starts(&data, "acl_group ")) {
1621                    unsigned int group;
1622                    if (sscanf(data, "%u", &group) == 1 &&
1623                        group < CCS_MAX_ACL_GROUPS) {
1624                            data = strchr(data, ' ');
1625                            if (data)
1626                                    return ccs_write_domain2(data + 1,
1627                                                             &ccs_acl_group[group],
1628                                                             is_delete);
1629                    }
1630          }          }
1631          return ccs_write_domain2(data, &ccs_global_domain, is_delete);          return -EINVAL;
1632  }  }
1633    
1634  /**  /**
# Line 1832  static bool ccs_read_policy(struct ccs_i Line 1739  static bool ccs_read_policy(struct ccs_i
1739                                  ccs_set_string(head, ptr->pattern->name);                                  ccs_set_string(head, ptr->pattern->name);
1740                          }                          }
1741                          break;                          break;
                 case CCS_ID_NO_REWRITE:  
                         {  
                                 struct ccs_no_rewrite *ptr =  
                                         container_of(acl, typeof(*ptr), head);  
                                 ccs_set_string(head, CCS_KEYWORD_DENY_REWRITE);  
                                 ccs_set_string(head, ptr->pattern->name);  
                         }  
                         break;  
1742                  case CCS_ID_RESERVEDPORT:                  case CCS_ID_RESERVEDPORT:
1743                          {                          {
1744                                  struct ccs_reserved *ptr =                                  struct ccs_reserved *ptr =
# Line 1883  static void ccs_read_exception(struct cc Line 1782  static void ccs_read_exception(struct cc
1782                  head->r.step++;                  head->r.step++;
1783          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
1784                  return;                  return;
1785          head->r.eof = ccs_read_domain2(head, &ccs_global_domain);          while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
1786                   + CCS_MAX_ACL_GROUPS) {
1787                    head->r.group_index = head->r.step - CCS_MAX_POLICY
1788                            - CCS_MAX_GROUP;
1789                    if (!ccs_read_domain2(head,
1790                                          &ccs_acl_group[head->r.group_index]))
1791                            return;
1792                    head->r.step++;
1793            }
1794            head->r.eof = true;
1795  }  }
1796    
1797  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
# Line 1893  static DECLARE_WAIT_QUEUE_HEAD(ccs_query Line 1801  static DECLARE_WAIT_QUEUE_HEAD(ccs_query
1801  static DEFINE_SPINLOCK(ccs_query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
1802    
1803  /* Structure for query. */  /* Structure for query. */
1804  struct ccs_query_entry {  struct ccs_query {
1805          struct list_head list;          struct list_head list;
1806          char *query;          char *query;
1807          int query_len;          int query_len;
# Line 1902  struct ccs_query_entry { Line 1810  struct ccs_query_entry {
1810          int answer;          int answer;
1811  };  };
1812    
1813  /* The list for "struct ccs_query_entry". */  /* The list for "struct ccs_query". */
1814  static LIST_HEAD(ccs_query_list);  static LIST_HEAD(ccs_query_list);
1815    
1816  /* Number of "struct file" referring /proc/ccs/query interface. */  /* Number of "struct file" referring /proc/ccs/query interface. */
# Line 1933  int ccs_supervisor(struct ccs_request_in Line 1841  int ccs_supervisor(struct ccs_request_in
1841          int pos;          int pos;
1842          int len;          int len;
1843          static unsigned int ccs_serial;          static unsigned int ccs_serial;
1844          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query *entry = NULL;
1845          bool quota_exceeded = false;          bool quota_exceeded = false;
1846          char *header;          char *header;
1847          struct ccs_domain_info * const domain = ccs_current_domain();          struct ccs_domain_info * const domain = ccs_current_domain();
# Line 1952  int ccs_supervisor(struct ccs_request_in Line 1860  int ccs_supervisor(struct ccs_request_in
1860                  header = ccs_init_log(&len, r);                  header = ccs_init_log(&len, r);
1861                  if (!header)                  if (!header)
1862                          return 0;                          return 0;
1863                  pref = ccs_profile(r->profile)->learning;                  pref = &ccs_profile(r->profile)->preference;
1864                  /* strstr() will return NULL if ordering is wrong. */                  /* strstr() will return NULL if ordering is wrong. */
1865                  if (r->param_type == CCS_TYPE_PATH_ACL &&                  if (r->param_type == CCS_TYPE_PATH_ACL &&
1866                      r->param.path.operation == CCS_TYPE_EXECUTE) {                      r->param.path.operation == CCS_TYPE_EXECUTE) {
# Line 2015  int ccs_supervisor(struct ccs_request_in Line 1923  int ccs_supervisor(struct ccs_request_in
1923                  int i;                  int i;
1924                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
1925                          return -EPERM;                          return -EPERM;
1926                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->preference.
1927                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
1928                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
1929                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2025  int ccs_supervisor(struct ccs_request_in Line 1933  int ccs_supervisor(struct ccs_request_in
1933          header = ccs_init_log(&len, r);          header = ccs_init_log(&len, r);
1934          if (!header)          if (!header)
1935                  goto out;                  goto out;
1936          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
1937          if (!ccs_query_entry)          if (!entry)
1938                  goto out;                  goto out;
1939          len = ccs_round2(len);          len = ccs_round2(len);
1940          ccs_query_entry->query = kzalloc(len, CCS_GFP_FLAGS);          entry->query = kzalloc(len, CCS_GFP_FLAGS);
1941          if (!ccs_query_entry->query)          if (!entry->query)
1942                  goto out;                  goto out;
         INIT_LIST_HEAD(&ccs_query_entry->list);  
1943          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1944          if (ccs_quota_for_query && ccs_query_memory_size + len +          if (ccs_quota_for_query && ccs_query_memory_size + len +
1945              sizeof(*ccs_query_entry) >= ccs_quota_for_query) {              sizeof(*entry) >= ccs_quota_for_query) {
1946                  quota_exceeded = true;                  quota_exceeded = true;
1947          } else {          } else {
1948                  ccs_query_memory_size += len + sizeof(*ccs_query_entry);                  ccs_query_memory_size += len + sizeof(*entry);
1949                  ccs_query_entry->serial = ccs_serial++;                  entry->serial = ccs_serial++;
1950          }          }
1951          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1952          if (quota_exceeded)          if (quota_exceeded)
1953                  goto out;                  goto out;
1954          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",          pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
1955                         ccs_query_entry->serial, r->retry, header);                         entry->serial, r->retry, header);
1956          kfree(header);          kfree(header);
1957          header = NULL;          header = NULL;
1958          va_start(args, fmt);          va_start(args, fmt);
1959          vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);          vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
1960          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;          entry->query_len = strlen(entry->query) + 1;
1961          va_end(args);          va_end(args);
1962          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1963          list_add_tail(&ccs_query_entry->list, &ccs_query_list);          list_add_tail(&entry->list, &ccs_query_list);
1964          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1965          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
1966          for (ccs_query_entry->timer = 0;          for (entry->timer = 0;
1967               atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;               atomic_read(&ccs_query_observers) && entry->timer < 100;
1968               ccs_query_entry->timer++) {               entry->timer++) {
1969                  wake_up(&ccs_query_wait);                  wake_up(&ccs_query_wait);
1970                  set_current_state(TASK_INTERRUPTIBLE);                  set_current_state(TASK_INTERRUPTIBLE);
1971                  schedule_timeout(HZ / 10);                  schedule_timeout(HZ / 10);
1972                  if (ccs_query_entry->answer)                  if (entry->answer)
1973                          break;                          break;
1974          }          }
1975          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1976          list_del(&ccs_query_entry->list);          list_del(&entry->list);
1977          ccs_query_memory_size -= len + sizeof(*ccs_query_entry);          ccs_query_memory_size -= len + sizeof(*entry);
1978          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1979          switch (ccs_query_entry->answer) {          switch (entry->answer) {
1980          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
1981                  error = CCS_RETRY_REQUEST;                  error = CCS_RETRY_REQUEST;
1982                  r->retry++;                  r->retry++;
# Line 2086  int ccs_supervisor(struct ccs_request_in Line 1993  int ccs_supervisor(struct ccs_request_in
1993                  break;                  break;
1994          }          }
1995   out:   out:
1996          if (ccs_query_entry)          if (entry)
1997                  kfree(ccs_query_entry->query);                  kfree(entry->query);
1998          kfree(ccs_query_entry);          kfree(entry);
1999          kfree(header);          kfree(header);
2000          return error;          return error;
2001  }  }
# Line 2111  static int ccs_poll_query(struct file *f Line 2018  static int ccs_poll_query(struct file *f
2018          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2019                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2020                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2021                          struct ccs_query_entry *ptr =                          struct ccs_query *ptr =
2022                                  list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, typeof(*ptr), list);
2023                          if (ptr->answer)                          if (ptr->answer)
2024                                  continue;                                  continue;
2025                          found = true;                          found = true;
# Line 2147  static void ccs_read_query(struct ccs_io Line 2054  static void ccs_read_query(struct ccs_io
2054          }          }
2055          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2056          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2057                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2058                  if (ptr->answer)                  if (ptr->answer)
2059                          continue;                          continue;
2060                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2167  static void ccs_read_query(struct ccs_io Line 2073  static void ccs_read_query(struct ccs_io
2073          pos = 0;          pos = 0;
2074          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2075          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2076                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2077                  if (ptr->answer)                  if (ptr->answer)
2078                          continue;                          continue;
2079                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2206  static int ccs_write_answer(struct ccs_i Line 2111  static int ccs_write_answer(struct ccs_i
2111          unsigned int answer;          unsigned int answer;
2112          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2113          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2114                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2115                  ptr->timer = 0;                  ptr->timer = 0;
2116          }          }
2117          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
# Line 2215  static int ccs_write_answer(struct ccs_i Line 2119  static int ccs_write_answer(struct ccs_i
2119                  return -EINVAL;                  return -EINVAL;
2120          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2121          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2122                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2123                  if (ptr->serial != serial)                  if (ptr->serial != serial)
2124                          continue;                          continue;
2125                  if (!ptr->answer)                  if (!ptr->answer)
# Line 2236  static void ccs_read_version(struct ccs_ Line 2139  static void ccs_read_version(struct ccs_
2139  {  {
2140          if (head->r.eof)          if (head->r.eof)
2141                  return;                  return;
2142          ccs_set_string(head, "1.7.2");          ccs_set_string(head, "1.8.0-pre");
2143          head->r.eof = true;          head->r.eof = true;
2144  }  }
2145    

Legend:
Removed from v.3780  
changed lines
  Added in v.3892

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