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

Subversion リポジトリの参照

Diff of /branches/ccs-patch/security/ccsecurity/policy_io.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c revision 3945 by kumaneko, Sat Sep 4 12:08:57 2010 UTC branches/ccs-patch/security/ccsecurity/policy_io.c revision 4014 by kumaneko, Sat Sep 25 08:54:30 2010 UTC
# Line 12  Line 12 
12    
13  #include "internal.h"  #include "internal.h"
14    
15  static struct ccs_profile ccs_default_profile = {  struct ccs_preference ccs_preference = {
16  #ifdef CONFIG_CCSECURITY_AUDIT          .audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,
17          .preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,          .audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,
18          .preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,          .audit_task_info = true,
19  #endif          .audit_path_info = true,
20          .preference.audit_task_info = true,          .enforcing_penalty = 0,
21          .preference.audit_path_info = true,          .learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,
         .preference.enforcing_penalty = 0,  
         .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,  
         .preference.learning_exec_realpath = true,  
         .preference.learning_exec_argv0 = true,  
         .preference.learning_symlink_target = true,  
22  };  };
23    
24  /* Profile version. Currently only 20100903 is defined. */  /* Profile version. Currently only 20100903 is defined. */
# Line 33  static unsigned int ccs_profile_version; Line 28  static unsigned int ccs_profile_version;
28  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];  static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
29    
30  /* String table for functionality that takes 4 modes. */  /* String table for functionality that takes 4 modes. */
31  const char *ccs_mode[CCS_CONFIG_MAX_MODE] = {  const char * const ccs_mode[CCS_CONFIG_MAX_MODE] = {
32          [CCS_CONFIG_DISABLED] = "disabled",          [CCS_CONFIG_DISABLED]   = "disabled",
33          [CCS_CONFIG_LEARNING] = "learning",          [CCS_CONFIG_LEARNING]   = "learning",
34          [CCS_CONFIG_PERMISSIVE] = "permissive",          [CCS_CONFIG_PERMISSIVE] = "permissive",
35          [CCS_CONFIG_ENFORCING] = "enforcing"          [CCS_CONFIG_ENFORCING]  = "enforcing"
36  };  };
37    
38  /* String table for /proc/ccs/profile */  /* String table for /proc/ccs/profile */
39  static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX +  const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX
40                                      CCS_MAX_CAPABILITY_INDEX +                                      + CCS_MAX_MAC_CATEGORY_INDEX] = {
41                                      CCS_MAX_MAC_CATEGORY_INDEX] = {          [CCS_MAC_FILE_EXECUTE]    = "execute",
42          [CCS_MAC_FILE_EXECUTE]          [CCS_MAC_FILE_OPEN]       = "open",
43          = "file::execute",          [CCS_MAC_FILE_CREATE]     = "create",
44          [CCS_MAC_FILE_OPEN]          [CCS_MAC_FILE_UNLINK]     = "unlink",
45          = "file::open",          [CCS_MAC_FILE_MKDIR]      = "mkdir",
46          [CCS_MAC_FILE_CREATE]          [CCS_MAC_FILE_RMDIR]      = "rmdir",
47          = "file::create",          [CCS_MAC_FILE_MKFIFO]     = "mkfifo",
48          [CCS_MAC_FILE_UNLINK]          [CCS_MAC_FILE_MKSOCK]     = "mksock",
49          = "file::unlink",          [CCS_MAC_FILE_TRUNCATE]   = "truncate",
50          [CCS_MAC_FILE_MKDIR]          [CCS_MAC_FILE_SYMLINK]    = "symlink",
51          = "file::mkdir",          [CCS_MAC_FILE_MKBLOCK]    = "mkblock",
52          [CCS_MAC_FILE_RMDIR]          [CCS_MAC_FILE_MKCHAR]     = "mkchar",
53          = "file::rmdir",          [CCS_MAC_FILE_LINK]       = "link",
54          [CCS_MAC_FILE_MKFIFO]          [CCS_MAC_FILE_RENAME]     = "rename",
55          = "file::mkfifo",          [CCS_MAC_FILE_CHMOD]      = "chmod",
56          [CCS_MAC_FILE_MKSOCK]          [CCS_MAC_FILE_CHOWN]      = "chown",
57          = "file::mksock",          [CCS_MAC_FILE_CHGRP]      = "chgrp",
58          [CCS_MAC_FILE_TRUNCATE]          [CCS_MAC_FILE_IOCTL]      = "ioctl",
59          = "file::truncate",          [CCS_MAC_FILE_CHROOT]     = "chroot",
60          [CCS_MAC_FILE_SYMLINK]          [CCS_MAC_FILE_MOUNT]      = "mount",
61          = "file::symlink",          [CCS_MAC_FILE_UMOUNT]     = "unmount",
62          [CCS_MAC_FILE_MKBLOCK]          [CCS_MAC_FILE_PIVOT_ROOT] = "pivot_root",
63          = "file::mkblock",          [CCS_MAC_ENVIRON] = "env",
64          [CCS_MAC_FILE_MKCHAR]          [CCS_MAC_NETWORK_INET_STREAM_BIND]       = "inet_stream_bind",
65          = "file::mkchar",          [CCS_MAC_NETWORK_INET_STREAM_LISTEN]     = "inet_stream_listen",
66          [CCS_MAC_FILE_LINK]          [CCS_MAC_NETWORK_INET_STREAM_CONNECT]    = "inet_stream_connect",
67          = "file::link",          [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]     = "inet_stream_accept",
68          [CCS_MAC_FILE_RENAME]          [CCS_MAC_NETWORK_INET_DGRAM_BIND]        = "inet_dgram_bind",
69          = "file::rename",          [CCS_MAC_NETWORK_INET_DGRAM_SEND]        = "inet_dgram_send",
70          [CCS_MAC_FILE_CHMOD]          [CCS_MAC_NETWORK_INET_DGRAM_RECV]        = "inet_dgram_recv",
71          = "file::chmod",          [CCS_MAC_NETWORK_INET_RAW_BIND]          = "inet_raw_bind",
72          [CCS_MAC_FILE_CHOWN]          [CCS_MAC_NETWORK_INET_RAW_SEND]          = "inet_raw_send",
73          = "file::chown",          [CCS_MAC_NETWORK_INET_RAW_RECV]          = "inet_raw_recv",
74          [CCS_MAC_FILE_CHGRP]          [CCS_MAC_NETWORK_UNIX_STREAM_BIND]       = "unix_stream_bind",
75          = "file::chgrp",          [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]     = "unix_stream_listen",
76          [CCS_MAC_FILE_IOCTL]          [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]    = "unix_stream_connect",
77          = "file::ioctl",          [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]     = "unix_stream_accept",
78          [CCS_MAC_FILE_CHROOT]          [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]        = "unix_dgram_bind",
79          = "file::chroot",          [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]        = "unix_dgram_send",
80          [CCS_MAC_FILE_MOUNT]          [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]        = "unix_dgram_recv",
81          = "file::mount",          [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = "unix_seqpacket_bind",
82          [CCS_MAC_FILE_UMOUNT]          [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = "unix_seqpacket_listen",
83          = "file::umount",          [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
84          [CCS_MAC_FILE_PIVOT_ROOT]          [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = "unix_seqpacket_accept",
85          = "file::pivot_root",          [CCS_MAC_SIGNAL] = "signal",
86          [CCS_MAC_ENVIRON]          [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = "use_route",
87          = "misc::env",          [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = "use_packet",
88          [CCS_MAC_NETWORK_INET_STREAM_BIND]          [CCS_MAC_CAPABILITY_SYS_REBOOT]        = "SYS_REBOOT",
89          = "network::inet_stream_bind",          [CCS_MAC_CAPABILITY_SYS_VHANGUP]       = "SYS_VHANGUP",
90          [CCS_MAC_NETWORK_INET_STREAM_LISTEN]          [CCS_MAC_CAPABILITY_SYS_SETTIME]       = "SYS_TIME",
91          = "network::inet_stream_listen",          [CCS_MAC_CAPABILITY_SYS_NICE]          = "SYS_NICE",
92          [CCS_MAC_NETWORK_INET_STREAM_CONNECT]          [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = "SYS_SETHOSTNAME",
93          = "network::inet_stream_connect",          [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
94          [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]          [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = "SYS_KEXEC_LOAD",
95          = "network::inet_stream_accept",          [CCS_MAC_CAPABILITY_SYS_PTRACE]        = "SYS_PTRACE",
96          [CCS_MAC_NETWORK_INET_DGRAM_BIND]          [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE]       = "file",
97          = "network::inet_dgram_bind",          [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NETWORK]    = "network",
98          [CCS_MAC_NETWORK_INET_DGRAM_SEND]          [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_MISC]       = "misc",
99          = "network::inet_dgram_send",          [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_IPC]        = "ipc",
100          [CCS_MAC_NETWORK_INET_DGRAM_RECV]          [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
101          = "network::inet_dgram_recv",  };
102          [CCS_MAC_NETWORK_INET_RAW_BIND]  
103          = "network::inet_raw_bind",  const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = {
104          [CCS_MAC_NETWORK_INET_RAW_SEND]          [CCS_TYPE_EXECUTE]    = "execute",
105          = "network::inet_raw_send",          [CCS_TYPE_READ]       = "read",
106          [CCS_MAC_NETWORK_INET_RAW_RECV]          [CCS_TYPE_WRITE]      = "write",
107          = "network::inet_raw_recv",          [CCS_TYPE_APPEND]     = "append",
108          [CCS_MAC_NETWORK_UNIX_STREAM_BIND]          [CCS_TYPE_UNLINK]     = "unlink",
109          = "network::unix_stream_bind",          [CCS_TYPE_RMDIR]      = "rmdir",
110          [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]          [CCS_TYPE_TRUNCATE]   = "truncate",
111          = "network::unix_stream_listen",          [CCS_TYPE_SYMLINK]    = "symlink",
112          [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]          [CCS_TYPE_CHROOT]     = "chroot",
113          = "network::unix_stream_connect",          [CCS_TYPE_UMOUNT]     = "unmount",
114          [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]  };
115          = "network::unix_stream_accept",  
116          [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]  static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = {
117          = "network::unix_dgram_bind",          [CCS_MAC_CATEGORY_FILE]       = "file",
118          [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]          [CCS_MAC_CATEGORY_NETWORK]    = "network",
119          = "network::unix_dgram_send",          [CCS_MAC_CATEGORY_MISC]       = "misc",
120          [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]          [CCS_MAC_CATEGORY_IPC]        = "ipc",
121          = "network::unix_dgram_recv",          [CCS_MAC_CATEGORY_CAPABILITY] = "capability",
122          [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]  };
123          = "network::unix_seqpacket_bind",  
124          [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = {
125          = "network::unix_seqpacket_listen",          [CCS_TASK_UID]             = "task.uid",
126          [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT]          [CCS_TASK_EUID]            = "task.euid",
127          = "network::unix_seqpacket_connect",          [CCS_TASK_SUID]            = "task.suid",
128          [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]          [CCS_TASK_FSUID]           = "task.fsuid",
129          = "network::unix_seqpacket_accept",          [CCS_TASK_GID]             = "task.gid",
130          [CCS_MAC_SIGNAL]          [CCS_TASK_EGID]            = "task.egid",
131          = "ipc::signal",          [CCS_TASK_SGID]            = "task.sgid",
132          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]          [CCS_TASK_FSGID]           = "task.fsgid",
133          = "capability::use_route",          [CCS_TASK_PID]             = "task.pid",
134          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]          [CCS_TASK_PPID]            = "task.ppid",
135          = "capability::use_packet",          [CCS_EXEC_ARGC]            = "exec.argc",
136          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]          [CCS_EXEC_ENVC]            = "exec.envc",
137          = "capability::SYS_REBOOT",          [CCS_TYPE_IS_SOCKET]       = "socket",
138          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]          [CCS_TYPE_IS_SYMLINK]      = "symlink",
139          = "capability::SYS_VHANGUP",          [CCS_TYPE_IS_FILE]         = "file",
140          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]          [CCS_TYPE_IS_BLOCK_DEV]    = "block",
141          = "capability::SYS_TIME",          [CCS_TYPE_IS_DIRECTORY]    = "directory",
142          [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]          [CCS_TYPE_IS_CHAR_DEV]     = "char",
143          = "capability::SYS_NICE",          [CCS_TYPE_IS_FIFO]         = "fifo",
144          [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]          [CCS_MODE_SETUID]          = "setuid",
145          = "capability::SYS_SETHOSTNAME",          [CCS_MODE_SETGID]          = "setgid",
146          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]          [CCS_MODE_STICKY]          = "sticky",
147          = "capability::use_kernel_module",          [CCS_MODE_OWNER_READ]      = "owner_read",
148          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]          [CCS_MODE_OWNER_WRITE]     = "owner_write",
149          = "capability::SYS_KEXEC_LOAD",          [CCS_MODE_OWNER_EXECUTE]   = "owner_execute",
150          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]          [CCS_MODE_GROUP_READ]      = "group_read",
151          = "capability::SYS_PTRACE",          [CCS_MODE_GROUP_WRITE]     = "group_write",
152          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MODE_GROUP_EXECUTE]   = "group_execute",
153           + CCS_MAC_CATEGORY_FILE] = "file",          [CCS_MODE_OTHERS_READ]     = "others_read",
154          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_MODE_OTHERS_WRITE]    = "others_write",
155           + CCS_MAC_CATEGORY_NETWORK] = "network",          [CCS_MODE_OTHERS_EXECUTE]  = "others_execute",
156          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_TASK_TYPE]            = "task.type",
157           + CCS_MAC_CATEGORY_MISC] = "misc",          [CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
158          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_EXEC_REALPATH]        = "exec.realpath",
159           + CCS_MAC_CATEGORY_IPC] = "ipc",          [CCS_SYMLINK_TARGET]       = "symlink.target",
160          [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          [CCS_PATH1_UID]            = "path1.uid",
161           + CCS_MAC_CATEGORY_CAPABILITY] = "capability",          [CCS_PATH1_GID]            = "path1.gid",
162            [CCS_PATH1_INO]            = "path1.ino",
163            [CCS_PATH1_MAJOR]          = "path1.major",
164            [CCS_PATH1_MINOR]          = "path1.minor",
165            [CCS_PATH1_PERM]           = "path1.perm",
166            [CCS_PATH1_TYPE]           = "path1.type",
167            [CCS_PATH1_DEV_MAJOR]      = "path1.dev_major",
168            [CCS_PATH1_DEV_MINOR]      = "path1.dev_minor",
169            [CCS_PATH2_UID]            = "path2.uid",
170            [CCS_PATH2_GID]            = "path2.gid",
171            [CCS_PATH2_INO]            = "path2.ino",
172            [CCS_PATH2_MAJOR]          = "path2.major",
173            [CCS_PATH2_MINOR]          = "path2.minor",
174            [CCS_PATH2_PERM]           = "path2.perm",
175            [CCS_PATH2_TYPE]           = "path2.type",
176            [CCS_PATH2_DEV_MAJOR]      = "path2.dev_major",
177            [CCS_PATH2_DEV_MINOR]      = "path2.dev_minor",
178            [CCS_PATH1_PARENT_UID]     = "path1.parent.uid",
179            [CCS_PATH1_PARENT_GID]     = "path1.parent.gid",
180            [CCS_PATH1_PARENT_INO]     = "path1.parent.ino",
181            [CCS_PATH1_PARENT_PERM]    = "path1.parent.perm",
182            [CCS_PATH2_PARENT_UID]     = "path2.parent.uid",
183            [CCS_PATH2_PARENT_GID]     = "path2.parent.gid",
184            [CCS_PATH2_PARENT_INO]     = "path2.parent.ino",
185            [CCS_PATH2_PARENT_PERM]    = "path2.parent.perm",
186  };  };
187    
188  /* Permit policy management by non-root user? */  /* Permit policy management by non-root user? */
189  static bool ccs_manage_by_non_root;  static bool ccs_manage_by_non_root;
190    
191  /**  /**
  * ccs_cap2keyword - Convert capability operation to capability name.  
  *  
  * @operation: The capability index.  
  *  
  * Returns the name of the specified capability's name.  
  */  
 const char *ccs_cap2keyword(const u8 operation)  
 {  
         return operation < CCS_MAX_CAPABILITY_INDEX  
                 ? ccs_mac_keywords[CCS_MAX_MAC_INDEX + operation] + 12 : NULL;  
 }  
   
 /**  
192   * ccs_yesno - Return "yes" or "no".   * ccs_yesno - Return "yes" or "no".
193   *   *
194   * @value: Bool value.   * @value: Bool value.
# Line 322  static struct ccs_profile *ccs_assign_pr Line 328  static struct ccs_profile *ccs_assign_pr
328          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
329                  ptr = entry;                  ptr = entry;
330                  ptr->default_config = CCS_CONFIG_DISABLED |                  ptr->default_config = CCS_CONFIG_DISABLED |
                         CCS_CONFIG_VERBOSE |  
331                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;                          CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
332                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,                  memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
333                         sizeof(ptr->config));                         sizeof(ptr->config));
# Line 368  static void ccs_check_profile(void) Line 373  static void ccs_check_profile(void)
373   */   */
374  struct ccs_profile *ccs_profile(const u8 profile)  struct ccs_profile *ccs_profile(const u8 profile)
375  {  {
376            static struct ccs_profile ccs_null_profile;
377          struct ccs_profile *ptr = ccs_profile_ptr[profile];          struct ccs_profile *ptr = ccs_profile_ptr[profile];
378          if (!ccs_policy_loaded)          if (!ptr)
379                  return &ccs_default_profile;                  ptr = &ccs_null_profile;
         BUG_ON(!ptr);  
380          return ptr;          return ptr;
381  }  }
382    
# Line 407  static void ccs_set_uint(unsigned int *i Line 412  static void ccs_set_uint(unsigned int *i
412                  sscanf(cp + strlen(find), "=%u", i);                  sscanf(cp + strlen(find), "=%u", i);
413  }  }
414    
415  static void ccs_set_pref(const char *name, const char *value,  static int ccs_set_pref(char *data)
                          struct ccs_profile *profile)  
