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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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