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

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 3935 by kumaneko, Wed Sep 1 14:07:02 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/09/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 97  static const char *ccs_mac_keywords[CCS_ Line 88  static const char *ccs_mac_keywords[CCS_
88          = "file::umount",          = "file::umount",
89          [CCS_MAC_FILE_PIVOT_ROOT]          [CCS_MAC_FILE_PIVOT_ROOT]
90          = "file::pivot_root",          = "file::pivot_root",
         [CCS_MAC_FILE_TRANSIT]  
         = "file::transit",  
91          [CCS_MAC_ENVIRON]          [CCS_MAC_ENVIRON]
92          = "misc::env",          = "misc::env",
93          [CCS_MAC_NETWORK_UDP_BIND]          [CCS_MAC_NETWORK_INET_STREAM_BIND]
94          = "network::inet_udp_bind",          = "network::inet_stream_bind",
95          [CCS_MAC_NETWORK_UDP_CONNECT]          [CCS_MAC_NETWORK_INET_STREAM_LISTEN]
96          = "network::inet_udp_connect",          = "network::inet_stream_listen",
97          [CCS_MAC_NETWORK_TCP_BIND]          [CCS_MAC_NETWORK_INET_STREAM_CONNECT]
98          = "network::inet_tcp_bind",          = "network::inet_stream_connect",
99          [CCS_MAC_NETWORK_TCP_LISTEN]          [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]
100          = "network::inet_tcp_listen",          = "network::inet_stream_accept",
101          [CCS_MAC_NETWORK_TCP_CONNECT]          [CCS_MAC_NETWORK_INET_DGRAM_BIND]
102          = "network::inet_tcp_connect",          = "network::inet_dgram_bind",
103          [CCS_MAC_NETWORK_TCP_ACCEPT]          [CCS_MAC_NETWORK_INET_DGRAM_SEND]
104          = "network::inet_tcp_accept",          = "network::inet_dgram_send",
105          [CCS_MAC_NETWORK_RAW_BIND]          [CCS_MAC_NETWORK_INET_DGRAM_RECV]
106            = "network::inet_dgram_recv",
107            [CCS_MAC_NETWORK_INET_RAW_BIND]
108          = "network::inet_raw_bind",          = "network::inet_raw_bind",
109          [CCS_MAC_NETWORK_RAW_CONNECT]          [CCS_MAC_NETWORK_INET_RAW_SEND]
110          = "network::inet_raw_connect",          = "network::inet_raw_send",
111            [CCS_MAC_NETWORK_INET_RAW_RECV]
112            = "network::inet_raw_recv",
113            [CCS_MAC_NETWORK_UNIX_STREAM_BIND]
114            = "network::unix_stream_bind",
115            [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]
116            = "network::unix_stream_listen",
117            [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]
118            = "network::unix_stream_connect",
119            [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]
120            = "network::unix_stream_accept",
121            [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]
122            = "network::unix_dgram_bind",
123            [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]
124            = "network::unix_dgram_send",
125            [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]
126            = "network::unix_dgram_recv",
127            [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]
128            = "network::unix_seqpacket_bind",
129            [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]
130            = "network::unix_seqpacket_listen",
131            [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT]
132            = "network::unix_seqpacket_connect",
133            [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]
134            = "network::unix_seqpacket_accept",
135          [CCS_MAC_SIGNAL]          [CCS_MAC_SIGNAL]
136          = "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",  
137          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
138          = "capability::use_route",          = "capability::use_route",
139          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
140          = "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",  
141          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
142          = "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",  
143          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
144          = "capability::SYS_VHANGUP",          = "capability::SYS_VHANGUP",
145          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
# Line 153  static const char *ccs_mac_keywords[CCS_ Line 150  static const char *ccs_mac_keywords[CCS_
150          = "capability::SYS_SETHOSTNAME",          = "capability::SYS_SETHOSTNAME",
151          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
152          = "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",  
153          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
154          = "capability::SYS_KEXEC_LOAD",          = "capability::SYS_KEXEC_LOAD",
         [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]  
         = "capability::SYS_PIVOT_ROOT",  
155          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
156          = "capability::SYS_PTRACE",          = "capability::SYS_PTRACE",
         [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]  
         = "capability::conceal_mount",  
157          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
158           + CCS_MAC_CATEGORY_FILE] = "file",           + CCS_MAC_CATEGORY_FILE] = "file",
159          [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 260  static void ccs_set_string(struct ccs_io
260                  head->r.w[head->r.w_pos++] = string;                  head->r.w[head->r.w_pos++] = string;
261                  ccs_flush(head);                  ccs_flush(head);
262          } else          } else
263                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
264  }  }
265    
266  /**  /**
# Line 310  void ccs_io_printf(struct ccs_io_buffer Line 281  void ccs_io_printf(struct ccs_io_buffer
281          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;          len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
282          va_end(args);          va_end(args);
283          if (pos + len >= head->readbuf_size) {          if (pos + len >= head->readbuf_size) {
284                  WARN_ON(1);                  printk(KERN_WARNING "Too many words in a line.\n");
285                  return;                  return;
286          }          }
287          head->r.avail += len;          head->r.avail += len;
# Line 350  static struct ccs_profile *ccs_assign_pr Line 321  static struct ccs_profile *ccs_assign_pr
321          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
322          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
323                  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;  
324                  ptr->default_config = CCS_CONFIG_DISABLED |                  ptr->default_config = CCS_CONFIG_DISABLED |
325                            CCS_CONFIG_VERBOSE |
326                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
327                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
328                         sizeof(ptr->config));                         sizeof(ptr->config));
# Line 387  static void ccs_check_profile(void) Line 355  static void ccs_check_profile(void)
355          if (ccs_profile_version != 20090903)          if (ccs_profile_version != 20090903)
356                  panic("Profile version %u is not supported.\n",                  panic("Profile version %u is not supported.\n",
357                        ccs_profile_version);                        ccs_profile_version);
358          printk(KERN_INFO "CCSecurity: 1.7.2+   2010/06/04\n");          printk(KERN_INFO "CCSecurity: 1.8.0-pre   2010/09/01\n");
359          printk(KERN_INFO "Mandatory Access Control activated.\n");          printk(KERN_INFO "Mandatory Access Control activated.\n");
360  }  }
361    
# Line 440  static void ccs_set_uint(unsigned int *i Line 408  static void ccs_set_uint(unsigned int *i
408  }  }
409    
410  static void ccs_set_pref(const char *name, const char *value,  static void ccs_set_pref(const char *name, const char *value,
411                           const bool use_default, struct ccs_profile *profile)                           struct ccs_profile *profile)
412  {  {
         struct ccs_preference **pref;  
         bool *verbose;  
413          if (!strcmp(name, "audit")) {          if (!strcmp(name, "audit")) {
                 if (use_default) {  
                         pref = &profile->audit;  
                         goto set_default;  
                 }  
                 profile->audit = &profile->preference;  
414  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
415                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,                  ccs_set_uint(&profile->preference.audit_max_grant_log, value,
416                               "max_grant_log");                               "max_grant_log");
# Line 463  static void ccs_set_pref(const char *nam Line 424  static void ccs_set_pref(const char *nam
424                  return;                  return;
425          }          }
426          if (!strcmp(name, "enforcing")) {          if (!strcmp(name, "enforcing")) {
                 if (use_default) {  
                         pref = &profile->enforcing;  
                         goto set_default;  
                 }  
                 profile->enforcing = &profile->preference;  
427                  ccs_set_uint(&profile->preference.enforcing_penalty, value,                  ccs_set_uint(&profile->preference.enforcing_penalty, value,
428                               "penalty");                               "penalty");
429                  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;  
430          }          }
431          if (!strcmp(name, "learning")) {          if (!strcmp(name, "learning")) {
                 if (use_default) {  
                         pref = &profile->learning;  
                         goto set_default;  
                 }  
                 profile->learning = &profile->preference;  
432                  ccs_set_uint(&profile->preference.learning_max_entry, value,                  ccs_set_uint(&profile->preference.learning_max_entry, value,
433                               "max_entry");                               "max_entry");
434                  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 437  static void ccs_set_pref(const char *nam
437                               "exec.argv0");                               "exec.argv0");
438                  ccs_set_bool(&profile->preference.learning_symlink_target,                  ccs_set_bool(&profile->preference.learning_symlink_target,
439                               value, "symlink.target");                               value, "symlink.target");
440                  verbose = &profile->preference.learning_verbose;                  return;
                 goto set_verbose;  
441          }          }
         return;  
  set_default:  
         *pref = &ccs_default_profile.preference;  
         return;  
  set_verbose:  
         ccs_set_bool(verbose, value, "verbose");  
442  }  }
443    
444  static int ccs_set_mode(char *name, const char *value, const bool use_default,  static int ccs_set_mode(char *name, const char *value,
445                          struct ccs_profile *profile)                          struct ccs_profile *profile)
446  {  {
447          u8 i;          u8 i;
# Line 531  static int ccs_set_mode(char *name, cons Line 465  static int ccs_set_mode(char *name, cons
465          } else {          } else {
466                  return -EINVAL;                  return -EINVAL;
467          }          }
468          if (use_default) {          if (strstr(value, "use_default")) {
469                  config = CCS_CONFIG_USE_DEFAULT;                  config = CCS_CONFIG_USE_DEFAULT;
470          } else {          } else {
471                  u8 mode;                  u8 mode;
# Line 542  static int ccs_set_mode(char *name, cons Line 476  static int ccs_set_mode(char *name, cons
476                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
477                                   */                                   */
478                                  config = (config & ~7) | mode;                                  config = (config & ~7) | mode;
 #ifdef CONFIG_CCSECURITY_AUDIT  