416  {  {
417          if (!strcmp(name, "audit")) {          if (ccs_str_starts(&data, "audit")) {
418  #ifdef CONFIG_CCSECURITY_AUDIT                  ccs_set_uint(&ccs_preference.audit_max_grant_log, data,
                 ccs_set_uint(&profile->preference.audit_max_grant_log, value,  
419                               "max_grant_log");                               "max_grant_log");
420                  ccs_set_uint(&profile->preference.audit_max_reject_log, value,                  ccs_set_uint(&ccs_preference.audit_max_reject_log, data,
421                               "max_reject_log");                               "max_reject_log");
422  #endif                  ccs_set_bool(&ccs_preference.audit_task_info, data,
                 ccs_set_bool(&profile->preference.audit_task_info, value,  
423                               "task_info");                               "task_info");
424                  ccs_set_bool(&profile->preference.audit_path_info, value,                  ccs_set_bool(&ccs_preference.audit_path_info, data,
425                               "path_info");                               "path_info");
426                  return;          } else if (ccs_str_starts(&data, "enforcing")) {
427          }                  ccs_set_uint(&ccs_preference.enforcing_penalty, data,
         if (!strcmp(name, "enforcing")) {  
                 ccs_set_uint(&profile->preference.enforcing_penalty, value,  
428                               "penalty");                               "penalty");
429                  return;          } else if (ccs_str_starts(&data, "learning")) {
430          }                  ccs_set_uint(&ccs_preference.learning_max_entry, data,
         if (!strcmp(name, "learning")) {  
                 ccs_set_uint(&profile->preference.learning_max_entry, value,  
431                               "max_entry");                               "max_entry");
432                  ccs_set_bool(&profile->preference.learning_exec_realpath,          } else
433                               value, "exec.realpath");                  return -EINVAL;
434                  ccs_set_bool(&profile->preference.learning_exec_argv0, value,          return 0;
                              "exec.argv0");  
                 ccs_set_bool(&profile->preference.learning_symlink_target,  
                              value, "symlink.target");  
                 return;  
         }  
