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

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 3912 by kumaneko, Sun Aug 22 14:15:32 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",
95          [CCS_MAC_NETWORK_UDP_BIND]          [CCS_MAC_NETWORK_INET_TCP_BIND]
         = "network::inet_udp_bind",  
         [CCS_MAC_NETWORK_UDP_CONNECT]  
         = "network::inet_udp_connect",  
         [CCS_MAC_NETWORK_TCP_BIND]  
96          = "network::inet_tcp_bind",          = "network::inet_tcp_bind",
97          [CCS_MAC_NETWORK_TCP_LISTEN]          [CCS_MAC_NETWORK_INET_TCP_LISTEN]
98          = "network::inet_tcp_listen",          = "network::inet_tcp_listen",
99          [CCS_MAC_NETWORK_TCP_CONNECT]          [CCS_MAC_NETWORK_INET_TCP_CONNECT]
100          = "network::inet_tcp_connect",          = "network::inet_tcp_connect",
101          [CCS_MAC_NETWORK_TCP_ACCEPT]          [CCS_MAC_NETWORK_INET_TCP_ACCEPT]
102          = "network::inet_tcp_accept",          = "network::inet_tcp_accept",
103          [CCS_MAC_NETWORK_RAW_BIND]          [CCS_MAC_NETWORK_INET_UDP_BIND]
104            = "network::inet_udp_bind",
105            [CCS_MAC_NETWORK_INET_UDP_SEND]
106            = "network::inet_udp_send",
107            [CCS_MAC_NETWORK_INET_UDP_RECV]
108            = "network::inet_udp_recv",
109            [CCS_MAC_NETWORK_INET_RAW_BIND]
110          = "network::inet_raw_bind",          = "network::inet_raw_bind",
111          [CCS_MAC_NETWORK_RAW_CONNECT]          [CCS_MAC_NETWORK_INET_RAW_SEND]
112          = "network::inet_raw_connect",          = "network::inet_raw_send",
113            [CCS_MAC_NETWORK_INET_RAW_RECV]
114            = "network::inet_raw_recv",
115            [CCS_MAC_NETWORK_UNIX_STREAM_BIND]
116            = "network::unix_stream_bind",
117            [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]
118            = "network::unix_stream_listen",
119            [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]
120            = "network::unix_stream_connect",
121            [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]
122            = "network::unix_stream_accept",
123            [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]
124            = "network::unix_dgram_bind",
125            [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]
126            = "network::unix_dgram_send",
127            [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]
128            = "network::unix_dgram_recv",
129            [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]
130            = "network::unix_seqpacket_bind",
131            [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]
132            = "network::unix_seqpacket_listen",
133            [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT]
134            = "network::unix_seqpacket_connect",
135            [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]
136            = "network::unix_seqpacket_accept",
137          [CCS_MAC_SIGNAL]          [CCS_MAC_SIGNAL]
138          = "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",  
139          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
140          = "capability::use_route",          = "capability::use_route",
141          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
142          = "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",  
143          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
144          = "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",  
145          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
146          = "capability::SYS_VHANGUP",          = "capability::SYS_VHANGUP",
147          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
# Line 153  static const char *ccs_mac_keywords[CCS_ Line 152  static const char *ccs_mac_keywords[CCS_
152          = "capability::SYS_SETHOSTNAME",          = "capability::SYS_SETHOSTNAME",
153          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
154          = "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",  
155          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
156          = "capability::SYS_KEXEC_LOAD",          = "capability::SYS_KEXEC_LOAD",
         [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]  
         = "capability::SYS_PIVOT_ROOT",  
157          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
158          = "capability::SYS_PTRACE",          = "capability::SYS_PTRACE",
         [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]  
         = "capability::conceal_mount",  