479                  if (config != CCS_CONFIG_USE_DEFAULT) {                  if (config != CCS_CONFIG_USE_DEFAULT) {
480                            switch (ccs_find_yesno(value, "verbose")) {
481                            case 1:
482                                    config |= CCS_CONFIG_VERBOSE;
483                                    break;
484                            case 0:
485                                    config &= ~CCS_CONFIG_VERBOSE;
486                                    break;
487                            }
488    #ifdef CONFIG_CCSECURITY_AUDIT
489                          switch (ccs_find_yesno(value, "grant_log")) {                          switch (ccs_find_yesno(value, "grant_log")) {
490                          case 1:                          case 1:
491                                  config |= CCS_CONFIG_WANT_GRANT_LOG;                                  config |= CCS_CONFIG_WANT_GRANT_LOG;
# Line 560  static int ccs_set_mode(char *name, cons Line 502  static int ccs_set_mode(char *name, cons
502                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;
503                                  break;                                  break;
504                          }                          }
                 }  
505  #endif  #endif
506                    }
507          }          }
508          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
509              + CCS_MAX_MAC_CATEGORY_INDEX)              + CCS_MAX_MAC_CATEGORY_INDEX)
# Line 581  static int ccs_set_mode(char *name, cons Line 523  static int ccs_set_mode(char *name, cons
523  static int ccs_write_profile(struct ccs_io_buffer *head)  static int ccs_write_profile(struct ccs_io_buffer *head)
524  {  {
525          char *data = head->write_buf;          char *data = head->write_buf;
526          bool use_default = false;          unsigned int i;
527          char *cp;          char *cp;
         int i;  
528          struct ccs_profile *profile;          struct ccs_profile *profile;
529          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
530                  return 0;                  return 0;
531          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
532          if (data == cp) {          if (*cp != '-')
533                  profile = &ccs_default_profile;                  return -EINVAL;
534          } else {          data = cp + 1;
535                  if (*cp != '-')          profile = ccs_assign_profile(i);
536                          return -EINVAL;          if (!profile)
537                  data = cp + 1;                  return -EINVAL;
                 profile = ccs_assign_profile(i);  
                 if (!profile)  
                         return -EINVAL;  
         }  
538          cp = strchr(data, '=');          cp = strchr(data, '=');
539          if (!cp)          if (!cp)
540                  return -EINVAL;                  return -EINVAL;
541          *cp++ = '\0';          *cp++ = '\0';
         if (profile != &ccs_default_profile)  
                 use_default = strstr(cp, "use_default") != NULL;  
542          if (ccs_str_starts(&data, "PREFERENCE::")) {          if (ccs_str_starts(&data, "PREFERENCE::")) {
543                  ccs_set_pref(data, cp, use_default, profile);                  ccs_set_pref(data, cp, profile);
544                  return 0;                  return 0;
545          }          }
         if (profile == &ccs_default_profile)  
                 return -EINVAL;  
546          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
547                  const struct ccs_path_info *old_comment = profile->comment;                  const struct ccs_path_info *old_comment = profile->comment;
548                  profile->comment = ccs_get_name(cp);                  profile->comment = ccs_get_name(cp);
549                  ccs_put_name(old_comment);                  ccs_put_name(old_comment);
550                  return 0;                  return 0;
551          }          }
552          return ccs_set_mode(data, cp, use_default, profile);          return ccs_set_mode(data, cp, profile);
553  }  }
554    
555  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)
556  {  {
557          struct ccs_preference *pref = &ccs_default_profile.preference;          struct ccs_profile *profile = ccs_profile_ptr[index];
558          const struct ccs_profile *profile = idx >= 0 ?          struct ccs_preference *pref = &profile->preference;
559                  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={ "  
560  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
561                        "max_grant_log=%u max_reject_log=%u "                        "max_grant_log=%u max_reject_log=%u "
562  #endif  #endif
563                        "task_info=%s path_info=%s }\n", buffer,                        "task_info=%s path_info=%s }\n", index,
564                        "audit",                        "audit",
565  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
566                        pref->audit_max_grant_log,                        pref->audit_max_grant_log,
# Line 646  static void ccs_print_preference(struct Line 568  static void ccs_print_preference(struct
568  #endif  #endif
569                        ccs_yesno(pref->audit_task_info),                        ccs_yesno(pref->audit_task_info),
570                        ccs_yesno(pref->audit_path_info));                        ccs_yesno(pref->audit_path_info));
571   skip0:          ccs_io_printf(head, "%u-PREFERENCE::%s={ "
572          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 "  
573                        "exec.argv0=%s symlink.target=%s }\n",                        "exec.argv0=%s symlink.target=%s }\n",
574                        buffer, "learning",                        index, "learning",
                       ccs_yesno(pref->learning_verbose),  
575                        pref->learning_max_entry,                        pref->learning_max_entry,
576                        ccs_yesno(pref->learning_exec_realpath),                        ccs_yesno(pref->learning_exec_realpath),
577                        ccs_yesno(pref->learning_exec_argv0),                        ccs_yesno(pref->learning_exec_argv0),
578                        ccs_yesno(pref->learning_symlink_target));                        ccs_yesno(pref->learning_symlink_target));
579   skip1:          ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index,
580          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);  
581  }  }
582    
583  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)
584  {  {
585          ccs_io_printf(head, "={ mode=%s", ccs_mode[config & 3]);          ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3],
586                          ccs_yesno(config & CCS_CONFIG_VERBOSE));
587  #ifdef CONFIG_CCSECURITY_AUDIT  #ifdef CONFIG_CCSECURITY_AUDIT
588          ccs_io_printf(head, " grant_log=%s reject_log=%s",          ccs_io_printf(head, " grant_log=%s reject_log=%s",
589                        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 607  static void ccs_read_profile(struct ccs_
607          switch (head->r.step) {          switch (head->r.step) {
608          case 0:          case 0:
609                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
                 ccs_print_preference(head, -1);  
610                  head->r.step++;                  head->r.step++;
611                  break;                  break;
612          case 1:          case 1:
# Line 764  static void ccs_read_profile(struct ccs_ Line 662  static void ccs_read_profile(struct ccs_
662                  goto next;                  goto next;
663  }  }
664    
665  static bool ccs_same_manager_entry(const struct ccs_acl_head *a,  static bool ccs_same_manager(const struct ccs_acl_head *a,
666                                     const struct ccs_acl_head *b)                               const struct ccs_acl_head *b)
667  {  {
668          return container_of(a, struct ccs_manager, head)->manager          return container_of(a, struct ccs_manager, head)->manager
669                  == 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 694  static int ccs_update_manager_entry(cons
694                  return error;                  return error;
695          error = ccs_update_policy(&e.head, sizeof(e), is_delete,          error = ccs_update_policy(&e.head, sizeof(e), is_delete,
696                                    &ccs_policy_list[CCS_ID_MANAGER],                                    &ccs_policy_list[CCS_ID_MANAGER],
697                                    ccs_same_manager_entry);                                    ccs_same_manager);
698          ccs_put_name(e.manager);          ccs_put_name(e.manager);
699          return error;          return error;
700  }  }
# Line 906  static bool ccs_manager(void) Line 804  static bool ccs_manager(void)
804  static char *ccs_find_condition_part(char *data)  static char *ccs_find_condition_part(char *data)
805  {  {
806          char *cp = strstr(data, " if ");          char *cp = strstr(data, " if ");
807          if (!cp)          if (cp) {
808                  cp = strstr(data, " ; set ");                  while (1) {
809          if (cp)                          char *cp2 = strstr(cp + 3, " if ");
810                  *cp++ = '\0';                          if (!cp2)
811                                    break;
812                            cp = cp2;
813                    }
814                    *cp = '\0';
815                    cp += 4;
816            }
817          return cp;          return cp;
818  }  }
819    
# Line 928  static bool ccs_select_one(struct ccs_io Line 832  static bool ccs_select_one(struct ccs_io
832          unsigned int pid;          unsigned int pid;
833          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
834          bool global_pid = false;          bool global_pid = false;
835          if (!strcmp(data, "allow_execute")) {          if (!strcmp(data, "execute")) {
836                  head->r.print_execute_only = true;                  head->r.print_execute_only = true;
837                  return true;                  return true;
838          }          }
# Line 959  static bool ccs_select_one(struct ccs_io Line 863  static bool ccs_select_one(struct ccs_io
863                  return true; /* Do nothing if open(O_WRONLY). */                  return true; /* Do nothing if open(O_WRONLY). */
864          memset(&head->r, 0, sizeof(head->r));          memset(&head->r, 0, sizeof(head->r));
865          head->r.print_this_domain_only = true;          head->r.print_this_domain_only = true;
866          head->r.eof = !domain;          if (domain)
867          head->r.domain = &domain->list;                  head->r.domain = &domain->list;
868            else
869                    head->r.eof = true;
870          ccs_io_printf(head, "# select %s\n", data);          ccs_io_printf(head, "# select %s\n", data);
871          if (domain && domain->is_deleted)          if (domain && domain->is_deleted)
872                  ccs_set_string(head, "# This is a deleted domain.\n");                  ccs_set_string(head, "# This is a deleted domain.\n");
873          return true;          return true;
874  }  }
875    
876    static bool ccs_same_handler_acl(const struct ccs_acl_info *a,
877                                     const struct ccs_acl_info *b)
878    {
879            const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head);
880            const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head);
881            return ccs_same_acl_head(&p1->head, &p2->head) &&
882                    p1->handler == p2->handler;
883    }
884    
885    static bool ccs_same_task_acl(const struct ccs_acl_info *a,
886                                  const struct ccs_acl_info *b)
887    {
888            const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head);
889            const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head);
890            return ccs_same_acl_head(&p1->head, &p2->head) &&
891                    p1->domainname == p2->domainname;
892    }
893    
894    /**
895     * ccs_write_task - Update task related list.
896     *
897     * @data:      String to parse.
898     * @domain:    Pointer to "struct ccs_domain_info".
899     * @condition: Pointer to "struct ccs_condition". Maybe NULL.
900     * @is_delete: True if it is a delete request.
901     *
902     * Returns 0 on success, negative value otherwise.
903     */
904    static int ccs_write_task(char *data, struct ccs_domain_info *domain,
905                              struct ccs_condition *condition,
906                              const bool is_delete)
907    {
908            int error;
909            const bool is_auto = ccs_str_starts(&data, "auto_domain_transition ");
910            if (!is_auto && !ccs_str_starts(&data, "manual_domain_transition ")) {
911                    struct ccs_handler_acl e = {
912                            .head.cond = condition,
913                    };
914                    if (ccs_str_starts(&data, "auto_execute_handler "))
915                            e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
916                    else if (ccs_str_starts(&data, "denied_execute_handler "))
917                            e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
918                    else
919                            return -EINVAL;
920                    if (!ccs_correct_path(data))
921                            return -EINVAL;
922                    e.handler = ccs_get_name(data);
923                    if (!e.handler)
924                            return -ENOMEM;
925                    if (e.handler->is_patterned)
926                            error = -EINVAL; /* No patterns allowed. */
927                    else
928                            error = ccs_update_domain(&e.head, sizeof(e),
929                                                      is_delete, domain,
930                                                      ccs_same_handler_acl, NULL);
931                    ccs_put_name(e.handler);
932            } else {
933                    struct ccs_task_acl e = {
934                            .head.type = is_auto ?
935                            CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL,
936                            .head.cond = condition,
937                    };
938                    if (!ccs_correct_domain(data))
939                            return -EINVAL;
940                    e.domainname = ccs_get_name(data);
941                    if (!e.domainname)
942                            return -ENOMEM;
943                    error = ccs_update_domain(&e.head, sizeof(e), is_delete,
944                                              domain, ccs_same_task_acl, NULL);
945                    ccs_put_name(e.domainname);
946            }
947            return error;
948    }
949    
950  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,
951                               const bool is_delete)                               const bool is_delete)
952  {  {
# Line 974  static int ccs_write_domain2(char *data, Line 954  static int ccs_write_domain2(char *data,
954                  const char *keyword;                  const char *keyword;
955                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (char *, struct ccs_domain_info *,
956                                struct ccs_condition *, const bool);                                struct ccs_condition *, const bool);
957          } ccs_callback[5] = {          } ccs_callback[7] = {
958                  { CCS_KEYWORD_ALLOW_NETWORK, ccs_write_network },                  { "file ", ccs_write_file },
959                  { CCS_KEYWORD_ALLOW_ENV, ccs_write_env },                  { "network inet ", ccs_write_inet_network },
960                  { CCS_KEYWORD_ALLOW_CAPABILITY, ccs_write_capability },                  { "network unix ", ccs_write_unix_network },
961                  { CCS_KEYWORD_ALLOW_SIGNAL, ccs_write_signal },                  { "misc ", ccs_write_misc },
962                  { CCS_KEYWORD_ALLOW_MOUNT, ccs_write_mount }                  { "capability ", ccs_write_capability },
963                    { "ipc ", ccs_write_ipc },
964                    { "task ", ccs_write_task },
965          };          };
966          int (*write) (char *, struct ccs_domain_info *, struct ccs_condition *,          int error = -EINVAL;
                       const bool) = ccs_write_file;  
         int error;  