435  }  }
436    
437  static int ccs_set_mode(char *name, const char *value,  static int ccs_set_mode(char *name, const char *value,
# Line 447  static int ccs_set_mode(char *name, cons Line 440  static int ccs_set_mode(char *name, cons
440          u8 i;          u8 i;
441          u8 config;          u8 config;
442          if (!strcmp(name, "CONFIG")) {          if (!strcmp(name, "CONFIG")) {
443                  i = CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX                  i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
                         + CCS_MAX_MAC_CATEGORY_INDEX;  
444                  config = profile->default_config;                  config = profile->default_config;
445          } else if (ccs_str_starts(&name, "CONFIG::")) {          } else if (ccs_str_starts(&name, "CONFIG::")) {
446                  config = 0;                  config = 0;
447                  for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX                  for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
448                               + CCS_MAX_MAC_CATEGORY_INDEX; i++) {                       i++) {
449                          if (strcmp(name, ccs_mac_keywords[i]))                          int len = 0;
450                            if (i < CCS_MAX_MAC_INDEX) {
451                                    const u8 c = ccs_index2category[i];
452                                    const char *category = ccs_category_keywords[c];
453                                    len = strlen(category);
454                                    if (strncmp(name, category, len) ||
455                                        name[len++] != ':' || name[len++] != ':')
456                                            continue;
457                            }
458                            if (strcmp(name + len, ccs_mac_keywords[i]))
459                                  continue;                                  continue;
460                          config = profile->config[i];                          config = profile->config[i];
461                          break;                          break;
462                  }                  }
463                  if (i == CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX                  if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
                     + CCS_MAX_MAC_CATEGORY_INDEX)  
464                          return -EINVAL;                          return -EINVAL;
465          } else {          } else {
466                  return -EINVAL;                  return -EINVAL;
# Line 477  static int ccs_set_mode(char *name, cons Line 477  static int ccs_set_mode(char *name, cons
477                                   */                                   */
478                                  config = (config & ~7) | mode;                                  config = (config & ~7) | mode;
479                  if (config != CCS_CONFIG_USE_DEFAULT) {                  if (config != CCS_CONFIG_USE_DEFAULT) {
                         switch (ccs_find_yesno(value, "verbose")) {  
                         case 1:  
                                 config |= CCS_CONFIG_VERBOSE;  
                                 break;  
                         case 0:  
                                 config &= ~CCS_CONFIG_VERBOSE;  
                                 break;  
                         }  
 #ifdef CONFIG_CCSECURITY_AUDIT  
480                          switch (ccs_find_yesno(value, "grant_log")) {                          switch (ccs_find_yesno(value, "grant_log")) {
481                          case 1:                          case 1:
482                                  config |= CCS_CONFIG_WANT_GRANT_LOG;                                  config |= CCS_CONFIG_WANT_GRANT_LOG;
# Line 502  static int ccs_set_mode(char *name, cons Line 493  static int ccs_set_mode(char *name, cons
493                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;
494                                  break;                                  break;
495                          }                          }
 #endif  
496                  }                  }
497          }          }
498          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
             + CCS_MAX_MAC_CATEGORY_INDEX)  
499                  profile->config[i] = config;                  profile->config[i] = config;
500          else if (config != CCS_CONFIG_USE_DEFAULT)          else if (config != CCS_CONFIG_USE_DEFAULT)
501                  profile->default_config = config;                  profile->default_config = config;
# Line 528  static int ccs_write_profile(struct ccs_ Line 517  static int ccs_write_profile(struct ccs_
517          struct ccs_profile *profile;          struct ccs_profile *profile;
518          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)          if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
519                  return 0;                  return 0;
520            if (ccs_str_starts(&data, "PREFERENCE::"))
521                    return ccs_set_pref(data);
522          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
523          if (*cp != '-')          if (*cp != '-')
524                  return -EINVAL;                  return -EINVAL;
# Line 539  static int ccs_write_profile(struct ccs_ Line 530  static int ccs_write_profile(struct ccs_
530          if (!cp)          if (!cp)
531                  return -EINVAL;                  return -EINVAL;
532          *cp++ = '\0';          *cp++ = '\0';
         if (ccs_str_starts(&data, "PREFERENCE::")) {  
                 ccs_set_pref(data, cp, profile);  
                 return 0;  
         }  
