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

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 2930 by kumaneko, Fri Aug 21 01:55:58 2009 UTC trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c revision 3136 by kumaneko, Wed Nov 4 00:31:28 2009 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2009  NTT DATA CORPORATION   * Copyright (C) 2005-2009  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.0-pre   2009/08/08   * Version: 1.7.1-pre   2009/11/03
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 12  Line 12 
12    
13  #include "internal.h"  #include "internal.h"
14    
15  /* Lock for protecting ccs_profile->comment  */  static struct ccs_profile ccs_default_profile = {
16  static DEFINE_SPINLOCK(ccs_profile_comment_lock);          .learning = &ccs_default_profile.preference,
17            .permissive = &ccs_default_profile.preference,
18  /* String table for functionality that takes 2 modes. */          .enforcing = &ccs_default_profile.preference,
19  static const char *ccs_mode_2[2] = {          .audit = &ccs_default_profile.preference,
20          "disabled", "enabled"  #ifdef CONFIG_CCSECURITY_AUDIT
21            .preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,
22            .preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,
23    #endif
24            .preference.audit_task_info = true,
25            .preference.audit_path_info = true,
26            .preference.enforcing_penalty = 0,
27            .preference.enforcing_verbose = true,
28            .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,
29            .preference.learning_verbose = false,
30            .preference.learning_exec_realpath = true,
31            .preference.learning_exec_argv0 = true,
32            .preference.learning_symlink_target = true,
33            .preference.permissive_verbose = true
34  };  };
35    
36    /* Profile table. Memory is allocated as needed. */
37    static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
38    
39    /* String table for functionality that takes 4 modes. */
40  static const char *ccs_mode_4[4] = {  static const char *ccs_mode_4[4] = {
41          "disabled", "learning", "permissive", "enforcing"          "disabled", "learning", "permissive", "enforcing"
42  };  };
43    
44  static bool ccs_mac_keywords_used[CCS_MAX_MAC_INDEX +  /* String table for /proc/ccs/profile */
                                   CCS_MAX_CAPABILITY_INDEX];  
   