967          u8 i;          u8 i;
968          struct ccs_condition *cond = NULL;          struct ccs_condition *cond = NULL;
969          char *cp = ccs_find_condition_part(data);          char *cp = ccs_find_condition_part(data);
# Line 992  static int ccs_write_domain2(char *data, Line 972  static int ccs_write_domain2(char *data,
972                  if (!cond)                  if (!cond)
973                          return -EINVAL;                          return -EINVAL;
974          }          }
975          for (i = 0; i < 5; i++) {          for (i = 0; i < 7; i++) {
976                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))
977                          continue;                          continue;
978                  write = ccs_callback[i].write;                  error = ccs_callback[i].write(data, domain, cond, is_delete);
979                  break;                  break;
980          }          }
         error = write(data, domain, cond, is_delete);  
981          if (cond)          if (cond)
982                  ccs_put_condition(cond);                  ccs_put_condition(cond);
983          return error;          return error;
# Line 1006  static int ccs_write_domain2(char *data, Line 985  static int ccs_write_domain2(char *data,
985    
986  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
987          [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",  
988          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"
989  };  };
990                    
# Line 1044  static int ccs_write_domain(struct ccs_i Line 1018  static int ccs_write_domain(struct ccs_i
1018                  else if (is_select)                  else if (is_select)
1019                          domain = ccs_find_domain(data);                          domain = ccs_find_domain(data);
1020                  else                  else
1021                          domain = ccs_assign_domain(data, 0);                          domain = ccs_assign_domain(data, 0, 0, false);
1022                  head->w.domain = domain;                  head->w.domain = domain;
1023                  return 0;                  return 0;
1024          }          }
# Line 1057  static int ccs_write_domain(struct ccs_i Line 1031  static int ccs_write_domain(struct ccs_i
1031                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
1032                  return 0;                  return 0;
1033          }          }
1034            if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1
1035                && profile < CCS_MAX_ACL_GROUPS) {
1036                    domain->group = (u8) profile;
1037                    return 0;
1038            }
1039          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {          for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
1040                  const char *cp = ccs_dif[profile];                  const char *cp = ccs_dif[profile];
1041                  if (strncmp(data, cp, strlen(cp) - 1))                  if (strncmp(data, cp, strlen(cp) - 1))
# Line 1152  static bool ccs_print_condition(struct c Line 1131  static bool ccs_print_condition(struct c
1131          switch (head->r.cond_step) {          switch (head->r.cond_step) {
1132          case 0:          case 0:
1133                  {                  {
1134                          if (cond->condc)                          ccs_set_string(head, " if");
                                 ccs_set_string(head, " if");  
1135                          head->r.cond_index = 0;                          head->r.cond_index = 0;
1136                          head->r.cond_step++;                          head->r.cond_step++;
1137                  }                  }
# Line 1265  static bool ccs_print_condition(struct c Line 1243  static bool ccs_print_condition(struct c
1243                  head->r.cond_step++;                  head->r.cond_step++;
1244                  /* fall through */                  /* fall through */
1245          case 3:          case 3:
1246                  {                  if (cond->audit)
1247                          u8 j;                          ccs_io_printf(head, " audit=%s",
1248                          const u8 i = cond->post_state[3];                                        ccs_yesno(cond->audit == 2));
1249                          if (i)                  if (cond->transit) {
1250                                  ccs_set_string(head, " ; set");                          ccs_set_string(head, " auto_domain_transitition=\"");
1251                          for (j = 0; j < 3; j++)                          ccs_set_string(head, cond->transit->name);
1252                                  if ((i & (1 << j)))                          ccs_set_string(head, "\"");
                                         ccs_io_printf(head,  
                                                       " task.state[%u]=%u", j,  
                                                       cond->post_state[j]);  
                         if (i & (1 << 4))  
                                 ccs_io_printf(head, " audit=%s",  
                                               ccs_yesno(cond->post_state[4]));  
1253                  }                  }
1254                  ccs_set_lf(head);                  ccs_set_lf(head);
1255                  return true;                  return true;
# Line 1301  static u8 ccs_fns(const u8 perm, u8 bit) Line 1273  static u8 ccs_fns(const u8 perm, u8 bit)
1273          return bit;          return bit;
1274  }  }
1275    
1276    static void ccs_set_group(struct ccs_io_buffer *head)
1277    {
1278            if (head->type == CCS_EXCEPTIONPOLICY)
1279                    ccs_io_printf(head, "acl_group %u ", head->r.group_index);
1280    }
1281    
1282  /**  /**
1283   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1284   *   *
# Line 1330  static bool ccs_print_entry(struct ccs_i Line 1308  static bool ccs_print_entry(struct ccs_i
1308                          if (!(perm & (1 << bit)))                          if (!(perm & (1 << bit)))
1309                                  continue;                                  continue;
1310                          if (head->r.print_execute_only &&                          if (head->r.print_execute_only &&
1311                              bit != CCS_TYPE_EXECUTE && bit != CCS_TYPE_TRANSIT)                              bit != CCS_TYPE_EXECUTE
1312                                  continue;                              /* && bit != CCS_TYPE_TRANSIT */)
                         /* Print "read/write" instead of "read" and "write". */  
                         if ((bit == CCS_TYPE_READ || bit == CCS_TYPE_WRITE)  
                             && (perm & (1 << CCS_TYPE_READ_WRITE)))  