533          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
534                  const struct ccs_path_info *old_comment = profile->comment;                  const struct ccs_path_info *old_comment = profile->comment;
535                  profile->comment = ccs_get_name(cp);                  profile->comment = ccs_get_name(cp);
# Line 552  static int ccs_write_profile(struct ccs_ Line 539  static int ccs_write_profile(struct ccs_
539          return ccs_set_mode(data, cp, profile);          return ccs_set_mode(data, cp, profile);
540  }  }
541    
542  static void ccs_print_preference(struct ccs_io_buffer *head, const int index)  static void ccs_print_preference(struct ccs_io_buffer *head)
543  {  {
544          struct ccs_profile *profile = ccs_profile_ptr[index];          ccs_io_printf(head, "PREFERENCE::%s={ "
         struct ccs_preference *pref = &profile->preference;  
         ccs_io_printf(head, "%u-PREFERENCE::%s={ "  
 #ifdef CONFIG_CCSECURITY_AUDIT  
545                        "max_grant_log=%u max_reject_log=%u "                        "max_grant_log=%u max_reject_log=%u "
546  #endif                        "task_info=%s path_info=%s }\n", "audit",
547                        "task_info=%s path_info=%s }\n", index,                        ccs_preference.audit_max_grant_log,
548                        "audit",                        ccs_preference.audit_max_reject_log,
549  #ifdef CONFIG_CCSECURITY_AUDIT                        ccs_yesno(ccs_preference.audit_task_info),
550                        pref->audit_max_grant_log,                        ccs_yesno(ccs_preference.audit_path_info));
551                        pref->audit_max_reject_log,          ccs_io_printf(head, "PREFERENCE::%s={ max_entry=%u }\n",
552  #endif                        "learning", ccs_preference.learning_max_entry);
553                        ccs_yesno(pref->audit_task_info),          ccs_io_printf(head, "PREFERENCE::%s={ penalty=%u }\n",
554                        ccs_yesno(pref->audit_path_info));                        "enforcing", ccs_preference.enforcing_penalty);
         ccs_io_printf(head, "%u-PREFERENCE::%s={ "  
                       "max_entry=%u exec.realpath=%s "  
                       "exec.argv0=%s symlink.target=%s }\n",  
                       index, "learning",  
                       pref->learning_max_entry,  
                       ccs_yesno(pref->learning_exec_realpath),  
                       ccs_yesno(pref->learning_exec_argv0),  
                       ccs_yesno(pref->learning_symlink_target));  
         ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index,  
                       "enforcing", pref->enforcing_penalty);  
555  }  }
556    
557  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)
558  {  {
559          ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3],          ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
560                        ccs_yesno(config & CCS_CONFIG_VERBOSE));                        ccs_mode[config & 3],
 #ifdef CONFIG_CCSECURITY_AUDIT  
         ccs_io_printf(head, " grant_log=%s reject_log=%s",  
561                        ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),                        ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
562                        ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));                        ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));
 #endif  
         ccs_set_string(head, " }\n");  
563  }  }
564    
565  /**  /**
# Line 607  static void ccs_read_profile(struct ccs_ Line 577  static void ccs_read_profile(struct ccs_
577          switch (head->r.step) {          switch (head->r.step) {
578          case 0:          case 0:
579                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20100903");                  ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20100903");
580                    ccs_print_preference(head);
581                  head->r.step++;                  head->r.step++;
582                  break;                  break;
583          case 1:          case 1:
# Line 637  static void ccs_read_profile(struct ccs_ Line 608  static void ccs_read_profile(struct ccs_
608                  break;                  break;
609          case 4:          case 4:
610                  for ( ; head->r.bit < CCS_MAX_MAC_INDEX                  for ( ; head->r.bit < CCS_MAX_MAC_INDEX
                               + CCS_MAX_CAPABILITY_INDEX  
611                                + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {                                + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
612                          const u8 i = head->r.bit;                          const u8 i = head->r.bit;
613                          const u8 config = profile->config[i];                          const u8 config = profile->config[i];
614                          if (config == CCS_CONFIG_USE_DEFAULT)                          if (config == CCS_CONFIG_USE_DEFAULT)
615                                  continue;                                  continue;
616                          ccs_io_printf(head, "%u-%s%s", index, "CONFIG::",                          if (i < CCS_MAX_MAC_INDEX)
617                                        ccs_mac_keywords[i]);                                  ccs_io_printf(head, "%u-CONFIG::%s::%s", index,
618                                                  ccs_category_keywords
619                                                  [ccs_index2category[i]],
620                                                  ccs_mac_keywords[i]);
621                            else
622                                    ccs_io_printf(head, "%u-CONFIG::%s", index,
623                                                  ccs_mac_keywords[i]);
624                          ccs_print_config(head, config);                          ccs_print_config(head, config);
625                          head->r.bit++;                          head->r.bit++;
626                          break;                          break;
627                  }                  }
628                  if (head->r.bit == CCS_MAX_MAC_INDEX                  if (head->r.bit == CCS_MAX_MAC_INDEX
                     + CCS_MAX_CAPABILITY_INDEX  
629                      + CCS_MAX_MAC_CATEGORY_INDEX) {                      + CCS_MAX_MAC_CATEGORY_INDEX) {
                         ccs_print_preference(head, index);  
630                          head->r.index++;                          head->r.index++;
631                          head->r.step = 1;                          head->r.step = 1;
632                  }                  }
# Line 709  static int ccs_update_manager_entry(cons Line 683  static int ccs_update_manager_entry(cons
683  static int ccs_write_manager(struct ccs_io_buffer *head)  static int ccs_write_manager(struct ccs_io_buffer *head)
684  {  {
685          char *data = head->write_buf;          char *data = head->write_buf;
686          bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);          bool is_delete = ccs_str_starts(&data, "delete ");
687          if (!strcmp(data, "manage_by_non_root")) {          if (!strcmp(data, "manage_by_non_root")) {
688                  ccs_manage_by_non_root = !is_delete;                  ccs_manage_by_non_root = !is_delete;
689                  return 0;                  return 0;
# Line 794  static bool ccs_manager(void) Line 768  static bool ccs_manager(void)
768  }  }
769    
770  /**  /**
  * ccs_find_condition_part - Find condition part from the statement.  
  *  
  * @data: String to parse.  
  *  
  * Returns pointer to the condition part if it was found in the statement,  
  * NULL otherwise.  
  */  
 static char *ccs_find_condition_part(char *data)  
 {  
         char *cp = strstr(data, " if ");  
         if (cp) {  
                 while (1) {  
                         char *cp2 = strstr(cp + 3, " if ");  
                         if (!cp2)  
                                 break;  
                         cp = cp2;  
                 }  
                 *cp = '\0';  
                 cp += 4;  
         }  
         return cp;  
 }  
   
 /**  
771   * ccs_select_one - Parse select command.   * ccs_select_one - Parse select command.
772   *   *
773   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 878  static bool ccs_same_handler_acl(const s Line 828  static bool ccs_same_handler_acl(const s
828  {  {
829          const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head);          const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head);
830          const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head);          const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head);
831          return ccs_same_acl_head(&p1->head, &p2->head) &&          return p1->handler == p2->handler;
                 p1->handler == p2->handler;  
832  }  }
833    
834  static bool ccs_same_task_acl(const struct ccs_acl_info *a,  static bool ccs_same_task_acl(const struct ccs_acl_info *a,
# Line 887  static bool ccs_same_task_acl(const stru Line 836  static bool ccs_same_task_acl(const stru
836  {  {
837          const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head);          const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head);
838          const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head);          const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head);
839          return ccs_same_acl_head(&p1->head, &p2->head) &&          return p1->domainname == p2->domainname;
                 p1->domainname == p2->domainname;  
840  }  }
841    
842  /**  /**
843   * ccs_write_task - Update task related list.   * ccs_write_task - Update task related list.
844   *   *
845   * @data:      String to parse.   * @param: Pointer to "struct ccs_acl_param".
  * @domain:    Pointer to "struct ccs_domain_info".  
  * @condition: Pointer to "struct ccs_condition". Maybe NULL.  
  * @is_delete: True if it is a delete request.  
846   *   *
847   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
848   */   */
849  static int ccs_write_task(char *data, struct ccs_domain_info *domain,  static int ccs_write_task(struct ccs_acl_param *param)
                           struct ccs_condition *condition,  
                           const bool is_delete)  