45  static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX +  static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX +
46                                      CCS_MAX_CAPABILITY_INDEX] = {                                      CCS_MAX_CAPABILITY_INDEX +
47          [CCS_MAC_EXECUTE]    = "execute",                                      CCS_MAX_MAC_CATEGORY_INDEX] = {
48          [CCS_MAC_OPEN]       = "open",          [CCS_MAC_FILE_EXECUTE]
49          [CCS_MAC_CREATE]     = "create",          = "file::execute",
50          [CCS_MAC_UNLINK]     = "unlink",          [CCS_MAC_FILE_OPEN]
51          [CCS_MAC_MKDIR]      = "mkdir",          = "file::open",
52          [CCS_MAC_RMDIR]      = "rmdir",          [CCS_MAC_FILE_CREATE]
53          [CCS_MAC_MKFIFO]     = "mkfifo",          = "file::create",
54          [CCS_MAC_MKSOCK]     = "mksock",          [CCS_MAC_FILE_UNLINK]
55          [CCS_MAC_TRUNCATE]   = "truncate",          = "file::unlink",
56          [CCS_MAC_SYMLINK]    = "symlink",          [CCS_MAC_FILE_MKDIR]
57          [CCS_MAC_REWRITE]    = "rewrite",          = "file::mkdir",
58          [CCS_MAC_MKBLOCK]    = "mkblock",          [CCS_MAC_FILE_RMDIR]
59          [CCS_MAC_MKCHAR]     = "mkchar",          = "file::rmdir",
60          [CCS_MAC_LINK]       = "link",          [CCS_MAC_FILE_MKFIFO]
61          [CCS_MAC_RENAME]     = "rename",          = "file::mkfifo",
62          [CCS_MAC_CHMOD]      = "chmod",          [CCS_MAC_FILE_MKSOCK]
63          [CCS_MAC_CHOWN]      = "chown",          = "file::mksock",
64          [CCS_MAC_CHGRP]      = "chgrp",          [CCS_MAC_FILE_TRUNCATE]
65          [CCS_MAC_IOCTL]      = "ioctl",          = "file::truncate",
66          [CCS_MAC_CHROOT]     = "chroot",          [CCS_MAC_FILE_SYMLINK]
67          [CCS_MAC_MOUNT]      = "mount",          = "file::symlink",
68          [CCS_MAC_UMOUNT]     = "umount",          [CCS_MAC_FILE_REWRITE]
69          [CCS_MAC_PIVOT_ROOT] = "pivot_root",          = "file::rewrite",
70          [CCS_MAC_ENVIRON]    = "env",          [CCS_MAC_FILE_MKBLOCK]
71          [CCS_MAC_NETWORK]    = "network",          = "file::mkblock",
72          [CCS_MAC_SIGNAL]     = "signal",          [CCS_MAC_FILE_MKCHAR]
73            = "file::mkchar",
74            [CCS_MAC_FILE_LINK]
75            = "file::link",
76            [CCS_MAC_FILE_RENAME]
77            = "file::rename",
78            [CCS_MAC_FILE_CHMOD]
79            = "file::chmod",
80            [CCS_MAC_FILE_CHOWN]
81            = "file::chown",
82            [CCS_MAC_FILE_CHGRP]
83            = "file::chgrp",
84            [CCS_MAC_FILE_IOCTL]
85            = "file::ioctl",
86            [CCS_MAC_FILE_CHROOT]
87            = "file::chroot",
88            [CCS_MAC_FILE_MOUNT]
89            = "file::mount",
90            [CCS_MAC_FILE_UMOUNT]
91            = "file::umount",
92            [CCS_MAC_FILE_PIVOT_ROOT]
93            = "file::pivot_root",
94            [CCS_MAC_ENVIRON]
95            = "misc::env",
96            [CCS_MAC_NETWORK_UDP_BIND]
97            = "network::inet_udp_bind",
98            [CCS_MAC_NETWORK_UDP_CONNECT]
99            = "network::inet_udp_connect",
100            [CCS_MAC_NETWORK_TCP_BIND]
101            = "network::inet_tcp_bind",
102            [CCS_MAC_NETWORK_TCP_LISTEN]
103            = "network::inet_tcp_listen",
104            [CCS_MAC_NETWORK_TCP_CONNECT]
105            = "network::inet_tcp_connect",
106            [CCS_MAC_NETWORK_TCP_ACCEPT]
107            = "network::inet_tcp_accept",
108            [CCS_MAC_NETWORK_RAW_BIND]
109            = "network::inet_raw_bind",
110            [CCS_MAC_NETWORK_RAW_CONNECT]
111            = "network::inet_raw_connect",
112            [CCS_MAC_SIGNAL]
113            = "ipc::signal",
114          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE]          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE]
115          = "inet_tcp_create",          = "capability::inet_tcp_create",
116          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN]          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN]
117          = "inet_tcp_listen",          = "capability::inet_tcp_listen",
118          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT]          [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT]
119          = "inet_tcp_connect",          = "capability::inet_tcp_connect",
120          [CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET] = "use_inet_udp",          [CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET]
121          [CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET]   = "use_inet_ip",          = "capability::use_inet_udp",
122          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]      = "use_route",          [CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET]
123          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]     = "use_packet",          = "capability::use_inet_ip",
124          [CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT]             = "SYS_MOUNT",          [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
125          [CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT]            = "SYS_UMOUNT",          = "capability::use_route",
126          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]            = "SYS_REBOOT",          [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
127          [CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT]            = "SYS_CHROOT",          = "capability::use_packet",
128          [CCS_MAX_MAC_INDEX + CCS_SYS_KILL]              = "SYS_KILL",          [CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT]
129          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]           = "SYS_VHANGUP",          = "capability::SYS_MOUNT",
130          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]           = "SYS_TIME",          [CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT]
131          [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]              = "SYS_NICE",          = "capability::SYS_UMOUNT",
132          [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]       = "SYS_SETHOSTNAME",          [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
133          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]     = "use_kernel_module",          = "capability::SYS_REBOOT",
134          [CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO]           = "create_fifo",          [CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT]
135          [CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV]      = "create_block_dev",          = "capability::SYS_CHROOT",
136          [CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV]       = "create_char_dev",          [CCS_MAX_MAC_INDEX + CCS_SYS_KILL]
137          [CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET]    = "create_unix_socket",          = "capability::SYS_KILL",
138          [CCS_MAX_MAC_INDEX + CCS_SYS_LINK]              = "SYS_LINK",          [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
139          [CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK]           = "SYS_SYMLINK",          = "capability::SYS_VHANGUP",
140          [CCS_MAX_MAC_INDEX + CCS_SYS_RENAME]            = "SYS_RENAME",          [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
141          [CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK]            = "SYS_UNLINK",          = "capability::SYS_TIME",
142          [CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD]             = "SYS_CHMOD",          [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]
143          [CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN]             = "SYS_CHOWN",          = "capability::SYS_NICE",
144          [CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL]             = "SYS_IOCTL",          [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]
145          [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]        = "SYS_KEXEC_LOAD",          = "capability::SYS_SETHOSTNAME",
146          [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]        = "SYS_PIVOT_ROOT",          [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
147          [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]            = "SYS_PTRACE",          = "capability::use_kernel_module",
148          [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]         = "conceal_mount"          [CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO]
149  };          = "capability::create_fifo",
150            [CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV]
151  /* Table for profile. */          = "capability::create_block_dev",
152  static struct {          [CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV]
153          const char *keyword;          = "capability::create_char_dev",
154          unsigned int current_value;          [CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET]
155          const unsigned int max_value;          = "capability::create_unix_socket",
156  } ccs_control_array[CCS_MAX_CONTROL_INDEX] = {          [CCS_MAX_MAC_INDEX + CCS_SYS_LINK]
157          [CCS_AUTOLEARN_EXEC_REALPATH] = { "AUTOLEARN_EXEC_REALPATH", 0, 1 },          = "capability::SYS_LINK",
158          [CCS_AUTOLEARN_EXEC_ARGV0] = { "AUTOLEARN_EXEC_ARGV0", 0, 1 },          [CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK]
159          [CCS_MAX_ACCEPT_ENTRY]          = "capability::SYS_SYMLINK",
160          = { "MAX_ACCEPT_ENTRY", CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY, INT_MAX },          [CCS_MAX_MAC_INDEX + CCS_SYS_RENAME]
161  #ifdef CONFIG_CCSECURITY_AUDIT          = "capability::SYS_RENAME",
162          [CCS_MAX_GRANT_LOG]          [CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK]
163          = { "MAX_GRANT_LOG", CONFIG_CCSECURITY_MAX_GRANT_LOG, INT_MAX },          = "capability::SYS_UNLINK",
164          [CCS_MAX_REJECT_LOG]          [CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD]
165          = { "MAX_REJECT_LOG", CONFIG_CCSECURITY_MAX_REJECT_LOG, INT_MAX },          = "capability::SYS_CHMOD",
166  #endif          [CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN]
167          [CCS_VERBOSE] = { "PRINT_VIOLATION",      1, 1 },          = "capability::SYS_CHOWN",
168          [CCS_SLEEP_PERIOD] = { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */          [CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL]
169            = "capability::SYS_IOCTL",
170            [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
171            = "capability::SYS_KEXEC_LOAD",
172            [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]
173            = "capability::SYS_PIVOT_ROOT",
174            [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
175            = "capability::SYS_PTRACE",
176            [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]
177            = "capability::conceal_mount",
178            [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
179             + CCS_MAC_CATEGORY_FILE] = "file",
180            [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
181             + CCS_MAC_CATEGORY_NETWORK] = "network",
182            [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
183             + CCS_MAC_CATEGORY_MISC] = "misc",
184            [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
185             + CCS_MAC_CATEGORY_IPC] = "ipc",
186            [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
187             + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
188  };  };
189    
190  /* Permit policy management by non-root user? */  /* Permit policy management by non-root user? */
# Line 125  static bool ccs_manage_by_non_root; Line 200  static bool ccs_manage_by_non_root;
200  const char *ccs_cap2keyword(const u8 operation)  const char *ccs_cap2keyword(const u8 operation)
201  {  {
202          return operation < CCS_MAX_CAPABILITY_INDEX          return operation < CCS_MAX_CAPABILITY_INDEX
203                  ? ccs_mac_keywords[CCS_MAX_MAC_INDEX + operation] : NULL;                  ? ccs_mac_keywords[CCS_MAX_MAC_INDEX + operation] + 12 : NULL;
204  }  }
205    
206  /**  /**
207   * ccs_quiet_setup - Set CCS_VERBOSE=0 by default.   * ccs_yesno - Return "yes" or "no".
208   *   *
209   * @str: Unused.   * @value: Bool value.
  *  
  * Returns 0.  
210   */   */
211  static int __init ccs_quiet_setup(char *str)  static const char *ccs_yesno(const unsigned int value)
212  {  {
213          ccs_control_array[CCS_VERBOSE].current_value = 0;          return value ? "yes" : "no";
         return 0;  
214  }  }
215    
 __setup("CCS_QUIET", ccs_quiet_setup);  
   
216  /**  /**
217   * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.   * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.
218   *   *
# Line 182  static struct ccs_profile *ccs_find_or_a Line 252  static struct ccs_profile *ccs_find_or_a
252  {  {
253          struct ccs_profile *ptr;          struct ccs_profile *ptr;
254          struct ccs_profile *entry;          struct ccs_profile *entry;
         int i;  
255          if (profile >= CCS_MAX_PROFILES)          if (profile >= CCS_MAX_PROFILES)
256                  return NULL;                  return NULL;
257          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
# Line 193  static struct ccs_profile *ccs_find_or_a Line 262  static struct ccs_profile *ccs_find_or_a
262          ptr = ccs_profile_ptr[profile];          ptr = ccs_profile_ptr[profile];
263          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {          if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
264                  ptr = entry;                  ptr = entry;
265                  for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++)                  ptr->audit = &ccs_default_profile.preference;
266                          ptr->value[i] = ccs_control_array[i].current_value;                  ptr->learning = &ccs_default_profile.preference;
267                    ptr->permissive = &ccs_default_profile.preference;
268                    ptr->enforcing = &ccs_default_profile.preference;
269                    ptr->default_config = CCS_CONFIG_DISABLED |
270                            CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
271                    memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
272                           sizeof(ptr->config));
273                  mb(); /* Avoid out-of-order execution. */                  mb(); /* Avoid out-of-order execution. */
274                  ccs_profile_ptr[profile] = ptr;                  ccs_profile_ptr[profile] = ptr;
275                  entry = NULL;                  entry = NULL;
# Line 205  static struct ccs_profile *ccs_find_or_a Line 280  static struct ccs_profile *ccs_find_or_a
280  }  }
281    
282  /**  /**
283     * ccs_check_profile - Check all profiles currently assigned to domains are defined.
284     */
285    void ccs_check_profile(void)
286    {
287            struct ccs_domain_info *domain;
288            ccs_policy_loaded = true;
289            list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
290                    const u8 profile = domain->profile;
291                    if (ccs_profile_ptr[profile])
292                            continue;
293                    panic("Profile %u (used by '%s') not defined.\n",
294                          profile, domain->domainname->name);
295            }
296    }
297    
298    /**
299     * ccs_profile - Find a profile.
300     *
301     * @profile: Profile number to find.
302     *
303     * Returns pointer to "struct ccs_profile".
304     */
305    struct ccs_profile *ccs_profile(const u8 profile)
306    {
307            struct ccs_profile *ptr = ccs_profile_ptr[profile];
308            if (!ccs_policy_loaded)
309                    return &ccs_default_profile;
310            BUG_ON(!ptr);
311            return ptr;
312    }
313    
314    /**
315   * ccs_write_profile - Write profile table.   * ccs_write_profile - Write profile table.
316   *   *
317   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 215  static int ccs_write_profile(struct ccs_ Line 322  static int ccs_write_profile(struct ccs_
322  {  {
323          char *data = head->write_buf;          char *data = head->write_buf;
324          unsigned int i;          unsigned int i;
325          unsigned int value;          int value;
         int index = -1;  
326          int mode;          int mode;
327            u8 config;
328            bool use_default = false;
329          char *cp;          char *cp;
330          struct ccs_profile *ccs_profile;          struct ccs_profile *profile;
331          i = simple_strtoul(data, &cp, 10);          i = simple_strtoul(data, &cp, 10);
332          if (data != cp) {          if (data == cp) {
333                    profile = &ccs_default_profile;
334            } else {
335                  if (*cp != '-')                  if (*cp != '-')
336                          return -EINVAL;                          return -EINVAL;
337                  data = cp + 1;                  data = cp + 1;
338                    profile = ccs_find_or_assign_new_profile(i);
339                    if (!profile)
340                            return -EINVAL;
341          }          }
         ccs_profile = ccs_find_or_assign_new_profile(i);  
         if (!ccs_profile)  
                 return -EINVAL;  
342          cp = strchr(data, '=');          cp = strchr(data, '=');
343          if (!cp)          if (!cp)
344                  return -EINVAL;                  return -EINVAL;
345          *cp++ = '\0';          *cp++ = '\0';
346            if (profile != &ccs_default_profile)
347                    use_default = strstr(cp, "use_default") != NULL;
348            if (strstr(cp, "verbose=yes"))
349                    value = 1;
350            else if (strstr(cp, "verbose=no"))
351                    value = 0;
352            else
353                    value = -1;
354            if (!strcmp(data, "PREFERENCE::audit")) {
355    #ifdef CONFIG_CCSECURITY_AUDIT
356                    char *cp2;
357    #endif
358                    if (use_default) {
359                            profile->audit = &ccs_default_profile.preference;
360                            return 0;
361                    }
362                    profile->audit = &profile->preference;
363    #ifdef CONFIG_CCSECURITY_AUDIT
364                    cp2 = strstr(cp, "max_grant_log=");
365                    if (cp2)
366                            sscanf(cp2 + 14, "%u",
367                                   &profile->preference.audit_max_grant_log);
368                    cp2 = strstr(cp, "max_reject_log=");
369                    if (cp2)
370                            sscanf(cp2 + 15, "%u",
371                                   &profile->preference.audit_max_reject_log);
372    #endif
373                    if (strstr(cp, "task_info=yes"))
374                            profile->preference.audit_task_info = true;
375                    else if (strstr(cp, "task_info=no"))
376                            profile->preference.audit_task_info = false;
377                    if (strstr(cp, "path_info=yes"))
378                            profile->preference.audit_path_info = true;
379                    else if (strstr(cp, "path_info=no"))
380                            profile->preference.audit_path_info = false;
381                    return 0;
382            }
383            if (!strcmp(data, "PREFERENCE::enforcing")) {
384                    char *cp2;
385                    if (use_default) {
386                            profile->enforcing = &ccs_default_profile.preference;
387                            return 0;
388                    }
389                    profile->enforcing = &profile->preference;
390                    if (value >= 0)
391                            profile->preference.enforcing_verbose = value;
392                    cp2 = strstr(cp, "penalty=");
393                    if (cp2)
394                            sscanf(cp2 + 8, "%u",
395                                   &profile->preference.enforcing_penalty);
396                    return 0;
397            }
398            if (!strcmp(data, "PREFERENCE::permissive")) {
399                    if (use_default) {
400                            profile->permissive = &ccs_default_profile.preference;
401                            return 0;
402                    }
403                    profile->permissive = &profile->preference;
404                    if (value >= 0)
405                            profile->preference.permissive_verbose = value;
406                    return 0;
407            }
408            if (!strcmp(data, "PREFERENCE::learning")) {
409                    char *cp2;
410                    if (use_default) {
411                            profile->learning = &ccs_default_profile.preference;
412                            return 0;
413                    }
414                    profile->learning = &profile->preference;
415                    if (value >= 0)
416                            profile->preference.learning_verbose = value;
417                    cp2 = strstr(cp, "max_entry=");
418                    if (cp2)
419                            sscanf(cp2 + 10, "%u",
420                                   &profile->preference.learning_max_entry);
421                    if (strstr(cp, "exec.realpath=yes"))
422                            profile->preference.learning_exec_realpath = true;
423                    else if (strstr(cp, "exec.realpath=no"))
424                            profile->preference.learning_exec_realpath = false;
425                    if (strstr(cp, "exec.argv0=yes"))
426                            profile->preference.learning_exec_argv0 = true;
427                    else if (strstr(cp, "exec.argv0=no"))
428                            profile->preference.learning_exec_argv0 = false;
429                    if (strstr(cp, "symlink.target=yes"))
430                            profile->preference.learning_symlink_target = true;
431                    else if (strstr(cp, "symlink.target=no"))
432                            profile->preference.learning_symlink_target = false;
433                    return 0;
434            }
435            if (profile == &ccs_default_profile)
436                    return -EINVAL;
437          if (!strcmp(data, "COMMENT")) {          if (!strcmp(data, "COMMENT")) {
438                  const struct ccs_path_info *new_comment = ccs_get_name(cp);                  const struct ccs_path_info *old_comment = profile->comment;
439                  const struct ccs_path_info *old_comment;                  profile->comment = ccs_get_name(cp);
                 /* Protect reader from ccs_put_name(). */  
                 spin_lock(&ccs_profile_comment_lock);  
                 old_comment = ccs_profile->comment;  
                 ccs_profile->comment = new_comment;  
                 spin_unlock(&ccs_profile_comment_lock);  
440                  ccs_put_name(old_comment);                  ccs_put_name(old_comment);
441                  return 0;                  return 0;
442          }          }
443          if (!ccs_str_starts(&data, "MAC::"))          if (!strcmp(data, "CONFIG")) {
444                  goto not_mac;                  i = CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
445          if (ccs_str_starts(&data, CCS_KEYWORD_CAPABILITY))                          + CCS_MAX_MAC_CATEGORY_INDEX;
446                  for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) {                  config = profile->default_config;
447                          if (strcmp(data,          } else if (ccs_str_starts(&data, "CONFIG::")) {
448                                     ccs_mac_keywords[CCS_MAX_MAC_INDEX + i]))                  config = 0;
449                                  continue;                  for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
450                          index = CCS_MAX_MAC_INDEX + i;                               + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
                         break;  
                 }  
         else  
                 for (i = 0; i < CCS_MAX_MAC_INDEX; i++) {  
451                          if (strcmp(data, ccs_mac_keywords[i]))                          if (strcmp(data, ccs_mac_keywords[i]))
452                                  continue;                                  continue;
453                          index = i;                          config = profile->config[i];
454                          break;                          break;
455                  }                  }
456          if (index < 0)                  if (i == CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
457                        + CCS_MAX_MAC_CATEGORY_INDEX)
458                            return -EINVAL;
459            } else {
460                  return -EINVAL;                  return -EINVAL;
         ccs_mac_keywords_used[index] = 1;  
         ccs_profile->no_grant_log[index] = !!strstr(cp, "no_grant_log");  
         ccs_profile->no_reject_log[index] = !!strstr(cp, "no_reject_log");  
         for (mode = 0; mode < 4; mode++)  
                 if (strstr(cp, ccs_mode_4[mode]))  
                         ccs_profile->mac_mode[index] = mode;  
         return 0;  
  not_mac:  
         for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {  
                 if (strcmp(data, ccs_control_array[i].keyword))  
                         continue;  
                 if (sscanf(cp, "%u", &value) != 1) {  
                         int j;  
                         for (j = 0; j < 2; j++) {  
                                 if (strcmp(cp, ccs_mode_2[j]))  
                                         continue;  
                                 value = j;  
                                 break;  
                         }  
                         if (j == 2)  
                                 return -EINVAL;  
                 } else if (value > ccs_control_array[i].max_value) {  
                         value = ccs_control_array[i].max_value;  
                 }  
                 ccs_profile->value[i] = value;  
                 return 0;  
461          }          }
462          return -EINVAL;          if (use_default) {
463  }                  config = CCS_CONFIG_USE_DEFAULT;
464            } else {
465  static bool ccs_print_mac_mode(struct ccs_io_buffer *head, u8 index)                  for (mode = 3; mode >= 0; mode--)
466  {                          if (strstr(cp, ccs_mode_4[mode]))
467          const int pos = head->read_avail;                                  /*
468          int i;                                   * Update lower 3 bits in order to distinguish
469          const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];                                   * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
470          for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX; i++) {                                   */
471                  if (!ccs_mac_keywords_used[index])                                  config = (config & ~7) | mode;
472                          continue;  #ifdef CONFIG_CCSECURITY_AUDIT
473                  if (!ccs_io_printf(head, "%u-MAC::%s%s=%s %s %s\n", index,                  if (config != CCS_CONFIG_USE_DEFAULT) {
474                                     i >= CCS_MAX_MAC_INDEX ?                          if (strstr(cp, "grant_log=yes"))
475                                     CCS_KEYWORD_CAPABILITY : "",                                  config |= CCS_CONFIG_WANT_GRANT_LOG;
476                                     ccs_mac_keywords[i],                          else if (strstr(cp, "grant_log=no"))
477                                     ccs_mode_4[ccs_profile->mac_mode[i]],                                  config &= ~CCS_CONFIG_WANT_GRANT_LOG;
478                                     ccs_profile->no_grant_log[i] ?                          if (strstr(cp, "reject_log=yes"))
479                                     "no_grant_log" : "",                                  config |= CCS_CONFIG_WANT_REJECT_LOG;
480                                     ccs_profile->no_reject_log[i] ?                          else if (strstr(cp, "reject_log=no"))
481                                     "no_reject_log" : ""))                                  config &= ~CCS_CONFIG_WANT_REJECT_LOG;
482                          goto out;                  }
483    #endif
484          }          }
485          return true;          if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
486   out:              + CCS_MAX_MAC_CATEGORY_INDEX)
487          head->read_avail = pos;                  profile->config[i] = config;
488          return false;          else if (config != CCS_CONFIG_USE_DEFAULT)
489                    profile->default_config = config;
490            return 0;
491  }  }
492    
493  /**  /**
494   * ccs_read_profile - Read profile table.   * ccs_read_profile - Read profile table.
495   *   *
496   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns 0.  
497   */   */
498  static int ccs_read_profile(struct ccs_io_buffer *head)  static void ccs_read_profile(struct ccs_io_buffer *head)
499  {  {
500          static const int ccs_total = CCS_MAX_CONTROL_INDEX + 2;          int index;
         int step;  
501          if (head->read_eof)          if (head->read_eof)
502                  return 0;                  return;
503          for (step = head->read_step; step < CCS_MAX_PROFILES * ccs_total;          if (head->read_bit)
504               step++) {                  goto body;
505                  const u8 index = step / ccs_total;          ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
506                  u8 type = step % ccs_total;          ccs_io_printf(head, "PREFERENCE::audit={ "
507                  const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];  #ifdef CONFIG_CCSECURITY_AUDIT
508                  head->read_step = step;                        "max_grant_log=%u max_reject_log=%u "
509                  if (!ccs_profile)  #endif
510                          continue;                        "task_info=%s path_info=%s }\n",
511                  if (!type) { /* Print profile' comment tag. */  #ifdef CONFIG_CCSECURITY_AUDIT
512                          bool done;                        ccs_default_profile.preference.audit_max_grant_log,
513                          spin_lock(&ccs_profile_comment_lock);                        ccs_default_profile.preference.audit_max_reject_log,
514                          done = ccs_io_printf(head, "%u-COMMENT=%s\n",  #endif
515                                               index, ccs_profile->comment ?                        ccs_yesno(ccs_default_profile.preference.
516                                               ccs_profile->comment->name : "");                                  audit_task_info),
517                          spin_unlock(&ccs_profile_comment_lock);                        ccs_yesno(ccs_default_profile.preference.
518                          if (!done)                                  audit_path_info));
519                                  break;          ccs_io_printf(head, "PREFERENCE::learning={ verbose=%s max_entry=%u "
520                          continue;                        "exec.realpath=%s exec.argv0=%s symlink.target=%s }\n",
521                  } else if (type == 1) {                        ccs_yesno(ccs_default_profile.preference.
522                          if (!ccs_print_mac_mode(head, index))                                  learning_verbose),
523                                  break;                        ccs_default_profile.preference.learning_max_entry,
524                          ccs_yesno(ccs_default_profile.preference.
525                                    learning_exec_realpath),
526                          ccs_yesno(ccs_default_profile.preference.
527                                    learning_exec_argv0),
528                          ccs_yesno(ccs_default_profile.preference.
529                                    learning_symlink_target));
530            ccs_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n",
531                          ccs_yesno(ccs_default_profile.preference.
532                                    permissive_verbose));
533            ccs_io_printf(head, "PREFERENCE::enforcing={ verbose=%s penalty=%u "
534                          "}\n",
535                          ccs_yesno(ccs_default_profile.preference.
536                                    enforcing_verbose),
537                          ccs_default_profile.preference.enforcing_penalty);
538            head->read_bit = 1;
539     body:
540            for (index = head->read_step; index < CCS_MAX_PROFILES; index++) {
541                    bool done;
542                    u8 config;
543                    int i;
544                    int pos;
545                    const struct ccs_profile *profile = ccs_profile_ptr[index];
546                    const struct ccs_path_info *comment;
547                    head->read_step = index;
548                    if (!profile)
549                          continue;                          continue;
550                    pos = head->read_avail;
551                    comment = profile->comment;
552                    done = ccs_io_printf(head, "%u-COMMENT=%s\n", index,
553                                         comment ? comment->name : "");
554                    if (!done)
555                            goto out;
556                    config = profile->default_config;
557    #ifdef CONFIG_CCSECURITY_AUDIT
558                    if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s grant_log=%s "
559                                       "reject_log=%s }\n", index,
560                                       ccs_mode_4[config & 3],
561                                       ccs_yesno(config &
562                                                 CCS_CONFIG_WANT_GRANT_LOG),
563                                       ccs_yesno(config &
564                                                 CCS_CONFIG_WANT_REJECT_LOG)))
565                            goto out;
566    #else
567                    if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,
568                                       ccs_mode_4[config & 3]))
569                            goto out;
570    #endif
571                    for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
572                                 + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
573    #ifdef CONFIG_CCSECURITY_AUDIT
574                            const char *g;
575                            const char *r;
576    #endif
577                            config = profile->config[i];
578                            if (config == CCS_CONFIG_USE_DEFAULT)
579                                    continue;
580    #ifdef CONFIG_CCSECURITY_AUDIT
581                            g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);
582                            r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);
583                            if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s "
584                                               "grant_log=%s reject_log=%s }\n",
585                                               index, ccs_mac_keywords[i],
586                                               ccs_mode_4[config & 3], g, r))
587                                    goto out;
588    #else
589                            if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s }\n",
590                                               index, ccs_mac_keywords[i],
591                                               ccs_mode_4[config & 3]))
592                                    goto out;
593    #endif
594                  }                  }
595                  type -= 2;                  if (profile->audit != &ccs_default_profile.preference &&
596                  {                      !ccs_io_printf(head, "%u-PREFERENCE::audit={ "
597                          const unsigned int value = ccs_profile->value[type];  #ifdef CONFIG_CCSECURITY_AUDIT
598                          const char *keyword = ccs_control_array[type].keyword;                                     "max_grant_log=%u max_reject_log=%u "
599                          if (ccs_control_array[type].max_value == 1) {  #endif
600                                  if (!ccs_io_printf(head, "%u-%s=%s\n", index,                                     "task_info=%s path_info=%s }\n", index,
601                                                     keyword, ccs_mode_2[value]))  #ifdef CONFIG_CCSECURITY_AUDIT
602                                          break;                                     profile->preference.audit_max_grant_log,
603                          } else {                                     profile->preference.audit_max_reject_log,
604                                  if (!ccs_io_printf(head, "%u-%s=%u\n", index,  #endif
605                                                     keyword, value))                                     ccs_yesno(profile->preference.
606                                          break;                                               audit_task_info),
607                          }                                     ccs_yesno(profile->preference.
608                  }                                               audit_path_info)))
609                            goto out;
610                    if (profile->learning != &ccs_default_profile.preference &&
611                        !ccs_io_printf(head, "%u-PREFERENCE::learning={ "
612                                       "verbose=%s max_entry=%u exec.realpath=%s "
613                                       "exec.argv0=%s symlink.target=%s }\n",
614                                       index,
615                                       ccs_yesno(profile->preference.
616                                                 learning_verbose),
617                                       profile->preference.learning_max_entry,
618                                       ccs_yesno(profile->preference.
619                                                 learning_exec_realpath),
620                                       ccs_yesno(profile->preference.
621                                                 learning_exec_argv0),
622                                       ccs_yesno(profile->preference.
623                                                 learning_symlink_target)))
624                            goto out;
625                    if (profile->permissive != &ccs_default_profile.preference &&
626                        !ccs_io_printf(head, "%u-PREFERENCE::permissive={ "
627                                       "verbose=%s }\n", index,
628                                       ccs_yesno(profile->preference.
629                                                 permissive_verbose)))
630                            goto out;
631                    if (profile->enforcing != &ccs_default_profile.preference &&
632                        !ccs_io_printf(head, "%u-PREFERENCE::enforcing={ "
633                                       "verbose=%s penalty=%u }\n", index,
634                                       ccs_yesno(profile->preference.
635                                                 enforcing_verbose),
636                                       profile->preference.enforcing_penalty))
637                            goto out;
638                    continue;
639     out:
640                    head->read_avail = pos;
641                    break;
642          }          }
643          if (step == CCS_MAX_PROFILES * ccs_total)          if (index == CCS_MAX_PROFILES)
644                  head->read_eof = true;                  head->read_eof = true;
         return 0;  
