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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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