850  {  {
851          int error;          int error;
852          const bool is_auto = ccs_str_starts(&data, "auto_domain_transition ");          const bool is_auto = ccs_str_starts(&param->data,
853          if (!is_auto && !ccs_str_starts(&data, "manual_domain_transition ")) {                                              "auto_domain_transition ");
854                  struct ccs_handler_acl e = {          if (!is_auto && !ccs_str_starts(&param->data,
855                          .head.cond = condition,                                          "manual_domain_transition ")) {
856                  };                  struct ccs_handler_acl e = { };
857                  if (ccs_str_starts(&data, "auto_execute_handler "))                  char *handler;
858                    if (ccs_str_starts(&param->data, "auto_execute_handler "))
859                          e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;                          e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
860                  else if (ccs_str_starts(&data, "denied_execute_handler "))                  else if (ccs_str_starts(&param->data,
861                                            "denied_execute_handler "))
862                          e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;                          e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
863                  else                  else
864                          return -EINVAL;                          return -EINVAL;
865                  if (!ccs_correct_path(data))                  handler = ccs_read_token(param);
866                    if (!ccs_correct_path(handler))
867                          return -EINVAL;                          return -EINVAL;
868                  e.handler = ccs_get_name(data);                  e.handler = ccs_get_name(handler);
869                  if (!e.handler)                  if (!e.handler)
870                          return -ENOMEM;                          return -ENOMEM;
871                  if (e.handler->is_patterned)                  if (e.handler->is_patterned)
872                          error = -EINVAL; /* No patterns allowed. */                          error = -EINVAL; /* No patterns allowed. */
873                  else                  else
874                          error = ccs_update_domain(&e.head, sizeof(e),                          error = ccs_update_domain(&e.head, sizeof(e), param,
                                                   is_delete, domain,  
875                                                    ccs_same_handler_acl, NULL);                                                    ccs_same_handler_acl, NULL);
876                  ccs_put_name(e.handler);                  ccs_put_name(e.handler);
877          } else {          } else {
878                  struct ccs_task_acl e = {                  struct ccs_task_acl e = {
879                          .head.type = is_auto ?                          .head.type = is_auto ?
880                          CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL,                          CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL,
881                          .head.cond = condition,                          .domainname = ccs_get_domainname(param),
882                  };                  };
                 if (!ccs_correct_domain(data))  
                         return -EINVAL;  
                 e.domainname = ccs_get_name(data);  
883                  if (!e.domainname)                  if (!e.domainname)
884                          return -ENOMEM;                          error = -EINVAL;
885                  error = ccs_update_domain(&e.head, sizeof(e), is_delete,                  else
886                                            domain, ccs_same_task_acl, NULL);                          error = ccs_update_domain(&e.head, sizeof(e), param,
887                                                      ccs_same_task_acl, NULL);
888                  ccs_put_name(e.domainname);                  ccs_put_name(e.domainname);
889          }          }
890          return error;          return error;
# Line 950  static int ccs_write_task(char *data, st Line 893  static int ccs_write_task(char *data, st
893  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,  static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,
894                               const bool is_delete)                               const bool is_delete)
895  {  {
896            struct ccs_acl_param param = {
897                    .data = data,
898                    .domain = domain,
899                    .is_delete = is_delete,
900            };
901          static const struct {          static const struct {
902                  const char *keyword;                  const char *keyword;
903                  int (*write) (char *, struct ccs_domain_info *,                  int (*write) (struct ccs_acl_param *);
                               struct ccs_condition *, const bool);  
904          } ccs_callback[7] = {          } ccs_callback[7] = {
905                  { "file ", ccs_write_file },                  { "file ", ccs_write_file },
906                  { "network inet ", ccs_write_inet_network },                  { "network inet ", ccs_write_inet_network },
# Line 963  static int ccs_write_domain2(char *data, Line 910  static int ccs_write_domain2(char *data,
910                  { "ipc ", ccs_write_ipc },                  { "ipc ", ccs_write_ipc },
911                  { "task ", ccs_write_task },                  { "task ", ccs_write_task },
912          };          };
         int error = -EINVAL;  
913          u8 i;          u8 i;
         struct ccs_condition *cond = NULL;  
         char *cp = ccs_find_condition_part(data);  
         if (cp) {  
                 cond = ccs_get_condition(cp);  
                 if (!cond)  
                         return -EINVAL;  
         }  
914          for (i = 0; i < 7; i++) {          for (i = 0; i < 7; i++) {
915                  if (!ccs_str_starts(&data, ccs_callback[i].keyword))                  if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
916                          continue;                          continue;
917                  error = ccs_callback[i].write(data, domain, cond, is_delete);                  return ccs_callback[i].write(&param);
                 break;  
918          }          }
919          if (cond)          return -EINVAL;
                 ccs_put_condition(cond);  
         return error;  
920  }  }
921    
922  static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {  const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
923          [CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n",          [CCS_DIF_QUOTA_WARNED]      = "quota_exceeded\n",
924          [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"          [CCS_DIF_TRANSITION_FAILED] = "transition_failed\n",
925  };  };
926            
927  /**  /**
928   * ccs_write_domain - Write domain policy.   * ccs_write_domain - Write domain policy.
929   *   *
# Line 1002  static int ccs_write_domain(struct ccs_i Line 938  static int ccs_write_domain(struct ccs_i
938          bool is_delete = false;          bool is_delete = false;
939          bool is_select = false;          bool is_select = false;
940          unsigned int profile;          unsigned int profile;
941          if (ccs_str_starts(&data, CCS_KEYWORD_DELETE))          if (ccs_str_starts(&data, "delete "))
942                  is_delete = true;                  is_delete = true;
943          else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))          else if (ccs_str_starts(&data, "select "))
944                  is_select = true;                  is_select = true;
945          if (is_select && ccs_select_one(head, data))          if (is_select && ccs_select_one(head, data))
946                  return 0;                  return 0;
# Line 1025  static int ccs_write_domain(struct ccs_i Line 961  static int ccs_write_domain(struct ccs_i
961          if (!domain)          if (!domain)
962                  return -EINVAL;                  return -EINVAL;
963    
964          if (sscanf(data, CCS_KEYWORD_USE_PROFILE "%u", &profile) == 1          if (sscanf(data, "use_profile %u\n", &profile) == 1
965              && profile < CCS_MAX_PROFILES) {              && profile < CCS_MAX_PROFILES) {
966                  if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])                  if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])
967                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
968                  return 0;                  return 0;
969          }          }
970          if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1          if (sscanf(data, "use_group %u\n", &profile) == 1
971              && profile < CCS_MAX_ACL_GROUPS) {              && profile < CCS_MAX_ACL_GROUPS) {
972                  domain->group = (u8) profile;                  domain->group = (u8) profile;
973                  return 0;                  return 0;
# Line 1130  static bool ccs_print_condition(struct c Line 1066  static bool ccs_print_condition(struct c
1066  {  {
1067          switch (head->r.cond_step) {          switch (head->r.cond_step) {
1068          case 0:          case 0:
1069                  {                  head->r.cond_index = 0;
1070                          ccs_set_string(head, " if");                  head->r.cond_step++;
                         head->r.cond_index = 0;  
                         head->r.cond_step++;  
                 }  
1071                  /* fall through */                  /* fall through */
1072          case 1:          case 1:
1073                  {                  {
# Line 1243  static bool ccs_print_condition(struct c Line 1176  static bool ccs_print_condition(struct c
1176                  head->r.cond_step++;                  head->r.cond_step++;
1177                  /* fall through */                  /* fall through */
1178          case 3:          case 3:
1179                  if (cond->audit)                  if (cond->grant_log)
1180                          ccs_io_printf(head, " audit=%s",                          ccs_io_printf(head, " grant_log=%s",
1181                                        ccs_yesno(cond->audit == 2));                                        ccs_yesno(cond->grant_log == 2));
1182                  if (cond->transit) {                  if (cond->transit) {
1183                          ccs_set_string(head, " auto_domain_transitition=\"");                          ccs_set_string(head, " auto_domain_transitition=\"");
1184                          ccs_set_string(head, cond->transit->name);                          ccs_set_string(head, cond->transit->name);
# Line 1349  static bool ccs_print_entry(struct ccs_i Line 1282  static bool ccs_print_entry(struct ccs_i
1282                          goto done;                          goto done;
1283                  ccs_set_group(head);                  ccs_set_group(head);
1284                  ccs_set_string(head, "file ");                  ccs_set_string(head, "file ");
1285                  ccs_set_string(head, ccs_mkdev_keyword[bit]);                  ccs_set_string(head, ccs_mac_keywords[ccs_pnnn2mac[bit]]);
1286                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1287                  ccs_print_number_union(head, &ptr->mode);                  ccs_print_number_union(head, &ptr->mode);
1288                  ccs_print_number_union(head, &ptr->major);                  ccs_print_number_union(head, &ptr->major);
# Line 1362  static bool ccs_print_entry(struct ccs_i Line 1295  static bool ccs_print_entry(struct ccs_i
1295                          goto done;                          goto done;
1296                  ccs_set_group(head);                  ccs_set_group(head);
1297                  ccs_set_string(head, "file ");                  ccs_set_string(head, "file ");
1298                  ccs_set_string(head, ccs_path2_keyword[bit]);                  ccs_set_string(head, ccs_mac_keywords[ccs_pp2mac[bit]]);
1299                  ccs_print_name_union(head, &ptr->name1);                  ccs_print_name_union(head, &ptr->name1);
1300                  ccs_print_name_union(head, &ptr->name2);                  ccs_print_name_union(head, &ptr->name2);
1301          } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {          } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
# Line 1373  static bool ccs_print_entry(struct ccs_i Line 1306  static bool ccs_print_entry(struct ccs_i
1306                          goto done;                          goto done;
1307                  ccs_set_group(head);                  ccs_set_group(head);
1308                  ccs_set_string(head, "file ");                  ccs_set_string(head, "file ");
1309                  ccs_set_string(head, ccs_path_number_keyword[bit]);                  ccs_set_string(head, ccs_mac_keywords[ccs_pn2mac[bit]]);
1310                  ccs_print_name_union(head, &ptr->name);                  ccs_print_name_union(head, &ptr->name);
1311                  ccs_print_number_union(head, &ptr->number);                  ccs_print_number_union(head, &ptr->number);
1312          } else if (acl_type == CCS_TYPE_ENV_ACL) {          } else if (acl_type == CCS_TYPE_ENV_ACL) {
# Line 1387  static bool ccs_print_entry(struct ccs_i Line 1320  static bool ccs_print_entry(struct ccs_i
1320                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
1321                  ccs_set_group(head);                  ccs_set_group(head);
1322                  ccs_set_string(head, "capability ");                  ccs_set_string(head, "capability ");
1323                  ccs_set_string(head, ccs_cap2keyword(ptr->operation));                  ccs_set_string(head,
1324                                   ccs_mac_keywords[ccs_c2mac[ptr->operation]]);
1325          } else if (acl_type == CCS_TYPE_INET_ACL) {          } else if (acl_type == CCS_TYPE_INET_ACL) {
1326                  struct ccs_inet_acl *ptr =                  struct ccs_inet_acl *ptr =
1327                          container_of(acl, typeof(*ptr), head);                          container_of(acl, typeof(*ptr), head);
# Line 1523  static void ccs_read_domain(struct ccs_i Line 1457  static void ccs_read_domain(struct ccs_i
1457                          /* Print domainname and flags. */                          /* Print domainname and flags. */
1458                          ccs_set_string(head, domain->domainname->name);                          ccs_set_string(head, domain->domainname->name);
1459                          ccs_set_lf(head);                          ccs_set_lf(head);
1460                          ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",                          ccs_io_printf(head, "use_profile %u\n",
1461                                        domain->profile);                                        domain->profile);
1462                          ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",                          ccs_io_printf(head, "use_group %u\n", domain->group);
                                       domain->group);  
1463                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)                          for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1464                                  if (domain->flags[i])                                  if (domain->flags[i])
1465                                          ccs_set_string(head, ccs_dif[i]);                                          ccs_set_string(head, ccs_dif[i]);
# Line 1693  static void ccs_read_pid(struct ccs_io_b Line 1626  static void ccs_read_pid(struct ccs_io_b
1626          }          }
1627  }  }
1628    
1629  static const char *ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {  static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
1630          [CCS_TRANSITION_CONTROL_NO_INITIALIZE]          [CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1631          = CCS_KEYWORD_NO_INITIALIZE_DOMAIN,          [CCS_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
1632          [CCS_TRANSITION_CONTROL_INITIALIZE] = CCS_KEYWORD_INITIALIZE_DOMAIN,          [CCS_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
1633          [CCS_TRANSITION_CONTROL_NO_KEEP] = CCS_KEYWORD_NO_KEEP_DOMAIN,          [CCS_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
         [CCS_TRANSITION_CONTROL_KEEP] = CCS_KEYWORD_KEEP_DOMAIN  
1634  };  };
1635    
1636  static const char *ccs_group_name[CCS_MAX_GROUP] = {  static const char * const ccs_group_name[CCS_MAX_GROUP] = {
1637          [CCS_PATH_GROUP] = CCS_KEYWORD_PATH_GROUP,          [CCS_PATH_GROUP]    = "path_group ",
1638          [CCS_NUMBER_GROUP] = CCS_KEYWORD_NUMBER_GROUP,          [CCS_NUMBER_GROUP]  = "number_group ",
1639          [CCS_ADDRESS_GROUP] = CCS_KEYWORD_ADDRESS_GROUP          [CCS_ADDRESS_GROUP] = "address_group ",
1640  };  };
1641    
1642  /**  /**
# Line 1717  static const char *ccs_group_name[CCS_MA Line 1649  static const char *ccs_group_name[CCS_MA
1649  static int ccs_write_exception(struct ccs_io_buffer *head)  static int ccs_write_exception(struct ccs_io_buffer *head)
1650  {  {
1651          char *data = head->write_buf;          char *data = head->write_buf;
1652          const bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);          const bool is_delete = ccs_str_starts(&data, "delete ");
1653          u8 i;          u8 i;
1654          static const struct {          static const struct {
1655                  const char *keyword;                  const char *keyword;
1656                  int (*write) (char *, const bool);                  int (*write) (char *, const bool);
1657          } ccs_callback[3] = {          } ccs_callback[2] = {
1658                  { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },                  { "aggregator ",    ccs_write_aggregator },
1659                  { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },                  { "deny_autobind ", ccs_write_reserved_port },
                 { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }  
1660          };          };
1661          for (i = 0; i < 3; i++)          for (i = 0; i < 2; i++)
1662                  if (ccs_str_starts(&data, ccs_callback[i].keyword))                  if (ccs_str_starts(&data, ccs_callback[i].keyword))
1663                          return ccs_callback[i].write(data, is_delete);                          return ccs_callback[i].write(data, is_delete);
1664          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)          for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
# Line 1844  static bool ccs_read_policy(struct ccs_i Line 1775  static bool ccs_read_policy(struct ccs_i
1775                          {                          {
1776                                  struct ccs_aggregator *ptr =                                  struct ccs_aggregator *ptr =
1777                                          container_of(acl, typeof(*ptr), head);                                          container_of(acl, typeof(*ptr), head);
1778                                  ccs_set_string(head, CCS_KEYWORD_AGGREGATOR);                                  ccs_set_string(head, "aggregator ");
1779                                  ccs_set_string(head, ptr->original_name->name);                                  ccs_set_string(head, ptr->original_name->name);
1780                                  ccs_set_space(head);                                  ccs_set_space(head);
1781                                  ccs_set_string(head,                                  ccs_set_string(head,
1782                                                 ptr->aggregated_name->name);                                                 ptr->aggregated_name->name);
1783                          }                          }
1784                          break;                          break;
                 case CCS_ID_PATTERN:  
                         {  
                                 struct ccs_pattern *ptr =  
                                         container_of(acl, typeof(*ptr), head);  
                                 ccs_set_string(head, CCS_KEYWORD_FILE_PATTERN);  
                                 ccs_set_string(head, ptr->pattern->name);  
                         }  
                         break;  
1785                  case CCS_ID_RESERVEDPORT:                  case CCS_ID_RESERVEDPORT:
1786                          {                          {
1787                                  struct ccs_reserved *ptr =                                  struct ccs_reserved *ptr =
1788                                          container_of(acl, typeof(*ptr), head);                                          container_of(acl, typeof(*ptr), head);
1789                                  const u16 min_port = ptr->min_port;                                  const u16 min_port = ptr->min_port;
1790                                  const u16 max_port = ptr->max_port;                                  const u16 max_port = ptr->max_port;
1791                                  ccs_set_string(head,                                  ccs_set_string(head, "deny_autobind ");
                                                CCS_KEYWORD_DENY_AUTOBIND);  
1792                                  ccs_io_printf(head, "%u", min_port);                                  ccs_io_printf(head, "%u", min_port);
1793                                  if (min_port != max_port)                                  if (min_port != max_port)
1794                                          ccs_io_printf(head, "-%u", max_port);                                          ccs_io_printf(head, "-%u", max_port);
# Line 1917  static void ccs_read_exception(struct cc Line 1839  static void ccs_read_exception(struct cc
1839    
1840  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
1841  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1842    static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait);
1843    
1844  /* Lock for manipulating ccs_query_list. */  /* Lock for manipulating ccs_query_list. */
1845  static DEFINE_SPINLOCK(ccs_query_list_lock);  static DEFINE_SPINLOCK(ccs_query_list_lock);
# Line 1929  struct ccs_query { Line 1852  struct ccs_query {
1852          unsigned int serial;          unsigned int serial;
1853          int timer;          int timer;
1854          int answer;          int answer;
1855            u8 retry;
1856  };  };
1857    
1858  /* The list for "struct ccs_query". */  /* The list for "struct ccs_query". */
# Line 1937  static LIST_HEAD(ccs_query_list); Line 1861  static LIST_HEAD(ccs_query_list);
1861  /* Number of "struct file" referring /proc/ccs/query interface. */  /* Number of "struct file" referring /proc/ccs/query interface. */
1862  static atomic_t ccs_query_observers = ATOMIC_INIT(0);  static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1863    
1864  static void ccs_truncate(char *str)  static int ccs_truncate(char *str)
1865  {  {
1866            char *start = str;
1867          while (* (unsigned char *) str > (unsigned char) ' ')          while (* (unsigned char *) str > (unsigned char) ' ')
1868                  str++;                  str++;
1869          *str = '\0';          *str = '\0';
1870            return strlen(start) + 1;
1871    }
1872    
1873    static void ccs_add_entry(char *header)
1874    {
1875            char *buffer;
1876            char *realpath = NULL;
1877            char *argv0 = NULL;
1878            char *symlink = NULL;
1879            char *handler;
1880            char *cp = strchr(header, '\n');
1881            int len;
1882            if (!cp)
1883                    return;
1884            cp = strchr(cp + 1, '\n');
1885            if (!cp)
1886                    return;
1887            *cp++ = '\0';
1888            len = strlen(cp) + 1;
1889            /* strstr() will return NULL if ordering is wrong. */
1890            if (*cp == 'f') {
1891                    argv0 = strstr(header, " argv[]={ \"");
1892                    if (argv0) {
1893                            argv0 += 10;
1894                            len += ccs_truncate(argv0) + 14;
1895                    }
1896                    realpath = strstr(header, " exec={ realpath=\"");
1897                    if (realpath) {
1898                            realpath += 8;
1899                            len += ccs_truncate(realpath) + 6;
1900                    }
1901                    symlink = strstr(header, " symlink.target=\"");
1902                    if (symlink)
1903                            len += ccs_truncate(symlink + 1) + 1;
1904            }
1905            handler = strstr(header, "type=execute_handler");
1906            if (handler)
1907                    len += ccs_truncate(handler) + 6;
1908            buffer = kmalloc(len, CCS_GFP_FLAGS);
1909            if (!buffer)
1910                    return;
1911            snprintf(buffer, len - 1, "%s", cp);
1912            if (handler)
1913                    ccs_addprintf(buffer, len, " task.%s", handler);
1914            if (realpath)
1915                    ccs_addprintf(buffer, len, " exec.%s", realpath);
1916            if (argv0)
1917                    ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
1918            if (symlink)
1919                    ccs_addprintf(buffer, len, "%s", symlink);
1920            //printk(KERN_DEBUG "'%s'\n", buffer);
1921            ccs_normalize_line(buffer);
1922            ccs_write_domain2(buffer, ccs_current_domain(), false);
1923            kfree(buffer);
1924  }  }
1925    
1926  /**  /**
# Line 1958  static void ccs_truncate(char *str) Line 1937  static void ccs_truncate(char *str)
1937  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)  int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
1938  {  {
1939          va_list args;          va_list args;
1940          int error = -EPERM;          int error;
         int pos;  
1941          int len;          int len;
1942          static unsigned int ccs_serial;          static unsigned int ccs_serial;
1943          struct ccs_query *entry = NULL;          struct ccs_query entry = { };
1944          bool quota_exceeded = false;          bool quota_exceeded = false;
1945          char *header;          /* Write /proc/ccs/grant_log or /proc/ccs/reject_log . */
         struct ccs_domain_info * const domain = ccs_current_domain();  
1946          va_start(args, fmt);          va_start(args, fmt);
1947          len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 80;          ccs_write_log2(r, fmt, args);
1948          va_end(args);          va_end(args);
1949          if (r->mode == CCS_CONFIG_LEARNING) {          /* Nothing more to do if granted. */
1950                  char *buffer;          if (r->granted)
                 char *realpath = NULL;  
                 char *argv0 = NULL;  
                 char *symlink = NULL;  
                 char *handler = NULL;  
                 const struct ccs_preference *pref;  
                 if (!ccs_domain_quota_ok(r))  
                         return 0;  
                 header = ccs_init_log(&len, r);  
                 if (!header)  
                         return 0;  
                 pref = &ccs_profile(r->profile)->preference;  
                 /* strstr() will return NULL if ordering is wrong. */  
                 if (r->param_type == CCS_TYPE_PATH_ACL &&  
                     r->param.path.operation == CCS_TYPE_EXECUTE) {  
                         if (pref->learning_exec_argv0) {  
                                 argv0 = strstr(header, " argv[]={ \"");  
                                 if (argv0) {  
                                         argv0 += 10;  
                                         ccs_truncate(argv0);  
                                 }  
                         }  
                         if (pref->learning_exec_realpath) {  
                                 realpath = strstr(header,  
                                                   " exec={ realpath=\"");  
                                 if (realpath) {  
                                         realpath += 8;  
                                         ccs_truncate(realpath);  
                                 }  
                         }  
                 } else if (r->param_type == CCS_TYPE_PATH_ACL &&  
                            r->param.path.operation == CCS_TYPE_SYMLINK &&  
                            pref->learning_symlink_target) {  
                         symlink = strstr(header, " symlink.target=\"");  
                         if (symlink)  
                                 ccs_truncate(symlink + 1);  
                 }  
                 handler = strstr(header, "type=execute_handler");  
                 if (handler)  
                         ccs_truncate(handler);  
                 buffer = kmalloc(len, CCS_GFP_FLAGS);  
                 if (buffer) {  
                         va_start(args, fmt);  
                         vsnprintf(buffer, len - 1, fmt, args);  
                         va_end(args);  
                         if (handler || realpath || argv0 || symlink) {  
                                 ccs_addprintf(buffer, len, " if");  
                                 if (handler)  
                                         ccs_addprintf(buffer, len, " task.%s",  
                                                       handler);  
                                 if (realpath)  
                                         ccs_addprintf(buffer, len, " exec.%s",  
                                                       realpath);  
                                 if (argv0)  
                                         ccs_addprintf(buffer, len,  
                                                       " exec.argv[0]=%s",  
                                                       argv0);  
                                 if (symlink)  
                                         ccs_addprintf(buffer, len, "%s",  
                                                       symlink);  
                         }  
                         ccs_normalize_line(buffer);  
                         ccs_write_domain2(buffer, domain, false);  
                         kfree(buffer);  
                 }  
                 kfree(header);  
1951                  return 0;                  return 0;
1952          }          switch (r->mode) {
         if (r->mode != CCS_CONFIG_ENFORCING)  
                 return 0;  
         if (!atomic_read(&ccs_query_observers)) {  
1953                  int i;                  int i;
1954            case CCS_CONFIG_ENFORCING:
1955                    error = -EPERM;
1956                    if (atomic_read(&ccs_query_observers))
1957                            break;
1958                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
1959                          return -EPERM;                          goto out;
1960                  for (i = 0; i < ccs_profile(domain->profile)->preference.                  /* Check PREFERENCE::enforcing sleep parameter. */
1961                               enforcing_penalty; i++) {                  for (i = 0; i < ccs_preference.enforcing_penalty; i++) {
1962                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
1963                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
1964                  }                  }
                 return -EPERM;  
         }  
         header = ccs_init_log(&len, r);  
         if (!header)  
1965                  goto out;                  goto out;
1966          entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);          case CCS_CONFIG_LEARNING:
1967          if (!entry)                  error = 0;
1968                    /* Check PREFERENCE::learning max_entry parameter. */
1969                    if (ccs_domain_quota_ok(r))
1970                            break;
1971                    /* fall through */
1972            default:
1973                    return 0;
1974            }
1975            /* Get message. */
1976            va_start(args, fmt);
1977            entry.query = ccs_init_log(&len, r, fmt, args);
1978            va_end(args);
1979            if (!entry.query)
1980                  goto out;                  goto out;
1981          len = ccs_round2(len);          entry.query_len = strlen(entry.query) + 1;
1982          entry->query = kzalloc(len, CCS_GFP_FLAGS);          if (!error) {
1983          if (!entry->query)                  ccs_add_entry(entry.query);
1984                  goto out;                  goto out;
1985            }
1986          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
1987          if (ccs_quota_for_query && ccs_query_memory_size + len +          if (ccs_quota_for_query && ccs_query_memory_size + len
1988              sizeof(*entry) >= ccs_quota_for_query) {              >= ccs_quota_for_query) {
1989                  quota_exceeded = true;                  quota_exceeded = true;
1990          } else {          } else {
1991                  ccs_query_memory_size += len + sizeof(*entry);                  entry.serial = ccs_serial++;
1992                  entry->serial = ccs_serial++;                  entry.retry = r->retry;
1993                    ccs_query_memory_size += len;
1994                    list_add_tail(&entry.list, &ccs_query_list);
1995          }          }
1996          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
1997          if (quota_exceeded)          if (quota_exceeded)
1998                  goto out;                  goto out;
         pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",  
                        entry->serial, r->retry, header);  
         kfree(header);  
         header = NULL;  
         va_start(args, fmt);  
         vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);  
         entry->query_len = strlen(entry->query) + 1;  
         va_end(args);  
         spin_lock(&ccs_query_list_lock);  
         list_add_tail(&entry->list, &ccs_query_list);  
         spin_unlock(&ccs_query_list_lock);  
