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

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 3780 by kumaneko, Thu Jun 24 08:50:05 2010 UTC revision 3872 by kumaneko, Sun Aug 1 02:11:31 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 974  static int ccs_write_domain2(char *data, Line 852  static int ccs_write_domain2(char *data,
852                  const char *keyword;                  const char *keyword;
853                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (char *, struct ccs_domain_info *,
854                                struct ccs_condition *, const bool);                                struct ccs_condition *, const bool);
855          } ccs_callback[5] = {          } ccs_callback[4] = {
856                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },                  { "network ", ccs_write_network },
857                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },                  { "misc ", ccs_write_misc },
858                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },                  { "capability ", ccs_write_capability },
859                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },                  { "ipc ", ccs_write_ipc },
                 { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }  
860          };          };
861          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
862                        const bool) = ccs_write_file;                        const bool) = ccs_write_file;
# Line 992  static int ccs_write_domain2(char *data, Line 869  static int ccs_write_domain2(char *data,
869                  if (!cond)                  if (!cond)
870                          return -EINVAL;                          return -EINVAL;
871          }          }
872          for (i = 0; i < 5; i++) {          for (i = 0; i < 4; i++) {
873                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))
874                          continue;                          continue;
875                  write = ccs_callback[i].write;                  write = ccs_callback[i].write;
# Line 1006  static int ccs_write_domain2(char *data, Line 883  static int ccs_write_domain2(char *data,
883    
884  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
885          [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",  
886          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"
887  };  };
888                    
# Line 1044  static int ccs_write_domain(struct ccs_i Line 916  static int ccs_write_domain(struct ccs_i
916                  else if (is_select)                  else if (is_select)
917                          domain = ccs_find_domain(data);                          domain = ccs_find_domain(data);
918                  else                  else
919                          domain = ccs_assign_domain(data, 0);                          domain = ccs_assign_domain(data, 0, 0);
920                  head->w.domain = domain;                  head->w.domain = domain;
921                  return 0;                  return 0;
922          }          }
# Line 1057  static int ccs_write_domain(struct ccs_i Line 929  static int ccs_write_domain(struct ccs_i
929                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
930                  return 0;                  return 0;
931          }          }
932            if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1
933                && profile < CCS_MAX_ACL_GROUPS) {
934                    domain->group = (u8) profile;
935                    return 0;
936            }
937          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
938                  const char *cp = ccs_dif[profile];                  const char *cp = ccs_dif[profile];
939                  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 1178  static u8 ccs_fns(const u8 perm, u8 bit)
1178          return bit;          return bit;
1179  }  }
1180    
1181    static void ccs_set_group(struct ccs_io_buffer *head)
1182    {
1183            if (head->type == CCS_EXCEPTIONPOLICY)
1184                    ccs_io_printf(head, "acl_group %u ", head->r.group_index);
1185    }
1186    
1187  /**  /**
1188   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1189   *   *
# Line 1332  static bool ccs_print_entry(struct ccs_i Line 1215  static bool ccs_print_entry(struct ccs_i
1215                          if (head->r.print_execute_only &&                          if (head->r.print_execute_only &&
1216                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)
1217                                  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;  
1218                          break;                          break;
1219                  }                  }
1220                  if (bit >= CCS_MAX_PATH_OPERATION)                  if (bit >= CCS_MAX_PATH_OPERATION)
1221                          goto done;                          goto done;
1222                  ccs_io_printf(head, "allow_%s", ccs_path_keyword[bit]);                  ccs_set_group(head);
1223                    ccs_set_string(head, "file ");
1224                    ccs_set_string(head, ccs_path_keyword[bit]);
1225                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1226          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||
1227                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1228                  struct ccs_execute_handler *ptr                  struct ccs_execute_handler *ptr
1229                          = container_of(acl, typeof(*ptr), head);                          = container_of(acl, typeof(*ptr), head);
1230                    ccs_set_group(head);
1231                  ccs_io_printf(head, "%s ",                  ccs_io_printf(head, "%s ",
1232                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?
1233                                CCS_KEYWORD_EXECUTE_HANDLER :                                CCS_KEYWORD_EXECUTE_HANDLER :
# Line 1359  static bool ccs_print_entry(struct ccs_i Line 1241  static bool ccs_print_entry(struct ccs_i
1241                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1242                  if (bit >= CCS_MAX_MKDEV_OPERATION)                  if (bit >= CCS_MAX_MKDEV_OPERATION)
1243                          goto done;                          goto done;
1244                  ccs_io_printf(head, "allow_%s", ccs_mkdev_keyword[bit]);                  ccs_set_group(head);
1245                    ccs_set_string(head, "file ");
1246                    ccs_set_string(head, ccs_mkdev_keyword[bit]);
1247                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1248                  ccs_print_number_union(head, &ptr->mode);                  ccs_print_number_union(head, &ptr->mode);
1249                  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 1254  static bool ccs_print_entry(struct ccs_i
1254                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1255                  if (bit >= CCS_MAX_PATH2_OPERATION)                  if (bit >= CCS_MAX_PATH2_OPERATION)
1256                          goto done;                          goto done;
1257                  ccs_io_printf(head, "allow_%s", ccs_path2_keyword[bit]);                  ccs_set_group(head);
1258                    ccs_set_string(head, "file ");
1259                    ccs_set_string(head, ccs_path2_keyword[bit]);
1260                  ccs_print_name_union(head, &ptr->name1);                  ccs_print_name_union(head, &ptr->name1);
1261                  ccs_print_name_union(head, &ptr->name2);                  ccs_print_name_union(head, &ptr->name2);
1262          } 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 1265  static bool ccs_print_entry(struct ccs_i
1265                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1266                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)
1267                          goto done;                          goto done;
1268                  ccs_io_printf(head, "allow_%s",                  ccs_set_group(head);
1269                                ccs_path_number_keyword[bit]);                  ccs_set_string(head, "file ");
1270                    ccs_set_string(head, ccs_path_number_keyword[bit]);
1271                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1272                  ccs_print_number_union(head, &ptr->number);                  ccs_print_number_union(head, &ptr->number);
1273          } else if (acl_type == CCS_TYPE_ENV_ACL) {          } else if (acl_type == CCS_TYPE_ENV_ACL) {
1274                  struct ccs_env_acl *ptr =                  struct ccs_env_acl *ptr =
1275                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1276                  ccs_set_string(head, CCS_KEYWORD_ALLOW_ENV);                  ccs_set_group(head);
1277                    ccs_set_string(head, "misc env ");
1278                  ccs_set_string(head, ptr->env->name);                  ccs_set_string(head, ptr->env->name);
1279          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1280                  struct ccs_capability_acl *ptr =                  struct ccs_capability_acl *ptr =
1281                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1282                  ccs_set_string(head, CCS_KEYWORD_ALLOW_CAPABILITY);                  ccs_set_group(head);
1283                    ccs_set_string(head, "capability ");
1284                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));
1285          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1286                  struct ccs_ip_network_acl *ptr =                  struct ccs_ip_network_acl *ptr =
# Line 1399  static bool ccs_print_entry(struct ccs_i Line 1288  static bool ccs_print_entry(struct ccs_i
1288                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1289                  if (bit >= CCS_MAX_NETWORK_OPERATION)                  if (bit >= CCS_MAX_NETWORK_OPERATION)
1290                          goto done;                          goto done;
1291                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",                  ccs_set_group(head);
1292                                ccs_net_keyword[bit]);                  ccs_set_string(head, "network ");
1293                    ccs_set_string(head, ccs_net_protocol_keyword[ptr->protocol]);
1294                    ccs_set_space(head);
1295                    ccs_set_string(head, ccs_net_keyword[bit]);
1296                    ccs_set_space(head);
1297                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1298                          char buf[128];                          char buf[128];
1299                  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 1316  static bool ccs_print_entry(struct ccs_i
1316          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1317                  struct ccs_signal_acl *ptr =                  struct ccs_signal_acl *ptr =
1318                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1319                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u ", ptr->sig);                  ccs_set_group(head);
1320                    ccs_set_string(head, "ipc signal ");
1321                    ccs_io_printf(head, "%u ", ptr->sig);
1322                  ccs_set_string(head, ptr->domainname->name);                  ccs_set_string(head, ptr->domainname->name);
1323          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
1324                  struct ccs_mount_acl *ptr =                  struct ccs_mount_acl *ptr =
1325                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1326                  ccs_io_printf(head, "allow_mount");                  ccs_set_group(head);
1327                    ccs_io_printf(head, "file mount");
1328                  ccs_print_name_union(head, &ptr->dev_name);                  ccs_print_name_union(head, &ptr->dev_name);
1329                  ccs_print_name_union(head, &ptr->dir_name);                  ccs_print_name_union(head, &ptr->dir_name);
1330                  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 1404  static void ccs_read_domain(struct ccs_i
1404                          ccs_set_lf(head);                          ccs_set_lf(head);
1405                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",
1406                                        domain->profile);                                        domain->profile);
1407                            ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",
1408                                          domain->group);
1409                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1410                                  if (domain->flags[i])                                  if (domain->flags[i])
1411                                          ccs_set_string(head, ccs_dif[i]);                                          ccs_set_string(head, ccs_dif[i]);
# Line 1702  static int ccs_write_exception(struct cc Line 1600  static int ccs_write_exception(struct cc
1600          static const struct {          static const struct {
1601                  const char *keyword;                  const char *keyword;
1602                  int (*write) (char *, const bool);                  int (*write) (char *, const bool);
1603          } ccs_callback[4] = {          } ccs_callback[3] = {
1604                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1605                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
                 { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },  
1606                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1607          };          };
1608          for (i = 0; i < 4; i++) {          for (i = 0; i < 3; i++)
1609                  if (ccs_str_starts(&data, ccs_callback[i].keyword))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1610                          return ccs_callback[i].write(data, is_delete);                          return ccs_callback[i].write(data, is_delete);
1611          }          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) {  
1612                  if (ccs_str_starts(&data, ccs_transition_type[i]))                  if (ccs_str_starts(&data, ccs_transition_type[i]))
1613                          return ccs_write_transition_control(data, is_delete,                          return ccs_write_transition_control(data, is_delete,
1614                                                              i);                                                              i);
1615          }          for (i = 0; i < CCS_MAX_GROUP; i++)
         for (i = 0; i < CCS_MAX_GROUP; i++) {  
1616                  if (ccs_str_starts(&data, ccs_group_name[i]))                  if (ccs_str_starts(&data, ccs_group_name[i]))
1617                          return ccs_write_group(data, is_delete, i);                          return ccs_write_group(data, is_delete, i);
1618            if (ccs_str_starts(&data, "acl_group ")) {
1619                    unsigned int group;
1620                    if (sscanf(data, "%u", &group) == 1 &&
1621                        group < CCS_MAX_ACL_GROUPS) {
1622                            data = strchr(data, ' ');
1623                            if (data)
1624                                    return ccs_write_domain2(data + 1,
1625                                                             &ccs_acl_group[group],
1626                                                             is_delete);
1627                    }
1628          }          }
1629          return ccs_write_domain2(data, &ccs_global_domain, is_delete);          return -EINVAL;
1630  }  }
1631    
1632  /**  /**
# Line 1832  static bool ccs_read_policy(struct ccs_i Line 1737  static bool ccs_read_policy(struct ccs_i
1737                                  ccs_set_string(head, ptr->pattern->name);                                  ccs_set_string(head, ptr->pattern->name);
1738                          }                          }
1739                          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;  
1740                  case CCS_ID_RESERVEDPORT:                  case CCS_ID_RESERVEDPORT:
1741                          {                          {
1742                                  struct ccs_reserved *ptr =                                  struct ccs_reserved *ptr =
# Line 1883  static void ccs_read_exception(struct cc Line 1780  static void ccs_read_exception(struct cc
1780                  head->r.step++;                  head->r.step++;
1781          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
1782                  return;                  return;
1783          head->r.eof = ccs_read_domain2(head, &ccs_global_domain);          while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
1784                   + CCS_MAX_ACL_GROUPS) {
1785                    head->r.group_index = head->r.step - CCS_MAX_POLICY
1786                            - CCS_MAX_GROUP;
1787                    if (!ccs_read_domain2(head,
1788                                          &ccs_acl_group[head->r.group_index]))
1789                            return;
1790                    head->r.step++;
1791            }
1792            head->r.eof = true;
1793  }  }
1794    
1795  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
# Line 1893  static DECLARE_WAIT_QUEUE_HEAD(ccs_query Line 1799  static DECLARE_WAIT_QUEUE_HEAD(ccs_query
1799  static DEFINE_SPINLOCK(ccs_query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
1800    
1801  /* Structure for query. */  /* Structure for query. */
1802  struct ccs_query_entry {  struct ccs_query {
1803          struct list_head list;          struct list_head list;
1804          char *query;          char *query;
1805          int query_len;          int query_len;
# Line 1902  struct ccs_query_entry { Line 1808  struct ccs_query_entry {
1808          int answer;          int answer;
1809  };  };
1810    
1811  /* The list for "struct ccs_query_entry". */  /* The list for "struct ccs_query". */
1812  static LIST_HEAD(ccs_query_list);  static LIST_HEAD(ccs_query_list);
1813    
1814  /* 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 1839  int ccs_supervisor(struct ccs_request_in
1839          int pos;          int pos;
1840          int len;          int len;
1841          static unsigned int ccs_serial;          static unsigned int ccs_serial;
1842          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query *entry = NULL;
1843          bool quota_exceeded = false;          bool quota_exceeded = false;
1844          char *header;          char *header;
1845          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 1858  int ccs_supervisor(struct ccs_request_in
1858                  header = ccs_init_log(&len, r);                  header = ccs_init_log(&len, r);
1859                  if (!header)                  if (!header)
1860                          return 0;                          return 0;
1861                  pref = ccs_profile(r->profile)->learning;                  pref = &ccs_profile(r->profile)->preference;
1862                  /* strstr() will return NULL if ordering is wrong. */                  /* strstr() will return NULL if ordering is wrong. */
1863                  if (r->param_type == CCS_TYPE_PATH_ACL &&                  if (r->param_type == CCS_TYPE_PATH_ACL &&
1864                      r->param.path.operation == CCS_TYPE_EXECUTE) {                      r->param.path.operation == CCS_TYPE_EXECUTE) {
# Line 2015  int ccs_supervisor(struct ccs_request_in Line 1921  int ccs_supervisor(struct ccs_request_in
1921                  int i;                  int i;
1922                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
1923                          return -EPERM;                          return -EPERM;
1924                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->preference.
1925                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
1926                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
1927                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2025  int ccs_supervisor(struct ccs_request_in Line 1931  int ccs_supervisor(struct ccs_request_in
1931          header = ccs_init_log(&len, r);          header = ccs_init_log(&len, r);
1932          if (!header)          if (!header)
1933                  goto out;                  goto out;
1934          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
1935          if (!ccs_query_entry)          if (!entry)
1936                  goto out;                  goto out;
1937          len = ccs_round2(len);          len = ccs_round2(len);
1938          ccs_query_entry->query = kzalloc(len, CCS_GFP_FLAGS);          entry->query = kzalloc(len, CCS_GFP_FLAGS);
1939          if (!ccs_query_entry->query)          if (!entry->query)
1940                  goto out;                  goto out;
         INIT_LIST_HEAD(&ccs_query_entry->list);  
1941          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1942          if (ccs_quota_for_query && ccs_query_memory_size + len +          if (ccs_quota_for_query && ccs_query_memory_size + len +
1943              sizeof(*ccs_query_entry) >= ccs_quota_for_query) {              sizeof(*entry) >= ccs_quota_for_query) {
1944                  quota_exceeded = true;                  quota_exceeded = true;
1945          } else {          } else {
1946                  ccs_query_memory_size += len + sizeof(*ccs_query_entry);                  ccs_query_memory_size += len + sizeof(*entry);
1947                  ccs_query_entry->serial = ccs_serial++;                  entry->serial = ccs_serial++;
1948          }          }
1949          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1950          if (quota_exceeded)          if (quota_exceeded)
1951                  goto out;                  goto out;
1952          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",          pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
1953                         ccs_query_entry->serial, r->retry, header);                         entry->serial, r->retry, header);
1954          kfree(header);          kfree(header);
1955          header = NULL;          header = NULL;
1956          va_start(args, fmt);          va_start(args, fmt);
1957          vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);          vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
1958          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;          entry->query_len = strlen(entry->query) + 1;
1959          va_end(args);          va_end(args);
1960          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1961          list_add_tail(&ccs_query_entry->list, &ccs_query_list);          list_add_tail(&entry->list, &ccs_query_list);
1962          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1963          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
1964          for (ccs_query_entry->timer = 0;          for (entry->timer = 0;
1965               atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;               atomic_read(&ccs_query_observers) && entry->timer < 100;
1966               ccs_query_entry->timer++) {               entry->timer++) {
1967                  wake_up(&ccs_query_wait);                  wake_up(&ccs_query_wait);
1968                  set_current_state(TASK_INTERRUPTIBLE);                  set_current_state(TASK_INTERRUPTIBLE);
1969                  schedule_timeout(HZ / 10);                  schedule_timeout(HZ / 10);
1970                  if (ccs_query_entry->answer)                  if (entry->answer)
1971                          break;                          break;
1972          }          }
1973          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1974          list_del(&ccs_query_entry->list);          list_del(&entry->list);
1975          ccs_query_memory_size -= len + sizeof(*ccs_query_entry);          ccs_query_memory_size -= len + sizeof(*entry);
1976          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1977          switch (ccs_query_entry->answer) {          switch (entry->answer) {
1978          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
1979                  error = CCS_RETRY_REQUEST;                  error = CCS_RETRY_REQUEST;
1980                  r->retry++;                  r->retry++;
# Line 2086  int ccs_supervisor(struct ccs_request_in Line 1991  int ccs_supervisor(struct ccs_request_in
1991                  break;                  break;
1992          }          }
1993   out:   out:
1994          if (ccs_query_entry)          if (entry)
1995                  kfree(ccs_query_entry->query);                  kfree(entry->query);
1996          kfree(ccs_query_entry);          kfree(entry);
1997          kfree(header);          kfree(header);
1998          return error;          return error;
1999  }  }
# Line 2111  static int ccs_poll_query(struct file *f Line 2016  static int ccs_poll_query(struct file *f
2016          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2017                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2018                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2019                          struct ccs_query_entry *ptr =                          struct ccs_query *ptr =
2020                                  list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, typeof(*ptr), list);
2021                          if (ptr->answer)                          if (ptr->answer)
2022                                  continue;                                  continue;
2023                          found = true;                          found = true;
# Line 2147  static void ccs_read_query(struct ccs_io Line 2052  static void ccs_read_query(struct ccs_io
2052          }          }
2053          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2054          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2055                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2056                  if (ptr->answer)                  if (ptr->answer)
2057                          continue;                          continue;
2058                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2167  static void ccs_read_query(struct ccs_io Line 2071  static void ccs_read_query(struct ccs_io
2071          pos = 0;          pos = 0;
2072          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2073          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2074                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2075                  if (ptr->answer)                  if (ptr->answer)
2076                          continue;                          continue;
2077                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2206  static int ccs_write_answer(struct ccs_i Line 2109  static int ccs_write_answer(struct ccs_i
2109          unsigned int answer;          unsigned int answer;
2110          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2111          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2112                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2113                  ptr->timer = 0;                  ptr->timer = 0;
2114          }          }
2115          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
# Line 2215  static int ccs_write_answer(struct ccs_i Line 2117  static int ccs_write_answer(struct ccs_i
2117                  return -EINVAL;                  return -EINVAL;
2118          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2119          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2120                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2121                  if (ptr->serial != serial)                  if (ptr->serial != serial)
2122                          continue;                          continue;
2123                  if (!ptr->answer)                  if (!ptr->answer)
# Line 2236  static void ccs_read_version(struct ccs_ Line 2137  static void ccs_read_version(struct ccs_
2137  {  {
2138          if (head->r.eof)          if (head->r.eof)
2139                  return;                  return;
2140          ccs_set_string(head, "1.7.2");          ccs_set_string(head, "1.8.0-pre");
2141          head->r.eof = true;          head->r.eof = true;
2142  }  }
2143    

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

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