645  }  }
646    
647  /* The list for "struct ccs_policy_manager_entry". */  /* The list for "struct ccs_policy_manager_entry". */
# Line 446  static int ccs_write_manager_policy(stru Line 716  static int ccs_write_manager_policy(stru
716   *   *
717   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
718   *   *
  * Returns 0.  
  *  
719   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
720   */   */
721  static int ccs_read_manager_policy(struct ccs_io_buffer *head)  static void ccs_read_manager_policy(struct ccs_io_buffer *head)
722  {  {
723          struct list_head *pos;          struct list_head *pos;
         ccs_assert_read_lock();  
724          if (head->read_eof)          if (head->read_eof)
725                  return 0;                  return;
726          list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {          list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {
727                  struct ccs_policy_manager_entry *ptr;                  struct ccs_policy_manager_entry *ptr;
728                  ptr = list_entry(pos, struct ccs_policy_manager_entry, list);                  ptr = list_entry(pos, struct ccs_policy_manager_entry, list);
729                  if (ptr->is_deleted)                  if (ptr->is_deleted)
730                          continue;                          continue;
731                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))                  if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
732                          return 0;                          return;
733          }          }
734          head->read_eof = true;          head->read_eof = true;
         return 0;  
735  }  }
736    
737  /**  /**
# Line 484  static bool ccs_is_policy_manager(void) Line 750  static bool ccs_is_policy_manager(void)
750          const struct ccs_path_info *domainname          const struct ccs_path_info *domainname
751                  = ccs_current_domain()->domainname;                  = ccs_current_domain()->domainname;
752          bool found = false;          bool found = false;
         ccs_assert_read_lock();  
753          if (!ccs_policy_loaded)          if (!ccs_policy_loaded)
754                  return true;                  return true;
755          if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)          if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)
# Line 565  static bool ccs_is_select_one(struct ccs Line 830  static bool ccs_is_select_one(struct ccs
830  {  {
831          unsigned int pid;          unsigned int pid;
832          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
833          ccs_assert_read_lock();          bool global_pid = false;
834          if (!strcmp(data, "allow_execute")) {          if (!strcmp(data, "allow_execute")) {
835                  head->read_execute_only = true;                  head->read_execute_only = true;
836                  return true;                  return true;
837          }          }
838          if (sscanf(data, "pid=%u", &pid) == 1) {          if (sscanf(data, "pid=%u", &pid) == 1 ||
839                (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
840                  struct task_struct *p;                  struct task_struct *p;
841                  read_lock(&tasklist_lock);                  read_lock(&tasklist_lock);
842    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
843                    if (global_pid)
844                            p = find_task_by_pid_ns(pid, &init_pid_ns);
845                    else
846                            p = find_task_by_vpid(pid);
847    #else
848                  p = find_task_by_pid(pid);                  p = find_task_by_pid(pid);
849    #endif
850                  if (p)                  if (p)
851                          domain = ccs_task_domain(p);                          domain = ccs_task_domain(p);
852                  read_unlock(&tasklist_lock);                  read_unlock(&tasklist_lock);
# Line 622  static int ccs_write_domain_policy2(char Line 895  static int ccs_write_domain_policy2(char
895                  return ccs_write_env_policy(data, domain, cond, is_delete);                  return ccs_write_env_policy(data, domain, cond, is_delete);
896          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))          if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))
897                  return ccs_write_mount_policy(data, domain, cond, is_delete);                  return ccs_write_mount_policy(data, domain, cond, is_delete);
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_UNMOUNT))  
                 return ccs_write_umount_policy(data, domain, cond, is_delete);  
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CHROOT))  
                 return ccs_write_chroot_policy(data, domain, cond, is_delete);  
         if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_PIVOT_ROOT))  
                 return ccs_write_pivot_root_policy(data, domain, cond,  
                                                    is_delete);  
898          return ccs_write_file_policy(data, domain, cond, is_delete);          return ccs_write_file_policy(data, domain, cond, is_delete);
899  }  }
900    
# Line 674  static int ccs_write_domain_policy(struc Line 940  static int ccs_write_domain_policy(struc
940    
941          if (sscanf(data, CCS_KEYWORD_USE_PROFILE "%u", &profile) == 1          if (sscanf(data, CCS_KEYWORD_USE_PROFILE "%u", &profile) == 1
942              && profile < CCS_MAX_PROFILES) {              && profile < CCS_MAX_PROFILES) {
943                  if (ccs_profile_ptr[profile] || !ccs_policy_loaded)                  if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])
944                          domain->profile = (u8) profile;                          domain->profile = (u8) profile;
945                  return 0;                  return 0;
946          }          }
# Line 698  static int ccs_write_domain_policy(struc Line 964  static int ccs_write_domain_policy(struc
964          return error;          return error;
965  }  }
966    
967    /**
968     * ccs_print_name_union - Print a ccs_name_union.
969     *
970     * @head: Pointer to "struct ccs_io_buffer".
971     * @ptr:  Pointer to "struct ccs_name_union".
972     *
973     * Returns true on success, false otherwise.
974     */
975  static bool ccs_print_name_union(struct ccs_io_buffer *head,  static bool ccs_print_name_union(struct ccs_io_buffer *head,
976                                   const struct ccs_name_union *ptr)                                   const struct ccs_name_union *ptr)
977  {  {
# Line 710  static bool ccs_print_name_union(struct Line 984  static bool ccs_print_name_union(struct
984          return ccs_io_printf(head, " %s", ptr->filename->name);          return ccs_io_printf(head, " %s", ptr->filename->name);
985  }  }
986    
987    /**
988     * ccs_print_name_union_quoted - Print a ccs_name_union with double quotes.
989     *
990     * @head: Pointer to "struct ccs_io_buffer".
991     * @ptr:  Pointer to "struct ccs_name_union".
992     *
993     * Returns true on success, false otherwise.
994     */
995  static bool ccs_print_name_union_quoted(struct ccs_io_buffer *head,  static bool ccs_print_name_union_quoted(struct ccs_io_buffer *head,
996                                          const struct ccs_name_union *ptr)                                          const struct ccs_name_union *ptr)
997  {  {
# Line 719  static bool ccs_print_name_union_quoted( Line 1001  static bool ccs_print_name_union_quoted(
1001          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);          return ccs_io_printf(head, "\"%s\"", ptr->filename->name);
1002  }  }
1003    
1004    /**
1005     * ccs_print_number_union_common - Print a ccs_number_union.
1006     *
1007     * @head:       Pointer to "struct ccs_io_buffer".
1008     * @ptr:        Pointer to "struct ccs_number_union".
1009     * @need_space: True if a space character is needed.
1010     *
1011     * Returns true on success, false otherwise.
1012     */
1013  static bool ccs_print_number_union_common(struct ccs_io_buffer *head,  static bool ccs_print_number_union_common(struct ccs_io_buffer *head,
1014                                            const struct ccs_number_union *ptr,                                            const struct ccs_number_union *ptr,
1015                                            const bool need_space)                                            const bool need_space)
# Line 762  static bool ccs_print_number_union_commo Line 1053  static bool ccs_print_number_union_commo
1053          }          }
1054  }  }
1055    
1056    /**
1057     * ccs_print_number_union - Print a ccs_number_union.
1058     *
1059     * @head:       Pointer to "struct ccs_io_buffer".
1060     * @ptr:        Pointer to "struct ccs_number_union".
1061     *
1062     * Returns true on success, false otherwise.
1063     */
1064  bool ccs_print_number_union(struct ccs_io_buffer *head,  bool ccs_print_number_union(struct ccs_io_buffer *head,
1065                              const struct ccs_number_union *ptr)                              const struct ccs_number_union *ptr)
1066  {  {
1067          return ccs_print_number_union_common(head, ptr, true);          return ccs_print_number_union_common(head, ptr, true);
1068  }  }
1069    
1070    /**
1071     * ccs_print_number_union_nospace - Print a ccs_number_union without a space character.
1072     *
1073     * @head:       Pointer to "struct ccs_io_buffer".
1074     * @ptr:        Pointer to "struct ccs_number_union".
1075     *
1076     * Returns true on success, false otherwise.
1077     */
1078  static bool ccs_print_number_union_nospace(struct ccs_io_buffer *head,  static bool ccs_print_number_union_nospace(struct ccs_io_buffer *head,
1079                                             const struct ccs_number_union *ptr)                                             const struct ccs_number_union *ptr)
1080  {  {
# Line 886  static bool ccs_print_condition(struct c Line 1193  static bool ccs_print_condition(struct c
1193  }  }
1194    
1195  /**  /**
1196   * ccs_print_path_acl - Print a single path ACL entry.   * ccs_print_path_acl - Print a path ACL entry.
1197   *   *
1198   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1199   * @ptr:  Pointer to "struct ccs_path_acl".   * @ptr:  Pointer to "struct ccs_path_acl".
# Line 895  static bool ccs_print_condition(struct c Line 1202  static bool ccs_print_condition(struct c
1202   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1203   */   */
1204  static bool ccs_print_path_acl(struct ccs_io_buffer *head,  static bool ccs_print_path_acl(struct ccs_io_buffer *head,
1205                                        struct ccs_path_acl *ptr,                                 struct ccs_path_acl *ptr,
1206                                        const struct ccs_condition *cond)                                 const struct ccs_condition *cond)
1207  {  {
1208          int pos;          int pos;
1209          u8 bit;          u8 bit;
# Line 933  static bool ccs_print_path_acl(struct cc Line 1240  static bool ccs_print_path_acl(struct cc
1240   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1241   */   */
1242  static bool ccs_print_path_number3_acl(struct ccs_io_buffer *head,  static bool ccs_print_path_number3_acl(struct ccs_io_buffer *head,
1243                                  struct ccs_path_number3_acl *ptr,                                         struct ccs_path_number3_acl *ptr,
1244                                  const struct ccs_condition *cond)                                         const struct ccs_condition *cond)
1245  {  {
1246          int pos;          int pos;
1247          u8 bit;          u8 bit;
# Line 961  static bool ccs_print_path_number3_acl(s Line 1268  static bool ccs_print_path_number3_acl(s
1268  }  }
1269    
1270  /**  /**
1271   * ccs_print_path2_acl - Print a double path ACL entry.   * ccs_print_path2_acl - Print a path2 ACL entry.
1272   *   *
1273   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1274   * @ptr:  Pointer to "struct ccs_path2_acl".   * @ptr:  Pointer to "struct ccs_path2_acl".
# Line 970  static bool ccs_print_path_number3_acl(s Line 1277  static bool ccs_print_path_number3_acl(s
1277   * Returns true on success, false otherwise.   * Returns true on success, false otherwise.
1278   */   */
1279  static bool ccs_print_path2_acl(struct ccs_io_buffer *head,  static bool ccs_print_path2_acl(struct ccs_io_buffer *head,
1280                                        struct ccs_path2_acl *ptr,                                  struct ccs_path2_acl *ptr,
1281                                        const struct ccs_condition *cond)                                  const struct ccs_condition *cond)
1282  {  {
1283          int pos;          int pos;
1284          u8 bit;          u8 bit;
# Line 995  static bool ccs_print_path2_acl(struct c Line 1302  static bool ccs_print_path2_acl(struct c
1302  }  }
1303    
1304  /**  /**
1305   * ccs_print_path_number_acl - Print an ioctl/chmod/chown/chgrp ACL entry.   * ccs_print_path_number_acl - Print a path_number ACL entry.
1306   *   *
1307   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1308   * @ptr:  Pointer to "struct ccs_path_number_acl".   * @ptr:  Pointer to "struct ccs_path_number_acl".
# Line 1237  static bool ccs_print_mount_acl(struct c Line 1544  static bool ccs_print_mount_acl(struct c
1544  }  }
1545    
1546  /**  /**
  * ccs_print_umount_acl - Print a mount ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_umount_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_umount_acl(struct ccs_io_buffer *head,  
                                  struct ccs_umount_acl *ptr,  
                                  const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT) ||  
             !ccs_print_name_union(head, &ptr->dir) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
  * ccs_print_chroot_acl - Print a chroot ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_chroot_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_chroot_acl(struct ccs_io_buffer *head,  
                                  struct ccs_chroot_acl *ptr,  
                                  const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT) ||  
             !ccs_print_name_union(head, &ptr->dir) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
  * ccs_print_pivot_root_acl - Print a pivot_root ACL entry.  
  *  
  * @head: Pointer to "struct ccs_io_buffer".  
  * @ptr:  Pointer to "struct ccs_pivot_root_acl".  
  * @cond: Pointer to "struct ccs_condition". May be NULL.  
  *  
  * Returns true on success, false otherwise.  
  */  
 static bool ccs_print_pivot_root_acl(struct ccs_io_buffer *head,  
                                      struct ccs_pivot_root_acl *ptr,  
                                      const struct ccs_condition *cond)  
 {  
         const int pos = head->read_avail;  
         if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT) ||  
             !ccs_print_name_union(head, &ptr->new_root) ||  
             !ccs_print_name_union(head, &ptr->old_root) ||  
             !ccs_print_condition(head, cond)) {  
                 head->read_avail = pos;  
                 return false;  
         }  
         return true;  
 }  
   
 /**  
1547   * ccs_print_entry - Print an ACL entry.   * ccs_print_entry - Print an ACL entry.
1548   *   *
1549   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
# Line 1323  static bool ccs_print_entry(struct ccs_i Line 1560  static bool ccs_print_entry(struct ccs_i
1560                  return true;                  return true;
1561          if (acl_type == CCS_TYPE_PATH_ACL) {          if (acl_type == CCS_TYPE_PATH_ACL) {
1562                  struct ccs_path_acl *acl                  struct ccs_path_acl *acl
1563                          = container_of(ptr, struct ccs_path_acl,                          = container_of(ptr, struct ccs_path_acl, head);
                                        head);  
1564                  return ccs_print_path_acl(head, acl, cond);                  return ccs_print_path_acl(head, acl, cond);
1565          }          }
1566          if (acl_type == CCS_TYPE_EXECUTE_HANDLER) {          if (acl_type == CCS_TYPE_EXECUTE_HANDLER) {
# Line 1350  static bool ccs_print_entry(struct ccs_i Line 1586  static bool ccs_print_entry(struct ccs_i
1586          }          }
1587          if (acl_type == CCS_TYPE_PATH2_ACL) {          if (acl_type == CCS_TYPE_PATH2_ACL) {
1588                  struct ccs_path2_acl *acl                  struct ccs_path2_acl *acl
1589                          = container_of(ptr, struct ccs_path2_acl,                          = container_of(ptr, struct ccs_path2_acl, head);
                                        head);  
1590                  return ccs_print_path2_acl(head, acl, cond);                  return ccs_print_path2_acl(head, acl, cond);
1591          }          }
1592          if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {          if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
1593                  struct ccs_path_number_acl *acl                  struct ccs_path_number_acl *acl
1594                          = container_of(ptr, struct ccs_path_number_acl,                          = container_of(ptr, struct ccs_path_number_acl, head);
                                        head);  
1595                  return ccs_print_path_number_acl(head, acl, cond);                  return ccs_print_path_number_acl(head, acl, cond);
1596          }          }
1597          if (acl_type == CCS_TYPE_ENV_ACL) {          if (acl_type == CCS_TYPE_ENV_ACL) {
# Line 1367  static bool ccs_print_entry(struct ccs_i Line 1601  static bool ccs_print_entry(struct ccs_i
1601          }          }
1602          if (acl_type == CCS_TYPE_CAPABILITY_ACL) {          if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1603                  struct ccs_capability_acl *acl                  struct ccs_capability_acl *acl
1604                          = container_of(ptr, struct ccs_capability_acl,                          = container_of(ptr, struct ccs_capability_acl, head);
                                        head);  
1605                  return ccs_print_capability_acl(head, acl, cond);                  return ccs_print_capability_acl(head, acl, cond);
1606          }          }
1607          if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {          if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1608                  struct ccs_ip_network_acl *acl                  struct ccs_ip_network_acl *acl
1609                          = container_of(ptr, struct ccs_ip_network_acl,                          = container_of(ptr, struct ccs_ip_network_acl, head);
                                        head);  
1610                  return ccs_print_network_acl(head, acl, cond);                  return ccs_print_network_acl(head, acl, cond);
1611          }          }
1612          if (acl_type == CCS_TYPE_SIGNAL_ACL) {          if (acl_type == CCS_TYPE_SIGNAL_ACL) {
# Line 1387  static bool ccs_print_entry(struct ccs_i Line 1619  static bool ccs_print_entry(struct ccs_i
1619                          = container_of(ptr, struct ccs_mount_acl, head);                          = container_of(ptr, struct ccs_mount_acl, head);
1620                  return ccs_print_mount_acl(head, acl, cond);                  return ccs_print_mount_acl(head, acl, cond);
1621          }          }
         if (acl_type == CCS_TYPE_UMOUNT_ACL) {  
                 struct ccs_umount_acl *acl  
                         = container_of(ptr, struct ccs_umount_acl, head);  
                 return ccs_print_umount_acl(head, acl, cond);  
         }  
         if (acl_type == CCS_TYPE_CHROOT_ACL) {  
                 struct ccs_chroot_acl *acl  
                         = container_of(ptr, struct ccs_chroot_acl, head);  
                 return ccs_print_chroot_acl(head, acl, cond);  
         }  
         if (acl_type == CCS_TYPE_PIVOT_ROOT_ACL) {  
                 struct ccs_pivot_root_acl *acl  
                         = container_of(ptr, struct ccs_pivot_root_acl,  
                                        head);  
                 return ccs_print_pivot_root_acl(head, acl, cond);  
         }  
1622          BUG(); /* This must not happen. */          BUG(); /* This must not happen. */
1623          return false;          return false;
1624  }  }
# Line 1412  static bool ccs_print_entry(struct ccs_i Line 1628  static bool ccs_print_entry(struct ccs_i
1628   *   *
1629   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1630   *   *
  * Returns 0.  
  *  