1999          /* Give 10 seconds for supervisor's opinion. */          /* Give 10 seconds for supervisor's opinion. */
2000          for (entry->timer = 0;          while (entry.timer < 10) {
2001               atomic_read(&ccs_query_observers) && entry->timer < 100;                  wake_up_all(&ccs_query_wait);
2002               entry->timer++) {                  if (wait_event_interruptible_timeout
2003                  wake_up(&ccs_query_wait);                      (ccs_answer_wait, entry.answer ||
2004                  set_current_state(TASK_INTERRUPTIBLE);                       !atomic_read(&ccs_query_observers), HZ))
                 schedule_timeout(HZ / 10);  
                 if (entry->answer)  
2005                          break;                          break;
2006                    else
2007                            entry.timer++;
2008          }          }
2009          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2010          list_del(&entry->list);          list_del(&entry.list);
2011          ccs_query_memory_size -= len + sizeof(*entry);          ccs_query_memory_size -= len;
2012          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2013          switch (entry->answer) {          switch (entry.answer) {
2014          case 3: /* Asked to retry by administrator. */          case 3: /* Asked to retry by administrator. */
2015                  error = CCS_RETRY_REQUEST;                  error = CCS_RETRY_REQUEST;
2016                  r->retry++;                  r->retry++;
# Line 2106  int ccs_supervisor(struct ccs_request_in Line 2019  int ccs_supervisor(struct ccs_request_in
2019                  /* Granted by administrator. */                  /* Granted by administrator. */
2020                  error = 0;                  error = 0;
2021                  break;                  break;
         case 0:  
                 /* Timed out. */  
                 break;  
2022          default:          default:
2023                  /* Rejected by administrator. */                  /* Timed out or rejected by administrator. */
2024                  break;                  break;
2025          }          }
2026   out:   out:
2027          if (entry)          kfree(entry.query);
                 kfree(entry->query);  
         kfree(entry);  
         kfree(header);  
