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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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