1631   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1632   */   */
1633  static int ccs_read_domain_policy(struct ccs_io_buffer *head)  static void ccs_read_domain_policy(struct ccs_io_buffer *head)
1634  {  {
1635          struct list_head *dpos;          struct list_head *dpos;
1636          struct list_head *apos;          struct list_head *apos;
         ccs_assert_read_lock();  
1637          if (head->read_eof)          if (head->read_eof)
1638                  return 0;                  return;
1639          if (head->read_step == 0)          if (head->read_step == 0)
1640                  head->read_step = 1;                  head->read_step = 1;
1641          list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {          list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
# Line 1453  static int ccs_read_domain_policy(struct Line 1666  static int ccs_read_domain_policy(struct
1666                                     transition_failed,                                     transition_failed,
1667                                     ignore_global_allow_read,                                     ignore_global_allow_read,
1668                                     ignore_global_allow_env))                                     ignore_global_allow_env))
1669                          return 0;                          return;
1670                  head->read_step = 2;                  head->read_step = 2;
1671   acl_loop:   acl_loop:
1672                  if (head->read_step == 3)                  if (head->read_step == 3)
# Line 1464  static int ccs_read_domain_policy(struct Line 1677  static int ccs_read_domain_policy(struct
1677                          struct ccs_acl_info *ptr                          struct ccs_acl_info *ptr
1678                                  = list_entry(apos, struct ccs_acl_info, list);                                  = list_entry(apos, struct ccs_acl_info, list);
1679                          if (!ccs_print_entry(head, ptr))                          if (!ccs_print_entry(head, ptr))
1680                                  return 0;                                  return;
1681                  }                  }
1682                  head->read_step = 3;                  head->read_step = 3;
1683   tail_mark:   tail_mark:
1684                  if (!ccs_io_printf(head, "\n"))                  if (!ccs_io_printf(head, "\n"))
1685                          return 0;                          return;
1686                  head->read_step = 1;                  head->read_step = 1;
1687                  if (head->read_single_domain)                  if (head->read_single_domain)
1688                          break;                          break;
1689          }          }
1690          head->read_eof = true;          head->read_eof = true;
         return 0;  
