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

Subversion リポジトリの参照

Annotation of /trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3690 - (hide annotations) (download) (as text)
Sat May 22 13:22:07 2010 UTC (14 years ago) by kumaneko
Original Path: branches/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 79215 byte(s)


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