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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2922 - (hide annotations) (download) (as text)
Wed Aug 19 04:26:56 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: 70010 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 kumaneko 2922 ccs_assert_read_lock();
530 kumaneko 2863 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 kumaneko 2922 ccs_assert_read_lock();
561 kumaneko 2863 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 kumaneko 2922 ccs_assert_read_lock();
642 kumaneko 2863 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 2922 * ccs_print_path_number3_acl - Print a path_number3 ACL entry.
1003 kumaneko 2863 *
1004     * @head: Pointer to "struct ccs_io_buffer".
1005 kumaneko 2922 * @ptr: Pointer to "struct ccs_path_number3_acl".
1006 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1007     *
1008     * Returns true on success, false otherwise.
1009     */
1010 kumaneko 2922 static bool ccs_print_path_number3_acl(struct ccs_io_buffer *head,
1011     struct ccs_path_number3_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 2922 for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER3_OPERATION;
1018 kumaneko 2916 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 kumaneko 2922 ccs_path_number32keyword(bit)) ||
1024 kumaneko 2888 !ccs_print_name_union(head, &ptr->name) ||
1025 kumaneko 2922 !ccs_print_number_union(head, &ptr->mode) ||
1026 kumaneko 2888 !ccs_print_number_union(head, &ptr->major) ||
1027     !ccs_print_number_union(head, &ptr->minor) ||
1028 kumaneko 2897 !ccs_print_condition(head, cond)) {
1029     head->read_bit = bit;
1030     head->read_avail = pos;
1031     return false;
1032     }
1033 kumaneko 2863 }
1034     head->read_bit = 0;
1035     return true;
1036     }
1037    
1038     /**
1039 kumaneko 2922 * ccs_print_path2_acl - Print a double path ACL entry.
1040 kumaneko 2863 *
1041     * @head: Pointer to "struct ccs_io_buffer".
1042 kumaneko 2922 * @ptr: Pointer to "struct ccs_path2_acl".
1043 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1044     *
1045     * Returns true on success, false otherwise.
1046     */
1047 kumaneko 2922 static bool ccs_print_path2_acl(struct ccs_io_buffer *head,
1048     struct ccs_path2_acl *ptr,
1049 kumaneko 2863 const struct ccs_condition *cond)
1050     {
1051     int pos;
1052     u8 bit;
1053     const u8 perm = ptr->perm;
1054 kumaneko 2922 for (bit = head->read_bit; bit < CCS_MAX_PATH2_OPERATION; bit++) {
1055 kumaneko 2863 if (!(perm & (1 << bit)))
1056     continue;
1057     pos = head->read_avail;
1058 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s",
1059 kumaneko 2922 ccs_path22keyword(bit)) ||
1060 kumaneko 2888 !ccs_print_name_union(head, &ptr->name1) ||
1061     !ccs_print_name_union(head, &ptr->name2) ||
1062 kumaneko 2897 !ccs_print_condition(head, cond)) {
1063     head->read_bit = bit;
1064     head->read_avail = pos;
1065     return false;
1066     }
1067 kumaneko 2863 }
1068     head->read_bit = 0;
1069     return true;
1070     }
1071    
1072     /**
1073 kumaneko 2871 * ccs_print_path_number_acl - Print an ioctl/chmod/chown/chgrp ACL entry.
1074 kumaneko 2863 *
1075     * @head: Pointer to "struct ccs_io_buffer".
1076 kumaneko 2915 * @ptr: Pointer to "struct ccs_path_number_acl".
1077 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1078     *
1079     * Returns true on success, false otherwise.
1080     */
1081 kumaneko 2871 static bool ccs_print_path_number_acl(struct ccs_io_buffer *head,
1082 kumaneko 2915 struct ccs_path_number_acl *ptr,
1083 kumaneko 2871 const struct ccs_condition *cond)
1084 kumaneko 2863 {
1085 kumaneko 2871 int pos;
1086     u8 bit;
1087     const u8 perm = ptr->perm;
1088 kumaneko 2916 for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER_OPERATION;
1089     bit++) {
1090 kumaneko 2871 if (!(perm & (1 << bit)))
1091     continue;
1092     pos = head->read_avail;
1093 kumaneko 2916 if (!ccs_io_printf(head, "allow_%s",
1094     ccs_path_number2keyword(bit)) ||
1095 kumaneko 2888 !ccs_print_name_union(head, &ptr->name) ||
1096     !ccs_print_number_union(head, &ptr->number) ||
1097 kumaneko 2897 !ccs_print_condition(head, cond)) {
1098     head->read_bit = bit;
1099     head->read_avail = pos;
1100     return false;
1101     }
1102 kumaneko 2871 }
1103     head->read_bit = 0;
1104 kumaneko 2863 return true;
1105     }
1106    
1107     /**
1108     * ccs_print_env_acl - Print an evironment variable name's ACL entry.
1109     *
1110     * @head: Pointer to "struct ccs_io_buffer".
1111 kumaneko 2915 * @ptr: Pointer to "struct ccs_env_acl".
1112 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1113     *
1114     * Returns true on success, false otherwise.
1115     */
1116     static bool ccs_print_env_acl(struct ccs_io_buffer *head,
1117 kumaneko 2915 struct ccs_env_acl *ptr,
1118 kumaneko 2863 const struct ccs_condition *cond)
1119     {
1120 kumaneko 2897 const int pos = head->read_avail;
1121     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_ENV "%s", ptr->env->name) ||
1122     !ccs_print_condition(head, cond)) {
1123     head->read_avail = pos;
1124     return false;
1125     }
1126 kumaneko 2863 return true;
1127     }
1128    
1129     /**
1130     * ccs_print_capability_acl - Print a capability ACL entry.
1131     *
1132     * @head: Pointer to "struct ccs_io_buffer".
1133 kumaneko 2915 * @ptr: Pointer to "struct ccs_capability_acl".
1134 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1135     *
1136     * Returns true on success, false otherwise.
1137     */
1138     static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
1139 kumaneko 2915 struct ccs_capability_acl *ptr,
1140 kumaneko 2863 const struct ccs_condition *cond)
1141     {
1142 kumaneko 2897 const int pos = head->read_avail;
1143 kumaneko 2892 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CAPABILITY "%s",
1144 kumaneko 2897 ccs_cap2keyword(ptr->operation)) ||
1145     !ccs_print_condition(head, cond)) {
1146     head->read_avail = pos;
1147     return false;
1148     }
1149 kumaneko 2863 return true;
1150     }
1151    
1152     /**
1153     * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
1154     *
1155     * @head: Pointer to "struct ccs_io_buffer".
1156 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1157 kumaneko 2863 *
1158     * Returns true on success, false otherwise.
1159     */
1160     static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
1161 kumaneko 2915 struct ccs_ip_network_acl *ptr)
1162 kumaneko 2863 {
1163     const u32 min_address = ptr->address.ipv4.min;
1164     const u32 max_address = ptr->address.ipv4.max;
1165     if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
1166     return false;
1167     if (min_address != max_address
1168     && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
1169     return false;
1170     return true;
1171     }
1172    
1173     /**
1174     * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
1175     *
1176     * @head: Pointer to "struct ccs_io_buffer".
1177 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1178 kumaneko 2863 *
1179     * Returns true on success, false otherwise.
1180     */
1181     static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
1182 kumaneko 2915 struct ccs_ip_network_acl *ptr)
1183 kumaneko 2863 {
1184     char buf[64];
1185     const struct in6_addr *min_address = ptr->address.ipv6.min;
1186     const struct in6_addr *max_address = ptr->address.ipv6.max;
1187     ccs_print_ipv6(buf, sizeof(buf), min_address);
1188     if (!ccs_io_printf(head, "%s", buf))
1189     return false;
1190     if (min_address != max_address) {
1191     ccs_print_ipv6(buf, sizeof(buf), max_address);
1192     if (!ccs_io_printf(head, "-%s", buf))
1193     return false;
1194     }
1195     return true;
1196     }
1197    
1198     /**
1199     * ccs_print_network_acl - Print a network ACL entry.
1200     *
1201     * @head: Pointer to "struct ccs_io_buffer".
1202 kumaneko 2915 * @ptr: Pointer to "struct ccs_ip_network_acl".
1203 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1204     *
1205     * Returns true on success, false otherwise.
1206     */
1207     static bool ccs_print_network_acl(struct ccs_io_buffer *head,
1208 kumaneko 2915 struct ccs_ip_network_acl *ptr,
1209 kumaneko 2863 const struct ccs_condition *cond)
1210     {
1211 kumaneko 2916 int pos;
1212     u8 bit;
1213     const u16 perm = ptr->perm;
1214     for (bit = head->read_bit; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
1215     if (!(perm & (1 << bit)))
1216     continue;
1217     pos = head->read_avail;
1218     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_NETWORK "%s ",
1219     ccs_net2keyword(bit)))
1220 kumaneko 2863 goto out;
1221 kumaneko 2916 switch (ptr->address_type) {
1222     case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
1223     if (!ccs_io_printf(head, "@%s", ptr->address.group->
1224     group_name->name))
1225     goto out;
1226     break;
1227     case CCS_IP_ADDRESS_TYPE_IPv4:
1228     if (!ccs_print_ipv4_entry(head, ptr))
1229     goto out;
1230     break;
1231     case CCS_IP_ADDRESS_TYPE_IPv6:
1232     if (!ccs_print_ipv6_entry(head, ptr))
1233     goto out;
1234     break;
1235     }
1236     if (!ccs_print_number_union(head, &ptr->port) ||
1237     !ccs_print_condition(head, cond))
1238 kumaneko 2863 goto out;
1239     }
1240 kumaneko 2916 head->read_bit = 0;
1241 kumaneko 2863 return true;
1242     out:
1243 kumaneko 2916 head->read_bit = bit;
1244 kumaneko 2863 head->read_avail = pos;
1245     return false;
1246     }
1247    
1248     /**
1249     * ccs_print_signal_acl - Print a signal ACL entry.
1250     *
1251     * @head: Pointer to "struct ccs_io_buffer".
1252 kumaneko 2915 * @ptr: Pointer to "struct signale_acl".
1253 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1254     *
1255     * Returns true on success, false otherwise.
1256     */
1257     static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
1258 kumaneko 2915 struct ccs_signal_acl *ptr,
1259 kumaneko 2863 const struct ccs_condition *cond)
1260     {
1261 kumaneko 2897 const int pos = head->read_avail;
1262 kumaneko 2892 if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_SIGNAL "%u %s",
1263 kumaneko 2897 ptr->sig, ptr->domainname->name) ||
1264     !ccs_print_condition(head, cond)) {
1265     head->read_avail = pos;
1266     return false;
1267     }
1268 kumaneko 2863 return true;
1269     }
1270    
1271     /**
1272     * ccs_print_execute_handler_record - Print an execute handler ACL entry.
1273     *
1274     * @head: Pointer to "struct ccs_io_buffer".
1275     * @keyword: Name of the keyword.
1276     * @ptr: Pointer to "struct ccs_execute_handler_record".
1277     *
1278     * Returns true on success, false otherwise.
1279     */
1280     static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1281     const char *keyword,
1282     struct ccs_execute_handler_record *
1283     ptr)
1284     {
1285     return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1286     }
1287    
1288     /**
1289     * ccs_print_mount_acl - Print a mount ACL entry.
1290     *
1291     * @head: Pointer to "struct ccs_io_buffer".
1292 kumaneko 2915 * @ptr: Pointer to "struct ccs_mount_acl".
1293 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1294     *
1295     * Returns true on success, false otherwise.
1296     */
1297     static bool ccs_print_mount_acl(struct ccs_io_buffer *head,
1298 kumaneko 2915 struct ccs_mount_acl *ptr,
1299 kumaneko 2863 const struct ccs_condition *cond)
1300     {
1301 kumaneko 2897 const int pos = head->read_avail;
1302     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_MOUNT) ||
1303     !ccs_print_name_union(head, &ptr->dev_name) ||
1304     !ccs_print_name_union(head, &ptr->dir_name) ||
1305     !ccs_print_name_union(head, &ptr->fs_type) ||
1306     !ccs_print_number_union(head, &ptr->flags) ||
1307     !ccs_print_condition(head, cond)) {
1308     head->read_avail = pos;
1309     return false;
1310     }
1311 kumaneko 2863 return true;
1312     }
1313    
1314     /**
1315     * ccs_print_umount_acl - Print a mount ACL entry.
1316     *
1317     * @head: Pointer to "struct ccs_io_buffer".
1318 kumaneko 2915 * @ptr: Pointer to "struct ccs_umount_acl".
1319 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1320     *
1321     * Returns true on success, false otherwise.
1322     */
1323     static bool ccs_print_umount_acl(struct ccs_io_buffer *head,
1324 kumaneko 2915 struct ccs_umount_acl *ptr,
1325 kumaneko 2863 const struct ccs_condition *cond)
1326     {
1327 kumaneko 2897 const int pos = head->read_avail;
1328     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_UNMOUNT) ||
1329     !ccs_print_name_union(head, &ptr->dir) ||
1330     !ccs_print_condition(head, cond)) {
1331     head->read_avail = pos;
1332     return false;
1333     }
1334 kumaneko 2863 return true;
1335     }
1336    
1337     /**
1338     * ccs_print_chroot_acl - Print a chroot ACL entry.
1339     *
1340     * @head: Pointer to "struct ccs_io_buffer".
1341 kumaneko 2915 * @ptr: Pointer to "struct ccs_chroot_acl".
1342 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1343     *
1344     * Returns true on success, false otherwise.
1345     */
1346     static bool ccs_print_chroot_acl(struct ccs_io_buffer *head,
1347 kumaneko 2915 struct ccs_chroot_acl *ptr,
1348 kumaneko 2863 const struct ccs_condition *cond)
1349     {
1350 kumaneko 2897 const int pos = head->read_avail;
1351     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_CHROOT) ||
1352     !ccs_print_name_union(head, &ptr->dir) ||
1353     !ccs_print_condition(head, cond)) {
1354     head->read_avail = pos;
1355     return false;
1356     }
1357 kumaneko 2863 return true;
1358     }
1359    
1360     /**
1361     * ccs_print_pivot_root_acl - Print a pivot_root ACL entry.
1362     *
1363     * @head: Pointer to "struct ccs_io_buffer".
1364 kumaneko 2915 * @ptr: Pointer to "struct ccs_pivot_root_acl".
1365 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
1366     *
1367     * Returns true on success, false otherwise.
1368     */
1369     static bool ccs_print_pivot_root_acl(struct ccs_io_buffer *head,
1370 kumaneko 2915 struct ccs_pivot_root_acl *ptr,
1371 kumaneko 2863 const struct ccs_condition *cond)
1372     {
1373 kumaneko 2897 const int pos = head->read_avail;
1374     if (!ccs_io_printf(head, CCS_KEYWORD_ALLOW_PIVOT_ROOT) ||
1375     !ccs_print_name_union(head, &ptr->new_root) ||
1376     !ccs_print_name_union(head, &ptr->old_root) ||
1377     !ccs_print_condition(head, cond)) {
1378     head->read_avail = pos;
1379     return false;
1380     }
1381 kumaneko 2863 return true;
1382     }
1383    
1384     /**
1385     * ccs_print_entry - Print an ACL entry.
1386     *
1387     * @head: Pointer to "struct ccs_io_buffer".
1388     * @ptr: Pointer to an ACL entry.
1389     *
1390     * Returns true on success, false otherwise.
1391     */
1392     static bool ccs_print_entry(struct ccs_io_buffer *head,
1393     struct ccs_acl_info *ptr)
1394     {
1395     const struct ccs_condition *cond = ptr->cond;
1396 kumaneko 2900 const u8 acl_type = ptr->type;
1397     if (ptr->is_deleted)
1398 kumaneko 2863 return true;
1399 kumaneko 2915 if (acl_type == CCS_TYPE_PATH_ACL) {
1400     struct ccs_path_acl *acl
1401     = container_of(ptr, struct ccs_path_acl,
1402 kumaneko 2863 head);
1403 kumaneko 2915 return ccs_print_path_acl(head, acl, cond);
1404 kumaneko 2863 }
1405 kumaneko 2892 if (acl_type == CCS_TYPE_EXECUTE_HANDLER) {
1406 kumaneko 2863 struct ccs_execute_handler_record *acl
1407     = container_of(ptr, struct ccs_execute_handler_record,
1408     head);
1409 kumaneko 2892 const char *keyword = CCS_KEYWORD_EXECUTE_HANDLER;
1410 kumaneko 2863 return ccs_print_execute_handler_record(head, keyword, acl);
1411     }
1412 kumaneko 2892 if (acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1413 kumaneko 2863 struct ccs_execute_handler_record *acl
1414     = container_of(ptr, struct ccs_execute_handler_record,
1415     head);
1416 kumaneko 2892 const char *keyword = CCS_KEYWORD_DENIED_EXECUTE_HANDLER;
1417 kumaneko 2863 return ccs_print_execute_handler_record(head, keyword, acl);
1418     }
1419     if (head->read_execute_only)
1420     return true;
1421 kumaneko 2922 if (acl_type == CCS_TYPE_PATH_NUMBER3_ACL) {
1422     struct ccs_path_number3_acl *acl
1423     = container_of(ptr, struct ccs_path_number3_acl, head);
1424     return ccs_print_path_number3_acl(head, acl, cond);
1425 kumaneko 2863 }
1426 kumaneko 2922 if (acl_type == CCS_TYPE_PATH2_ACL) {
1427     struct ccs_path2_acl *acl
1428     = container_of(ptr, struct ccs_path2_acl,
1429 kumaneko 2863 head);
1430 kumaneko 2922 return ccs_print_path2_acl(head, acl, cond);
1431 kumaneko 2863 }
1432 kumaneko 2892 if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
1433 kumaneko 2915 struct ccs_path_number_acl *acl
1434     = container_of(ptr, struct ccs_path_number_acl,
1435 kumaneko 2871 head);
1436     return ccs_print_path_number_acl(head, acl, cond);
1437 kumaneko 2863 }
1438 kumaneko 2892 if (acl_type == CCS_TYPE_ENV_ACL) {
1439 kumaneko 2915 struct ccs_env_acl *acl
1440     = container_of(ptr, struct ccs_env_acl, head);
1441 kumaneko 2863 return ccs_print_env_acl(head, acl, cond);
1442     }
1443 kumaneko 2892 if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1444 kumaneko 2915 struct ccs_capability_acl *acl
1445     = container_of(ptr, struct ccs_capability_acl,
1446 kumaneko 2863 head);
1447     return ccs_print_capability_acl(head, acl, cond);
1448     }
1449 kumaneko 2892 if (acl_type == CCS_TYPE_IP_NETWORK_ACL) {
1450 kumaneko 2915 struct ccs_ip_network_acl *acl
1451     = container_of(ptr, struct ccs_ip_network_acl,
1452 kumaneko 2863 head);
1453     return ccs_print_network_acl(head, acl, cond);
1454     }
1455 kumaneko 2892 if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1456 kumaneko 2915 struct ccs_signal_acl *acl
1457     = container_of(ptr, struct ccs_signal_acl, head);
1458 kumaneko 2863 return ccs_print_signal_acl(head, acl, cond);
1459     }
1460 kumaneko 2892 if (acl_type == CCS_TYPE_MOUNT_ACL) {
1461 kumaneko 2915 struct ccs_mount_acl *acl
1462     = container_of(ptr, struct ccs_mount_acl, head);
1463 kumaneko 2863 return ccs_print_mount_acl(head, acl, cond);
1464     }
1465 kumaneko 2892 if (acl_type == CCS_TYPE_UMOUNT_ACL) {
1466 kumaneko 2915 struct ccs_umount_acl *acl
1467     = container_of(ptr, struct ccs_umount_acl, head);
1468 kumaneko 2863 return ccs_print_umount_acl(head, acl, cond);
1469     }
1470 kumaneko 2892 if (acl_type == CCS_TYPE_CHROOT_ACL) {
1471 kumaneko 2915 struct ccs_chroot_acl *acl
1472     = container_of(ptr, struct ccs_chroot_acl, head);
1473 kumaneko 2863 return ccs_print_chroot_acl(head, acl, cond);
1474     }
1475 kumaneko 2892 if (acl_type == CCS_TYPE_PIVOT_ROOT_ACL) {
1476 kumaneko 2915 struct ccs_pivot_root_acl *acl
1477     = container_of(ptr, struct ccs_pivot_root_acl,
1478 kumaneko 2863 head);
1479     return ccs_print_pivot_root_acl(head, acl, cond);
1480     }
1481     BUG(); /* This must not happen. */
1482     return false;
1483     }
1484    
1485     /**
1486     * ccs_read_domain_policy - Read domain policy.
1487     *
1488     * @head: Pointer to "struct ccs_io_buffer".
1489     *
1490     * Returns 0.
1491     *
1492     * Caller holds ccs_read_lock().
1493     */
1494     static int ccs_read_domain_policy(struct ccs_io_buffer *head)
1495     {
1496     struct list_head *dpos;
1497     struct list_head *apos;
1498 kumaneko 2922 ccs_assert_read_lock();
1499 kumaneko 2863 if (head->read_eof)
1500     return 0;
1501     if (head->read_step == 0)
1502     head->read_step = 1;
1503     list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
1504     struct ccs_domain_info *domain;
1505     const char *quota_exceeded = "";
1506     const char *transition_failed = "";
1507     const char *ignore_global_allow_read = "";
1508     const char *ignore_global_allow_env = "";
1509     domain = list_entry(dpos, struct ccs_domain_info, list);
1510     if (head->read_step != 1)
1511     goto acl_loop;
1512     if (domain->is_deleted && !head->read_single_domain)
1513     continue;
1514     /* Print domainname and flags. */
1515     if (domain->quota_warned)
1516     quota_exceeded = "quota_exceeded\n";
1517     if (domain->domain_transition_failed)
1518     transition_failed = "transition_failed\n";
1519     if (domain->ignore_global_allow_read)
1520     ignore_global_allow_read
1521 kumaneko 2892 = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1522 kumaneko 2863 if (domain->ignore_global_allow_env)
1523     ignore_global_allow_env
1524 kumaneko 2892 = CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
1525     if (!ccs_io_printf(head, "%s\n" CCS_KEYWORD_USE_PROFILE "%u\n"
1526 kumaneko 2863 "%s%s%s%s\n", domain->domainname->name,
1527     domain->profile, quota_exceeded,
1528     transition_failed,
1529     ignore_global_allow_read,
1530     ignore_global_allow_env))
1531     return 0;
1532     head->read_step = 2;
1533     acl_loop:
1534     if (head->read_step == 3)
1535     goto tail_mark;
1536     /* Print ACL entries in the domain. */
1537     list_for_each_cookie(apos, head->read_var2,
1538     &domain->acl_info_list) {
1539     struct ccs_acl_info *ptr
1540     = list_entry(apos, struct ccs_acl_info, list);
1541     if (!ccs_print_entry(head, ptr))
1542     return 0;
1543     }
1544     head->read_step = 3;
1545     tail_mark:
1546     if (!ccs_io_printf(head, "\n"))
1547     return 0;
1548     head->read_step = 1;
1549     if (head->read_single_domain)
1550     break;
1551     }
1552     head->read_eof = true;
1553     return 0;
1554     }
1555    
1556     /**
1557     * ccs_write_domain_profile - Assign profile for specified domain.
1558     *
1559     * @head: Pointer to "struct ccs_io_buffer".
1560     *
1561     * Returns 0 on success, -EINVAL otherwise.
1562     *
1563     * This is equivalent to doing
1564     *
1565     * ( echo "select " $domainname; echo "use_profile " $profile ) |
1566     * /usr/lib/ccs/loadpolicy -d
1567     *
1568     * Caller holds ccs_read_lock().
1569     */
1570     static int ccs_write_domain_profile(struct ccs_io_buffer *head)
1571     {
1572     char *data = head->write_buf;
1573     char *cp = strchr(data, ' ');
1574     struct ccs_domain_info *domain;
1575     unsigned int profile;
1576 kumaneko 2922 ccs_assert_read_lock();
1577 kumaneko 2863 if (!cp)
1578     return -EINVAL;
1579     *cp = '\0';
1580     profile = simple_strtoul(data, NULL, 10);
1581 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
1582 kumaneko 2863 return -EINVAL;
1583     domain = ccs_find_domain(cp + 1);
1584     if (domain && (ccs_profile_ptr[profile] || !ccs_policy_loaded))
1585     domain->profile = (u8) profile;
1586     return 0;
1587     }
1588    
1589     /**
1590     * ccs_read_domain_profile - Read only domainname and profile.
1591     *
1592     * @head: Pointer to "struct ccs_io_buffer".
1593     *
1594     * Returns list of profile number and domainname pairs.
1595     *
1596     * This is equivalent to doing
1597     *
1598     * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
1599     * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1600     * domainname = $0; } else if ( $1 == "use_profile" ) {
1601     * print $2 " " domainname; domainname = ""; } } ; '
1602     *
1603     * Caller holds ccs_read_lock().
1604     */
1605     static int ccs_read_domain_profile(struct ccs_io_buffer *head)
1606     {
1607     struct list_head *pos;
1608 kumaneko 2922 ccs_assert_read_lock();
1609 kumaneko 2863 if (head->read_eof)
1610     return 0;
1611     list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
1612     struct ccs_domain_info *domain;
1613     domain = list_entry(pos, struct ccs_domain_info, list);
1614     if (domain->is_deleted)
1615     continue;
1616     if (!ccs_io_printf(head, "%u %s\n", domain->profile,
1617     domain->domainname->name))
1618     return 0;
1619     }
1620     head->read_eof = true;
1621     return 0;
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     static int ccs_read_pid(struct ccs_io_buffer *head)
1649     {
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     goto done; /* Do nothing if open(O_RDONLY). */
1660     if (head->read_avail || head->read_eof)
1661     goto done;
1662     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     /***** CRITICAL SECTION START *****/
1667     read_lock(&tasklist_lock);
1668     p = find_task_by_pid(pid);
1669     if (p) {
1670     domain = ccs_task_domain(p);
1671     ccs_flags = p->ccs_flags;
1672     }
1673     read_unlock(&tasklist_lock);
1674     /***** CRITICAL SECTION END *****/
1675     if (!domain)
1676     goto done;
1677     if (!task_info)
1678     ccs_io_printf(head, "%u %u %s", pid, domain->profile,
1679     domain->domainname->name);
1680     else
1681     ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1682     "state[0]=%u state[1]=%u state[2]=%u", pid,
1683     ccs_flags & CCS_TASK_IS_POLICY_MANAGER ?
1684     "yes" : "no",
1685     ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ?
1686     "yes" : "no",
1687     (u8) (ccs_flags >> 24),
1688     (u8) (ccs_flags >> 16),
1689     (u8) (ccs_flags >> 8));
1690     done:
1691     return 0;
1692     }
1693    
1694     /**
1695     * ccs_write_exception_policy - Write exception policy.
1696     *
1697     * @head: Pointer to "struct ccs_io_buffer".
1698     *
1699     * Returns 0 on success, negative value otherwise.
1700     */
1701     static int ccs_write_exception_policy(struct ccs_io_buffer *head)
1702     {
1703     char *data = head->write_buf;
1704 kumaneko 2892 bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
1705     if (ccs_str_starts(&data, CCS_KEYWORD_KEEP_DOMAIN))
1706 kumaneko 2863 return ccs_write_domain_keeper_policy(data, false, is_delete);
1707 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NO_KEEP_DOMAIN))
1708 kumaneko 2863 return ccs_write_domain_keeper_policy(data, true, is_delete);
1709 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_INITIALIZE_DOMAIN))
1710 kumaneko 2863 return ccs_write_domain_initializer_policy(data, false,
1711     is_delete);
1712 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NO_INITIALIZE_DOMAIN))
1713 kumaneko 2863 return ccs_write_domain_initializer_policy(data, true,
1714     is_delete);
1715 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_AGGREGATOR))
1716 kumaneko 2863 return ccs_write_aggregator_policy(data, is_delete);
1717 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_READ))
1718 kumaneko 2863 return ccs_write_globally_readable_policy(data, is_delete);
1719 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ALLOW_ENV))
1720 kumaneko 2863 return ccs_write_globally_usable_env_policy(data, is_delete);
1721 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_FILE_PATTERN))
1722 kumaneko 2863 return ccs_write_pattern_policy(data, is_delete);
1723 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_PATH_GROUP))
1724 kumaneko 2863 return ccs_write_path_group_policy(data, is_delete);
1725 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_NUMBER_GROUP))
1726 kumaneko 2863 return ccs_write_number_group_policy(data, is_delete);
1727 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DENY_REWRITE))
1728 kumaneko 2863 return ccs_write_no_rewrite_policy(data, is_delete);
1729 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_ADDRESS_GROUP))
1730 kumaneko 2863 return ccs_write_address_group_policy(data, is_delete);
1731 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DENY_AUTOBIND))
1732 kumaneko 2863 return ccs_write_reserved_port_policy(data, is_delete);
1733     return -EINVAL;
1734     }
1735    
1736     /**
1737     * ccs_read_exception_policy - Read exception policy.
1738     *
1739     * @head: Pointer to "struct ccs_io_buffer".
1740     *
1741     * Returns 0 on success, -EINVAL otherwise.
1742     *
1743     * Caller holds ccs_read_lock().
1744     */
1745     static int ccs_read_exception_policy(struct ccs_io_buffer *head)
1746     {
1747 kumaneko 2922 ccs_assert_read_lock();
1748 kumaneko 2863 if (!head->read_eof) {
1749     switch (head->read_step) {
1750     case 0:
1751     head->read_var2 = NULL;
1752     head->read_step = 1;
1753     case 1:
1754     if (!ccs_read_domain_keeper_policy(head))
1755     break;
1756     head->read_var2 = NULL;
1757     head->read_step = 2;
1758     case 2:
1759     if (!ccs_read_globally_readable_policy(head))
1760     break;
1761     head->read_var2 = NULL;
1762     head->read_step = 3;
1763     case 3:
1764     if (!ccs_read_globally_usable_env_policy(head))
1765     break;
1766     head->read_var2 = NULL;
1767     head->read_step = 4;
1768     case 4:
1769     if (!ccs_read_domain_initializer_policy(head))
1770     break;
1771     head->read_var2 = NULL;
1772     head->read_step = 6;
1773     case 6:
1774     if (!ccs_read_aggregator_policy(head))
1775     break;
1776     head->read_var2 = NULL;
1777     head->read_step = 7;
1778     case 7:
1779     if (!ccs_read_file_pattern(head))
1780     break;
1781     head->read_var2 = NULL;
1782     head->read_step = 8;
1783     case 8:
1784     if (!ccs_read_no_rewrite_policy(head))
1785     break;
1786     head->read_var2 = NULL;
1787     head->read_step = 9;
1788     case 9:
1789     if (!ccs_read_path_group_policy(head))
1790     break;
1791     head->read_var1 = NULL;
1792     head->read_var2 = NULL;
1793     head->read_step = 10;
1794     case 10:
1795     if (!ccs_read_number_group_policy(head))
1796     break;
1797     head->read_var1 = NULL;
1798     head->read_var2 = NULL;
1799     head->read_step = 11;
1800     case 11:
1801     if (!ccs_read_address_group_policy(head))
1802     break;
1803     head->read_var2 = NULL;
1804     head->read_step = 12;
1805     case 12:
1806     if (!ccs_read_reserved_port_policy(head))
1807     break;
1808     head->read_eof = true;
1809     break;
1810     default:
1811     return -EINVAL;
1812     }
1813     }
1814     return 0;
1815     }
1816    
1817 kumaneko 2897 /**
1818     * ccs_get_argv0 - Get argv[0].
1819     *
1820     * @ee: Pointer to "struct ccs_execve_entry".
1821     *
1822     * Returns true on success, false otherwise.
1823     */
1824     static bool ccs_get_argv0(struct ccs_execve_entry *ee)
1825     {
1826     struct linux_binprm *bprm = ee->bprm;
1827     char *arg_ptr = ee->tmp;
1828     int arg_len = 0;
1829     unsigned long pos = bprm->p;
1830     int offset = pos % PAGE_SIZE;
1831     bool done = false;
1832     if (!bprm->argc)
1833     goto out;
1834     while (1) {
1835     if (!ccs_dump_page(bprm, pos, &ee->dump))
1836     goto out;
1837     pos += PAGE_SIZE - offset;
1838     /* Read. */
1839     while (offset < PAGE_SIZE) {
1840     const char *kaddr = ee->dump.data;
1841     const unsigned char c = kaddr[offset++];
1842     if (c && arg_len < CCS_MAX_PATHNAME_LEN - 10) {
1843     if (c == '\\') {
1844     arg_ptr[arg_len++] = '\\';
1845     arg_ptr[arg_len++] = '\\';
1846     } else if (c == '/') {
1847     arg_len = 0;
1848     } else if (c > ' ' && c < 127) {
1849     arg_ptr[arg_len++] = c;
1850     } else {
1851     arg_ptr[arg_len++] = '\\';
1852     arg_ptr[arg_len++] = (c >> 6) + '0';
1853     arg_ptr[arg_len++]
1854     = ((c >> 3) & 7) + '0';
1855     arg_ptr[arg_len++] = (c & 7) + '0';
1856     }
1857     } else {
1858     arg_ptr[arg_len] = '\0';
1859     done = true;
1860     break;
1861     }
1862     }
1863     offset = 0;
1864     if (done)
1865     break;
1866     }
1867     return true;
1868     out:
1869     return false;
1870     }
1871    
1872     static struct ccs_condition *ccs_get_execute_condition(struct ccs_execve_entry
1873     *ee)
1874     {
1875     struct ccs_condition *cond;
1876     char *buf;
1877     int len = 256;
1878     char *realpath = NULL;
1879     char *argv0 = NULL;
1880 kumaneko 2922 if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {
1881 kumaneko 2897 struct file *file = ee->bprm->file;
1882 kumaneko 2911 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
1883     struct path path = { file->f_vfsmnt, file->f_dentry };
1884     realpath = ccs_realpath_from_path(&path);
1885     #else
1886     realpath = ccs_realpath_from_path(&file->f_path);
1887     #endif
1888 kumaneko 2897 if (realpath)
1889     len += strlen(realpath) + 17;
1890     }
1891 kumaneko 2922 if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) {
1892 kumaneko 2897 if (ccs_get_argv0(ee)) {
1893     argv0 = ee->tmp;
1894     len += strlen(argv0) + 16;
1895     }
1896     }
1897     buf = kmalloc(len, GFP_KERNEL);
1898     if (!buf)
1899     return NULL;
1900     snprintf(buf, len - 1, "if");
1901     if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) {
1902     const int pos = strlen(buf);
1903     snprintf(buf + pos, len - pos - 1,
1904     " task.type=execute_handler");
1905     }
1906     if (realpath) {
1907     const int pos = strlen(buf);
1908     snprintf(buf + pos, len - pos - 1, " exec.realpath=\"%s\"",
1909     realpath);
1910     kfree(realpath);
1911     }
1912     if (argv0) {
1913     const int pos = strlen(buf);
1914     snprintf(buf + pos, len - pos - 1, " exec.argv[0]=\"%s\"",
1915     argv0);
1916     }
1917     cond = ccs_get_condition(buf);
1918     kfree(buf);
1919     return cond;
1920     }
1921    
1922 kumaneko 2863 /* Wait queue for ccs_query_list. */
1923     static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1924    
1925     /* Lock for manipulating ccs_query_list. */
1926     static DEFINE_SPINLOCK(ccs_query_list_lock);
1927    
1928     /* Structure for query. */
1929     struct ccs_query_entry {
1930     struct list_head list;
1931     char *query;
1932     int query_len;
1933     unsigned int serial;
1934     int timer;
1935     int answer;
1936     };
1937    
1938     /* The list for "struct ccs_query_entry". */
1939     static LIST_HEAD(ccs_query_list);
1940    
1941     /* Number of "struct file" referring /proc/ccs/query interface. */
1942     static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1943    
1944     /**
1945 kumaneko 2922 * ccs_supervisor - Ask for the supervisor's decision.
1946 kumaneko 2863 *
1947     * @r: Pointer to "struct ccs_request_info".
1948     * @fmt: The printf()'s format string, followed by parameters.
1949     *
1950     * Returns 0 if the supervisor decided to permit the access request which
1951     * violated the policy in enforcing mode, 1 if the supervisor decided to
1952     * retry the access request which violated the policy in enforcing mode,
1953 kumaneko 2897 * 0 if it is not in enforcing mode, -EPERM otherwise.
1954 kumaneko 2863 */
1955 kumaneko 2922 int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
1956 kumaneko 2863 {
1957     va_list args;
1958     int error = -EPERM;
1959     int pos;
1960     int len;
1961     static unsigned int ccs_serial;
1962     struct ccs_query_entry *ccs_query_entry = NULL;
1963     bool quota_exceeded = false;
1964     char *header;
1965     if (!r->domain)
1966     r->domain = ccs_current_domain();
1967 kumaneko 2897 switch (r->mode) {
1968     char *buffer;
1969     struct ccs_condition *cond;
1970     case 1:
1971     if (!ccs_domain_quota_ok(r))
1972     return 0;
1973     va_start(args, fmt);
1974     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
1975     va_end(args);
1976     buffer = kmalloc(len, GFP_KERNEL);
1977     if (!buffer)
1978     return 0;
1979     va_start(args, fmt);
1980     vsnprintf(buffer, len - 1, fmt, args);
1981     va_end(args);
1982     ccs_normalize_line(buffer);
1983     if (r->ee && !strncmp(buffer, "allow_execute ", 14))
1984     cond = ccs_get_execute_condition(r->ee);
1985     else if ((current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
1986     char str[] = "if task.type=execute_handler";
1987     cond = ccs_get_condition(str);
1988     } else
1989     cond = NULL;
1990     ccs_write_domain_policy2(buffer, r->domain, cond, false);
1991     ccs_put_condition(cond);
1992     kfree(buffer);
1993     /* fall through */
1994     case 2:
1995     return 0;
1996     }
1997 kumaneko 2863 if (!atomic_read(&ccs_query_observers)) {
1998     int i;
1999     if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2000     return -EPERM;
2001 kumaneko 2922 for (i = 0; i < ccs_flags(r->domain, CCS_SLEEP_PERIOD);
2002 kumaneko 2863 i++) {
2003     set_current_state(TASK_INTERRUPTIBLE);
2004     schedule_timeout(HZ / 10);
2005     }
2006     return -EPERM;
2007     }
2008     va_start(args, fmt);
2009     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2010     va_end(args);
2011     header = ccs_init_audit_log(&len, r);
2012     if (!header)
2013     goto out;
2014     ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), GFP_KERNEL);
2015     if (!ccs_query_entry)
2016     goto out;
2017 kumaneko 2900 len = ccs_round2(len);
2018 kumaneko 2863 ccs_query_entry->query = kzalloc(len, GFP_KERNEL);
2019     if (!ccs_query_entry->query)
2020     goto out;
2021     INIT_LIST_HEAD(&ccs_query_entry->list);
2022     /***** CRITICAL SECTION START *****/
2023     spin_lock(&ccs_query_list_lock);
2024     if (ccs_quota_for_query && ccs_query_memory_size + len +
2025     sizeof(*ccs_query_entry) >= ccs_quota_for_query) {
2026     quota_exceeded = true;
2027     } else {
2028     ccs_query_memory_size += len + sizeof(*ccs_query_entry);
2029     ccs_query_entry->serial = ccs_serial++;
2030     }
2031     spin_unlock(&ccs_query_list_lock);
2032     /***** CRITICAL SECTION END *****/
2033     if (quota_exceeded)
2034     goto out;
2035     pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
2036     ccs_query_entry->serial, r->retry, header);
2037     kfree(header);
2038     header = NULL;
2039     va_start(args, fmt);
2040     vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);
2041     ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
2042     va_end(args);
2043     /***** CRITICAL SECTION START *****/
2044     spin_lock(&ccs_query_list_lock);
2045     list_add_tail(&ccs_query_entry->list, &ccs_query_list);
2046     spin_unlock(&ccs_query_list_lock);
2047     /***** CRITICAL SECTION END *****/
2048     /* Give 10 seconds for supervisor's opinion. */
2049     for (ccs_query_entry->timer = 0;
2050     atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;
2051     ccs_query_entry->timer++) {
2052     wake_up(&ccs_query_wait);
2053     set_current_state(TASK_INTERRUPTIBLE);
2054     schedule_timeout(HZ / 10);
2055     if (ccs_query_entry->answer)
2056     break;
2057     }
2058     /***** CRITICAL SECTION START *****/
2059     spin_lock(&ccs_query_list_lock);
2060     list_del(&ccs_query_entry->list);
2061     ccs_query_memory_size -= len + sizeof(*ccs_query_entry);
2062     spin_unlock(&ccs_query_list_lock);
2063     /***** CRITICAL SECTION END *****/
2064     switch (ccs_query_entry->answer) {
2065     case 3: /* Asked to retry by administrator. */
2066     error = 1;
2067     r->retry++;
2068     break;
2069     case 1:
2070     /* Granted by administrator. */
2071     error = 0;
2072     break;
2073     case 0:
2074     /* Timed out. */
2075     break;
2076     default:
2077     /* Rejected by administrator. */
2078     break;
2079     }
2080     out:
2081     if (ccs_query_entry)
2082     kfree(ccs_query_entry->query);
2083     kfree(ccs_query_entry);
2084     kfree(header);
2085     return error;
2086     }
2087    
2088     /**
2089     * ccs_poll_query - poll() for /proc/ccs/query.
2090     *
2091     * @file: Pointer to "struct file".
2092     * @wait: Pointer to "poll_table".
2093     *
2094     * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2095     *
2096     * Waits for access requests which violated policy in enforcing mode.
2097     */
2098     static int ccs_poll_query(struct file *file, poll_table *wait)
2099     {
2100     struct list_head *tmp;
2101     bool found = false;
2102     u8 i;
2103     for (i = 0; i < 2; i++) {
2104     /***** CRITICAL SECTION START *****/
2105     spin_lock(&ccs_query_list_lock);
2106     list_for_each(tmp, &ccs_query_list) {
2107     struct ccs_query_entry *ptr
2108     = list_entry(tmp, struct ccs_query_entry, list);
2109     if (ptr->answer)
2110     continue;
2111     found = true;
2112     break;
2113     }
2114     spin_unlock(&ccs_query_list_lock);
2115     /***** CRITICAL SECTION END *****/
2116     if (found)
2117     return POLLIN | POLLRDNORM;
2118     if (i)
2119     break;
2120     poll_wait(file, &ccs_query_wait, wait);
2121     }
2122     return 0;
2123     }
2124    
2125     /**
2126     * ccs_read_query - Read access requests which violated policy in enforcing mode.
2127     *
2128     * @head: Pointer to "struct ccs_io_buffer".
2129     *
2130     * Returns 0.
2131     */
2132     static int ccs_read_query(struct ccs_io_buffer *head)
2133     {
2134     struct list_head *tmp;
2135     int pos = 0;
2136     int len = 0;
2137     char *buf;
2138     if (head->read_avail)
2139     return 0;
2140     if (head->read_buf) {
2141     kfree(head->read_buf);
2142     head->read_buf = NULL;
2143     head->readbuf_size = 0;
2144     }
2145     /***** CRITICAL SECTION START *****/
2146     spin_lock(&ccs_query_list_lock);
2147     list_for_each(tmp, &ccs_query_list) {
2148     struct ccs_query_entry *ptr
2149     = list_entry(tmp, struct ccs_query_entry, list);
2150     if (ptr->answer)
2151     continue;
2152     if (pos++ != head->read_step)
2153     continue;
2154     len = ptr->query_len;
2155     break;
2156     }
2157     spin_unlock(&ccs_query_list_lock);
2158     /***** CRITICAL SECTION END *****/
2159     if (!len) {
2160     head->read_step = 0;
2161     return 0;
2162     }
2163     buf = kzalloc(len, GFP_KERNEL);
2164     if (!buf)
2165     return 0;
2166     pos = 0;
2167     /***** CRITICAL SECTION START *****/
2168     spin_lock(&ccs_query_list_lock);
2169     list_for_each(tmp, &ccs_query_list) {
2170     struct ccs_query_entry *ptr
2171     = list_entry(tmp, struct ccs_query_entry, list);
2172     if (ptr->answer)
2173     continue;
2174     if (pos++ != head->read_step)
2175     continue;
2176     /*
2177     * Some query can be skipped because ccs_query_list
2178     * can change, but I don't care.
2179     */
2180     if (len == ptr->query_len)
2181     memmove(buf, ptr->query, len);
2182     break;
2183     }
2184     spin_unlock(&ccs_query_list_lock);
2185     /***** CRITICAL SECTION END *****/
2186     if (buf[0]) {
2187     head->read_avail = len;
2188     head->readbuf_size = head->read_avail;
2189     head->read_buf = buf;
2190     head->read_step++;
2191     } else {
2192     kfree(buf);
2193     }
2194     return 0;
2195     }
2196    
2197     /**
2198     * ccs_write_answer - Write the supervisor's decision.
2199     *
2200     * @head: Pointer to "struct ccs_io_buffer".
2201     *
2202     * Returns 0 on success, -EINVAL otherwise.
2203     */
2204     static int ccs_write_answer(struct ccs_io_buffer *head)
2205     {
2206     char *data = head->write_buf;
2207     struct list_head *tmp;
2208     unsigned int serial;
2209     unsigned int answer;
2210     /***** CRITICAL SECTION START *****/
2211     spin_lock(&ccs_query_list_lock);
2212     list_for_each(tmp, &ccs_query_list) {
2213     struct ccs_query_entry *ptr
2214     = list_entry(tmp, struct ccs_query_entry, list);
2215     ptr->timer = 0;
2216     }
2217     spin_unlock(&ccs_query_list_lock);
2218     /***** CRITICAL SECTION END *****/
2219     if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2220     return -EINVAL;
2221     /***** CRITICAL SECTION START *****/
2222     spin_lock(&ccs_query_list_lock);
2223     list_for_each(tmp, &ccs_query_list) {
2224     struct ccs_query_entry *ptr
2225     = list_entry(tmp, struct ccs_query_entry, list);
2226     if (ptr->serial != serial)
2227     continue;
2228     if (!ptr->answer)
2229     ptr->answer = answer;
2230     break;
2231     }
2232     spin_unlock(&ccs_query_list_lock);
2233     /***** CRITICAL SECTION END *****/
2234     return 0;
2235     }
2236    
2237     /**
2238     * ccs_read_version: Get version.
2239     *
2240     * @head: Pointer to "struct ccs_io_buffer".
2241     *
2242     * Returns version information.
2243     */
2244     static int ccs_read_version(struct ccs_io_buffer *head)
2245     {
2246     if (!head->read_eof) {
2247     ccs_io_printf(head, "1.7.0-pre");
2248     head->read_eof = true;
2249     }
2250     return 0;
2251     }
2252    
2253     /**
2254     * ccs_read_self_domain - Get the current process's domainname.
2255     *
2256     * @head: Pointer to "struct ccs_io_buffer".
2257     *
2258     * Returns the current process's domainname.
2259     */
2260     static int ccs_read_self_domain(struct ccs_io_buffer *head)
2261     {
2262     if (!head->read_eof) {
2263     /*
2264     * ccs_current_domain()->domainname != NULL
2265     * because every process belongs to a domain and
2266     * the domain's name cannot be NULL.
2267     */
2268     ccs_io_printf(head, "%s",
2269     ccs_current_domain()->domainname->name);
2270     head->read_eof = true;
2271     }
2272     return 0;
2273     }
2274    
2275     /**
2276     * ccs_open_control - open() for /proc/ccs/ interface.
2277     *
2278     * @type: Type of interface.
2279     * @file: Pointer to "struct file".
2280     *
2281     * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
2282     */
2283     int ccs_open_control(const u8 type, struct file *file)
2284     {
2285     struct ccs_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
2286     if (!head)
2287     return -ENOMEM;
2288     mutex_init(&head->io_sem);
2289     head->type = type;
2290     switch (type) {
2291     case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
2292     head->write = ccs_write_domain_policy;
2293     head->read = ccs_read_domain_policy;
2294     break;
2295     case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
2296     head->write = ccs_write_exception_policy;
2297     head->read = ccs_read_exception_policy;
2298     break;
2299     #ifdef CONFIG_CCSECURITY_AUDIT
2300     case CCS_GRANTLOG: /* /proc/ccs/grant_log */
2301     head->poll = ccs_poll_grant_log;
2302     head->read = ccs_read_grant_log;
2303     break;
2304     case CCS_REJECTLOG: /* /proc/ccs/reject_log */
2305     head->poll = ccs_poll_reject_log;
2306     head->read = ccs_read_reject_log;
2307     break;
2308     #endif
2309     case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
2310     head->read = ccs_read_self_domain;
2311     break;
2312     case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */
2313     head->write = ccs_write_domain_profile;
2314     head->read = ccs_read_domain_profile;
2315     break;
2316     case CCS_EXECUTE_HANDLER: /* /proc/ccs/.execute_handler */
2317     /* Allow execute_handler to read process's status. */
2318     if (!(current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
2319     kfree(head);
2320     return -EPERM;
2321     }
2322     /* fall through */
2323     case CCS_PROCESS_STATUS: /* /proc/ccs/.process_status */
2324     head->write = ccs_write_pid;
2325     head->read = ccs_read_pid;
2326     break;
2327     case CCS_VERSION: /* /proc/ccs/version */
2328     head->read = ccs_read_version;
2329     head->readbuf_size = 128;
2330     break;
2331     case CCS_MEMINFO: /* /proc/ccs/meminfo */
2332     head->write = ccs_write_memory_quota;
2333     head->read = ccs_read_memory_counter;
2334     head->readbuf_size = 512;
2335     break;
2336     case CCS_PROFILE: /* /proc/ccs/profile */
2337     head->write = ccs_write_profile;
2338     head->read = ccs_read_profile;
2339     break;
2340     case CCS_QUERY: /* /proc/ccs/query */
2341     head->poll = ccs_poll_query;
2342     head->write = ccs_write_answer;
2343     head->read = ccs_read_query;
2344     break;
2345     case CCS_MANAGER: /* /proc/ccs/manager */
2346     head->write = ccs_write_manager_policy;
2347     head->read = ccs_read_manager_policy;
2348     break;
2349     }
2350     if (!(file->f_mode & FMODE_READ)) {
2351     /*
2352     * No need to allocate read_buf since it is not opened
2353     * for reading.
2354     */
2355     head->read = NULL;
2356     head->poll = NULL;
2357     } else if (type != CCS_QUERY &&
2358     type != CCS_GRANTLOG && type != CCS_REJECTLOG) {
2359     /*
2360     * Don't allocate buffer for reading if the file is one of
2361     * /proc/ccs/grant_log , /proc/ccs/reject_log , /proc/ccs/query.
2362     */
2363     if (!head->readbuf_size)
2364     head->readbuf_size = 4096 * 2;
2365     head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
2366     if (!head->read_buf) {
2367     kfree(head);
2368     return -ENOMEM;
2369     }
2370     }
2371     if (!(file->f_mode & FMODE_WRITE)) {
2372     /*
2373     * No need to allocate write_buf since it is not opened
2374     * for writing.
2375     */
2376     head->write = NULL;
2377     } else if (head->write) {
2378     head->writebuf_size = 4096 * 2;
2379     head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
2380     if (!head->write_buf) {
2381     kfree(head->read_buf);
2382     kfree(head);
2383     return -ENOMEM;
2384     }
2385     }
2386     if (type != CCS_QUERY &&
2387     type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2388     head->reader_idx = ccs_read_lock();
2389     file->private_data = head;
2390     /*
2391     * Call the handler now if the file is /proc/ccs/self_domain
2392     * so that the user can use "cat < /proc/ccs/self_domain" to
2393     * know the current process's domainname.
2394     */
2395     if (type == CCS_SELFDOMAIN)
2396     ccs_read_control(file, NULL, 0);
2397     /*
2398     * If the file is /proc/ccs/query , increment the observer counter.
2399 kumaneko 2922 * The obserber counter is used by ccs_supervisor() to see if
2400 kumaneko 2863 * there is some process monitoring /proc/ccs/query.
2401     */
2402     else if (type == CCS_QUERY)
2403     atomic_inc(&ccs_query_observers);
2404     return 0;
2405     }
2406    
2407     /**
2408     * ccs_poll_control - poll() for /proc/ccs/ interface.
2409     *
2410     * @file: Pointer to "struct file".
2411     * @wait: Pointer to "poll_table".
2412     *
2413     * Waits for read readiness.
2414     * /proc/ccs/query is handled by /usr/lib/ccs/ccs-queryd and
2415     * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by
2416     * /usr/lib/ccs/ccs-auditd.
2417     */
2418     int ccs_poll_control(struct file *file, poll_table *wait)
2419     {
2420     struct ccs_io_buffer *head = file->private_data;
2421     if (!head->poll)
2422     return -ENOSYS;
2423     return head->poll(file, wait);
2424     }
2425    
2426     /**
2427     * ccs_read_control - read() for /proc/ccs/ interface.
2428     *
2429     * @file: Pointer to "struct file".
2430     * @buffer: Poiner to buffer to write to.
2431     * @buffer_len: Size of @buffer.
2432     *