1313                                  continue;                                  continue;
1314                          break;                          break;
1315                  }                  }
1316                  if (bit >= CCS_MAX_PATH_OPERATION)                  if (bit >= CCS_MAX_PATH_OPERATION)
1317                          goto done;                          goto done;
1318                  ccs_io_printf(head, "allow_%s", ccs_path_keyword[bit]);                  ccs_set_group(head);
1319                    ccs_set_string(head, "file ");
1320                    ccs_set_string(head, ccs_path_keyword[bit]);
1321                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1322          } else if (acl_type == CCS_TYPE_EXECUTE_HANDLER ||          } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
1323                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {                     acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1324                  struct ccs_execute_handler *ptr                  struct ccs_handler_acl *ptr
1325                          = container_of(acl, typeof(*ptr), head);                          = container_of(acl, typeof(*ptr), head);
1326                  ccs_io_printf(head, "%s ",                  ccs_set_group(head);
1327                                acl_type == CCS_TYPE_EXECUTE_HANDLER ?                  ccs_set_string(head, "task ");
1328                                CCS_KEYWORD_EXECUTE_HANDLER :                  ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
1329                                CCS_KEYWORD_DENIED_EXECUTE_HANDLER);                                 ? "auto_execute_handler " :
1330                                   "denied_execute_handler ");
1331                  ccs_set_string(head, ptr->handler->name);                  ccs_set_string(head, ptr->handler->name);
1332            } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
1333                       acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
1334                    struct ccs_task_acl *ptr =
1335                            container_of(acl, typeof(*ptr), head);
1336                    ccs_set_group(head);
1337                    ccs_set_string(head, "task ");
1338                    ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ?
1339                                   "auto_domain_transition " :
1340                                   "manual_domain_transition ");
1341                    ccs_set_string(head, ptr->domainname->name);
1342          } else if (head->r.print_execute_only) {          } else if (head->r.print_execute_only) {
1343                  return true;                  return true;
1344          } else if (acl_type == CCS_TYPE_MKDEV_ACL) {          } else if (acl_type == CCS_TYPE_MKDEV_ACL) {
# Line 1359  static bool ccs_print_entry(struct ccs_i Line 1347  static bool ccs_print_entry(struct ccs_i
1347                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1348                  if (bit >= CCS_MAX_MKDEV_OPERATION)                  if (bit >= CCS_MAX_MKDEV_OPERATION)
1349                          goto done;                          goto done;
1350                  ccs_io_printf(head, "allow_%s", ccs_mkdev_keyword[bit]);                  ccs_set_group(head);
1351                    ccs_set_string(head, "file ");
1352                    ccs_set_string(head, ccs_mkdev_keyword[bit]);
1353                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1354                  ccs_print_number_union(head, &ptr->mode);                  ccs_print_number_union(head, &ptr->mode);
1355                  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 1360  static bool ccs_print_entry(struct ccs_i
1360                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1361                  if (bit >= CCS_MAX_PATH2_OPERATION)                  if (bit >= CCS_MAX_PATH2_OPERATION)
1362                          goto done;                          goto done;
1363                  ccs_io_printf(head, "allow_%s", ccs_path2_keyword[bit]);                  ccs_set_group(head);
1364                    ccs_set_string(head, "file ");
1365                    ccs_set_string(head, ccs_path2_keyword[bit]);
1366                  ccs_print_name_union(head, &ptr->name1);                  ccs_print_name_union(head, &ptr->name1);
1367                  ccs_print_name_union(head, &ptr->name2);                  ccs_print_name_union(head, &ptr->name2);
1368          } 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 1371  static bool ccs_print_entry(struct ccs_i
1371                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1372                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)                  if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)
1373                          goto done;                          goto done;
1374                  ccs_io_printf(head, "allow_%s",                  ccs_set_group(head);
1375                                ccs_path_number_keyword[bit]);                  ccs_set_string(head, "file ");
1376                    ccs_set_string(head, ccs_path_number_keyword[bit]);
1377                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1378                  ccs_print_number_union(head, &ptr->number);                  ccs_print_number_union(head, &ptr->number);
1379          } else if (acl_type == CCS_TYPE_ENV_ACL) {          } else if (acl_type == CCS_TYPE_ENV_ACL) {
1380                  struct ccs_env_acl *ptr =                  struct ccs_env_acl *ptr =
1381                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1382                  ccs_set_string(head, CCS_KEYWORD_ALLOW_ENV);                  ccs_set_group(head);
1383                    ccs_set_string(head, "misc env ");
1384                  ccs_set_string(head, ptr->env->name);                  ccs_set_string(head, ptr->env->name);
1385          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1386                  struct ccs_capability_acl *ptr =                  struct ccs_capability_acl *ptr =
1387                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1388                  ccs_set_string(head, CCS_KEYWORD_ALLOW_CAPABILITY);                  ccs_set_group(head);
1389                    ccs_set_string(head, "capability ");
1390                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));
1391          } else if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          } else if (acl_type == CCS_TYPE_INET_ACL) {
1392                  struct ccs_ip_network_acl *ptr =                  struct ccs_inet_acl *ptr =
1393                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1394                  bit = ccs_fns(ptr->perm, bit);                  bit = ccs_fns(ptr->perm, bit);
1395                  if (bit >= CCS_MAX_NETWORK_OPERATION)                  if (bit >= CCS_MAX_NETWORK_OPERATION)
1396                          goto done;                          goto done;
1397                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",                  ccs_set_group(head);
1398                                ccs_net_keyword[bit]);                  ccs_set_string(head, "network inet ");
1399                    ccs_set_string(head, ccs_proto_keyword[ptr->protocol]);
1400                    ccs_set_space(head);
1401                    ccs_set_string(head, ccs_socket_keyword[bit]);
1402                    ccs_set_space(head);
1403                  switch (ptr->address_type) {                  switch (ptr->address_type) {
1404                          char buf[128];                          char buf[128];
1405                  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 1419  static bool ccs_print_entry(struct ccs_i
1419                          break;                          break;
1420                  }                  }
1421                  ccs_print_number_union(head, &ptr->port);                  ccs_print_number_union(head, &ptr->port);
1422            } else if (acl_type == CCS_TYPE_UNIX_ACL) {
1423                    struct ccs_unix_acl *ptr =
1424                            container_of(acl, typeof(*ptr), head);
1425                    bit = ccs_fns(ptr->perm, bit);
1426                    if (bit >= CCS_MAX_NETWORK_OPERATION)
1427                            goto done;
1428                    ccs_set_group(head);
1429                    ccs_set_string(head, "network unix ");
1430                    ccs_set_string(head, ccs_proto_keyword[ptr->protocol]);
1431                    ccs_set_space(head);
1432                    ccs_set_string(head, ccs_socket_keyword[bit]);
1433                    ccs_print_name_union(head, &ptr->name);
1434          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {          } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1435                  struct ccs_signal_acl *ptr =                  struct ccs_signal_acl *ptr =
1436                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1437                  ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u ", ptr->sig);                  ccs_set_group(head);
1438                    ccs_set_string(head, "ipc signal ");
1439                    ccs_io_printf(head, "%u ", ptr->sig);
1440                  ccs_set_string(head, ptr->domainname->name);                  ccs_set_string(head, ptr->domainname->name);
1441          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {          } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
1442                  struct ccs_mount_acl *ptr =                  struct ccs_mount_acl *ptr =
1443                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1444                  ccs_io_printf(head, "allow_mount");                  ccs_set_group(head);
1445                    ccs_io_printf(head, "file mount");
1446                  ccs_print_name_union(head, &ptr->dev_name);                  ccs_print_name_union(head, &ptr->dev_name);
1447                  ccs_print_name_union(head, &ptr->dir_name);                  ccs_print_name_union(head, &ptr->dir_name);
1448                  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 1466  static bool ccs_print_entry(struct ccs_i
1466          case CCS_TYPE_MKDEV_ACL:          case CCS_TYPE_MKDEV_ACL:
1467          case CCS_TYPE_PATH2_ACL:          case CCS_TYPE_PATH2_ACL:
1468          case CCS_TYPE_PATH_NUMBER_ACL:          case CCS_TYPE_PATH_NUMBER_ACL:
1469          case CCS_TYPE_IP_NETWORK_ACL:          case CCS_TYPE_INET_ACL:
1470            case CCS_TYPE_UNIX_ACL:
1471                  goto next;                  goto next;
1472          }          }
1473   done:   done:
# Line 1465  static bool ccs_print_entry(struct ccs_i Line 1480  static bool ccs_print_entry(struct ccs_i
1480   *   *
1481   * @head:   Pointer to "struct ccs_io_buffer".   * @head:   Pointer to "struct ccs_io_buffer".
1482   * @domain: Pointer to "struct ccs_domain_info".   * @domain: Pointer to "struct ccs_domain_info".
1483     * @index:  Index number.
1484   *   *
1485   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1486   *   *
1487   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1488   */   */
1489  static bool ccs_read_domain2(struct ccs_io_buffer *head,  static bool ccs_read_domain2(struct ccs_io_buffer *head,
1490                               struct ccs_domain_info *domain)                               struct ccs_domain_info *domain,
1491                                 const u8 index)
1492  {  {
1493          list_for_each_cookie(head->r.acl, &domain->acl_info_list) {          list_for_each_cookie(head->r.acl, &domain->acl_info_list[index]) {
1494                  struct ccs_acl_info *ptr =                  struct ccs_acl_info *ptr =
1495                          list_entry(head->r.acl, typeof(*ptr), list);                          list_entry(head->r.acl, typeof(*ptr), list);
1496                  if (!ccs_print_entry(head, ptr))                  if (!ccs_print_entry(head, ptr))
# Line 1508  static void ccs_read_domain(struct ccs_i Line 1525  static void ccs_read_domain(struct ccs_i
1525                          ccs_set_lf(head);                          ccs_set_lf(head);
1526                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",
1527                                        domain->profile);                                        domain->profile);
1528                            ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",
1529                                          domain->group);
1530                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1531                                  if (domain->flags[i])                                  if (domain->flags[i])
1532                                          ccs_set_string(head, ccs_dif[i]);                                          ccs_set_string(head, ccs_dif[i]);
# Line 1515  static void ccs_read_domain(struct ccs_i Line 1534  static void ccs_read_domain(struct ccs_i
1534                          ccs_set_lf(head);                          ccs_set_lf(head);
1535                          /* fall through */                          /* fall through */
1536                  case 1:                  case 1:
1537                          if (!ccs_read_domain2(head, domain))                          if (!ccs_read_domain2(head, domain, 0))
1538                                    return;
1539                            head->r.step++;
1540                            /* fall through */
1541                    case 2:
1542                            if (!ccs_read_domain2(head, domain, 1))
1543                                  return;                                  return;
1544                          head->r.step++;                          head->r.step++;
1545                          if (!ccs_set_lf(head))                          if (!ccs_set_lf(head))
1546                                  return;                                  return;
1547                          /* fall through */                          /* fall through */
1548                  case 2:                  case 3:
1549                          head->r.step = 0;                          head->r.step = 0;
1550                          if (head->r.print_this_domain_only)                          if (head->r.print_this_domain_only)
1551                                  goto done;                                  goto done;
# Line 1661  static void ccs_read_pid(struct ccs_io_b Line 1685  static void ccs_read_pid(struct ccs_io_b
1685                  ccs_io_printf(head, "%u %u ", pid, domain->profile);                  ccs_io_printf(head, "%u %u ", pid, domain->profile);
1686                  ccs_set_string(head, domain->domainname->name);                  ccs_set_string(head, domain->domainname->name);
1687          } else {          } else {
1688                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "                  ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid,
                               "state[0]=%u state[1]=%u state[2]=%u", pid,  
1689                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1690                                          CCS_TASK_IS_MANAGER),                                          CCS_TASK_IS_MANAGER),
1691                                ccs_yesno(ccs_flags &                                ccs_yesno(ccs_flags &
1692                                          CCS_TASK_IS_EXECUTE_HANDLER),                                          CCS_TASK_IS_EXECUTE_HANDLER));
                               (u8) (ccs_flags >> 24),  
                               (u8) (ccs_flags >> 16),  
                               (u8) (ccs_flags >> 8));  
