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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2948 - (hide annotations) (download) (as text)
Mon Aug 24 11:59:18 2009 UTC (14 years, 8 months ago) by kumaneko
Original Path: trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 70816 byte(s)


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