1691  }  }
1692    
1693  /**  /**
# Line 1488  static int ccs_read_domain_policy(struct Line 1700  static int ccs_read_domain_policy(struct
1700   * This is equivalent to doing   * This is equivalent to doing
1701   *   *
1702   *     ( echo "select " $domainname; echo "use_profile " $profile ) |   *     ( echo "select " $domainname; echo "use_profile " $profile ) |
1703   *     /usr/lib/ccs/loadpolicy -d   *     /usr/sbin/ccs-loadpolicy -d
1704   *   *
1705   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1706   */   */
# Line 1498  static int ccs_write_domain_profile(stru Line 1710  static int ccs_write_domain_profile(stru
1710          char *cp = strchr(data, ' ');          char *cp = strchr(data, ' ');
1711          struct ccs_domain_info *domain;          struct ccs_domain_info *domain;
1712          unsigned int profile;          unsigned int profile;
         ccs_assert_read_lock();  
1713          if (!cp)          if (!cp)
1714                  return -EINVAL;                  return -EINVAL;
1715          *cp = '\0';          *cp = '\0';
# Line 1506  static int ccs_write_domain_profile(stru Line 1717  static int ccs_write_domain_profile(stru
1717          if (profile >= CCS_MAX_PROFILES)          if (profile >= CCS_MAX_PROFILES)
1718                  return -EINVAL;                  return -EINVAL;
1719          domain = ccs_find_domain(cp + 1);          domain = ccs_find_domain(cp + 1);
1720          if (domain && (ccs_profile_ptr[profile] || !ccs_policy_loaded))          if (domain && (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile]))
1721                  domain->profile = (u8) profile;                  domain->profile = (u8) profile;
1722          return 0;          return 0;
1723  }  }
# Line 1516  static int ccs_write_domain_profile(stru Line 1727  static int ccs_write_domain_profile(stru
1727   *   *
1728   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1729   *   *
  * Returns list of profile number and domainname pairs.  
  *  