159          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
160           + CCS_MAC_CATEGORY_FILE] = "file",           + CCS_MAC_CATEGORY_FILE] = "file",
161          [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 262  static void ccs_set_string(struct ccs_io
262                  head->r.w[head->r.w_pos++] = string;                  head->r.w[head->r.w_pos++] = string;
263                  ccs_flush(head);                  ccs_flush(head);
264          } else          } else
265                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
266  }  }
267    
268  /**  /**
# Line 310  void ccs_io_printf(struct ccs_io_buffer Line 283  void ccs_io_printf(struct ccs_io_buffer
283          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
284          va_end(args);          va_end(args);
285          if (pos + len >= head->readbuf_size) {          if (pos + len >= head->readbuf_size) {
286                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
287                  return;                  return;
288          }          }
289          head->r.avail += len;          head->r.avail += len;
# Line 350  static struct ccs_profile *ccs_assign_pr Line 323  static struct ccs_profile *ccs_assign_pr
323          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
324          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
325                  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;  
326                  ptr->default_config = CCS_CONFIG_DISABLED |                  ptr->default_config = CCS_CONFIG_DISABLED |
327                            CCS_CONFIG_VERBOSE |
328                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
329                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
330                         sizeof(ptr->config));                         sizeof(ptr->config));
# Line 387  static void ccs_check_profile(void) Line 357  static void ccs_check_profile(void)
357          if (ccs_profile_version != 20090903)          if (ccs_profile_version != 20090903)
358                  panic("Profile version %u is not supported.\n",                  panic("Profile version %u is not supported.\n",
359                        ccs_profile_version);                        ccs_profile_version);
360          printk(KERN_INFO "CCSecurity: 1.7.2+   2010/06/04\n");          printk(KERN_INFO "CCSecurity: 1.8.0-pre   2010/08/01\n");
361          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
362  }  }
363    
# Line 440  static void ccs_set_uint(unsigned int *i Line 410  static void ccs_set_uint(unsigned int *i
410  }  }
411    
412  static void ccs_set_pref(const char *name, const char *value,  static void ccs_set_pref(const char *name, const char *value,
413                           const bool use_default, struct ccs_profile *profile)                           struct ccs_profile *profile)
414  {  {
         struct ccs_preference **pref;  
         bool *verbose;  
415          if (!strcmp(name, "audit")) {          if (!strcmp(name, "audit")) {
                 if (use_default) {  
                         pref = &profile->audit;  
                         goto set_default;  
                 }  
                 profile->audit = &profile->preference;  
416  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
417                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,
418                               "max_grant_log");                               "max_grant_log");
# Line 463  static void ccs_set_pref(const char *nam Line 426  static void ccs_set_pref(const char *nam
426                  return;                  return;
427          }          }
428          if (!strcmp(name, "enforcing")) {          if (!strcmp(name, "enforcing")) {
                 if (use_default) {  
                         pref = &profile->enforcing;  
                         goto set_default;  
                 }  
                 profile->enforcing = &profile->preference;  
429                  ccs_set_uint(&profile->preference.enforcing_penalty, value,                  ccs_set_uint(&profile->preference.enforcing_penalty, value,
430                               "penalty");                               "penalty");
431                  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;  
432          }          }
433          if (!strcmp(name, "learning")) {          if (!strcmp(name, "learning")) {
                 if (use_default) {  
                         pref = &profile->learning;  
                         goto set_default;  
                 }  
                 profile->learning = &profile->preference;  
434                  ccs_set_uint(&profile->preference.learning_max_entry, value,                  ccs_set_uint(&profile->preference.learning_max_entry, value,
435                               "max_entry");                               "max_entry");
436                  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 439  static void ccs_set_pref(const char *nam
439                               "exec.argv0");                               "exec.argv0");
440                  ccs_set_bool(&profile->preference.learning_symlink_target,                  ccs_set_bool(&profile->preference.learning_symlink_target,
441                               value, "symlink.target");                               value, "symlink.target");
442                  verbose = &profile->preference.learning_verbose;                  return;
                 goto set_verbose;  
443          }          }
         return;  
  set_default:  
         *pref = &ccs_default_profile.preference;  
         return;  
  set_verbose:  
         ccs_set_bool(verbose, value, "verbose");  
444  }  }
445    
446  static int ccs_set_mode(char *name, const char *value, const bool use_default,  static int ccs_set_mode(char *name, const char *value,
447                          struct ccs_profile *profile)                          struct ccs_profile *profile)
448  {  {
449          u8 i;          u8 i;
# Line 531  static int ccs_set_mode(char *name, cons Line 467  static int ccs_set_mode(char *name, cons
467          } else {          } else {
468                  return -EINVAL;                  return -EINVAL;
469          }          }
470          if (use_default) {          if (strstr(value, "use_default")) {
471                  config = CCS_CONFIG_USE_DEFAULT;                  config = CCS_CONFIG_USE_DEFAULT;
472          } else {          } else {
473                  u8 mode;                  u8 mode;
# Line 542  static int ccs_set_mode(char *name, cons Line 478  static int ccs_set_mode(char *name, cons
478                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
479                                   */                                   */
480                                  config = (config & ~7) | mode;                                  config = (config & ~7) | mode;
 #ifdef CONFIG_CCSECURITY_AUDIT  
