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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2991 - (hide annotations) (download) (as text)
Fri Sep 4 03:58:47 2009 UTC (14 years, 8 months ago) by kumaneko
Original Path: trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 78016 byte(s)
Fix wrong ccs_profile() calls.
1 kumaneko 2863 /*
2 kumaneko 2864 * security/ccsecurity/policy_io.c
3 kumaneko 2863 *
4     * Copyright (C) 2005-2009 NTT DATA CORPORATION
5     *
6 kumaneko 2991 * Version: 1.7.0 2009/09/04
7 kumaneko 2863 *
8     * This file is applicable to both 2.4.30 and 2.6.11 and later.
9     * See README.ccs for ChangeLog.
10     *
11     */
12    
13     #include "internal.h"
14    
15 kumaneko 2962 static struct ccs_profile ccs_default_profile = {
16     .learning = &ccs_default_profile.preference,
17     .permissive = &ccs_default_profile.preference,
18     .enforcing = &ccs_default_profile.preference,
19     #ifdef CONFIG_CCSECURITY_AUDIT
20 kumaneko 2963 .audit = &ccs_default_profile.preference,
21 kumaneko 2962 .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.enforcing_penalty = 0,
25     .preference.enforcing_verbose = true,
26     .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,
27     .preference.learning_verbose = false,
28     .preference.learning_exec_realpath = true,
29     .preference.learning_exec_argv0 = true,
30     .preference.learning_symlink_target = true,
31     .preference.permissive_verbose = true
32     };
33    
34 kumaneko 2958 /* Profile table. Memory is allocated as needed. */
35     static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
36    
37     /* Lock for protecting "struct ccs_profile"->comment */
38 kumaneko 2863 static DEFINE_SPINLOCK(ccs_profile_comment_lock);
39    
40 kumaneko 2948 /* String table for functionality that takes 4 modes. */
41 kumaneko 2925 static const char *ccs_mode_4[4] = {
42     "disabled", "learning", "permissive", "enforcing"
43 kumaneko 2863 };
44 kumaneko 2915
45 kumaneko 2948 /* String table for /proc/ccs/profile */
46 kumaneko 2918 static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX +
47 kumaneko 2943 CCS_MAX_CAPABILITY_INDEX +
48     CCS_MAX_MAC_CATEGORY_INDEX] = {
49     [CCS_MAC_FILE_EXECUTE]
50     = "file::execute",
51     [CCS_MAC_FILE_OPEN]
52     = "file::open",
53     [CCS_MAC_FILE_CREATE]
54     = "file::create",
55     [CCS_MAC_FILE_UNLINK]
56     = "file::unlink",
57     [CCS_MAC_FILE_MKDIR]
58     = "file::mkdir",
59     [CCS_MAC_FILE_RMDIR]
60     = "file::rmdir",
61     [CCS_MAC_FILE_MKFIFO]
62     = "file::mkfifo",
63     [CCS_MAC_FILE_MKSOCK]
64     = "file::mksock",
65     [CCS_MAC_FILE_TRUNCATE]
66     = "file::truncate",
67     [CCS_MAC_FILE_SYMLINK]
68     = "file::symlink",
69     [CCS_MAC_FILE_REWRITE]
70     = "file::rewrite",
71     [CCS_MAC_FILE_MKBLOCK]
72     = "file::mkblock",
73     [CCS_MAC_FILE_MKCHAR]
74     = "file::mkchar",
75     [CCS_MAC_FILE_LINK]
76     = "file::link",
77     [CCS_MAC_FILE_RENAME]
78     = "file::rename",
79     [CCS_MAC_FILE_CHMOD]
80     = "file::chmod",
81     [CCS_MAC_FILE_CHOWN]
82     = "file::chown",
83     [CCS_MAC_FILE_CHGRP]
84     = "file::chgrp",
85     [CCS_MAC_FILE_IOCTL]
86     = "file::ioctl",
87     [CCS_MAC_FILE_CHROOT]
88     = "file::chroot",
89     [CCS_MAC_FILE_MOUNT]
90     = "file::mount",
91     [CCS_MAC_FILE_UMOUNT]
92     = "file::umount",
93     [CCS_MAC_FILE_PIVOT_ROOT]
94     = "file::pivot_root",
95     [CCS_MAC_ENVIRON]
96     = "misc::env",
97     [CCS_MAC_NETWORK_UDP_BIND]
98     = "network::inet_udp_bind",
99     [CCS_MAC_NETWORK_UDP_CONNECT]
100     = "network::inet_udp_connect",
101     [CCS_MAC_NETWORK_TCP_BIND]
102     = "network::inet_tcp_bind",
103     [CCS_MAC_NETWORK_TCP_LISTEN]
104     = "network::inet_tcp_listen",
105     [CCS_MAC_NETWORK_TCP_CONNECT]
106     = "network::inet_tcp_connect",
107     [CCS_MAC_NETWORK_TCP_ACCEPT]
108     = "network::inet_tcp_accept",
109     [CCS_MAC_NETWORK_RAW_BIND]
110     = "network::inet_raw_bind",
111     [CCS_MAC_NETWORK_RAW_CONNECT]
112     = "network::inet_raw_connect",
113     [CCS_MAC_SIGNAL]
114     = "ipc::signal",
115 kumaneko 2918 [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CREATE]
116 kumaneko 2943 = "capability::inet_tcp_create",
117 kumaneko 2918 [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_LISTEN]
118 kumaneko 2943 = "capability::inet_tcp_listen",
119 kumaneko 2918 [CCS_MAX_MAC_INDEX + CCS_INET_STREAM_SOCKET_CONNECT]
120 kumaneko 2943 = "capability::inet_tcp_connect",
121     [CCS_MAX_MAC_INDEX + CCS_USE_INET_DGRAM_SOCKET]
122     = "capability::use_inet_udp",
123     [CCS_MAX_MAC_INDEX + CCS_USE_INET_RAW_SOCKET]
124     = "capability::use_inet_ip",
125     [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
126     = "capability::use_route",
127     [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
128     = "capability::use_packet",
129     [CCS_MAX_MAC_INDEX + CCS_SYS_MOUNT]
130     = "capability::SYS_MOUNT",
131     [CCS_MAX_MAC_INDEX + CCS_SYS_UMOUNT]
132     = "capability::SYS_UMOUNT",
133     [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
134     = "capability::SYS_REBOOT",
135     [CCS_MAX_MAC_INDEX + CCS_SYS_CHROOT]
136     = "capability::SYS_CHROOT",
137     [CCS_MAX_MAC_INDEX + CCS_SYS_KILL]
138     = "capability::SYS_KILL",
139     [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
140     = "capability::SYS_VHANGUP",
141     [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
142     = "capability::SYS_TIME",
143     [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]
144     = "capability::SYS_NICE",
145     [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]
146     = "capability::SYS_SETHOSTNAME",
147     [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
148     = "capability::use_kernel_module",
149     [CCS_MAX_MAC_INDEX + CCS_CREATE_FIFO]
150     = "capability::create_fifo",
151     [CCS_MAX_MAC_INDEX + CCS_CREATE_BLOCK_DEV]
152     = "capability::create_block_dev",
153     [CCS_MAX_MAC_INDEX + CCS_CREATE_CHAR_DEV]
154     = "capability::create_char_dev",
155     [CCS_MAX_MAC_INDEX + CCS_CREATE_UNIX_SOCKET]
156     = "capability::create_unix_socket",
157     [CCS_MAX_MAC_INDEX + CCS_SYS_LINK]
158     = "capability::SYS_LINK",
159     [CCS_MAX_MAC_INDEX + CCS_SYS_SYMLINK]
160     = "capability::SYS_SYMLINK",
161     [CCS_MAX_MAC_INDEX + CCS_SYS_RENAME]
162     = "capability::SYS_RENAME",
163     [CCS_MAX_MAC_INDEX + CCS_SYS_UNLINK]
164     = "capability::SYS_UNLINK",
165     [CCS_MAX_MAC_INDEX + CCS_SYS_CHMOD]
166     = "capability::SYS_CHMOD",
167     [CCS_MAX_MAC_INDEX + CCS_SYS_CHOWN]
168     = "capability::SYS_CHOWN",
169     [CCS_MAX_MAC_INDEX + CCS_SYS_IOCTL]
170     = "capability::SYS_IOCTL",
171     [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
172     = "capability::SYS_KEXEC_LOAD",
173     [CCS_MAX_MAC_INDEX + CCS_SYS_PIVOT_ROOT]
174     = "capability::SYS_PIVOT_ROOT",
175     [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
176     = "capability::SYS_PTRACE",
177     [CCS_MAX_MAC_INDEX + CCS_CONCEAL_MOUNT]
178     = "capability::conceal_mount",
179     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
180     + CCS_MAC_CATEGORY_FILE] = "file",
181     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
182     + CCS_MAC_CATEGORY_NETWORK] = "network",
183     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
184     + CCS_MAC_CATEGORY_MISC] = "misc",
185     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
186     + CCS_MAC_CATEGORY_IPC] = "ipc",
187     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
188     + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
189 kumaneko 2915 };
190    
191 kumaneko 2863 /* Permit policy management by non-root user? */
192     static bool ccs_manage_by_non_root;
193    
194     /**
195 kumaneko 2918 * ccs_cap2keyword - Convert capability operation to capability name.
196     *
197     * @operation: The capability index.
198     *
199     * Returns the name of the specified capability's name.
200     */
201     const char *ccs_cap2keyword(const u8 operation)
202     {
203     return operation < CCS_MAX_CAPABILITY_INDEX
204 kumaneko 2943 ? ccs_mac_keywords[CCS_MAX_MAC_INDEX + operation] + 12 : NULL;
205 kumaneko 2918 }
206    
207     /**
208 kumaneko 2958 * ccs_yesno - Return "yes" or "no".
209 kumaneko 2863 *
210 kumaneko 2958 * @value: Bool value.
211 kumaneko 2863 */
212 kumaneko 2958 static const char *ccs_yesno(const unsigned int value)
213 kumaneko 2863 {
214 kumaneko 2958 return value ? "yes" : "no";
215 kumaneko 2863 }
216    
217     /**
218     * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.
219     *
220     * @head: Pointer to "struct ccs_io_buffer".
221     * @fmt: The printf()'s format string, followed by parameters.
222     *
223     * Returns true on success, false otherwise.
224     *
225     * The snprintf() will truncate, but ccs_io_printf() won't.
226     */
227     bool ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
228     {
229     va_list args;
230     int len;
231     int pos = head->read_avail;
232     int size = head->readbuf_size - pos;
233     if (size <= 0)
234     return false;
235     va_start(args, fmt);
236     len = vsnprintf(head->read_buf + pos, size, fmt, args);
237     va_end(args);
238     if (pos + len >= head->readbuf_size)
239     return false;
240     head->read_avail += len;
241     return true;
242     }
243    
244     /**
245     * ccs_find_or_assign_new_profile - Create a new profile.
246     *
247     * @profile: Profile number to create.
248     *
249     * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
250     */
251 kumaneko 2892 static struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int
252     profile)
253 kumaneko 2863 {
254     struct ccs_profile *ptr;
255     struct ccs_profile *entry;
256 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
257 kumaneko 2863 return NULL;
258     ptr = ccs_profile_ptr[profile];
259     if (ptr)
260     return ptr;
261     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
262     mutex_lock(&ccs_policy_lock);
263     ptr = ccs_profile_ptr[profile];
264     if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
265     ptr = entry;
266 kumaneko 2963 #ifdef CONFIG_CCSECURITY_AUDIT
267 kumaneko 2962 ptr->audit = &ccs_default_profile.preference;
268 kumaneko 2963 #endif
269 kumaneko 2962 ptr->learning = &ccs_default_profile.preference;
270     ptr->permissive = &ccs_default_profile.preference;
271     ptr->enforcing = &ccs_default_profile.preference;
272 kumaneko 2958 ptr->default_config = CCS_CONFIG_DISABLED |
273     CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
274     memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
275 kumaneko 2943 sizeof(ptr->config));
276 kumaneko 2863 mb(); /* Avoid out-of-order execution. */
277     ccs_profile_ptr[profile] = ptr;
278     entry = NULL;
279     }
280     mutex_unlock(&ccs_policy_lock);
281     kfree(entry);
282     return ptr;
283     }
284    
285     /**
286 kumaneko 2991 * ccs_check_profile - Check all profiles currently assigned to domains are defined.
287     */
288     void ccs_check_profile(void)
289     {
290     struct ccs_domain_info *domain;
291     ccs_policy_loaded = true;
292     list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
293     const u8 profile = domain->profile;
294     if (ccs_profile_ptr[profile])
295     continue;
296     panic("Profile %u (used by '%s') not defined.\n",
297     profile, domain->domainname->name);
298     }
299     }
300    
301     /**
302 kumaneko 2958 * ccs_profile - Find a profile.
303     *
304     * @profile: Profile number to find.
305     *
306 kumaneko 2991 * Returns pointer to "struct ccs_profile".
307 kumaneko 2958 */
308     struct ccs_profile *ccs_profile(const u8 profile)
309     {
310 kumaneko 2974 struct ccs_profile *ptr = ccs_profile_ptr[profile];
311 kumaneko 2962 if (!ccs_policy_loaded)
312     return &ccs_default_profile;
313 kumaneko 2974 BUG_ON(!ptr);
314     return ptr;
315 kumaneko 2958 }
316    
317     /**
318 kumaneko 2863 * ccs_write_profile - Write profile table.
319     *
320     * @head: Pointer to "struct ccs_io_buffer".
321     *
322     * Returns 0 on success, negative value otherwise.
323     */
324     static int ccs_write_profile(struct ccs_io_buffer *head)
325     {
326     char *data = head->write_buf;
327     unsigned int i;
328 kumaneko 2958 int value;
329 kumaneko 2915 int mode;
330 kumaneko 2943 u8 config;
331 kumaneko 2962 bool use_default = false;
332 kumaneko 2863 char *cp;
333 kumaneko 2958 struct ccs_profile *profile;
334 kumaneko 2863 i = simple_strtoul(data, &cp, 10);
335 kumaneko 2962 if (data == cp) {
336     profile = &ccs_default_profile;
337     } else {
338 kumaneko 2863 if (*cp != '-')
339     return -EINVAL;
340     data = cp + 1;
341 kumaneko 2962 profile = ccs_find_or_assign_new_profile(i);
342     if (!profile)
343     return -EINVAL;
344 kumaneko 2863 }
345     cp = strchr(data, '=');
346     if (!cp)
347     return -EINVAL;
348 kumaneko 2925 *cp++ = '\0';
349 kumaneko 2962 if (profile != &ccs_default_profile)
350     use_default = strstr(cp, "use_default") != NULL;
351     if (strstr(cp, "verbose=yes"))
352     value = 1;
353     else if (strstr(cp, "verbose=no"))
354     value = 0;
355     else
356     value = -1;
357 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
358 kumaneko 2958 if (!strcmp(data, "PREFERENCE::audit")) {
359 kumaneko 2962 char *cp2;
360     if (use_default) {
361     profile->audit = &ccs_default_profile.preference;
362     return 0;
363     }
364     profile->audit = &profile->preference;
365     cp2 = strstr(cp, "max_grant_log=");
366 kumaneko 2958 if (cp2)
367 kumaneko 2962 sscanf(cp2 + 14, "%u",
368     &profile->preference.audit_max_grant_log);
369 kumaneko 2958 cp2 = strstr(cp, "max_reject_log=");
370     if (cp2)
371 kumaneko 2962 sscanf(cp2 + 15, "%u",
372     &profile->preference.audit_max_reject_log);
373 kumaneko 2863 return 0;
374     }
375 kumaneko 2959 #endif
376 kumaneko 2958 if (!strcmp(data, "PREFERENCE::enforcing")) {
377     char *cp2;
378 kumaneko 2962 if (use_default) {
379     profile->enforcing = &ccs_default_profile.preference;
380     return 0;
381     }
382     profile->enforcing = &profile->preference;
383 kumaneko 2958 if (value >= 0)
384 kumaneko 2962 profile->preference.enforcing_verbose = value;
385 kumaneko 2958 cp2 = strstr(cp, "penalty=");
386     if (cp2)
387 kumaneko 2962 sscanf(cp2 + 8, "%u",
388     &profile->preference.enforcing_penalty);
389 kumaneko 2958 return 0;
390     }
391     if (!strcmp(data, "PREFERENCE::permissive")) {
392 kumaneko 2962 if (use_default) {
393     profile->permissive = &ccs_default_profile.preference;
394     return 0;
395     }
396     profile->permissive = &profile->preference;
397 kumaneko 2958 if (value >= 0)
398 kumaneko 2962 profile->preference.permissive_verbose = value;
399 kumaneko 2958 return 0;
400     }
401     if (!strcmp(data, "PREFERENCE::learning")) {
402     char *cp2;
403 kumaneko 2962 if (use_default) {
404     profile->learning = &ccs_default_profile.preference;
405     return 0;
406     }
407     profile->learning = &profile->preference;
408 kumaneko 2958 if (value >= 0)
409 kumaneko 2962 profile->preference.learning_verbose = value;
410 kumaneko 2958 cp2 = strstr(cp, "max_entry=");
411     if (cp2)
412 kumaneko 2962 sscanf(cp2 + 10, "%u",
413     &profile->preference.learning_max_entry);
414 kumaneko 2958 if (strstr(cp, "exec.realpath=yes"))
415 kumaneko 2962 profile->preference.learning_exec_realpath = true;
416 kumaneko 2958 else if (strstr(cp, "exec.realpath=no"))
417 kumaneko 2962 profile->preference.learning_exec_realpath = false;
418 kumaneko 2958 if (strstr(cp, "exec.argv0=yes"))
419 kumaneko 2962 profile->preference.learning_exec_argv0 = true;
420 kumaneko 2958 else if (strstr(cp, "exec.argv0=no"))
421 kumaneko 2962 profile->preference.learning_exec_argv0 = false;
422 kumaneko 2961 if (strstr(cp, "symlink.target=yes"))
423 kumaneko 2962 profile->preference.learning_symlink_target = true;
424 kumaneko 2961 else if (strstr(cp, "symlink.target=no"))
425 kumaneko 2962 profile->preference.learning_symlink_target = false;
426 kumaneko 2958 return 0;
427     }
428 kumaneko 2962 if (profile == &ccs_default_profile)
429     return -EINVAL;
430     if (!strcmp(data, "COMMENT")) {
431     const struct ccs_path_info *new_comment = ccs_get_name(cp);
432     const struct ccs_path_info *old_comment;
433     /* Protect reader from ccs_put_name(). */
434     spin_lock(&ccs_profile_comment_lock);
435     old_comment = profile->comment;
436     profile->comment = new_comment;
437     spin_unlock(&ccs_profile_comment_lock);
438     ccs_put_name(old_comment);
439     return 0;
440     }
441 kumaneko 2958 if (!strcmp(data, "CONFIG")) {
442     i = CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
443     + CCS_MAX_MAC_CATEGORY_INDEX;
444     config = profile->default_config;
445     } else if (ccs_str_starts(&data, "CONFIG::")) {
446     config = 0;
447 kumaneko 2943 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
448     + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
449     if (strcmp(data, ccs_mac_keywords[i]))
450     continue;
451 kumaneko 2958 config = profile->config[i];
452 kumaneko 2943 break;
453     }
454 kumaneko 2958 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
455     + CCS_MAX_MAC_CATEGORY_INDEX)
456     return -EINVAL;
457     } else {
458     return -EINVAL;
459     }
460 kumaneko 2962 if (use_default) {
461 kumaneko 2958 config = CCS_CONFIG_USE_DEFAULT;
462     } else {
463     for (mode = 3; mode >= 0; mode--)
464     if (strstr(cp, ccs_mode_4[mode]))
465     /*
466     * Update lower 3 bits in order to distinguish
467     * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
468     */
469     config = (config & ~7) | mode;
470 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
471 kumaneko 2958 if (config != CCS_CONFIG_USE_DEFAULT) {
472     if (strstr(cp, "grant_log=yes"))
473     config |= CCS_CONFIG_WANT_GRANT_LOG;
474     else if (strstr(cp, "grant_log=no"))
475     config &= ~CCS_CONFIG_WANT_GRANT_LOG;
476     if (strstr(cp, "reject_log=yes"))
477     config |= CCS_CONFIG_WANT_REJECT_LOG;
478     else if (strstr(cp, "reject_log=no"))
479     config &= ~CCS_CONFIG_WANT_REJECT_LOG;
480     }
481 kumaneko 2959 #endif
482 kumaneko 2958 }
483     if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
484     + CCS_MAX_MAC_CATEGORY_INDEX)
485     profile->config[i] = config;
486     else if (config != CCS_CONFIG_USE_DEFAULT)
487     profile->default_config = config;
488 kumaneko 2943 return 0;
489 kumaneko 2863 }
490    
491     /**
492     * ccs_read_profile - Read profile table.
493     *
494     * @head: Pointer to "struct ccs_io_buffer".
495     */
496 kumaneko 2943 static void ccs_read_profile(struct ccs_io_buffer *head)
497 kumaneko 2863 {
498 kumaneko 2958 int index;
499 kumaneko 2863 if (head->read_eof)
500 kumaneko 2943 return;
501 kumaneko 2965 if (head->read_bit)
502     goto body;
503 kumaneko 2976 ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
504 kumaneko 2962 #ifdef CONFIG_CCSECURITY_AUDIT
505     ccs_io_printf(head, "PREFERENCE::audit={ max_grant_log=%u "
506     "max_reject_log=%u }\n",
507     ccs_default_profile.preference.audit_max_grant_log,
508     ccs_default_profile.preference.audit_max_reject_log);
509     #endif
510     ccs_io_printf(head, "PREFERENCE::learning={ verbose=%s max_entry=%u "
511     "exec.realpath=%s exec.argv0=%s symlink.target=%s }\n",
512 kumaneko 2973 ccs_yesno(ccs_default_profile.preference.
513     learning_verbose),
514 kumaneko 2962 ccs_default_profile.preference.learning_max_entry,
515     ccs_yesno(ccs_default_profile.preference.
516 kumaneko 2973 learning_exec_realpath),
517     ccs_yesno(ccs_default_profile.preference.
518     learning_exec_argv0),
519     ccs_yesno(ccs_default_profile.preference.
520 kumaneko 2962 learning_symlink_target));
521     ccs_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n",
522 kumaneko 2973 ccs_yesno(ccs_default_profile.preference.
523     permissive_verbose));
524 kumaneko 2962 ccs_io_printf(head, "PREFERENCE::enforcing={ verbose=%s penalty=%u "
525     "}\n",
526 kumaneko 2973 ccs_yesno(ccs_default_profile.preference.
527     enforcing_verbose),
528 kumaneko 2962 ccs_default_profile.preference.enforcing_penalty);
529 kumaneko 2965 head->read_bit = 1;
530     body:
531 kumaneko 2958 for (index = head->read_step; index < CCS_MAX_PROFILES; index++) {
532     bool done;
533     u8 config;
534     int i;
535 kumaneko 2965 int pos;
536 kumaneko 2958 const struct ccs_profile *profile = ccs_profile_ptr[index];
537     head->read_step = index;
538     if (!profile)
539 kumaneko 2863 continue;
540 kumaneko 2965 pos = head->read_avail;
541 kumaneko 2958 spin_lock(&ccs_profile_comment_lock);
542     done = ccs_io_printf(head, "%u-COMMENT=%s\n", index,
543     profile->comment ? profile->comment->name
544     : "");
545     spin_unlock(&ccs_profile_comment_lock);
546     if (!done)
547     goto out;
548     config = profile->default_config;
549 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
550 kumaneko 2958 if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s grant_log=%s "
551     "reject_log=%s }\n", index,
552     ccs_mode_4[config & 3],
553     ccs_yesno(config &
554     CCS_CONFIG_WANT_GRANT_LOG),
555     ccs_yesno(config &
556     CCS_CONFIG_WANT_REJECT_LOG)))
557     goto out;
558 kumaneko 2959 #else
559     if (!ccs_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,
560     ccs_mode_4[config & 3]))
561     goto out;
562     #endif
563 kumaneko 2958 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
564     + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
565 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
566 kumaneko 2958 const char *g;
567     const char *r;
568 kumaneko 2959 #endif
569 kumaneko 2958 config = profile->config[i];
570     if (config == CCS_CONFIG_USE_DEFAULT)
571     continue;
572 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
573 kumaneko 2958 g = ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG);
574     r = ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG);
575     if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s "
576     "grant_log=%s reject_log=%s }\n",
577     index, ccs_mac_keywords[i],
578     ccs_mode_4[config & 3], g, r))
579     goto out;
580 kumaneko 2959 #else
581     if (!ccs_io_printf(head, "%u-CONFIG::%s={ mode=%s }\n",
582     index, ccs_mac_keywords[i],
583     ccs_mode_4[config & 3]))
584     goto out;
585     #endif
586 kumaneko 2908 }
587 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
588 kumaneko 2962 if (profile->audit != &ccs_default_profile.preference &&
589     !ccs_io_printf(head, "%u-PREFERENCE::audit={ "
590 kumaneko 2958 "max_grant_log=%u max_reject_log=%u }\n",
591 kumaneko 2962 index,
592     profile->preference.audit_max_grant_log,
593     profile->preference.audit_max_reject_log))
594 kumaneko 2959 goto out;
595     #endif
596 kumaneko 2962 if (profile->learning != &ccs_default_profile.preference &&
597     !ccs_io_printf(head, "%u-PREFERENCE::learning={ "
598 kumaneko 2958 "verbose=%s max_entry=%u exec.realpath=%s "
599 kumaneko 2961 "exec.argv0=%s symlink.target=%s }\n",
600 kumaneko 2962 index,
601     ccs_yesno(profile->preference.
602     learning_verbose),
603     profile->preference.learning_max_entry,
604     ccs_yesno(profile->preference.
605     learning_exec_realpath),
606     ccs_yesno(profile->preference.
607     learning_exec_argv0),
608     ccs_yesno(profile->preference.
609     learning_symlink_target)))
610 kumaneko 2958 goto out;
611 kumaneko 2962 if (profile->permissive != &ccs_default_profile.preference &&
612     !ccs_io_printf(head, "%u-PREFERENCE::permissive={ "
613     "verbose=%s }\n", index,
614     ccs_yesno(profile->preference.
615     permissive_verbose)))
616     goto out;
617     if (profile->enforcing != &ccs_default_profile.preference &&
618     !ccs_io_printf(head, "%u-PREFERENCE::enforcing={ "
619     "verbose=%s penalty=%u }\n", index,
620     ccs_yesno(profile->preference.
621     enforcing_verbose),
622     profile->preference.enforcing_penalty))
623     goto out;
624 kumaneko 2958 continue;
625     out:
626     head->read_avail = pos;
627     break;
628 kumaneko 2863 }
629 kumaneko 2958 if (index == CCS_MAX_PROFILES)
630 kumaneko 2863 head->read_eof = true;
631     }
632    
633     /* The list for "struct ccs_policy_manager_entry". */
634     LIST_HEAD(ccs_policy_manager_list);
635    
636     /**
637     * ccs_update_manager_entry - Add a manager entry.
638     *
639     * @manager: The path to manager or the domainnamme.
640     * @is_delete: True if it is a delete request.
641     *
642     * Returns 0 on success, negative value otherwise.
643     */
644     static int ccs_update_manager_entry(const char *manager, const bool is_delete)
645     {
646     struct ccs_policy_manager_entry *entry = NULL;
647     struct ccs_policy_manager_entry *ptr;
648 kumaneko 2900 struct ccs_policy_manager_entry e = { };
649 kumaneko 2863 int error = is_delete ? -ENOENT : -ENOMEM;
650     if (ccs_is_domain_def(manager)) {
651     if (!ccs_is_correct_domain(manager))
652     return -EINVAL;
653 kumaneko 2900 e.is_domain = true;
654 kumaneko 2863 } else {
655     if (!ccs_is_correct_path(manager, 1, -1, -1))
656     return -EINVAL;
657     }
658 kumaneko 2900 e.manager = ccs_get_name(manager);
659     if (!e.manager)
660 kumaneko 2863 return -ENOMEM;
661     if (!is_delete)
662 kumaneko 2900 entry = kmalloc(sizeof(e), GFP_KERNEL);
663 kumaneko 2863 mutex_lock(&ccs_policy_lock);
664     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
665 kumaneko 2900 if (ptr->manager != e.manager)
666 kumaneko 2863 continue;
667     ptr->is_deleted = is_delete;
668     error = 0;
669     break;
670     }
671 kumaneko 2900 if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {
672 kumaneko 2863 list_add_tail_rcu(&entry->list, &ccs_policy_manager_list);
673     entry = NULL;
674     error = 0;
675     }
676     mutex_unlock(&ccs_policy_lock);
677 kumaneko 2900 ccs_put_name(e.manager);
678 kumaneko 2863 kfree(entry);
679     return error;
680     }
681    
682     /**
683     * ccs_write_manager_policy - Write manager policy.
684     *
685     * @head: Pointer to "struct ccs_io_buffer".
686     *
687     * Returns 0 on success, negative value otherwise.
688     */
689     static int ccs_write_manager_policy(struct ccs_io_buffer *head)
690     {
691     char *data = head->write_buf;
692 kumaneko 2892 bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
693 kumaneko 2863 if (!strcmp(data, "manage_by_non_root")) {
694     ccs_manage_by_non_root = !is_delete;
695     return 0;
696     }
697     return ccs_update_manager_entry(data, is_delete);
698     }
699    
700     /**
701     * ccs_read_manager_policy - Read manager policy.
702     *
703     * @head: Pointer to "struct ccs_io_buffer".
704     *
705     * Caller holds ccs_read_lock().
706     */
707 kumaneko 2943 static void ccs_read_manager_policy(struct ccs_io_buffer *head)
708 kumaneko 2863 {
709     struct list_head *pos;
710     if (head->read_eof)
711 kumaneko 2943 return;
712 kumaneko 2863 list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {
713     struct ccs_policy_manager_entry *ptr;
714     ptr = list_entry(pos, struct ccs_policy_manager_entry, list);
715     if (ptr->is_deleted)
716     continue;
717     if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
718 kumaneko 2943 return;
719 kumaneko 2863 }
720     head->read_eof = true;
721     }
722    
723     /**
724     * ccs_is_policy_manager - Check whether the current process is a policy manager.
725     *
726     * Returns true if the current process is permitted to modify policy
727     * via /proc/ccs/ interface.
728     *
729     * Caller holds ccs_read_lock().
730     */
731     static bool ccs_is_policy_manager(void)
732     {
733     struct ccs_policy_manager_entry *ptr;
734     const char *exe;
735     struct task_struct *task = current;
736     const struct ccs_path_info *domainname
737     = ccs_current_domain()->domainname;
738     bool found = false;
739     if (!ccs_policy_loaded)
740     return true;
741     if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)
742     return true;
743     if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
744     return false;
745     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
746     if (!ptr->is_deleted && ptr->is_domain
747     && !ccs_pathcmp(domainname, ptr->manager)) {
748     /* Set manager flag. */
749     task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
750     return true;
751     }
752     }
753     exe = ccs_get_exe();
754     if (!exe)
755     return false;
756     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
757     if (!ptr->is_deleted && !ptr->is_domain
758     && !strcmp(exe, ptr->manager->name)) {
759     found = true;
760     /* Set manager flag. */
761     task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
762     break;
763     }
764     }
765     if (!found) { /* Reduce error messages. */
766     static pid_t ccs_last_pid;
767     const pid_t pid = current->pid;
768     if (ccs_last_pid != pid) {
769     printk(KERN_WARNING "%s ( %s ) is not permitted to "
770     "update policies.\n", domainname->name, exe);
771     ccs_last_pid = pid;
772     }
773     }
774     kfree(exe);
775     return found;
776     }
777    
778     /**
779     * ccs_find_condition_part - Find condition part from the statement.
780     *
781     * @data: String to parse.
782     *
783     * Returns pointer to the condition part if it was found in the statement,
784     * NULL otherwise.
785     */
786     static char *ccs_find_condition_part(char *data)
787     {
788     char *cp = strstr(data, " if ");
789     if (cp) {
790     while (1) {
791     char *cp2 = strstr(cp + 3, " if ");
792     if (!cp2)
793     break;
794     cp = cp2;
795     }
796     *cp++ = '\0';
797     } else {
798     cp = strstr(data, " ; set ");
799     if (cp)
800     *cp++ = '\0';
801     }
802     return cp;
803     }
804    
805     /**
806     * ccs_is_select_one - Parse select command.
807     *
808     * @head: Pointer to "struct ccs_io_buffer".
809     * @data: String to parse.
810     *
811     * Returns true on success, false otherwise.
812     *
813     * Caller holds ccs_read_lock().
814     */
815     static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)
816     {
817     unsigned int pid;
818     struct ccs_domain_info *domain = NULL;
819 kumaneko 2970 bool global_pid = false;
820 kumaneko 2863 if (!strcmp(data, "allow_execute")) {
821     head->read_execute_only = true;
822     return true;
823     }
824 kumaneko 2970 if (sscanf(data, "pid=%u", &pid) == 1 ||
825     (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
826 kumaneko 2863 struct task_struct *p;
827     read_lock(&tasklist_lock);
828 kumaneko 2970 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
829     if (global_pid)
830     p = find_task_by_pid_ns(pid, &init_pid_ns);
831     else
832     p = find_task_by_vpid(pid);
833     #else
834 kumaneko 2863 p = find_task_by_pid(pid);
835 kumaneko 2970 #endif
836 kumaneko 2863 if (p)
837     domain = ccs_task_domain(p);
838     read_unlock(&tasklist_lock);
839     } else if (!strncmp(data, "domain=", 7)) {
840     if (ccs_is_domain_def(data + 7))
841     domain = ccs_find_domain(data + 7);
842     } else
843     return false;
844     head->write_var1 = domain;
845     /* Accessing read_buf is safe because head->io_sem is held. */
846     if (!head->read_buf)
847     return true; /* Do nothing if open(O_WRONLY). */
848     head->read_avail = 0;
849     ccs_io_printf(head, "# select %s\n", data);
850     head->read_single_domain = true;
851     head->read_eof = !domain;
852     if (domain) {
853     struct ccs_domain_info *d;
854     head->read_var1 = NULL;
855     list_for_each_entry_rcu(d, &ccs_domain_list, list) {
856     if (d == domain)
857     break;
858     head->read_var1 = &d->list;
859     }
860     head->read_var2 = NULL;
861     head->read_bit = 0;
862     head->read_step = 0;
863     if (domain->is_deleted)
864     ccs_io_printf(head, "# This is a deleted domain.\n");
865     }
866     return true;
867     }
868    
869 kumaneko 2897 static int ccs_write_domain_policy2(char *data, struct ccs_domain_info *domain,
870     struct ccs_condition *cond,
871     const bool is_delete)
872     {
873     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CAPABILITY))
874     return ccs_write_capability_policy(data, domain, cond,
875     is_delete);
876     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_NETWORK))
877     return ccs_write_network_policy(data, domain, cond, is_delete);
878     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_SIGNAL))
879     return ccs_write_signal_policy(data, domain, cond, is_delete);
880     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))
881     return ccs_write_env_policy(data, domain, cond, is_delete);
882     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_MOUNT))
883     return ccs_write_mount_policy(data, domain, cond, is_delete);
884     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_UNMOUNT))
885     return ccs_write_umount_policy(data, domain, cond, is_delete);
886     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_CHROOT))
887     return ccs_write_chroot_policy(data, domain, cond, is_delete);
888     if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_PIVOT_ROOT))
889     return ccs_write_pivot_root_policy(data, domain, cond,
890     is_delete);
891     return ccs_write_file_policy(data, domain, cond, is_delete);
892     }
893    
894 kumaneko 2863 /**
895     * ccs_write_domain_policy - Write domain policy.
896     *
897     * @head: Pointer to "struct ccs_io_buffer".
898     *
899     * Returns 0 on success, negative value otherwise.
900     */
901     static int ccs_write_domain_policy(struct ccs_io_buffer *head)
902     {
903     char *data = head->write_buf;
904     struct ccs_domain_info *domain = head->write_var1;
905     bool is_delete = false;
906     bool is_select = false;
907     unsigned int profile;
908     struct ccs_condition *cond = NULL;
909     char *cp;
910     int error;
911 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DELETE))
912 kumaneko 2863 is_delete = true;
913 kumaneko 2892 else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))
914 kumaneko 2863 is_select = true;
915     if (is_select && ccs_is_select_one(head, data))
916     return 0;
917     /* Don't allow updating policies by non manager programs. */
918     if (!ccs_is_policy_manager())
919     return -EPERM;
920     if (ccs_is_domain_def(data)) {
921     domain = NULL;
922     if (is_delete)
923     ccs_delete_domain(data);
924     else if (is_select)
925     domain = ccs_find_domain(data);
926     else
927     domain = ccs_find_or_assign_new_domain(data, 0);
928     head->write_var1 = domain;
929     return 0;
930     }
931     if (!domain)
932     return -EINVAL;
933    
934 kumaneko 2892 if (sscanf(data, CCS_KEYWORD_USE_PROFILE "%u", &profile) == 1
935     && profile < CCS_MAX_PROFILES) {
936 kumaneko 2991 if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])
937 kumaneko 2863 domain->profile = (u8) profile;
938     return 0;
939     }
940 kumaneko 2892 if (!strcmp(data, CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
941 kumaneko 2863 domain->ignore_global_allow_read = !is_delete;
942     return 0;
943     }
944 kumaneko 2892 if (!strcmp(data, CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV)) {
945 kumaneko 2863 domain->ignore_global_allow_env = !is_delete;
946     return 0;
947     }
948     cp = ccs_find_condition_part(data);
949     if (cp) {
950     cond = ccs_get_condition(cp);
951     if (!cond)
952     return -EINVAL;
953     }
954 kumaneko 2897 error = ccs_write_domain_policy2(data, domain, cond, is_delete);
955 kumaneko 2863 if (cond)
956     ccs_put_condition(cond);
957     return error;
958     }
959    
960 kumaneko 2948 /**
961     * ccs_print_name_union - Print a ccs_name_union.
962     *
963     * @head: Pointer to "struct ccs_io_buffer".
964     * @ptr: Pointer to "struct ccs_name_union".
965     *
966     * Returns true on success, false otherwise.
967     */
968 kumaneko 2888 static bool ccs_print_name_union(struct ccs_io_buffer *head,
969 kumaneko 2894 const struct ccs_name_union *ptr)
970 kumaneko 2863 {
971 kumaneko 2894 int pos = head->read_avail;
972 kumaneko 2863 if (pos && head->read_buf[pos - 1] == ' ')
973     head->read_avail--;
974 kumaneko 2888 if (ptr->is_group)
975 kumaneko 2870 return ccs_io_printf(head, " @%s",
976 kumaneko 2888 ptr->group->group_name->name);
977     return ccs_io_printf(head, " %s", ptr->filename->name);
978 kumaneko 2863 }
979    
980 kumaneko 2948 /**
981     * ccs_print_name_union_quoted - Print a ccs_name_union with double quotes.
982     *
983     * @head: Pointer to "struct ccs_io_buffer".
984     * @ptr: Pointer to "struct ccs_name_union".
985     *
986     * Returns true on success, false otherwise.
987     */
988 kumaneko 2894 static bool ccs_print_name_union_quoted(struct ccs_io_buffer *head,
989     const struct ccs_name_union *ptr)
990 kumaneko 2863 {
991 kumaneko 2894 if (ptr->is_group)
992     return ccs_io_printf(head, "@%s",
993     ptr->group->group_name->name);
994     return ccs_io_printf(head, "\"%s\"", ptr->filename->name);
995     }
996    
997 kumaneko 2948 /**
998     * ccs_print_number_union_common - Print a ccs_number_union.
999     *
1000     * @head: Pointer to "struct ccs_io_buffer".
1001     * @ptr: Pointer to "struct ccs_number_union".
1002     * @need_space: True if a space character is needed.
1003     *
1004     * Returns true on success, false otherwise.
1005     */
1006 kumaneko 2894 static bool ccs_print_number_union_common(struct ccs_io_buffer *head,
1007     const struct ccs_number_union *ptr,
1008     const bool need_space)
1009     {
1010 kumaneko 2888 unsigned long min;
1011     unsigned long max;
1012 kumaneko 2890 u8 min_type;
1013     u8 max_type;
1014 kumaneko 2894 if (need_space && !ccs_io_printf(head, " "))
1015     return false;
1016 kumaneko 2888 if (ptr->is_group)
1017 kumaneko 2894 return ccs_io_printf(head, "@%s",
1018 kumaneko 2888 ptr->group->group_name->name);
1019 kumaneko 2890 min_type = ptr->min_type;
1020     max_type = ptr->max_type;
1021 kumaneko 2888 min = ptr->values[0];
1022     max = ptr->values[1];
1023 kumaneko 2890 switch (min_type) {
1024 kumaneko 2892 case CCS_VALUE_TYPE_HEXADECIMAL:
1025 kumaneko 2894 if (!ccs_io_printf(head, "0x%lX", min))
1026 kumaneko 2890 return false;
1027     break;
1028 kumaneko 2892 case CCS_VALUE_TYPE_OCTAL:
1029 kumaneko 2894 if (!ccs_io_printf(head, "0%lo", min))
1030 kumaneko 2890 return false;
1031     break;
1032     default:
1033 kumaneko 2894 if (!ccs_io_printf(head, "%lu", min))
1034 kumaneko 2890 return false;
1035     break;
1036     }
1037     if (min == max && min_type == max_type)
1038     return true;
1039     switch (max_type) {
1040 kumaneko 2892 case CCS_VALUE_TYPE_HEXADECIMAL:
1041 kumaneko 2890 return ccs_io_printf(head, "-0x%lX", max);
1042 kumaneko 2892 case CCS_VALUE_TYPE_OCTAL:
1043 kumaneko 2890 return ccs_io_printf(head, "-0%lo", max);
1044     default:
1045     return ccs_io_printf(head, "-%lu", max);
1046     }
1047 kumaneko 2863 }
1048    
1049 kumaneko 2948 /**
1050     * ccs_print_number_union - Print a ccs_number_union.
1051     *
1052     * @head: Pointer to "struct ccs_io_buffer".
1053     * @ptr: Pointer to "struct ccs_number_union".
1054     *
1055     * Returns true on success, false otherwise.
1056     */
1057 kumaneko 2900 bool ccs_print_number_union(struct ccs_io_buffer *head,
1058     const struct ccs_number_union *ptr)
1059 kumaneko 2894 {
1060     return ccs_print_number_union_common(head, ptr, true);
1061     }
1062    
1063 kumaneko 2948 /**
1064     * ccs_print_number_union_nospace - Print a ccs_number_union without a space character.
1065     *
1066     * @head: Pointer to "struct ccs_io_buffer".
1067     * @ptr: Pointer to "struct ccs_number_union".
1068     *
1069     * Returns true on success, false otherwise.
1070     */
1071 kumaneko 2894 static bool ccs_print_number_union_nospace(struct ccs_io_buffer *head,
1072     const struct ccs_number_union *ptr)
1073     {
1074     return ccs_print_number_union_common(head, ptr, false);
1075     }
1076    
1077 kumaneko 2863 /**
1078 kumaneko 2894 * ccs_print_condition - Print condition part.
1079     *
1080     * @head: Pointer to "struct ccs_io_buffer".
1081     * @cond: Pointer to "struct ccs_condition". May be NULL.
1082     *
1083     * Returns true on success, false otherwise.
1084     */
1085     static bool ccs_print_condition(struct ccs_io_buffer *head,
1086     const struct ccs_condition *cond)
1087     {
1088     const struct ccs_condition_element *condp;
1089     const struct ccs_number_union *numbers_p;
1090     const struct ccs_name_union *names_p;
1091     const struct ccs_argv_entry *argv;
1092     const struct ccs_envp_entry *envp;
1093     u16 condc;
1094     u16 i;
1095     u16 j;
1096     char buffer[32];
1097     if (!cond)
1098     goto no_condition;
1099     condc = cond->condc;
1100     condp = (const struct ccs_condition_element *) (cond + 1);
1101     numbers_p = (const struct ccs_number_union *) (condp + condc);
1102     names_p = (const struct ccs_name_union *)
1103     (numbers_p + cond->numbers_count);
1104     argv = (const struct ccs_argv_entry *) (names_p + cond->names_count);
1105     envp = (const struct ccs_envp_entry *) (argv + cond->argc);
1106     memset(buffer, 0, sizeof(buffer));
1107     if (condc && !ccs_io_printf(head, "%s", " if"))
1108     goto out;
1109     for (i = 0; i < condc; i++) {
1110     const u8 match = condp->equals;
1111     const u8 left = condp->left;
1112     const u8 right = condp->right;
1113     condp++;
1114     switch (left) {
1115     case CCS_ARGV_ENTRY:
1116     if (!ccs_io_printf(head, " exec.argv[%u]%s\"%s\"",
1117     argv->index, argv->is_not ?
1118     "!=" : "=", argv->value->name))
1119     goto out;
1120     argv++;
1121     continue;
1122     case CCS_ENVP_ENTRY:
1123     if (!ccs_io_printf(head, " exec.envp[\"%s\"]%s",
1124     envp->name->name, envp->is_not ?
1125     "!=" : "="))
1126     goto out;
1127     if (envp->value) {
1128     if (!ccs_io_printf(head, "\"%s\"",
1129     envp->value->name))
1130     goto out;
1131     } else {
1132     if (!ccs_io_printf(head, "NULL"))
1133     goto out;
1134     }
1135     envp++;
1136     continue;
1137     case CCS_NUMBER_UNION:
1138     if (!ccs_print_number_union(head, numbers_p++))
1139     goto out;
1140     break;
1141     default:
1142     if (left >= CCS_MAX_CONDITION_KEYWORD)
1143     goto out;
1144     if (!ccs_io_printf(head, " %s",
1145     ccs_condition_keyword[left]))
1146     goto out;
1147     break;
1148     }
1149     if (!ccs_io_printf(head, "%s", match ? "=" : "!="))
1150     goto out;
1151     switch (right) {
1152     case CCS_NAME_UNION:
1153     if (!ccs_print_name_union_quoted(head, names_p++))
1154     goto out;
1155     break;
1156     case CCS_NUMBER_UNION:
1157     if (!ccs_print_number_union_nospace(head, numbers_p++))
1158     goto out;
1159     break;
1160     default:
1161     if (right >= CCS_MAX_CONDITION_KEYWORD)
1162     goto out;
1163     if (!ccs_io_printf(head, "%s",
1164     ccs_condition_keyword[right]))
1165     goto out;
1166     break;
1167     }
1168     }
1169     i = cond->post_state[3];
1170     if (!i)
1171     goto no_condition;
1172     if (!ccs_io_printf(head, " ; set"))
1173     goto out;
1174     for (j = 0; j < 3; j++) {
1175     if (!(i & (1 << j)))
1176     continue;
1177     if (!ccs_io_printf(head, " task.state[%u]=%u", j,
1178     cond->post_state[j]))
1179     goto out;
1180     }
1181     no_condition:
1182     if (ccs_io_printf(head, "\n"))
1183     return true;
1184     out:
1185     return false;
1186     }
1187    
1188     /**
1189 kumaneko 2915 * ccs_print_path_acl - Print a single path ACL entry.
1190 kumaneko 2863 *
1191     * @head: Pointer to "struct ccs_io_buffer".
1192 kumaneko 2915 * @ptr: Pointer to "struct ccs_path_acl".
1193 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1194     *
1195     * Returns true on success, false otherwise.
1196     */
1197 kumaneko 2915 static bool ccs_print_path_acl(struct ccs_io_buffer *head,
1198 kumaneko 2943 struct ccs_path_acl *ptr,
1199     const struct ccs_condition *cond)
1200 kumaneko 2863 {
1201     int pos;
1202     u8 bit;
1203     const u16 perm = ptr->perm;
1204 kumaneko 2915 for (bit = head->read_bit; bit < CCS_MAX_PATH_OPERATION; bit++) {
1205 kumaneko 2863 if (!(perm & (1 << bit)))
1206     continue;
1207 kumaneko 2915 if (head->read_execute_only && bit != CCS_TYPE_EXECUTE)
1208 kumaneko 2863 continue;
1209     /* Print "read/write" instead of "read" and "write". */
1210 kumaneko 2915 if ((bit == CCS_TYPE_READ || bit == CCS_TYPE_WRITE)
1211     && (perm & (1 << CCS_TYPE_READ_WRITE)))
1212 kumaneko 2863 continue;
1213     pos = head->read_avail;
1214 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s", ccs_path2keyword(bit)) ||
1215 kumaneko 2888 !ccs_print_name_union(head, &ptr->name) ||
1216 kumaneko 2897 !ccs_print_condition(head, cond)) {
1217     head->read_bit = bit;
1218     head->read_avail = pos;
1219     return false;
1220     }
1221 kumaneko 2863 }
1222     head->read_bit = 0;
1223     return true;
1224     }
1225    
1226     /**
1227 kumaneko 2922 * ccs_print_path_number3_acl - Print a path_number3 ACL entry.
1228 kumaneko 2863 *
1229     * @head: Pointer to "struct ccs_io_buffer".
1230 kumaneko 2922 * @ptr: Pointer to "struct ccs_path_number3_acl".
1231 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1232     *
1233     * Returns true on success, false otherwise.
1234     */
1235 kumaneko 2922 static bool ccs_print_path_number3_acl(struct ccs_io_buffer *head,
1236 kumaneko 2943 struct ccs_path_number3_acl *ptr,
1237     const struct ccs_condition *cond)
1238 kumaneko 2863 {
1239     int pos;
1240     u8 bit;
1241     const u16 perm = ptr->perm;
1242 kumaneko 2922 for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER3_OPERATION;
1243 kumaneko 2916 bit++) {
1244 kumaneko 2863 if (!(perm & (1 << bit)))
1245     continue;
1246     pos = head->read_avail;
1247 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s",
1248 kumaneko 2922 ccs_path_number32keyword(bit)) ||
1249 kumaneko 2888 !ccs_print_name_union(head, &ptr->name) ||
1250 kumaneko 2922 !ccs_print_number_union(head, &ptr->mode) ||
1251 kumaneko 2888 !ccs_print_number_union(head, &ptr->major) ||
1252     !ccs_print_number_union(head, &ptr->minor) ||
1253 kumaneko 2897 !ccs_print_condition(head, cond)) {
1254     head->read_bit = bit;
1255     head->read_avail = pos;
1256     return false;
1257     }
1258 kumaneko 2863 }
1259     head->read_bit = 0;
1260     return true;
1261     }
1262    
1263     /**
1264 kumaneko 2948 * ccs_print_path2_acl - Print a path2 ACL entry.
1265 kumaneko 2863 *
1266     * @head: Pointer to "struct ccs_io_buffer".
1267 kumaneko 2922 * @ptr: Pointer to "struct ccs_path2_acl".
1268 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1269     *
1270     * Returns true on success, false otherwise.
1271     */
1272 kumaneko 2922 static bool ccs_print_path2_acl(struct ccs_io_buffer *head,
1273 kumaneko 2943 struct ccs_path2_acl *ptr,
1274     const struct ccs_condition *cond)
1275 kumaneko 2863 {
1276     int pos;
1277     u8 bit;
1278     const u8 perm = ptr->perm;
1279 kumaneko 2922 for (bit = head->read_bit; bit < CCS_MAX_PATH2_OPERATION; bit++) {
1280 kumaneko 2863 if (!(perm & (1 << bit)))
1281     continue;
1282     pos = head->read_avail;
1283 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s",
1284 kumaneko 2922 ccs_path22keyword(bit)) ||
1285 kumaneko 2888 !ccs_print_name_union(head, &ptr->name1) ||
1286     !ccs_print_name_union(head, &ptr->name2) ||
1287 kumaneko 2897 !ccs_print_condition(head, cond)) {
1288     head->read_bit = bit;
1289     head->read_avail = pos;
1290     return false;
1291     }
1292 kumaneko 2863 }
1293     head->read_bit = 0;
1294     return true;
1295     }
1296    
1297     /**
1298 kumaneko 2948 * ccs_print_path_number_acl - Print a path_number ACL entry.
1299 kumaneko 2863 *
1300     * @head: Pointer to "struct ccs_io_buffer".
1301 kumaneko 2915 * @ptr: Pointer to "struct ccs_path_number_acl".
1302 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1303     *
1304     * Returns true on success, false otherwise.
1305     */
1306 kumaneko 2871 static bool ccs_print_path_number_acl(struct ccs_io_buffer *head,
1307 kumaneko 2915 struct ccs_path_number_acl *ptr,
1308 kumaneko 2871 const struct ccs_condition *cond)
1309 kumaneko 2863 {
1310 kumaneko 2871 int pos;
1311     u8 bit;
1312     const u8 perm = ptr->perm;
1313 kumaneko 2916 for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER_OPERATION;
1314     bit++) {
1315 kumaneko 2871 if (!(perm & (1 << bit)))
1316     continue;
1317     pos = head->read_avail;
1318 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s",
1319     ccs_path_number2keyword(bit)) ||
1320 kumaneko 2888 !ccs_print_name_union(head, &ptr->name) ||
1321     !ccs_print_number_union(head, &ptr->number) ||
1322 kumaneko 2897 !ccs_print_condition(head, cond)) {
1323     head->read_bit = bit;
1324     head->read_avail = pos;
1325     return false;
1326     }
1327 kumaneko 2871 }
1328     head->read_bit = 0;
1329 kumaneko 2863 return true;
1330     }
1331    
1332     /**
1333     * ccs_print_env_acl - Print an evironment variable name's ACL entry.
1334     *
1335     * @head: Pointer to "struct ccs_io_buffer".
1336 kumaneko 2915 * @ptr: Pointer to "struct ccs_env_acl".
1337 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1338     *
1339     * Returns true on success, false otherwise.
1340     */
1341     static bool ccs_print_env_acl(struct ccs_io_buffer *head,
1342 kumaneko 2915 struct ccs_env_acl *ptr,
1343 kumaneko 2863 const struct ccs_condition *cond)
1344     {
1345 kumaneko 2897 const int pos = head->read_avail;
1346     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_ENV "%s", ptr->env->name) ||
1347     !ccs_print_condition(head, cond)) {
1348     head->read_avail = pos;
1349     return false;
1350     }
1351 kumaneko 2863 return true;
1352     }
1353    
1354     /**
1355     * ccs_print_capability_acl - Print a capability ACL entry.
1356     *
1357     * @head: Pointer to "struct ccs_io_buffer".
1358 kumaneko 2915 * @ptr: Pointer to "struct ccs_capability_acl".
1359 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1360     *
1361     * Returns true on success, false otherwise.
1362     */
1363     static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
1364 kumaneko 2915 struct ccs_capability_acl *ptr,
1365 kumaneko 2863 const struct ccs_condition *cond)
1366     {
1367 kumaneko 2897 const int pos = head->read_avail;
1368 kumaneko 2892 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CAPABILITY "%s",
1369 kumaneko 2897 ccs_cap2keyword(ptr->operation)) ||
1370     !ccs_print_condition(head, cond)) {
1371     head->read_avail = pos;
1372     return false;
1373     }
1374 kumaneko 2863 return true;
1375     }
1376    
1377     /**
1378     * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
1379     *
1380     * @head: Pointer to "struct ccs_io_buffer".
1381 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1382 kumaneko 2863 *
1383     * Returns true on success, false otherwise.
1384     */
1385     static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
1386 kumaneko 2915 struct ccs_ip_network_acl *ptr)
1387 kumaneko 2863 {
1388     const u32 min_address = ptr->address.ipv4.min;
1389     const u32 max_address = ptr->address.ipv4.max;
1390     if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
1391     return false;
1392     if (min_address != max_address
1393     && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
1394     return false;
1395     return true;
1396     }
1397    
1398     /**
1399     * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
1400     *
1401     * @head: Pointer to "struct ccs_io_buffer".
1402 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1403 kumaneko 2863 *
1404     * Returns true on success, false otherwise.
1405     */
1406     static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
1407 kumaneko 2915 struct ccs_ip_network_acl *ptr)
1408 kumaneko 2863 {
1409     char buf[64];
1410     const struct in6_addr *min_address = ptr->address.ipv6.min;
1411     const struct in6_addr *max_address = ptr->address.ipv6.max;
1412     ccs_print_ipv6(buf, sizeof(buf), min_address);
1413     if (!ccs_io_printf(head, "%s", buf))
1414     return false;
1415     if (min_address != max_address) {
1416     ccs_print_ipv6(buf, sizeof(buf), max_address);
1417     if (!ccs_io_printf(head, "-%s", buf))
1418     return false;
1419     }
1420     return true;
1421     }
1422    
1423     /**
1424     * ccs_print_network_acl - Print a network ACL entry.
1425     *
1426     * @head: Pointer to "struct ccs_io_buffer".
1427 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1428 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1429     *
1430     * Returns true on success, false otherwise.
1431     */
1432     static bool ccs_print_network_acl(struct ccs_io_buffer *head,
1433 kumaneko 2915 struct ccs_ip_network_acl *ptr,
1434 kumaneko 2863 const struct ccs_condition *cond)
1435     {
1436 kumaneko 2916 int pos;
1437     u8 bit;
1438     const u16 perm = ptr->perm;
1439     for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
1440     if (!(perm & (1 << bit)))
1441     continue;
1442     pos = head->read_avail;
1443     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",
1444     ccs_net2keyword(bit)))
1445 kumaneko 2863 goto out;
1446 kumaneko 2916 switch (ptr->address_type) {
1447     case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
1448     if (!ccs_io_printf(head, "@%s", ptr->address.group->
1449     group_name->name))
1450     goto out;
1451     break;
1452     case CCS_IP_ADDRESS_TYPE_IPv4:
1453     if (!ccs_print_ipv4_entry(head, ptr))
1454     goto out;
1455     break;
1456     case CCS_IP_ADDRESS_TYPE_IPv6:
1457     if (!ccs_print_ipv6_entry(head, ptr))
1458     goto out;
1459     break;
1460     }
1461     if (!ccs_print_number_union(head, &ptr->port) ||
1462     !ccs_print_condition(head, cond))
1463 kumaneko 2863 goto out;
1464     }
1465 kumaneko 2916 head->read_bit = 0;
1466 kumaneko 2863 return true;
1467     out:
1468 kumaneko 2916 head->read_bit = bit;
1469 kumaneko 2863 head->read_avail = pos;
1470     return false;
1471     }
1472    
1473     /**
1474     * ccs_print_signal_acl - Print a signal ACL entry.
1475     *
1476     * @head: Pointer to "struct ccs_io_buffer".
1477 kumaneko 2915 * @ptr: Pointer to "struct signale_acl".
1478 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1479     *
1480     * Returns true on success, false otherwise.
1481     */
1482     static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
1483 kumaneko 2915 struct ccs_signal_acl *ptr,
1484 kumaneko 2863 const struct ccs_condition *cond)
1485     {
1486 kumaneko 2897 const int pos = head->read_avail;
1487 kumaneko 2892 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u %s",
1488 kumaneko 2897 ptr->sig, ptr->domainname->name) ||
1489     !ccs_print_condition(head, cond)) {
1490     head->read_avail = pos;
1491     return false;
1492     }
1493 kumaneko 2863 return true;
1494     }
1495    
1496     /**
1497     * ccs_print_execute_handler_record - Print an execute handler ACL entry.
1498     *
1499     * @head: Pointer to "struct ccs_io_buffer".
1500     * @keyword: Name of the keyword.
1501     * @ptr: Pointer to "struct ccs_execute_handler_record".
1502     *
1503     * Returns true on success, false otherwise.
1504     */
1505     static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1506     const char *keyword,
1507     struct ccs_execute_handler_record *
1508     ptr)
1509     {
1510     return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1511     }
1512    
1513     /**
1514     * ccs_print_mount_acl - Print a mount ACL entry.
1515     *
1516     * @head: Pointer to "struct ccs_io_buffer".
1517 kumaneko 2915 * @ptr: Pointer to "struct ccs_mount_acl".
1518 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1519     *
1520     * Returns true on success, false otherwise.
1521     */
1522     static bool ccs_print_mount_acl(struct ccs_io_buffer *head,
1523 kumaneko 2915 struct ccs_mount_acl *ptr,
1524 kumaneko 2863 const struct ccs_condition *cond)
1525     {
1526 kumaneko 2897 const int pos = head->read_avail;
1527     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_MOUNT) ||
1528     !ccs_print_name_union(head, &ptr->dev_name) ||
1529     !ccs_print_name_union(head, &ptr->dir_name) ||
1530     !ccs_print_name_union(head, &ptr->fs_type) ||
1531     !ccs_print_number_union(head, &ptr->flags) ||
1532     !ccs_print_condition(head, cond)) {
1533     head->read_avail = pos;
1534     return false;
1535     }
1536 kumaneko 2863 return true;
1537     }
1538    
1539     /**
1540     * ccs_print_umount_acl - Print a mount ACL entry.
1541     *
1542     * @head: Pointer to "struct ccs_io_buffer".
1543 kumaneko 2915 * @ptr: Pointer to "struct ccs_umount_acl".
1544 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1545     *
1546     * Returns true on success, false otherwise.
1547     */
1548     static bool ccs_print_umount_acl(struct ccs_io_buffer *head,
1549 kumaneko 2915 struct ccs_umount_acl *ptr,
1550 kumaneko 2863 const struct ccs_condition *cond)
1551     {
1552 kumaneko 2897 const int pos = head->read_avail;
1553     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT) ||
1554     !ccs_print_name_union(head, &ptr->dir) ||
1555     !ccs_print_condition(head, cond)) {
1556     head->read_avail = pos;
1557     return false;
1558     }
1559 kumaneko 2863 return true;
1560     }
1561    
1562     /**
1563     * ccs_print_chroot_acl - Print a chroot ACL entry.
1564     *
1565     * @head: Pointer to "struct ccs_io_buffer".
1566 kumaneko 2915 * @ptr: Pointer to "struct ccs_chroot_acl".
1567 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1568     *
1569     * Returns true on success, false otherwise.
1570     */
1571     static bool ccs_print_chroot_acl(struct ccs_io_buffer *head,
1572 kumaneko 2915 struct ccs_chroot_acl *ptr,
1573 kumaneko 2863 const struct ccs_condition *cond)
1574     {
1575 kumaneko 2897 const int pos = head->read_avail;
1576     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT) ||
1577     !ccs_print_name_union(head, &ptr->dir) ||
1578     !ccs_print_condition(head, cond)) {
1579     head->read_avail = pos;
1580     return false;
1581     }
1582 kumaneko 2863 return true;
1583     }
1584    
1585     /**
1586     * ccs_print_pivot_root_acl - Print a pivot_root ACL entry.
1587     *
1588     * @head: Pointer to "struct ccs_io_buffer".
1589 kumaneko 2915 * @ptr: Pointer to "struct ccs_pivot_root_acl".
1590 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1591     *
1592     * Returns true on success, false otherwise.
1593     */
1594     static bool ccs_print_pivot_root_acl(struct ccs_io_buffer *head,
1595 kumaneko 2915 struct ccs_pivot_root_acl *ptr,
1596 kumaneko 2863 const struct ccs_condition *cond)
1597     {
1598 kumaneko 2897 const int pos = head->read_avail;
1599     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT) ||
1600     !ccs_print_name_union(head, &ptr->new_root) ||
1601     !ccs_print_name_union(head, &ptr->old_root) ||
1602     !ccs_print_condition(head, cond)) {
1603     head->read_avail = pos;
1604     return false;
1605     }
1606 kumaneko 2863 return true;
1607     }
1608    
1609     /**
1610     * ccs_print_entry - Print an ACL entry.
1611     *
1612     * @head: Pointer to "struct ccs_io_buffer".
1613     * @ptr: Pointer to an ACL entry.
1614     *
1615     * Returns true on success, false otherwise.
1616     */
1617     static bool ccs_print_entry(struct ccs_io_buffer *head,
1618     struct ccs_acl_info *ptr)
1619     {
1620     const struct ccs_condition *cond = ptr->cond;
1621 kumaneko 2900 const u8 acl_type = ptr->type;
1622     if (ptr->is_deleted)
1623 kumaneko 2863 return true;
1624 kumaneko 2915 if (acl_type == CCS_TYPE_PATH_ACL) {
1625     struct ccs_path_acl *acl
1626     = container_of(ptr, struct ccs_path_acl,
1627 kumaneko 2863 head);
1628 kumaneko 2915 return ccs_print_path_acl(head, acl, cond);
1629 kumaneko 2863 }
1630 kumaneko 2892 if (acl_type == CCS_TYPE_EXECUTE_HANDLER) {
1631 kumaneko 2863 struct ccs_execute_handler_record *acl
1632     = container_of(ptr, struct ccs_execute_handler_record,
1633     head);
1634 kumaneko 2892 const char *keyword = CCS_KEYWORD_EXECUTE_HANDLER;
1635 kumaneko 2863 return ccs_print_execute_handler_record(head, keyword, acl);
1636     }
1637 kumaneko 2892 if (acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1638 kumaneko 2863 struct ccs_execute_handler_record *acl
1639     = container_of(ptr, struct ccs_execute_handler_record,
1640     head);
1641 kumaneko 2892 const char *keyword = CCS_KEYWORD_DENIED_EXECUTE_HANDLER;
1642 kumaneko 2863 return ccs_print_execute_handler_record(head, keyword, acl);
1643     }
1644     if (head->read_execute_only)
1645     return true;
1646 kumaneko 2922 if (acl_type == CCS_TYPE_PATH_NUMBER3_ACL) {
1647     struct ccs_path_number3_acl *acl
1648     = container_of(ptr, struct ccs_path_number3_acl, head);
1649     return ccs_print_path_number3_acl(head, acl, cond);
1650 kumaneko 2863 }
1651 kumaneko 2922 if (acl_type == CCS_TYPE_PATH2_ACL) {
1652     struct ccs_path2_acl *acl
1653     = container_of(ptr, struct ccs_path2_acl,
1654 kumaneko 2863 head);
1655 kumaneko 2922 return ccs_print_path2_acl(head, acl, cond);
1656 kumaneko 2863 }
1657 kumaneko 2892 if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
1658 kumaneko 2915 struct ccs_path_number_acl *acl
1659     = container_of(ptr, struct ccs_path_number_acl,
1660 kumaneko 2871 head);
1661     return ccs_print_path_number_acl(head, acl, cond);
1662 kumaneko 2863 }
1663 kumaneko 2892 if (acl_type == CCS_TYPE_ENV_ACL) {
1664 kumaneko 2915 struct ccs_env_acl *acl
1665     = container_of(ptr, struct ccs_env_acl, head);
1666 kumaneko 2863 return ccs_print_env_acl(head, acl, cond);
1667     }
1668 kumaneko 2892 if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1669 kumaneko 2915 struct ccs_capability_acl *acl
1670     = container_of(ptr, struct ccs_capability_acl,
1671 kumaneko 2863 head);
1672     return ccs_print_capability_acl(head, acl, cond);
1673     }
1674 kumaneko 2892 if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1675 kumaneko 2915 struct ccs_ip_network_acl *acl
1676     = container_of(ptr, struct ccs_ip_network_acl,
1677 kumaneko 2863 head);
1678     return ccs_print_network_acl(head, acl, cond);
1679     }
1680 kumaneko 2892 if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1681 kumaneko 2915 struct ccs_signal_acl *acl
1682     = container_of(ptr, struct ccs_signal_acl, head);
1683 kumaneko 2863 return ccs_print_signal_acl(head, acl, cond);
1684     }
1685 kumaneko 2892 if (acl_type == CCS_TYPE_MOUNT_ACL) {
1686 kumaneko 2915 struct ccs_mount_acl *acl
1687     = container_of(ptr, struct ccs_mount_acl, head);
1688 kumaneko 2863 return ccs_print_mount_acl(head, acl, cond);
1689     }
1690 kumaneko 2892 if (acl_type == CCS_TYPE_UMOUNT_ACL) {
1691 kumaneko 2915 struct ccs_umount_acl *acl
1692     = container_of(ptr, struct ccs_umount_acl, head);
1693 kumaneko 2863 return ccs_print_umount_acl(head, acl, cond);
1694     }
1695 kumaneko 2892 if (acl_type == CCS_TYPE_CHROOT_ACL) {
1696 kumaneko 2915 struct ccs_chroot_acl *acl
1697     = container_of(ptr, struct ccs_chroot_acl, head);
1698 kumaneko 2863 return ccs_print_chroot_acl(head, acl, cond);
1699     }
1700 kumaneko 2892 if (acl_type == CCS_TYPE_PIVOT_ROOT_ACL) {
1701 kumaneko 2915 struct ccs_pivot_root_acl *acl
1702     = container_of(ptr, struct ccs_pivot_root_acl,
1703 kumaneko 2863 head);
1704     return ccs_print_pivot_root_acl(head, acl, cond);
1705     }
1706     BUG(); /* This must not happen. */
1707     return false;
1708     }
1709    
1710     /**
1711     * ccs_read_domain_policy - Read domain policy.
1712     *
1713     * @head: Pointer to "struct ccs_io_buffer".
1714     *
1715     * Caller holds ccs_read_lock().
1716     */
1717 kumaneko 2943 static void ccs_read_domain_policy(struct ccs_io_buffer *head)
1718 kumaneko 2863 {
1719     struct list_head *dpos;
1720     struct list_head *apos;
1721     if (head->read_eof)
1722 kumaneko 2943 return;
1723 kumaneko 2863 if (head->read_step == 0)
1724     head->read_step = 1;
1725     list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
1726     struct ccs_domain_info *domain;
1727     const char *quota_exceeded = "";
1728     const char *transition_failed = "";
1729     const char *ignore_global_allow_read = "";
1730     const char *ignore_global_allow_env = "";
1731     domain = list_entry(dpos, struct ccs_domain_info, list);
1732     if (head->read_step != 1)
1733     goto acl_loop;
1734     if (domain->is_deleted && !head->read_single_domain)
1735     continue;
1736     /* Print domainname and flags. */
1737     if (domain->quota_warned)
1738     quota_exceeded = "quota_exceeded\n";
1739     if (domain->domain_transition_failed)
1740     transition_failed = "transition_failed\n";
1741     if (domain->ignore_global_allow_read)
1742     ignore_global_allow_read
1743 kumaneko 2892 = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1744 kumaneko 2863 if (domain->ignore_global_allow_env)
1745     ignore_global_allow_env
1746 kumaneko 2892 = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
1747     if (!ccs_io_printf(head, "%s\n" CCS_KEYWORD_USE_PROFILE "%u\n"
1748 kumaneko 2863 "%s%s%s%s\n", domain->domainname->name,
1749     domain->profile, quota_exceeded,
1750     transition_failed,
1751     ignore_global_allow_read,
1752     ignore_global_allow_env))
1753 kumaneko 2943 return;
1754 kumaneko 2863 head->read_step = 2;
1755     acl_loop:
1756     if (head->read_step == 3)
1757     goto tail_mark;
1758     /* Print ACL entries in the domain. */
1759     list_for_each_cookie(apos, head->read_var2,
1760     &domain->acl_info_list) {
1761     struct ccs_acl_info *ptr
1762     = list_entry(apos, struct ccs_acl_info, list);
1763     if (!ccs_print_entry(head, ptr))
1764 kumaneko 2943 return;
1765 kumaneko 2863 }
1766     head->read_step = 3;
1767     tail_mark:
1768     if (!ccs_io_printf(head, "\n"))
1769 kumaneko 2943 return;
1770 kumaneko 2863 head->read_step = 1;
1771     if (head->read_single_domain)
1772     break;
1773     }
1774     head->read_eof = true;
1775     }
1776    
1777     /**
1778     * ccs_write_domain_profile - Assign profile for specified domain.
1779     *
1780     * @head: Pointer to "struct ccs_io_buffer".
1781     *
1782     * Returns 0 on success, -EINVAL otherwise.
1783     *
1784     * This is equivalent to doing
1785     *
1786     * ( echo "select " $domainname; echo "use_profile " $profile ) |
1787 kumaneko 2948 * /usr/sbin/ccs-loadpolicy -d
1788 kumaneko 2863 *
1789     * Caller holds ccs_read_lock().
1790     */
1791     static int ccs_write_domain_profile(struct ccs_io_buffer *head)
1792     {
1793     char *data = head->write_buf;
1794     char *cp = strchr(data, ' ');
1795     struct ccs_domain_info *domain;
1796     unsigned int profile;
1797     if (!cp)
1798     return -EINVAL;
1799     *cp = '\0';
1800     profile = simple_strtoul(data, NULL, 10);
1801 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
1802 kumaneko 2863 return -EINVAL;
1803     domain = ccs_find_domain(cp + 1);
1804 kumaneko 2991 if (domain && (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile]))
1805 kumaneko 2863 domain->profile = (u8) profile;
1806     return 0;
1807     }
1808    
1809     /**
1810     * ccs_read_domain_profile - Read only domainname and profile.
1811     *
1812     * @head: Pointer to "struct ccs_io_buffer".
1813     *
1814     * This is equivalent to doing
1815     *
1816     * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
1817     * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1818     * domainname = $0; } else if ( $1 == "use_profile" ) {
1819     * print $2 " " domainname; domainname = ""; } } ; '
1820     *
1821     * Caller holds ccs_read_lock().
1822     */
1823 kumaneko 2943 static void ccs_read_domain_profile(struct ccs_io_buffer *head)
1824 kumaneko 2863 {
1825     struct list_head *pos;
1826     if (head->read_eof)
1827 kumaneko 2943 return;
1828 kumaneko 2863 list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
1829     struct ccs_domain_info *domain;
1830     domain = list_entry(pos, struct ccs_domain_info, list);
1831     if (domain->is_deleted)
1832     continue;
1833     if (!ccs_io_printf(head, "%u %s\n", domain->profile,
1834     domain->domainname->name))
1835 kumaneko 2943 return;
1836 kumaneko 2863 }
1837     head->read_eof = true;
1838     }
1839    
1840     /**
1841     * ccs_write_pid: Specify PID to obtain domainname.
1842     *
1843     * @head: Pointer to "struct ccs_io_buffer".
1844     *
1845     * Returns 0.
1846     */
1847     static int ccs_write_pid(struct ccs_io_buffer *head)
1848     {
1849     head->read_eof = false;
1850     return 0;
1851     }
1852    
1853     /**
1854     * ccs_read_pid - Read information of a process.
1855     *
1856     * @head: Pointer to "struct ccs_io_buffer".
1857     *
1858     * Returns the domainname which the specified PID is in or
1859     * process information of the specified PID on success,
1860     * empty string otherwise.
1861     *
1862     * Caller holds ccs_read_lock().
1863     */
1864 kumaneko 2943 static void ccs_read_pid(struct ccs_io_buffer *head)
1865 kumaneko 2863 {
1866     char *buf = head->write_buf;
1867     bool task_info = false;
1868 kumaneko 2970 bool global_pid = false;
1869 kumaneko 2863 unsigned int pid;
1870     struct task_struct *p;
1871     struct ccs_domain_info *domain = NULL;
1872     u32 ccs_flags = 0;
1873     /* Accessing write_buf is safe because head->io_sem is held. */
1874     if (!buf)
1875 kumaneko 2943 return; /* Do nothing if open(O_RDONLY). */
1876 kumaneko 2863 if (head->read_avail || head->read_eof)
1877 kumaneko 2943 return;
1878 kumaneko 2863 head->read_eof = true;
1879     if (ccs_str_starts(&buf, "info "))
1880     task_info = true;
1881 kumaneko 2970 if (ccs_str_starts(&buf, "global-pid "))
1882     global_pid = true;
1883 kumaneko 2863 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1884     read_lock(&tasklist_lock);
1885 kumaneko 2970 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1886     if (global_pid)
1887     p = find_task_by_pid_ns(pid, &init_pid_ns);
1888     else
1889     p = find_task_by_vpid(pid);
1890     #else
1891 kumaneko 2863 p = find_task_by_pid(pid);
1892 kumaneko 2970 #endif
1893 kumaneko 2863 if (p) {
1894     domain = ccs_task_domain(p);
1895     ccs_flags = p->ccs_flags;
1896     }
1897     read_unlock(&tasklist_lock);
1898     if (!domain)
1899 kumaneko 2943 return;
1900 kumaneko 2863 if (!task_info)
1901     ccs_io_printf(head, "%u %u %s", pid, domain->profile,
1902     domain->domainname->name);
1903     else
1904     ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1905     "state[0]=%u state[1]=%u state[2]=%u", pid,
1906 kumaneko 2958 ccs_yesno(ccs_flags &
1907     CCS_TASK_IS_POLICY_MANAGER),
1908     ccs_yesno(ccs_flags &
1909     CCS_TASK_IS_EXECUTE_HANDLER),
1910 kumaneko 2863 (u8) (ccs_flags >> 24),
1911     (u8) (ccs_flags >> 16),
1912     (u8) (ccs_flags >> 8));
1913     }
1914    
1915     /**
1916     * ccs_write_exception_policy - Write exception policy.
1917     *
1918     * @head: Pointer to "struct ccs_io_buffer".
1919     *
1920     * Returns 0 on success, negative value otherwise.
1921     */
1922     static int ccs_write_exception_policy(struct ccs_io_buffer *head)
1923     {
1924     char *data = head->write_buf;
1925 kumaneko 2892 bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
1926     if (ccs_str_starts(&data, CCS_KEYWORD_KEEP_DOMAIN))
1927 kumaneko 2863 return ccs_write_domain_keeper_policy(data, false, is_delete);
1928 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NO_KEEP_DOMAIN))
1929 kumaneko 2863 return ccs_write_domain_keeper_policy(data, true, is_delete);
1930 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_INITIALIZE_DOMAIN))
1931 kumaneko 2863 return ccs_write_domain_initializer_policy(data, false,
1932     is_delete);
1933 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NO_INITIALIZE_DOMAIN))
1934 kumaneko 2863 return ccs_write_domain_initializer_policy(data, true,
1935     is_delete);
1936 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_AGGREGATOR))
1937 kumaneko 2863 return ccs_write_aggregator_policy(data, is_delete);
1938 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_READ))
1939 kumaneko 2863 return ccs_write_globally_readable_policy(data, is_delete);
1940 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))
1941 kumaneko 2863 return ccs_write_globally_usable_env_policy(data, is_delete);
1942 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_FILE_PATTERN))
1943 kumaneko 2863 return ccs_write_pattern_policy(data, is_delete);
1944 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_PATH_GROUP))
1945 kumaneko 2863 return ccs_write_path_group_policy(data, is_delete);
1946 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NUMBER_GROUP))
1947 kumaneko 2863 return ccs_write_number_group_policy(data, is_delete);
1948 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DENY_REWRITE))
1949 kumaneko 2863 return ccs_write_no_rewrite_policy(data, is_delete);
1950 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ADDRESS_GROUP))
1951 kumaneko 2863 return ccs_write_address_group_policy(data, is_delete);
1952 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DENY_AUTOBIND))
1953 kumaneko 2863 return ccs_write_reserved_port_policy(data, is_delete);
1954     return -EINVAL;
1955     }
1956    
1957     /**
1958     * ccs_read_exception_policy - Read exception policy.
1959     *
1960     * @head: Pointer to "struct ccs_io_buffer".
1961     *
1962     * Caller holds ccs_read_lock().
1963     */
1964 kumaneko 2943 static void ccs_read_exception_policy(struct ccs_io_buffer *head)
1965 kumaneko 2863 {
1966 kumaneko 2943 if (head->read_eof)
1967     return;
1968     switch (head->read_step) {
1969     case 0:
1970     head->read_var2 = NULL;
1971     head->read_step = 1;
1972     case 1:
1973     if (!ccs_read_domain_keeper_policy(head))
1974 kumaneko 2863 break;
1975 kumaneko 2943 head->read_var2 = NULL;
1976     head->read_step = 2;
1977     case 2:
1978     if (!ccs_read_globally_readable_policy(head))
1979     break;
1980     head->read_var2 = NULL;
1981     head->read_step = 3;
1982     case 3:
1983     if (!ccs_read_globally_usable_env_policy(head))
1984     break;
1985     head->read_var2 = NULL;
1986     head->read_step = 4;
1987     case 4:
1988     if (!ccs_read_domain_initializer_policy(head))
1989     break;
1990     head->read_var2 = NULL;
1991     head->read_step = 6;
1992     case 6:
1993     if (!ccs_read_aggregator_policy(head))
1994     break;
1995     head->read_var2 = NULL;
1996     head->read_step = 7;
1997     case 7:
1998     if (!ccs_read_file_pattern(head))
1999     break;
2000     head->read_var2 = NULL;
2001     head->read_step = 8;
2002     case 8:
2003     if (!ccs_read_no_rewrite_policy(head))
2004     break;
2005     head->read_var2 = NULL;
2006     head->read_step = 9;
2007     case 9:
2008     if (!ccs_read_path_group_policy(head))
2009     break;
2010     head->read_var1 = NULL;
2011     head->read_var2 = NULL;
2012     head->read_step = 10;
2013     case 10:
2014     if (!ccs_read_number_group_policy(head))
2015     break;
2016     head->read_var1 = NULL;
2017     head->read_var2 = NULL;
2018     head->read_step = 11;
2019     case 11:
2020     if (!ccs_read_address_group_policy(head))
2021     break;
2022     head->read_var2 = NULL;
2023     head->read_step = 12;
2024     case 12:
2025     if (!ccs_read_reserved_port_policy(head))
2026     break;
2027     head->read_eof = true;
2028 kumaneko 2863 }
2029     }
2030    
2031 kumaneko 2897 /**
2032     * ccs_get_argv0 - Get argv[0].
2033     *
2034     * @ee: Pointer to "struct ccs_execve_entry".
2035     *
2036     * Returns true on success, false otherwise.
2037     */
2038     static bool ccs_get_argv0(struct ccs_execve_entry *ee)
2039     {
2040     struct linux_binprm *bprm = ee->bprm;
2041     char *arg_ptr = ee->tmp;
2042     int arg_len = 0;
2043     unsigned long pos = bprm->p;
2044     int offset = pos % PAGE_SIZE;
2045     bool done = false;
2046     if (!bprm->argc)
2047     goto out;
2048     while (1) {
2049     if (!ccs_dump_page(bprm, pos, &ee->dump))
2050     goto out;
2051     pos += PAGE_SIZE - offset;
2052     /* Read. */
2053     while (offset < PAGE_SIZE) {
2054     const char *kaddr = ee->dump.data;
2055     const unsigned char c = kaddr[offset++];
2056 kumaneko 2932 if (c && arg_len < CCS_EXEC_TMPSIZE - 10) {
2057 kumaneko 2897 if (c == '\\') {
2058     arg_ptr[arg_len++] = '\\';
2059     arg_ptr[arg_len++] = '\\';
2060     } else if (c > ' ' && c < 127) {
2061     arg_ptr[arg_len++] = c;
2062     } else {
2063     arg_ptr[arg_len++] = '\\';
2064     arg_ptr[arg_len++] = (c >> 6) + '0';
2065     arg_ptr[arg_len++]
2066     = ((c >> 3) & 7) + '0';
2067     arg_ptr[arg_len++] = (c & 7) + '0';
2068     }
2069     } else {
2070     arg_ptr[arg_len] = '\0';
2071     done = true;
2072     break;
2073     }
2074     }
2075     offset = 0;
2076     if (done)
2077     break;
2078     }
2079     return true;
2080     out:
2081     return false;
2082     }
2083    
2084 kumaneko 2948 /**
2085     * ccs_get_execute_condition - Get condition part for execute requests.
2086     *
2087     * @ee: Pointer to "struct ccs_execve_entry".
2088     *
2089     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2090     */
2091 kumaneko 2897 static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry
2092     *ee)
2093     {
2094     struct ccs_condition *cond;
2095     char *buf;
2096     int len = 256;
2097     char *realpath = NULL;
2098     char *argv0 = NULL;
2099 kumaneko 2958 const struct ccs_profile *profile = ccs_profile(ee->r.domain->profile);
2100 kumaneko 2962 if (profile->learning->learning_exec_realpath) {
2101 kumaneko 2897 struct file *file = ee->bprm->file;
2102 kumaneko 2911 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
2103     struct path path = { file->f_vfsmnt, file->f_dentry };
2104     realpath = ccs_realpath_from_path(&path);
2105     #else
2106     realpath = ccs_realpath_from_path(&file->f_path);
2107     #endif
2108 kumaneko 2897 if (realpath)
2109     len += strlen(realpath) + 17;
2110     }
2111 kumaneko 2962 if (profile->learning->learning_exec_argv0) {
2112 kumaneko 2897 if (ccs_get_argv0(ee)) {
2113     argv0 = ee->tmp;
2114     len += strlen(argv0) + 16;
2115     }
2116     }
2117     buf = kmalloc(len, GFP_KERNEL);
2118 kumaneko 2958 if (!buf) {
2119     kfree(realpath);
2120 kumaneko 2897 return NULL;
2121 kumaneko 2958 }
2122 kumaneko 2897 snprintf(buf, len - 1, "if");
2123     if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
2124     const int pos = strlen(buf);
2125     snprintf(buf + pos, len - pos - 1,
2126     " task.type=execute_handler");
2127     }
2128     if (realpath) {
2129     const int pos = strlen(buf);
2130     snprintf(buf + pos, len - pos - 1, " exec.realpath=\"%s\"",
2131     realpath);
2132     kfree(realpath);
2133     }
2134     if (argv0) {
2135     const int pos = strlen(buf);
2136     snprintf(buf + pos, len - pos - 1, " exec.argv[0]=\"%s\"",
2137     argv0);
2138     }
2139     cond = ccs_get_condition(buf);
2140     kfree(buf);
2141     return cond;
2142     }
2143    
2144 kumaneko 2961 /**
2145     * ccs_get_symlink_condition - Get condition part for symlink requests.
2146     *
2147     * @r: Pointer to "struct ccs_request_info".
2148     *
2149     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2150     */
2151     static struct ccs_condition *ccs_get_symlink_condition(struct ccs_request_info
2152     *r)
2153     {
2154     struct ccs_condition *cond;
2155     char *buf;
2156     int len = 256;
2157     const char *symlink = NULL;
2158     const struct ccs_profile *profile = ccs_profile(r->profile);
2159 kumaneko 2962 if (profile->learning->learning_symlink_target) {
2160 kumaneko 2961 symlink = r->obj->symlink_target->name;
2161     len += strlen(symlink) + 18;
2162     }
2163     buf = kmalloc(len, GFP_KERNEL);
2164     if (!buf)
2165     return NULL;
2166     snprintf(buf, len - 1, "if");
2167     if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
2168     const int pos = strlen(buf);
2169     snprintf(buf + pos, len - pos - 1,
2170     " task.type=execute_handler");
2171     }
2172     if (symlink) {
2173     const int pos = strlen(buf);
2174     snprintf(buf + pos, len - pos - 1, " symlink.target=\"%s\"",
2175     symlink);
2176     }
2177     cond = ccs_get_condition(buf);
2178     kfree(buf);
2179     return cond;
2180     }
2181    
2182 kumaneko 2863 /* Wait queue for ccs_query_list. */
2183     static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
2184    
2185     /* Lock for manipulating ccs_query_list. */
2186     static DEFINE_SPINLOCK(ccs_query_list_lock);
2187    
2188     /* Structure for query. */
2189     struct ccs_query_entry {
2190     struct list_head list;
2191     char *query;
2192     int query_len;
2193     unsigned int serial;
2194     int timer;
2195     int answer;
2196     };
2197    
2198     /* The list for "struct ccs_query_entry". */
2199     static LIST_HEAD(ccs_query_list);
2200    
2201     /* Number of "struct file" referring /proc/ccs/query interface. */
2202     static atomic_t ccs_query_observers = ATOMIC_INIT(0);
2203    
2204     /**
2205 kumaneko 2922 * ccs_supervisor - Ask for the supervisor's decision.
2206 kumaneko 2863 *
2207     * @r: Pointer to "struct ccs_request_info".
2208     * @fmt: The printf()'s format string, followed by parameters.
2209     *
2210     * Returns 0 if the supervisor decided to permit the access request which
2211     * violated the policy in enforcing mode, 1 if the supervisor decided to
2212     * retry the access request which violated the policy in enforcing mode,
2213 kumaneko 2897 * 0 if it is not in enforcing mode, -EPERM otherwise.
2214 kumaneko 2863 */
2215 kumaneko 2922 int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
2216 kumaneko 2863 {
2217     va_list args;
2218     int error = -EPERM;
2219     int pos;
2220     int len;
2221     static unsigned int ccs_serial;
2222     struct ccs_query_entry *ccs_query_entry = NULL;
2223     bool quota_exceeded = false;
2224     char *header;
2225     if (!r->domain)
2226     r->domain = ccs_current_domain();
2227 kumaneko 2897 switch (r->mode) {
2228     char *buffer;
2229     struct ccs_condition *cond;
2230 kumaneko 2958 case CCS_CONFIG_LEARNING:
2231 kumaneko 2897 if (!ccs_domain_quota_ok(r))
2232     return 0;
2233     va_start(args, fmt);
2234     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
2235     va_end(args);
2236     buffer = kmalloc(len, GFP_KERNEL);
2237     if (!buffer)
2238     return 0;
2239     va_start(args, fmt);
2240     vsnprintf(buffer, len - 1, fmt, args);
2241     va_end(args);
2242     ccs_normalize_line(buffer);
2243     if (r->ee && !strncmp(buffer, "allow_execute ", 14))
2244     cond = ccs_get_execute_condition(r->ee);
2245 kumaneko 2961 else if (r->obj && r->obj->symlink_target)
2246     cond = ccs_get_symlink_condition(r);
2247 kumaneko 2897 else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
2248     char str[] = "if task.type=execute_handler";
2249     cond = ccs_get_condition(str);
2250     } else
2251     cond = NULL;
2252     ccs_write_domain_policy2(buffer, r->domain, cond, false);
2253     ccs_put_condition(cond);
2254     kfree(buffer);
2255     /* fall through */
2256 kumaneko 2958 case CCS_CONFIG_PERMISSIVE:
2257 kumaneko 2897 return 0;
2258     }
2259 kumaneko 2863 if (!atomic_read(&ccs_query_observers)) {
2260     int i;
2261     if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2262     return -EPERM;
2263 kumaneko 2962 for (i = 0; i < ccs_profile(r->domain->profile)->enforcing->
2264 kumaneko 2958 enforcing_penalty; i++) {
2265 kumaneko 2863 set_current_state(TASK_INTERRUPTIBLE);
2266     schedule_timeout(HZ / 10);
2267     }
2268     return -EPERM;
2269     }
2270     va_start(args, fmt);
2271     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2272     va_end(args);
2273     header = ccs_init_audit_log(&len, r);
2274     if (!header)
2275     goto out;
2276     ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), GFP_KERNEL);
2277     if (!ccs_query_entry)
2278     goto out;
2279 kumaneko 2900 len = ccs_round2(len);
2280 kumaneko 2863 ccs_query_entry->query = kzalloc(len, GFP_KERNEL);
2281     if (!ccs_query_entry->query)
2282     goto out;
2283     INIT_LIST_HEAD(&ccs_query_entry->list);
2284     spin_lock(&ccs_query_list_lock);
2285     if (ccs_quota_for_query && ccs_query_memory_size + len +
2286     sizeof(*ccs_query_entry) >= ccs_quota_for_query) {
2287     quota_exceeded = true;
2288     } else {
2289     ccs_query_memory_size += len + sizeof(*ccs_query_entry);
2290     ccs_query_entry->serial = ccs_serial++;
2291     }
2292     spin_unlock(&ccs_query_list_lock);
2293     if (quota_exceeded)
2294     goto out;
2295     pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
2296     ccs_query_entry->serial, r->retry, header);
2297     kfree(header);
2298     header = NULL;
2299     va_start(args, fmt);
2300     vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);
2301     ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
2302     va_end(args);
2303     spin_lock(&ccs_query_list_lock);
2304     list_add_tail(&ccs_query_entry->list, &ccs_query_list);
2305     spin_unlock(&ccs_query_list_lock);
2306     /* Give 10 seconds for supervisor's opinion. */
2307     for (ccs_query_entry->timer = 0;
2308     atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;
2309     ccs_query_entry->timer++) {
2310     wake_up(&ccs_query_wait);
2311     set_current_state(TASK_INTERRUPTIBLE);
2312     schedule_timeout(HZ / 10);
2313     if (ccs_query_entry->answer)
2314     break;
2315     }
2316     spin_lock(&ccs_query_list_lock);
2317     list_del(&ccs_query_entry->list);
2318     ccs_query_memory_size -= len + sizeof(*ccs_query_entry);
2319     spin_unlock(&ccs_query_list_lock);
2320     switch (ccs_query_entry->answer) {
2321     case 3: /* Asked to retry by administrator. */
2322     error = 1;
2323     r->retry++;
2324     break;
2325     case 1:
2326     /* Granted by administrator. */
2327     error = 0;
2328     break;
2329     case 0:
2330     /* Timed out. */
2331     break;
2332     default:
2333     /* Rejected by administrator. */
2334     break;
2335     }
2336     out:
2337     if (ccs_query_entry)
2338     kfree(ccs_query_entry->query);
2339     kfree(ccs_query_entry);
2340     kfree(header);
2341     return error;
2342     }
2343    
2344     /**
2345     * ccs_poll_query - poll() for /proc/ccs/query.
2346     *
2347     * @file: Pointer to "struct file".
2348     * @wait: Pointer to "poll_table".
2349     *
2350     * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2351     *
2352     * Waits for access requests which violated policy in enforcing mode.
2353     */
2354     static int ccs_poll_query(struct file *file, poll_table *wait)
2355     {
2356     struct list_head *tmp;
2357     bool found = false;
2358     u8 i;
2359     for (i = 0; i < 2; i++) {
2360     spin_lock(&ccs_query_list_lock);
2361     list_for_each(tmp, &ccs_query_list) {
2362     struct ccs_query_entry *ptr
2363     = list_entry(tmp, struct ccs_query_entry, list);
2364     if (ptr->answer)
2365     continue;
2366     found = true;
2367     break;
2368     }
2369     spin_unlock(&ccs_query_list_lock);
2370     if (found)
2371     return POLLIN | POLLRDNORM;
2372     if (i)
2373     break;
2374     poll_wait(file, &ccs_query_wait, wait);
2375     }
2376     return 0;
2377     }
2378    
2379     /**
2380     * ccs_read_query - Read access requests which violated policy in enforcing mode.
2381     *
2382     * @head: Pointer to "struct ccs_io_buffer".
2383     */
2384 kumaneko 2943 static void ccs_read_query(struct ccs_io_buffer *head)
2385 kumaneko 2863 {
2386     struct list_head *tmp;
2387     int pos = 0;
2388     int len = 0;
2389