1730   * This is equivalent to doing   * This is equivalent to doing
1731   *   *
1732   *     grep -A 1 '^<kernel>' /proc/ccs/domain_policy |   *     grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
# Line 1527  static int ccs_write_domain_profile(stru Line 1736  static int ccs_write_domain_profile(stru
1736   *   *
1737   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1738   */   */
1739  static int ccs_read_domain_profile(struct ccs_io_buffer *head)  static void ccs_read_domain_profile(struct ccs_io_buffer *head)
1740  {  {
1741          struct list_head *pos;          struct list_head *pos;
         ccs_assert_read_lock();  
1742          if (head->read_eof)          if (head->read_eof)
1743                  return 0;                  return;
1744          list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {          list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
1745                  struct ccs_domain_info *domain;                  struct ccs_domain_info *domain;
1746                  domain = list_entry(pos, struct ccs_domain_info, list);                  domain = list_entry(pos, struct ccs_domain_info, list);
# Line 1540  static int ccs_read_domain_profile(struc Line 1748  static int ccs_read_domain_profile(struc
1748                          continue;                          continue;
1749                  if (!ccs_io_printf(head, "%u %s\n", domain->profile,                  if (!ccs_io_printf(head, "%u %s\n", domain->profile,
1750                                     domain->domainname->name))                                     domain->domainname->name))
1751                          return 0;                          return;
1752          }          }
1753          head->read_eof = true;          head->read_eof = true;
         return 0;  
1754  }  }
1755    
1756  /**  /**
# Line 1570  static int ccs_write_pid(struct ccs_io_b Line 1777  static int ccs_write_pid(struct ccs_io_b
1777   *   *
1778   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1779   */   */
1780  static int ccs_read_pid(struct ccs_io_buffer *head)  static void ccs_read_pid(struct ccs_io_buffer *head)
1781  {  {
1782          char *buf = head->write_buf;          char *buf = head->write_buf;
1783          bool task_info = false;          bool task_info = false;
1784            bool global_pid = false;
1785          unsigned int pid;          unsigned int pid;
1786          struct task_struct *p;          struct task_struct *p;
1787          struct ccs_domain_info *domain = NULL;          struct ccs_domain_info *domain = NULL;
1788          u32 ccs_flags = 0;          u32 ccs_flags = 0;
         ccs_assert_read_lock();  
1789          /* Accessing write_buf is safe because head->io_sem is held. */          /* Accessing write_buf is safe because head->io_sem is held. */
1790          if (!buf)          if (!buf) {
1791                  goto done; /* Do nothing if open(O_RDONLY). */                  head->read_eof = true;
1792                    return; /* Do nothing if open(O_RDONLY). */
1793            }
1794          if (head->read_avail || head->read_eof)          if (head->read_avail || head->read_eof)
1795                  goto done;                  return;
1796          head->read_eof = true;          head->read_eof = true;
1797          if (ccs_str_starts(&buf, "info "))          if (ccs_str_starts(&buf, "info "))
1798                  task_info = true;                  task_info = true;
1799            if (ccs_str_starts(&buf, "global-pid "))
1800                    global_pid = true;
1801          pid = (unsigned int) simple_strtoul(buf, NULL, 10);          pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1802          read_lock(&tasklist_lock);          read_lock(&tasklist_lock);
1803    #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1804            if (global_pid)
1805                    p = find_task_by_pid_ns(pid, &init_pid_ns);
1806            else
1807                    p = find_task_by_vpid(pid);
1808    #else
1809          p = find_task_by_pid(pid);          p = find_task_by_pid(pid);
1810    #endif
1811          if (p) {          if (p) {
1812                  domain = ccs_task_domain(p);                  domain = ccs_task_domain(p);
1813                  ccs_flags = p->ccs_flags;                  ccs_flags = p->ccs_flags;
1814          }          }
1815          read_unlock(&tasklist_lock);          read_unlock(&tasklist_lock);
1816          if (!domain)          if (!domain)
1817                  goto done;                  return;
1818          if (!task_info)          if (!task_info)
1819                  ccs_io_printf(head, "%u %u %s", pid, domain->profile,                  ccs_io_printf(head, "%u %u %s", pid, domain->profile,
1820                                domain->domainname->name);                                domain->domainname->name);
1821          else          else
1822                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "                  ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1823                                "state[0]=%u state[1]=%u state[2]=%u", pid,                                "state[0]=%u state[1]=%u state[2]=%u", pid,
1824                                ccs_flags & CCS_TASK_IS_POLICY_MANAGER ?                                ccs_yesno(ccs_flags &
1825                                "yes" : "no",                                          CCS_TASK_IS_POLICY_MANAGER),
1826                                ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ?                                ccs_yesno(ccs_flags &
1827                                "yes" : "no",                                          CCS_TASK_IS_EXECUTE_HANDLER),
1828                                (u8) (ccs_flags >> 24),                                (u8) (ccs_flags >> 24),
1829                                (u8) (ccs_flags >> 16),                                (u8) (ccs_flags >> 16),
1830                                (u8) (ccs_flags >> 8));                                (u8) (ccs_flags >> 8));
  done:  
         return 0;  