481                  if (config != CCS_CONFIG_USE_DEFAULT) {                  if (config != CCS_CONFIG_USE_DEFAULT) {
482                            switch (ccs_find_yesno(value, "verbose")) {
483                            case 1:
484                                    config |= CCS_CONFIG_VERBOSE;
485                                    break;
486                            case 0:
487                                    config &= ~CCS_CONFIG_VERBOSE;
488                                    break;
489                            }
490    #ifdef CONFIG_CCSECURITY_AUDIT
491                          switch (ccs_find_yesno(value, "grant_log")) {                          switch (ccs_find_yesno(value, "grant_log")) {
492                          case 1:                          case 1:
493                                  config |= CCS_CONFIG_WANT_GRANT_LOG;                                  config |= CCS_CONFIG_WANT_GRANT_LOG;
# Line 560  static int ccs_set_mode(char *name, cons Line 504  static int ccs_set_mode(char *name, cons
504                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;
505                                  break;                                  break;
506                          }                          }
                 }  
507  #endif  #endif
508                    }
509          }          }
510          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
511              + CCS_MAX_MAC_CATEGORY_INDEX)              + CCS_MAX_MAC_CATEGORY_INDEX)
# Line 581  static int ccs_set_mode(char *name, cons Line 525  static int ccs_set_mode(char *name, cons
525  static int ccs_write_profile(struct ccs_io_buffer *head)  static int ccs_write_profile(struct ccs_io_buffer *head)
526  {  {
527          char *data = head->write_buf;          char *data = head->write_buf;
528          bool use_default = false;          unsigned int i;
529          char *cp;          char *cp;
         int i;  
530          struct ccs_profile *profile;          struct ccs_profile *profile;
531          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
532                  return 0;                  return 0;
533          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
534          if (data == cp) {          if (*cp != '-')
535                  profile = &ccs_default_profile;                  return -EINVAL;
536          } else {          data = cp + 1;
537                  if (*cp != '-')          profile = ccs_assign_profile(i);
538                          return -EINVAL;          if (!profile)
539                  data = cp + 1;                  return -EINVAL;
                 profile = ccs_assign_profile(i);  
                 if (!profile)  
                         return -EINVAL;  
         }  
540          cp = strchr(data, '=');          cp = strchr(data, '=');
541          if (!cp)          if (!cp)
542                  return -EINVAL;                  return -EINVAL;
543          *cp++ = '\0';          *cp++ = '\0';
         if (profile != &ccs_default_profile)  
                 use_default = strstr(cp, "use_default") != NULL;  
544          if (ccs_str_starts(&data, "PREFERENCE::")) {          if (ccs_str_starts(&data, "PREFERENCE::")) {
545                  ccs_set_pref(data, cp, use_default, profile);                  ccs_set_pref(data, cp, profile);
546                  return 0;                  return 0;
547          }          }
         if (profile == &ccs_default_profile)  
                 return -EINVAL;  
548          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
549                  const struct ccs_path_info *old_comment = profile->comment;                  const struct ccs_path_info *old_comment = profile->comment;
550                  profile->comment = ccs_get_name(cp);                  profile->comment = ccs_get_name(cp);
551                  ccs_put_name(old_comment);                  ccs_put_name(old_comment);
552                  return 0;                  return 0;
553          }          }
554          return ccs_set_mode(data, cp, use_default, profile);          return ccs_set_mode(data, cp, profile);
555  }  }
556    
557  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)
558  {  {
559          struct ccs_preference *pref = &ccs_default_profile.preference;          struct ccs_profile *profile = ccs_profile_ptr[index];
560          const struct ccs_profile *profile = idx >= 0 ?          struct ccs_preference *pref = &profile->preference;
561                  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={ "  
562  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
563                        "max_grant_log=%u max_reject_log=%u "                        "max_grant_log=%u max_reject_log=%u "
564  #endif  #endif
565                        "task_info=%s path_info=%s }\n", buffer,                        "task_info=%s path_info=%s }\n", index,
566                        "audit",                        "audit",
567  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
568                        pref->audit_max_grant_log,                        pref->audit_max_grant_log,
# Line 646  static void ccs_print_preference(struct Line 570  static void ccs_print_preference(struct
570  #endif  #endif
571                        ccs_yesno(pref->audit_task_info),                        ccs_yesno(pref->audit_task_info),
572                        ccs_yesno(pref->audit_path_info));                        ccs_yesno(pref->audit_path_info));
573   skip0:          ccs_io_printf(head, "%u-PREFERENCE::%s={ "
574          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 "  
575                        "exec.argv0=%s symlink.target=%s }\n",                        "exec.argv0=%s symlink.target=%s }\n",
576                        buffer, "learning",                        index, "learning",
                       ccs_yesno(pref->learning_verbose),  
577                        pref->learning_max_entry,                        pref->learning_max_entry,
578                        ccs_yesno(pref->learning_exec_realpath),                        ccs_yesno(pref->learning_exec_realpath),
579                        ccs_yesno(pref->learning_exec_argv0),                        ccs_yesno(pref->learning_exec_argv0),
580                        ccs_yesno(pref->learning_symlink_target));                        ccs_yesno(pref->learning_symlink_target));
581   skip1:          ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index,
582          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);  
583  }  }
584    
585  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)
586  {  {
587          ccs_io_printf(head, "={ mode=%s", ccs_mode[config & 3]);          ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3],
588                          ccs_yesno(config & CCS_CONFIG_VERBOSE));
589  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
590          ccs_io_printf(head, " grant_log=%s reject_log=%s",          ccs_io_printf(head, " grant_log=%s reject_log=%s",
591                        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 609  static void ccs_read_profile(struct ccs_
609          switch (head->r.step) {          switch (head->r.step) {
610          case 0:          case 0:
611                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
                 ccs_print_preference(head, -1);  
612                  head->r.step++;                  head->r.step++;
613                  break;                  break;
614          case 1:          case 1:
# Line 764  static void ccs_read_profile(struct ccs_ Line 664  static void ccs_read_profile(struct ccs_
664                  goto next;                  goto next;
665  }  }
666    
667  static bool ccs_same_manager_entry(const struct ccs_acl_head *a,  static bool ccs_same_manager(const struct ccs_acl_head *a,
668                                     const struct ccs_acl_head *b)                               const struct ccs_acl_head *b)
669  {  {
670          return container_of(a, struct ccs_manager, head)->manager          return container_of(a, struct ccs_manager, head)->manager
671                  == 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 696  static int ccs_update_manager_entry(cons
696                  return error;                  return error;
697          error = ccs_update_policy(&e.head, sizeof(e), is_delete,          error = ccs_update_policy(&e.head, sizeof(e), is_delete,
698                                    &ccs_policy_list[CCS_ID_MANAGER],                                    &ccs_policy_list[CCS_ID_MANAGER],
699                                    ccs_same_manager_entry);                                    ccs_same_manager);
700          ccs_put_name(e.manager);          ccs_put_name(e.manager);
701          return error;          return error;
702  }  }
# Line 928  static bool ccs_select_one(struct ccs_io Line 828  static bool ccs_select_one(struct ccs_io
828          unsigned int pid;          unsigned int pid;
829          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
830          bool global_pid = false;          bool global_pid = false;
831          if (!strcmp(data, "allow_execute")) {          if (!strcmp(data, "execute")) {
832                  head->r.print_execute_only = true;                  head->r.print_execute_only = true;
833                  return true;                  return true;
834          }          }
# Line 959  static bool ccs_select_one(struct ccs_io Line 859  static bool ccs_select_one(struct ccs_io
859                  return true; /* Do nothing if open(O_WRONLY). */                  return true; /* Do nothing if open(O_WRONLY). */
860          memset(&head->r, 0, sizeof(head->r));          memset(&head->r, 0, sizeof(head->r));
861          head->r.print_this_domain_only = true;          head->r.print_this_domain_only = true;
862          head->r.eof = !domain;          if (domain)
863          head->r.domain = &domain->list;                  head->r.domain = &domain->list;
864            else
865                    head->r.eof = true;
866          ccs_io_printf(head, "# select %s\n", data);          ccs_io_printf(head, "# select %s\n", data);
867          if (domain && domain->is_deleted)          if (domain && domain->is_deleted)
868                  ccs_set_string(head, "# This is a deleted domain.\n");                  ccs_set_string(head, "# This is a deleted domain.\n");
# Line 975  static int ccs_write_domain2(char *data, Line 877  static int ccs_write_domain2(char *data,
877                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (char *, struct ccs_domain_info *,
878                                struct ccs_condition *, const bool);                                struct ccs_condition *, const bool);
879          } ccs_callback[5] = {          } ccs_callback[5] = {
880                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },                  { "network inet ", ccs_write_inet_network },
881                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },                  { "network unix ", ccs_write_unix_network },
882                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },                  { "misc ", ccs_write_misc },
883                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },                  { "capability ", ccs_write_capability },
884                  { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }                  { "ipc ", ccs_write_ipc },
885          };          };
886          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,
887                        const bool) = ccs_write_file;                        const bool) = ccs_write_file;
# Line 1006  static int ccs_write_domain2(char *data, Line 908  static int ccs_write_domain2(char *data,
908    
909  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
910          [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",  
911          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"
912  };  };
913                    
# Line 1044  static int ccs_write_domain(struct ccs_i Line 941  static int ccs_write_domain(struct ccs_i
941                  else if (is_select)                  else if (is_select)
942                          domain = ccs_find_domain(data);                          domain = ccs_find_domain(data);
943                  else                  else
944                          domain = ccs_assign_domain(data, 0);                          domain = ccs_assign_domain(data, 0, 0, false);
945                  head->w.domain = domain;                  head->w.domain = domain;
946                  return 0;                  return 0;
947          }          }
# Line 1057  static int ccs_write_domain(struct ccs_i Line 954  static int ccs_write_domain(struct ccs_i
954                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
955                  return 0;                  return 0;
956          }          }
957            if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1
958                && profile < CCS_MAX_ACL_GROUPS) {
959                    domain->group = (u8) profile;
960                    return 0;
961            }
962          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
963                  const char *cp = ccs_dif[profile];                  const char *cp = ccs_dif[profile];
964                  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 1203  static u8 ccs_fns(const u8 perm, u8 bit)
1203          return bit;          return bit;
1204  }  }
1205    
1206    static void ccs_set_group(struct ccs_io_buffer *head)
1207    {
1208            if (head->type == CCS_EXCEPTIONPOLICY)
1209                    ccs_io_printf(head, "acl_group %u ", head->r.group_index);
1210    }
1211    
1212  /**  /**
1213   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1214   *   *
# Line 1332  static bool ccs_print_entry(struct ccs_i Line 1240  static bool ccs_print_entry(struct ccs_i
1240                          if (head->r.print_execute_only &&                          if (head->r.print_execute_only &&
1241                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)
1242                                  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;  
1243                          break;                          break;
1244                  }                  }
1245                  if (bit >= CCS_MAX_PATH_OPERATION)                  if (bit >= CCS_MAX_PATH_OPERATION)
1246                          goto done;                          goto done;
1247                  ccs_io_printf(head, "allow_%s", ccs_path_keyword[bit]);                  ccs_set_group(head);
1248                    ccs_set_string(head, "file ");
1249                    ccs_set_string(head, ccs_path_keyword[bit]);
1250                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1251          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||
1252                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1253                  struct ccs_execute_handler *ptr                  struct ccs_execute_handler *ptr
1254                          = container_of(acl, typeof(*ptr), head);                          = container_of(acl, typeof(*ptr), head);
1255                    ccs_set_group(head);
1256                  ccs_io_printf(head, "%s ",                  ccs_io_printf(head, "%s ",
1257                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?
1258                                CCS_KEYWORD_EXECUTE_HANDLER :                                CCS_KEYWORD_EXECUTE_HANDLER :
# Line 1359  static bool ccs_print_entry(struct ccs_i Line 1266  static bool ccs_print_entry(struct ccs_i
1266                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1267                  if (bit >= CCS_MAX_MKDEV_OPERATION)                  if (bit >= CCS_MAX_MKDEV_OPERATION)
1268                          goto done;                          goto done;
1269                  ccs_io_printf(head, "allow_%s", ccs_mkdev_keyword[bit]);                  ccs_set_group(head);
1270                    ccs_set_string(head, "file ");
1271                    ccs_set_string(head, ccs_mkdev_keyword[bit]);
1272                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1273                  ccs_print_number_union(head, &ptr->mode);                  ccs_print_number_union(head, &ptr->mode);
1274                  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 1279  static bool ccs_print_entry(struct ccs_i
1279                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1280                  if (bit >= CCS_MAX_PATH2_OPERATION)                  if (bit >= CCS_MAX_PATH2_OPERATION)
1281                          goto done;                          goto done;
1282                  ccs_io_printf(head, "allow_%s", ccs_path2_keyword[bit]);                  ccs_set_group(head);
1283                    ccs_set_string(head, "file ");
1284                    ccs_set_string(head, ccs_path2_keyword[bit]);
1285                  ccs_print_name_union(head, &ptr->name1);                  ccs_print_name_union(head, &ptr->name1);
1286                  ccs_print_name_union(head, &ptr->name2);                  ccs_print_name_union(head, &ptr->name2);
1287          } 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 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_PATH_NUMBER_OPERATION)                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)
1292                          goto done;                          goto done;
1293                  ccs_io_printf(head, "allow_%s",                  ccs_set_group(head);
1294                                ccs_path_number_keyword[bit]);                  ccs_set_string(head, "file ");
1295                    ccs_set_string(head, ccs_path_number_keyword[bit]);
1296                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1297                  ccs_print_number_union(head, &ptr->number);                  ccs_print_number_union(head, &ptr->number);
1298          } else if (acl_type == CCS_TYPE_ENV_ACL) {          } else if (acl_type == CCS_TYPE_ENV_ACL) {
1299                  struct ccs_env_acl *ptr =                  struct ccs_env_acl *ptr =
1300                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1301                  ccs_set_string(head, CCS_KEYWORD_ALLOW_ENV);                  ccs_set_group(head);
1302                    ccs_set_string(head, "misc env ");
1303                  ccs_set_string(head, ptr->env->name);                  ccs_set_string(head, ptr->env->name);
1304          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1305                  struct ccs_capability_acl *ptr =                  struct ccs_capability_acl *ptr =
1306                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1307                  ccs_set_string(head, CCS_KEYWORD_ALLOW_CAPABILITY);                  ccs_set_group(head);
1308                    ccs_set_string(head, "capability ");
1309                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));
1310          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          } else if (acl_type == CCS_TYPE_INET_ACL) {
1311                  struct ccs_ip_network_acl *ptr =                  struct ccs_inet_acl *ptr =
1312                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1313                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1314                  if (bit >= CCS_MAX_NETWORK_OPERATION)                  if (bit >= CCS_MAX_NETWORK_OPERATION)
1315                          goto done;                          goto done;
1316                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",                  ccs_set_group(head);
1317                                ccs_net_keyword[bit]);                  ccs_set_string(head, "network inet ");
1318                    ccs_set_string(head, ccs_inet_keyword[ptr->protocol]);
1319                    ccs_set_space(head);
1320                    ccs_set_string(head, ccs_net_keyword[bit]);
1321                    ccs_set_space(head);
1322                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1323                          char buf[128];                          char buf[128];
1324                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:                  case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
# Line 1420  static bool ccs_print_entry(struct ccs_i Line 1338  static bool ccs_print_entry(struct ccs_i
1338                          break;                          break;
1339                  }                  }
1340                  ccs_print_number_union(head, &ptr->port);                  ccs_print_number_union(head, &ptr->port);
1341            } else if (acl_type == CCS_TYPE_UNIX_ACL) {
1342                    struct ccs_unix_acl *ptr =
1343                            container_of(acl, typeof(*ptr), head);
1344                    bit = ccs_fns(ptr->perm, bit);
1345                    if (bit >= CCS_MAX_NETWORK_OPERATION)
1346                            goto done;
1347                    ccs_set_group(head);
1348                    ccs_set_string(head, "network unix ");
1349                    ccs_set_string(head, ccs_unix_keyword[ptr->protocol]);
1350                    ccs_set_space(head);
1351                    ccs_set_string(head, ccs_net_keyword[bit]);
1352                    ccs_print_name_union(head, &ptr->name);
1353          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1354                  struct ccs_signal_acl *ptr =                  struct ccs_signal_acl *ptr =
1355                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1356                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u ", ptr->sig);                  ccs_set_group(head);
1357                    ccs_set_string(head, "ipc signal ");
1358                    ccs_io_printf(head, "%u ", ptr->sig);
1359                  ccs_set_string(head, ptr->domainname->name);                  ccs_set_string(head, ptr->domainname->name);
1360          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
1361                  struct ccs_mount_acl *ptr =                  struct ccs_mount_acl *ptr =
1362                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1363                  ccs_io_printf(head, "allow_mount");                  ccs_set_group(head);
1364                    ccs_io_printf(head, "file mount");
1365                  ccs_print_name_union(head, &ptr->dev_name);                  ccs_print_name_union(head, &ptr->dev_name);
1366                  ccs_print_name_union(head, &ptr->dir_name);                  ccs_print_name_union(head, &ptr->dir_name);
1367                  ccs_print_name_union(head, &ptr->fs_type);                  ccs_print_name_union(head, &ptr->fs_type);
# Line 1452  static bool ccs_print_entry(struct ccs_i Line 1385  static bool ccs_print_entry(struct ccs_i
1385          case CCS_TYPE_MKDEV_ACL:          case CCS_TYPE_MKDEV_ACL:
1386          case CCS_TYPE_PATH2_ACL:          case CCS_TYPE_PATH2_ACL:
1387          case CCS_TYPE_PATH_NUMBER_ACL:          case CCS_TYPE_PATH_NUMBER_ACL:
1388          case CCS_TYPE_IP_NETWORK_ACL:          case CCS_TYPE_INET_ACL:
1389            case CCS_TYPE_UNIX_ACL:
1390                  goto next;                  goto next;
1391          }          }
1392   done:   done:
# Line 1508  static void ccs_read_domain(struct ccs_i Line 1442  static void ccs_read_domain(struct ccs_i
1442                          ccs_set_lf(head);                          ccs_set_lf(head);
1443                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",
1444                                        domain->profile);                                        domain->profile);
1445                            ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",
1446                                          domain->group);
1447                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1448                                  if (domain->flags[i])                                  if (domain->flags[i])
1449                                          ccs_set_string(head, ccs_dif[i]);                                          ccs_set_string(head, ccs_dif[i]);
# Line 1702  static int ccs_write_exception(struct cc Line 1638  static int ccs_write_exception(struct cc
1638          static const struct {          static const struct {
1639                  const char *keyword;                  const char *keyword;
1640                  int (*write) (char *, const bool);                  int (*write) (char *, const bool);
1641          } ccs_callback[4] = {          } ccs_callback[3] = {
1642                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1643                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
                 { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },  
1644                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1645          };          };
1646          for (i = 0; i < 4; i++) {          for (i = 0; i < 3; i++)
1647                  if (ccs_str_starts(&data, ccs_callback[i].keyword))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1648                          return ccs_callback[i].write(data, is_delete);                          return ccs_callback[i].write(data, is_delete);
1649          }          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) {  
1650                  if (ccs_str_starts(&data, ccs_transition_type[i]))                  if (ccs_str_starts(&data, ccs_transition_type[i]))
1651                          return ccs_write_transition_control(data, is_delete,                          return ccs_write_transition_control(data, is_delete,
1652                                                              i);                                                              i);
1653          }          for (i = 0; i < CCS_MAX_GROUP; i++)
         for (i = 0; i < CCS_MAX_GROUP; i++) {  
1654                  if (ccs_str_starts(&data, ccs_group_name[i]))                  if (ccs_str_starts(&data, ccs_group_name[i]))
1655                          return ccs_write_group(data, is_delete, i);                          return ccs_write_group(data, is_delete, i);
1656            if (ccs_str_starts(&data, "acl_group ")) {
1657                    unsigned int group;
1658                    if (sscanf(data, "%u", &group) == 1 &&
1659                        group < CCS_MAX_ACL_GROUPS) {
1660                            data = strchr(data, ' ');
1661                            if (data)
1662                                    return ccs_write_domain2(data + 1,
1663                                                             &ccs_acl_group[group],
1664                                                             is_delete);
1665                    }
1666          }          }
1667          return ccs_write_domain2(data, &ccs_global_domain, is_delete);          return -EINVAL;
1668  }  }
1669    
1670  /**  /**
# Line 1832  static bool ccs_read_policy(struct ccs_i Line 1775  static bool ccs_read_policy(struct ccs_i
1775                                  ccs_set_string(head, ptr->pattern->name);                                  ccs_set_string(head, ptr->pattern->name);
1776                          }                          }
1777                          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;  
1778                  case CCS_ID_RESERVEDPORT:                  case CCS_ID_RESERVEDPORT:
1779                          {                          {
1780                                  struct ccs_reserved *ptr =                                  struct ccs_reserved *ptr =
# Line 1883  static void ccs_read_exception(struct cc Line 1818  static void ccs_read_exception(struct cc
1818                  head->r.step++;                  head->r.step++;
1819          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
1820                  return;                  return;
1821          head->r.eof = ccs_read_domain2(head, &ccs_global_domain);          while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
1822                   + CCS_MAX_ACL_GROUPS) {
1823                    head->r.group_index = head->r.step - CCS_MAX_POLICY
1824                            - CCS_MAX_GROUP;
1825                    if (!ccs_read_domain2(head,
1826                                          &ccs_acl_group[head->r.group_index]))
1827                            return;
1828                    head->r.step++;
1829            }
1830            head->r.eof = true;
1831  }  }
1832    
1833  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
# Line 1893  static DECLARE_WAIT_QUEUE_HEAD(ccs_query Line 1837  static DECLARE_WAIT_QUEUE_HEAD(ccs_query
1837  static DEFINE_SPINLOCK(ccs_query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
1838    
1839  /* Structure for query. */  /* Structure for query. */
1840  struct ccs_query_entry {  struct ccs_query {
1841          struct list_head list;          struct list_head list;
1842          char *query;          char *query;
1843          int query_len;          int query_len;
# Line 1902  struct ccs_query_entry { Line 1846  struct ccs_query_entry {
1846          int answer;          int answer;
1847  };  };
1848    
1849  /* The list for "struct ccs_query_entry". */  /* The list for "struct ccs_query". */
1850  static LIST_HEAD(ccs_query_list);  static LIST_HEAD(ccs_query_list);
1851    
1852  /* 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 1877  int ccs_supervisor(struct ccs_request_in
1877          int pos;          int pos;
1878          int len;          int len;
1879          static unsigned int ccs_serial;          static unsigned int ccs_serial;
1880          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query *entry = NULL;
1881          bool quota_exceeded = false;          bool quota_exceeded = false;
1882          char *header;          char *header;
1883          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 1896  int ccs_supervisor(struct ccs_request_in
1896                  header = ccs_init_log(&len, r);                  header = ccs_init_log(&len, r);
1897                  if (!header)                  if (!header)
1898                          return 0;                          return 0;
1899                  pref = ccs_profile(r->profile)->learning;                  pref = &ccs_profile(r->profile)->preference;
1900                  /* strstr() will return NULL if ordering is wrong. */                  /* strstr() will return NULL if ordering is wrong. */
1901                  if (r->param_type == CCS_TYPE_PATH_ACL &&                  if (r->param_type == CCS_TYPE_PATH_ACL &&
1902                      r->param.path.operation == CCS_TYPE_EXECUTE) {                      r->param.path.operation == CCS_TYPE_EXECUTE) {
# Line 2015  int ccs_supervisor(struct ccs_request_in Line 1959  int ccs_supervisor(struct ccs_request_in
1959                  int i;                  int i;
1960                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
1961                          return -EPERM;                          return -EPERM;
1962                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->preference.
1963                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
1964                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
1965                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2025  int ccs_supervisor(struct ccs_request_in Line 1969  int ccs_supervisor(struct ccs_request_in
1969          header = ccs_init_log(&len, r);          header = ccs_init_log(&len, r);
1970          if (!header)          if (!header)
1971                  goto out;                  goto out;
1972          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
1973          if (!ccs_query_entry)          if (!entry)
1974                  goto out;                  goto out;
1975          len = ccs_round2(len);          len = ccs_round2(len);
1976          ccs_query_entry->query = kzalloc(len, CCS_GFP_FLAGS);          entry->query = kzalloc(len, CCS_GFP_FLAGS);
1977          if (!ccs_query_entry->query)          if (!entry->query)
1978                  goto out;                  goto out;
         INIT_LIST_HEAD(&ccs_query_entry->list);  
1979          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1980          if (ccs_quota_for_query && ccs_query_memory_size + len +          if (ccs_quota_for_query && ccs_query_memory_size + len +
1981              sizeof(*ccs_query_entry) >= ccs_quota_for_query) {              sizeof(*entry) >= ccs_quota_for_query) {
1982                  quota_exceeded = true;                  quota_exceeded = true;
1983          } else {          } else {
1984                  ccs_query_memory_size += len + sizeof(*ccs_query_entry);                  ccs_query_memory_size += len + sizeof(*entry);
1985                  ccs_query_entry->serial = ccs_serial++;                  entry->serial = ccs_serial++;
1986          }          }
1987          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1988          if (quota_exceeded)          if (quota_exceeded)
1989                  goto out;                  goto out;
1990          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",          pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
1991                         ccs_query_entry->serial, r->retry, header);                         entry->serial, r->retry, header);
1992          kfree(header);          kfree(header);
1993          header = NULL;          header = NULL;
1994          va_start(args, fmt);          va_start(args, fmt);
1995          vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);          vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
1996          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;          entry->query_len = strlen(entry->query) + 1;
1997          va_end(args);          va_end(args);
1998          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1999          list_add_tail(&ccs_query_entry->list, &ccs_query_list);          list_add_tail(&entry->list, &ccs_query_list);
2000          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2001          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
2002          for (ccs_query_entry->timer = 0;          for (entry->timer = 0;
2003               atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;               atomic_read(&ccs_query_observers) && entry->timer < 100;
2004               ccs_query_entry->timer++) {               entry->timer++) {
2005                  wake_up(&ccs_query_wait);                  wake_up(&ccs_query_wait);
2006                  set_current_state(TASK_INTERRUPTIBLE);                  set_current_state(TASK_INTERRUPTIBLE);
2007                  schedule_timeout(HZ / 10);                  schedule_timeout(HZ / 10);
2008                  if (ccs_query_entry->answer)                  if (entry->answer)
2009                          break;                          break;
2010          }          }
2011          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2012          list_del(&ccs_query_entry->list);          list_del(&entry->list);
2013          ccs_query_memory_size -= len + sizeof(*ccs_query_entry);          ccs_query_memory_size -= len + sizeof(*entry);
2014          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2015          switch (ccs_query_entry->answer) {          switch (entry->answer) {
2016          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
2017                  error = CCS_RETRY_REQUEST;                  error = CCS_RETRY_REQUEST;
2018                  r->retry++;                  r->retry++;
# Line 2086  int ccs_supervisor(struct ccs_request_in Line 2029  int ccs_supervisor(struct ccs_request_in
2029                  break;                  break;
2030          }          }
2031   out:   out:
2032          if (ccs_query_entry)          if (entry)
2033                  kfree(ccs_query_entry->query);                  kfree(entry->query);
2034          kfree(ccs_query_entry);          kfree(entry);
2035          kfree(header);          kfree(header);
2036          return error;          return error;
2037  }  }
# Line 2111  static int ccs_poll_query(struct file *f Line 2054  static int ccs_poll_query(struct file *f
2054          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
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 =
2058                                  list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, typeof(*ptr), list);
2059                          if (ptr->answer)                          if (ptr->answer)
2060                                  continue;                                  continue;
2061                          found = true;                          found = true;
# Line 2147  static void ccs_read_query(struct ccs_io Line 2090  static void ccs_read_query(struct ccs_io
2090          }          }
2091          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2092          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2093                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2094                  if (ptr->answer)                  if (ptr->answer)
2095                          continue;                          continue;
2096                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2167  static void ccs_read_query(struct ccs_io Line 2109  static void ccs_read_query(struct ccs_io
2109          pos = 0;          pos = 0;
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                  if (ptr->answer)                  if (ptr->answer)
2114                          continue;                          continue;
2115                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2206  static int ccs_write_answer(struct ccs_i Line 2147  static int ccs_write_answer(struct ccs_i
2147          unsigned int answer;          unsigned int answer;
2148          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2149          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2150                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2151                  ptr->timer = 0;                  ptr->timer = 0;
2152          }          }
2153          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
# Line 2215  static int ccs_write_answer(struct ccs_i Line 2155  static int ccs_write_answer(struct ccs_i
2155                  return -EINVAL;                  return -EINVAL;
2156          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2157          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2158                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2159                  if (ptr->serial != serial)                  if (ptr->serial != serial)
2160                          continue;                          continue;
2161                  if (!ptr->answer)                  if (!ptr->answer)
# Line 2236  static void ccs_read_version(struct ccs_ Line 2175  static void ccs_read_version(struct ccs_
2175  {  {
2176          if (head->r.eof)          if (head->r.eof)
2177                  return;                  return;
2178          ccs_set_string(head, "1.7.2");          ccs_set_string(head, "1.8.0-pre");
2179          head->r.eof = true;          head->r.eof = true;
2180  }  }
2181    

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

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