2028          return error;          return error;
2029  }  }
2030    
# Line 2188  static void ccs_read_query(struct ccs_io Line 2095  static void ccs_read_query(struct ccs_io
2095                  head->r.query_index = 0;                  head->r.query_index = 0;
2096                  return;                  return;
2097          }          }
2098          buf = kzalloc(len, CCS_GFP_FLAGS);          buf = kzalloc(len + 32, CCS_GFP_FLAGS);
2099          if (!buf)          if (!buf)
2100                  return;                  return;
2101          pos = 0;          pos = 0;
# Line 2204  static void ccs_read_query(struct ccs_io Line 2111  static void ccs_read_query(struct ccs_io
2111                   * can change, but I don't care.                   * can change, but I don't care.
2112                   */                   */
2113                  if (len == ptr->query_len)                  if (len == ptr->query_len)
2114                          memmove(buf, ptr->query, len);                          snprintf(buf, len + 32, "Q%u-%hu\n%s", ptr->serial,
2115                                     ptr->retry, ptr->query);
2116                  break;                  break;
2117          }          }
2118          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
# Line 2248  static int ccs_write_answer(struct ccs_i Line 2156  static int ccs_write_answer(struct ccs_i
2156                  break;                  break;
2157          }          }
2158          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2159            wake_up_all(&ccs_answer_wait);
2160          return 0;          return 0;
2161  }  }
2162    
# Line 2265  static void ccs_read_version(struct ccs_ Line 2174  static void ccs_read_version(struct ccs_
2174  }  }
2175    
2176  /**  /**
  * ccs_read_self_domain - Get the current process's domainname.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  */  
 static void ccs_read_self_domain(struct ccs_io_buffer *head)  
 {  
         if (head->r.eof)  
                 return;  
         /*  
          * ccs_current_domain()->domainname != NULL because every process  
          * belongs to a domain and the domain's name cannot be NULL.  
          */  
         ccs_io_printf(head, "%s", ccs_current_domain()->domainname->name);  
         head->r.eof = true;  
 }  
   
 /**  
2177   * ccs_open_control - open() for /proc/ccs/ interface.   * ccs_open_control - open() for /proc/ccs/ interface.
2178   *   *
2179   * @type: Type of interface.   * @type: Type of interface.
# Line 2305  int ccs_open_control(const u8 type, stru Line 2197  int ccs_open_control(const u8 type, stru
2197                  head->write = ccs_write_exception;                  head->write = ccs_write_exception;
2198                  head->read = ccs_read_exception;                  head->read = ccs_read_exception;
2199                  break;                  break;
 #ifdef CONFIG_CCSECURITY_AUDIT  
2200          case CCS_GRANTLOG: /* /proc/ccs/grant_log */          case CCS_GRANTLOG: /* /proc/ccs/grant_log */
2201          case CCS_REJECTLOG: /* /proc/ccs/reject_log */          case CCS_REJECTLOG: /* /proc/ccs/reject_log */
2202                  head->poll = ccs_poll_log;                  head->poll = ccs_poll_log;
2203                  head->read = ccs_read_log;                  head->read = ccs_read_log;
2204                  break;                  break;
 #endif  
         case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */  
                 head->read = ccs_read_self_domain;  
                 break;  