1831  }  }
1832    
1833  /**  /**
# Line 1661  static int ccs_write_exception_policy(st Line 1877  static int ccs_write_exception_policy(st
1877   *   *
1878   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
1879   *   *
  * Returns 0 on success, -EINVAL otherwise.  
  *  
1880   * Caller holds ccs_read_lock().   * Caller holds ccs_read_lock().
1881   */   */
1882  static int ccs_read_exception_policy(struct ccs_io_buffer *head)  static void ccs_read_exception_policy(struct ccs_io_buffer *head)
1883  {  {
1884          ccs_assert_read_lock();          if (head->read_eof)
1885          if (!head->read_eof) {                  return;
1886                  switch (head->read_step) {          switch (head->read_step) {
1887                  case 0:          case 0:
1888                          head->read_var2 = NULL;                  head->read_var2 = NULL;
1889                          head->read_step = 1;                  head->read_step = 1;
1890                  case 1:          case 1:
1891                          if (!ccs_read_domain_keeper_policy(head))                  if (!ccs_read_domain_keeper_policy(head))
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 2;  
                 case 2:  
                         if (!ccs_read_globally_readable_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 3;  
                 case 3:  
                         if (!ccs_read_globally_usable_env_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 4;  
                 case 4:  
                         if (!ccs_read_domain_initializer_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 6;  
                 case 6:  
                         if (!ccs_read_aggregator_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 7;  
                 case 7:  
                         if (!ccs_read_file_pattern(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 8;  
                 case 8:  
                         if (!ccs_read_no_rewrite_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 9;  
                 case 9:  
                         if (!ccs_read_path_group_policy(head))  
                                 break;  
                         head->read_var1 = NULL;  
                         head->read_var2 = NULL;  
                         head->read_step = 10;  
                 case 10:  
                         if (!ccs_read_number_group_policy(head))  
                                 break;  
                         head->read_var1 = NULL;  
                         head->read_var2 = NULL;  
                         head->read_step = 11;  
                 case 11:  
                         if (!ccs_read_address_group_policy(head))  
                                 break;  
                         head->read_var2 = NULL;  
                         head->read_step = 12;  
                 case 12:  
                         if (!ccs_read_reserved_port_policy(head))  
                                 break;  
                         head->read_eof = true;  
1892                          break;                          break;
1893                  default:                  head->read_var2 = NULL;
1894                          return -EINVAL;                  head->read_step = 2;
1895                  }          case 2:
1896                    if (!ccs_read_globally_readable_policy(head))
1897                            break;
1898                    head->read_var2 = NULL;
1899                    head->read_step = 3;
1900            case 3:
1901                    if (!ccs_read_globally_usable_env_policy(head))
1902                            break;
1903                    head->read_var2 = NULL;
1904                    head->read_step = 4;
1905            case 4:
1906                    if (!ccs_read_domain_initializer_policy(head))
1907                            break;
1908                    head->read_var2 = NULL;
1909                    head->read_step = 6;
1910            case 6:
1911                    if (!ccs_read_aggregator_policy(head))
1912                            break;
1913                    head->read_var2 = NULL;
1914                    head->read_step = 7;
1915            case 7:
1916                    if (!ccs_read_file_pattern(head))
1917                            break;
1918                    head->read_var2 = NULL;
1919                    head->read_step = 8;
1920            case 8:
1921                    if (!ccs_read_no_rewrite_policy(head))
1922                            break;
1923                    head->read_var2 = NULL;
1924                    head->read_step = 9;
1925            case 9:
1926                    if (!ccs_read_path_group_policy(head))
1927                            break;
1928                    head->read_var1 = NULL;
1929                    head->read_var2 = NULL;
1930                    head->read_step = 10;
1931            case 10:
1932                    if (!ccs_read_number_group_policy(head))
1933                            break;
1934                    head->read_var1 = NULL;
1935                    head->read_var2 = NULL;
1936                    head->read_step = 11;
1937            case 11:
1938                    if (!ccs_read_address_group_policy(head))
1939                            break;
1940                    head->read_var2 = NULL;
1941                    head->read_step = 12;
1942            case 12:
1943                    if (!ccs_read_reserved_port_policy(head))
1944                            break;
1945                    head->read_eof = true;
1946          }          }
         return 0;  
1947  }  }
1948    
1949  /**  /**
# Line 1762  static bool ccs_get_argv0(struct ccs_exe Line 1971  static bool ccs_get_argv0(struct ccs_exe
1971                  while (offset < PAGE_SIZE) {                  while (offset < PAGE_SIZE) {
1972                          const char *kaddr = ee->dump.data;                          const char *kaddr = ee->dump.data;
1973                          const unsigned char c = kaddr[offset++];                          const unsigned char c = kaddr[offset++];
1974                          if (c && arg_len < CCS_MAX_PATHNAME_LEN - 10) {                          if (c && arg_len < CCS_EXEC_TMPSIZE - 10) {
1975                                  if (c == '\\') {                                  if (c == '\\') {
1976                                          arg_ptr[arg_len++] = '\\';                                          arg_ptr[arg_len++] = '\\';
1977                                          arg_ptr[arg_len++] = '\\';                                          arg_ptr[arg_len++] = '\\';
                                 } else if (c == '/') {  
                                         arg_len = 0;  
1978                                  } else if (c > ' ' && c < 127) {                                  } else if (c > ' ' && c < 127) {
1979                                          arg_ptr[arg_len++] = c;                                          arg_ptr[arg_len++] = c;
1980                                  } else {                                  } else {
# Line 1792  static bool ccs_get_argv0(struct ccs_exe Line 1999  static bool ccs_get_argv0(struct ccs_exe
1999          return false;          return false;
2000  }  }
2001    
2002    /**
2003     * ccs_get_execute_condition - Get condition part for execute requests.
2004     *
2005     * @ee: Pointer to "struct ccs_execve_entry".
2006     *
2007     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2008     */
2009  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry  static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry
2010                                                         *ee)                                                         *ee)
2011  {  {
# Line 1800  static struct ccs_condition *ccs_get_exe Line 2014  static struct ccs_condition *ccs_get_exe
2014          int len = 256;          int len = 256;
2015          char *realpath = NULL;          char *realpath = NULL;
2016          char *argv0 = NULL;          char *argv0 = NULL;
2017          if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {          const struct ccs_profile *profile = ccs_profile(ee->r.domain->profile);
2018            if (profile->learning->learning_exec_realpath) {
2019                  struct file *file = ee->bprm->file;                  struct file *file = ee->bprm->file;
2020  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)  #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
2021                  struct path path = { file->f_vfsmnt, file->f_dentry };                  struct path path = { file->f_vfsmnt, file->f_dentry };
# Line 1811  static struct ccs_condition *ccs_get_exe Line 2026  static struct ccs_condition *ccs_get_exe
2026                  if (realpath)                  if (realpath)
2027                          len += strlen(realpath) + 17;                          len += strlen(realpath) + 17;
2028          }          }
2029          if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {          if (profile->learning->learning_exec_argv0) {
2030                  if (ccs_get_argv0(ee)) {                  if (ccs_get_argv0(ee)) {
2031                          argv0 = ee->tmp;                          argv0 = ee->tmp;
2032                          len += strlen(argv0) + 16;                          len += strlen(argv0) + 16;
2033                  }                  }
2034          }          }
2035          buf = kmalloc(len, GFP_KERNEL);          buf = kmalloc(len, GFP_KERNEL);
2036          if (!buf)          if (!buf) {
2037                    kfree(realpath);
2038                  return NULL;                  return NULL;
2039            }
2040          snprintf(buf, len - 1, "if");          snprintf(buf, len - 1, "if");
2041          if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {          if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
2042                  const int pos = strlen(buf);                  const int pos = strlen(buf);
# Line 1842  static struct ccs_condition *ccs_get_exe Line 2059  static struct ccs_condition *ccs_get_exe
2059          return cond;          return cond;
2060  }  }
2061    
2062    /**
2063     * ccs_get_symlink_condition - Get condition part for symlink requests.
2064     *
2065     * @r: Pointer to "struct ccs_request_info".
2066     *
2067     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2068     */
2069    static struct ccs_condition *ccs_get_symlink_condition(struct ccs_request_info
2070                                                           *r)
2071    {
2072            struct ccs_condition *cond;
2073            char *buf;
2074            int len = 256;
2075            const char *symlink = NULL;
2076            const struct ccs_profile *profile = ccs_profile(r->profile);
2077            if (profile->learning->learning_symlink_target) {
2078                    symlink = r->obj->symlink_target->name;
2079                    len += strlen(symlink) + 18;
2080            }
2081            buf = kmalloc(len, GFP_KERNEL);
2082            if (!buf)
2083                    return NULL;
2084            snprintf(buf, len - 1, "if");
2085            if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
2086                    const int pos = strlen(buf);
2087                    snprintf(buf + pos, len - pos - 1,
2088                             " task.type=execute_handler");
2089            }
2090            if (symlink) {
2091                    const int pos = strlen(buf);
2092                    snprintf(buf + pos, len - pos - 1, " symlink.target=\"%s\"",
2093                             symlink);
2094            }
2095            cond = ccs_get_condition(buf);
2096            kfree(buf);
2097            return cond;
2098    }
2099    
2100  /* Wait queue for ccs_query_list. */  /* Wait queue for ccs_query_list. */
2101  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);  static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
2102    
# Line 1890  int ccs_supervisor(struct ccs_request_in Line 2145  int ccs_supervisor(struct ccs_request_in
2145          switch (r->mode) {          switch (r->mode) {
2146                  char *buffer;                  char *buffer;
2147                  struct ccs_condition *cond;                  struct ccs_condition *cond;
2148          case 1:          case CCS_CONFIG_LEARNING:
2149                  if (!ccs_domain_quota_ok(r))                  if (!ccs_domain_quota_ok(r))
2150                          return 0;                          return 0;
2151                  va_start(args, fmt);                  va_start(args, fmt);
# Line 1905  int ccs_supervisor(struct ccs_request_in Line 2160  int ccs_supervisor(struct ccs_request_in
2160                  ccs_normalize_line(buffer);                  ccs_normalize_line(buffer);
2161                  if (r->ee && !strncmp(buffer, "allow_execute ", 14))                  if (r->ee && !strncmp(buffer, "allow_execute ", 14))
2162                          cond = ccs_get_execute_condition(r->ee);                          cond = ccs_get_execute_condition(r->ee);
2163                    else if (r->obj && r->obj->symlink_target)
2164                            cond = ccs_get_symlink_condition(r);
2165                  else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {                  else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
2166                          char str[] = "if task.type=execute_handler";                          char str[] = "if task.type=execute_handler";
2167                          cond = ccs_get_condition(str);                          cond = ccs_get_condition(str);
# Line 1914  int ccs_supervisor(struct ccs_request_in Line 2171  int ccs_supervisor(struct ccs_request_in
2171                  ccs_put_condition(cond);                  ccs_put_condition(cond);
2172                  kfree(buffer);                  kfree(buffer);
2173                  /* fall through */                  /* fall through */
2174          case 2:          case CCS_CONFIG_PERMISSIVE:
2175                  return 0;                  return 0;
2176          }          }
2177          if (!atomic_read(&ccs_query_observers)) {          if (!atomic_read(&ccs_query_observers)) {
2178                  int i;                  int i;
2179                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)                  if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2180                          return -EPERM;                          return -EPERM;
2181                  for (i = 0; i < ccs_flags(r->domain, CCS_SLEEP_PERIOD);                  for (i = 0; i < ccs_profile(r->domain->profile)->enforcing->
2182                       i++) {                               enforcing_penalty; i++) {
2183                          set_current_state(TASK_INTERRUPTIBLE);                          set_current_state(TASK_INTERRUPTIBLE);
2184                          schedule_timeout(HZ / 10);                          schedule_timeout(HZ / 10);
2185                  }                  }
# Line 2041  static int ccs_poll_query(struct file *f Line 2298  static int ccs_poll_query(struct file *f
2298   * ccs_read_query - Read access requests which violated policy in enforcing mode.   * ccs_read_query - Read access requests which violated policy in enforcing mode.
2299   *   *
2300   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns 0.  
2301   */   */
2302  static int ccs_read_query(struct ccs_io_buffer *head)  static void ccs_read_query(struct ccs_io_buffer *head)
2303  {  {
2304          struct list_head *tmp;          struct list_head *tmp;
2305          int pos = 0;          int pos = 0;
2306          int len = 0;          int len = 0;
2307          char *buf;          char *buf;
2308          if (head->read_avail)          if (head->read_avail)
2309                  return 0;                  return;
2310          if (head->read_buf) {          if (head->read_buf) {
2311                  kfree(head->read_buf);                  kfree(head->read_buf);
2312                  head->read_buf = NULL;                  head->read_buf = NULL;
# Line 2071  static int ccs_read_query(struct ccs_io_ Line 2326  static int ccs_read_query(struct ccs_io_
2326          spin_unlock(&ccs_query_list_lock);          spin_unlock(&ccs_query_list_lock);
2327          if (!len) {          if (!len) {
2328                  head->read_step = 0;                  head->read_step = 0;
2329                  return 0;                  return;
2330          }          }
2331          buf = kzalloc(len, GFP_KERNEL);          buf = kzalloc(len, GFP_KERNEL);
2332          if (!buf)          if (!buf)
2333                  return 0;                  return;
2334          pos = 0;          pos = 0;
2335          spin_lock(&ccs_query_list_lock);          spin_lock(&ccs_query_list_lock);
2336          list_for_each(tmp, &ccs_query_list) {          list_for_each(tmp, &ccs_query_list) {
# Line 2102  static int ccs_read_query(struct ccs_io_ Line 2357  static int ccs_read_query(struct ccs_io_
2357          } else {          } else {
2358                  kfree(buf);                  kfree(buf);
2359          }          }
         return 0;  
2360  }  }
2361    
2362  /**  /**
# Line 2145  static int ccs_write_answer(struct ccs_i Line 2399  static int ccs_write_answer(struct ccs_i
2399   * ccs_read_version: Get version.   * ccs_read_version: Get version.
2400   *   *
2401   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns version information.  
2402   */   */
2403  static int ccs_read_version(struct ccs_io_buffer *head)  static void ccs_read_version(struct ccs_io_buffer *head)
2404  {  {
2405          if (!head->read_eof) {          if (head->read_eof)
2406                  ccs_io_printf(head, "1.7.0-pre");                  return;
2407                  head->read_eof = true;          ccs_io_printf(head, "1.7.1-pre");
2408          }          head->read_eof = true;
         return 0;  
2409  }  }
2410    
2411  /**  /**
2412   * ccs_read_self_domain - Get the current process's domainname.   * ccs_read_self_domain - Get the current process's domainname.
2413   *   *
2414   * @head: Pointer to "struct ccs_io_buffer".   * @head: Pointer to "struct ccs_io_buffer".
  *  
  * Returns the current process's domainname.  
2415   */   */
2416  static int ccs_read_self_domain(struct ccs_io_buffer *head)  static void ccs_read_self_domain(struct ccs_io_buffer *head)
2417  {  {
2418          if (!head->read_eof) {          if (head->read_eof)
2419                  /*                  return;
2420                   * ccs_current_domain()->domainname != NULL          /*
2421                   * because every process belongs to a domain and           * ccs_current_domain()->domainname != NULL because every process
2422                   * the domain's name cannot be NULL.           * belongs to a domain and the domain's name cannot be NULL.
2423                   */           */
2424                  ccs_io_printf(head, "%s",          ccs_io_printf(head, "%s", ccs_current_domain()->domainname->name);
2425                                ccs_current_domain()->domainname->name);          head->read_eof = true;
                 head->read_eof = true;  
         }  
         return 0;  
2426  }  }
2427    
2428  /**  /**
# Line 2314  int ccs_open_control(const u8 type, stru Line 2560  int ccs_open_control(const u8 type, stru
2560   * @wait: Pointer to "poll_table".   * @wait: Pointer to "poll_table".
2561   *   *
2562   * Waits for read readiness.   * Waits for read readiness.
2563   * /proc/ccs/query is handled by /usr/lib/ccs/ccs-queryd and   * /proc/ccs/query is handled by /usr/sbin/ccs-queryd and
2564   * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by   * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by
2565   * /usr/lib/ccs/ccs-auditd.   * /usr/sbin/ccs-auditd .
2566   */   */
2567  int ccs_poll_control(struct file *file, poll_table *wait)  int ccs_poll_control(struct file *file, poll_table *wait)
2568  {  {
# Line 2347  int ccs_read_control(struct file *file, Line 2593  int ccs_read_control(struct file *file,
2593                  return -EFAULT;                  return -EFAULT;
2594          if (mutex_lock_interruptible(&head->io_sem))          if (mutex_lock_interruptible(&head->io_sem))
2595                  return -EINTR;                  return -EINTR;
2596   retry:          while (1) {
2597          /* Call the policy handler. */                  /* Call the policy handler. */
2598          len = head->read(head);                  head->read(head);
2599          if (len < 0)                  /* Write to buffer. */
2600                  goto out;                  len = head->read_avail;
2601          /* Write to buffer. */                  if (len || head->poll || head->read_eof)
2602          len = head->read_avail;                          break;
2603          if (!len && !head->poll && !head->read_eof) {                  len = head->readbuf_size * 2;
                 const int len = head->readbuf_size * 2;  
2604                  cp = kzalloc(len, GFP_KERNEL);                  cp = kzalloc(len, GFP_KERNEL);
2605                  if (cp) {                  if (!cp) {
2606                          kfree(head->read_buf);                          len = -ENOMEM;
2607                          head->read_buf = cp;                          goto out;
                         head->readbuf_size = len;  
                         goto retry;  
2608                  }                  }
2609                    kfree(head->read_buf);
2610                    head->read_buf = cp;
2611                    head->readbuf_size = len;
2612          }          }
2613          if (len > buffer_len)          if (len > buffer_len)
2614                  len = buffer_len;                  len = buffer_len;

Legend:
Removed from v.2930  
changed lines
  Added in v.3136

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