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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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