2205          case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */          case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */
2206                  head->write = ccs_write_domain_profile;                  head->write = ccs_write_domain_profile;
2207                  head->read = ccs_read_domain_profile;                  head->read = ccs_read_domain_profile;
# Line 2385  int ccs_open_control(const u8 type, stru Line 2272  int ccs_open_control(const u8 type, stru
2272                          return -ENOMEM;                          return -ENOMEM;
2273                  }                  }
2274          }          }
         if (type != CCS_QUERY &&  
             type != CCS_GRANTLOG && type != CCS_REJECTLOG)  
                 head->reader_idx = ccs_lock();  
         file->private_data = head;  
         /*  
          * Call the handler now if the file is /proc/ccs/self_domain  
          * so that the user can use "cat < /proc/ccs/self_domain" to  
          * know the current process's domainname.  
          */  
         if (type == CCS_SELFDOMAIN)  
                 ccs_read_control(file, NULL, 0);  
2275          /*          /*
2276           * If the file is /proc/ccs/query , increment the observer counter.           * If the file is /proc/ccs/query , increment the observer counter.
2277           * The obserber counter is used by ccs_supervisor() to see if           * The obserber counter is used by ccs_supervisor() to see if
2278           * there is some process monitoring /proc/ccs/query.           * there is some process monitoring /proc/ccs/query.
2279           */           */
2280          else if (type == CCS_QUERY)          if (type == CCS_QUERY)
2281                  atomic_inc(&ccs_query_observers);                  atomic_inc(&ccs_query_observers);
2282            else if (type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2283                    head->reader_idx = ccs_lock();
2284            file->private_data = head;
2285          return 0;          return 0;
2286  }  }
2287    
# Line 2540  int ccs_close_control(struct file *file) Line 2419  int ccs_close_control(struct file *file)
2419          /*          /*
2420           * If the file is /proc/ccs/query , decrement the observer counter.           * If the file is /proc/ccs/query , decrement the observer counter.
2421           */           */
2422          if (type == CCS_QUERY)          if (type == CCS_QUERY) {
2423                  atomic_dec(&ccs_query_observers);                  if (atomic_dec_and_test(&ccs_query_observers))
2424          if (type != CCS_QUERY &&                          wake_up_all(&ccs_answer_wait);
2425              type != CCS_GRANTLOG && type != CCS_REJECTLOG)          } else if (type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2426                  ccs_unlock(head->reader_idx);                  ccs_unlock(head->reader_idx);
2427          /* Release memory used for policy I/O. */          /* Release memory used for policy I/O. */
2428          kfree(head->read_buf);          kfree(head->read_buf);

Legend:
Removed from v.3945  
changed lines
  Added in v.4014

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