1693          }          }
1694  }  }
1695    
# Line 1702  static int ccs_write_exception(struct cc Line 1722  static int ccs_write_exception(struct cc
1722          static const struct {          static const struct {
1723                  const char *keyword;                  const char *keyword;
1724                  int (*write) (char *, const bool);                  int (*write) (char *, const bool);
1725          } ccs_callback[4] = {          } ccs_callback[3] = {
1726                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1727                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
                 { CCS_KEYWORD_DENY_REWRITE, ccs_write_no_rewrite },  
1728                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }                  { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1729          };          };
1730          for (i = 0; i < 4; i++) {          for (i = 0; i < 3; i++)
1731                  if (ccs_str_starts(&data, ccs_callback[i].keyword))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1732                          return ccs_callback[i].write(data, is_delete);                          return ccs_callback[i].write(data, is_delete);
1733          }          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) {  
1734                  if (ccs_str_starts(&data, ccs_transition_type[i]))                  if (ccs_str_starts(&data, ccs_transition_type[i]))
1735                          return ccs_write_transition_control(data, is_delete,                          return ccs_write_transition_control(data, is_delete,
1736                                                              i);                                                              i);
1737          }          for (i = 0; i < CCS_MAX_GROUP; i++)
         for (i = 0; i < CCS_MAX_GROUP; i++) {  
1738                  if (ccs_str_starts(&data, ccs_group_name[i]))                  if (ccs_str_starts(&data, ccs_group_name[i]))
1739                          return ccs_write_group(data, is_delete, i);                          return ccs_write_group(data, is_delete, i);
1740            if (ccs_str_starts(&data, "acl_group ")) {
1741                    unsigned int group;
1742                    if (sscanf(data, "%u", &group) == 1 &&
1743                        group < CCS_MAX_ACL_GROUPS) {
1744                            data = strchr(data, ' ');
1745                            if (data)
1746                                    return ccs_write_domain2(data + 1,
1747                                                             &ccs_acl_group[group],
1748                                                             is_delete);
1749                    }
1750          }          }
1751          return ccs_write_domain2(data, &ccs_global_domain, is_delete);          return -EINVAL;
1752  }  }
1753    
1754  /**  /**
# Line 1832  static bool ccs_read_policy(struct ccs_i Line 1859  static bool ccs_read_policy(struct ccs_i
1859                                  ccs_set_string(head, ptr->pattern->name);                                  ccs_set_string(head, ptr->pattern->name);
1860                          }                          }
1861                          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;  
1862                  case CCS_ID_RESERVEDPORT:                  case CCS_ID_RESERVEDPORT:
1863                          {                          {
1864                                  struct ccs_reserved *ptr =                                  struct ccs_reserved *ptr =
# Line 1883  static void ccs_read_exception(struct cc Line 1902  static void ccs_read_exception(struct cc
1902                  head->r.step++;                  head->r.step++;
1903          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)          if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
1904                  return;                  return;
1905          head->r.eof = ccs_read_domain2(head, &ccs_global_domain);          while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
1906                   + CCS_MAX_ACL_GROUPS * 2) {
1907                    head->r.group_index = (head->r.step - CCS_MAX_POLICY
1908                                           - CCS_MAX_GROUP) / 2;
1909                    if (!ccs_read_domain2(head,
1910                                          &ccs_acl_group[head->r.group_index],
1911                                          head->r.step & 1))
1912                            return;
1913                    head->r.step++;
1914            }
1915            head->r.eof = true;
1916  }  }
1917    
1918  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
# Line 1893  static DECLARE_WAIT_QUEUE_HEAD(ccs_query Line 1922  static DECLARE_WAIT_QUEUE_HEAD(ccs_query
1922  static DEFINE_SPINLOCK(ccs_query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
1923    
1924  /* Structure for query. */  /* Structure for query. */
1925  struct ccs_query_entry {  struct ccs_query {
1926          struct list_head list;          struct list_head list;
1927          char *query;          char *query;
1928          int query_len;          int query_len;
# Line 1902  struct ccs_query_entry { Line 1931  struct ccs_query_entry {
1931          int answer;          int answer;
1932  };  };
1933    
1934  /* The list for "struct ccs_query_entry". */  /* The list for "struct ccs_query". */
1935  static LIST_HEAD(ccs_query_list);  static LIST_HEAD(ccs_query_list);
1936    
1937  /* 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 1962  int ccs_supervisor(struct ccs_request_in
1962          int pos;          int pos;
1963          int len;          int len;
1964          static unsigned int ccs_serial;          static unsigned int ccs_serial;
1965          struct ccs_query_entry *ccs_query_entry = NULL;          struct ccs_query *entry = NULL;
1966          bool quota_exceeded = false;          bool quota_exceeded = false;
1967          char *header;          char *header;
1968          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 1981  int ccs_supervisor(struct ccs_request_in
1981                  header = ccs_init_log(&len, r);                  header = ccs_init_log(&len, r);
1982                  if (!header)                  if (!header)
1983                          return 0;                          return 0;
1984                  pref = ccs_profile(r->profile)->learning;                  pref = &ccs_profile(r->profile)->preference;
1985                  /* strstr() will return NULL if ordering is wrong. */                  /* strstr() will return NULL if ordering is wrong. */
1986                  if (r->param_type == CCS_TYPE_PATH_ACL &&                  if (r->param_type == CCS_TYPE_PATH_ACL &&
1987                      r->param.path.operation == CCS_TYPE_EXECUTE) {                      r->param.path.operation == CCS_TYPE_EXECUTE) {
# Line 2015  int ccs_supervisor(struct ccs_request_in Line 2044  int ccs_supervisor(struct ccs_request_in
2044                  int i;                  int i;
2045                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2046                          return -EPERM;                          return -EPERM;
2047                  for (i = 0; i < ccs_profile(domain->profile)->enforcing->                  for (i = 0; i < ccs_profile(domain->profile)->preference.
2048                               enforcing_penalty; i++) {                               enforcing_penalty; i++) {
2049                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2050                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
# Line 2025  int ccs_supervisor(struct ccs_request_in Line 2054  int ccs_supervisor(struct ccs_request_in
2054          header = ccs_init_log(&len, r);          header = ccs_init_log(&len, r);
2055          if (!header)          if (!header)
2056                  goto out;                  goto out;
2057          ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), CCS_GFP_FLAGS);          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
2058          if (!ccs_query_entry)          if (!entry)
2059                  goto out;                  goto out;
2060          len = ccs_round2(len);          len = ccs_round2(len);
2061          ccs_query_entry->query = kzalloc(len, CCS_GFP_FLAGS);          entry->query = kzalloc(len, CCS_GFP_FLAGS);
2062          if (!ccs_query_entry->query)          if (!entry->query)
2063                  goto out;                  goto out;
         INIT_LIST_HEAD(&ccs_query_entry->list);  
2064          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2065          if (ccs_quota_for_query && ccs_query_memory_size + len +          if (ccs_quota_for_query && ccs_query_memory_size + len +
2066              sizeof(*ccs_query_entry) >= ccs_quota_for_query) {              sizeof(*entry) >= ccs_quota_for_query) {
2067                  quota_exceeded = true;                  quota_exceeded = true;
2068          } else {          } else {
2069                  ccs_query_memory_size += len + sizeof(*ccs_query_entry);                  ccs_query_memory_size += len + sizeof(*entry);
2070                  ccs_query_entry->serial = ccs_serial++;                  entry->serial = ccs_serial++;
2071          }          }
2072          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2073          if (quota_exceeded)          if (quota_exceeded)
2074                  goto out;                  goto out;
2075          pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",          pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
2076                         ccs_query_entry->serial, r->retry, header);                         entry->serial, r->retry, header);
2077          kfree(header);          kfree(header);
2078          header = NULL;          header = NULL;
2079          va_start(args, fmt);          va_start(args, fmt);
2080          vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);          vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
2081          ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;          entry->query_len = strlen(entry->query) + 1;
2082          va_end(args);          va_end(args);
2083          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2084          list_add_tail(&ccs_query_entry->list, &ccs_query_list);          list_add_tail(&entry->list, &ccs_query_list);
2085          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2086          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
2087          for (ccs_query_entry->timer = 0;          for (entry->timer = 0;
2088               atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;               atomic_read(&ccs_query_observers) && entry->timer < 100;
2089               ccs_query_entry->timer++) {               entry->timer++) {
2090                  wake_up(&ccs_query_wait);                  wake_up(&ccs_query_wait);
2091                  set_current_state(TASK_INTERRUPTIBLE);                  set_current_state(TASK_INTERRUPTIBLE);
2092                  schedule_timeout(HZ / 10);                  schedule_timeout(HZ / 10);
2093                  if (ccs_query_entry->answer)                  if (entry->answer)
2094                          break;                          break;
2095          }          }
2096          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2097          list_del(&ccs_query_entry->list);          list_del(&entry->list);
2098          ccs_query_memory_size -= len + sizeof(*ccs_query_entry);          ccs_query_memory_size -= len + sizeof(*entry);
2099          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2100          switch (ccs_query_entry->answer) {          switch (entry->answer) {
2101          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
2102                  error = CCS_RETRY_REQUEST;                  error = CCS_RETRY_REQUEST;
2103                  r->retry++;                  r->retry++;
# Line 2086  int ccs_supervisor(struct ccs_request_in Line 2114  int ccs_supervisor(struct ccs_request_in
2114                  break;                  break;
2115          }          }
2116   out:   out:
2117          if (ccs_query_entry)          if (entry)
2118                  kfree(ccs_query_entry->query);                  kfree(entry->query);
2119          kfree(ccs_query_entry);          kfree(entry);
2120          kfree(header);          kfree(header);
2121          return error;          return error;
2122  }  }
# Line 2111  static int ccs_poll_query(struct file *f Line 2139  static int ccs_poll_query(struct file *f
2139          for (i = 0; i < 2; i++) {          for (i = 0; i < 2; i++) {
2140                  spin_lock(&ccs_query_list_lock);                  spin_lock(&ccs_query_list_lock);
2141                  list_for_each(tmp, &ccs_query_list) {                  list_for_each(tmp, &ccs_query_list) {
2142                          struct ccs_query_entry *ptr =                          struct ccs_query *ptr =
2143                                  list_entry(tmp, struct ccs_query_entry, list);                                  list_entry(tmp, typeof(*ptr), list);
2144                          if (ptr->answer)                          if (ptr->answer)
2145                                  continue;                                  continue;
2146                          found = true;                          found = true;
# Line 2147  static void ccs_read_query(struct ccs_io Line 2175  static void ccs_read_query(struct ccs_io
2175          }          }
2176          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2177          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2178                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2179                  if (ptr->answer)                  if (ptr->answer)
2180                          continue;                          continue;
2181                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2167  static void ccs_read_query(struct ccs_io Line 2194  static void ccs_read_query(struct ccs_io
2194          pos = 0;          pos = 0;
2195          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2196          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2197                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2198                  if (ptr->answer)                  if (ptr->answer)
2199                          continue;                          continue;
2200                  if (pos++ != head->r.query_index)                  if (pos++ != head->r.query_index)
# Line 2206  static int ccs_write_answer(struct ccs_i Line 2232  static int ccs_write_answer(struct ccs_i
2232          unsigned int answer;          unsigned int answer;
2233          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2234          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2235                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2236                  ptr->timer = 0;                  ptr->timer = 0;
2237          }          }
2238          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
# Line 2215  static int ccs_write_answer(struct ccs_i Line 2240  static int ccs_write_answer(struct ccs_i
2240                  return -EINVAL;                  return -EINVAL;
2241          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2242          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
2243                  struct ccs_query_entry *ptr                  struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
                         = list_entry(tmp, struct ccs_query_entry, list);  
2244                  if (ptr->serial != serial)                  if (ptr->serial != serial)
2245                          continue;                          continue;
2246                  if (!ptr->answer)                  if (!ptr->answer)
# Line 2236  static void ccs_read_version(struct ccs_ Line 2260  static void ccs_read_version(struct ccs_
2260  {  {
2261          if (head->r.eof)          if (head->r.eof)
2262                  return;                  return;
2263          ccs_set_string(head, "1.7.2");          ccs_set_string(head, "1.8.0-pre");
2264          head->r.eof = true;          head->r.eof = true;
2265  }  }
2266    

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

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