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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2871 - (hide annotations) (download) (as text)
Sat Aug 8 08:03:30 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: 59426 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     static bool ccs_profile_entry_used[CCS_MAX_CONTROL_INDEX +
19     CCS_MAX_CAPABILITY_INDEX + 1];
20    
21     /* String table for functionality that takes 4 modes. */
22     static const char *ccs_mode_4[4] = {
23     "disabled", "learning", "permissive", "enforcing"
24     };
25     /* String table for functionality that takes 2 modes. */
26     static const char *ccs_mode_2[4] = {
27     "disabled", "enabled", "enabled", "enabled"
28     };
29    
30     /* Table for profile. */
31     static struct {
32     const char *keyword;
33     unsigned int current_value;
34     const unsigned int max_value;
35     } ccs_control_array[CCS_MAX_CONTROL_INDEX] = {
36     [CCS_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
37     [CCS_MAC_FOR_IOCTL] = { "MAC_FOR_IOCTL", 0, 3 },
38 kumaneko 2871 [CCS_MAC_FOR_FILEATTR] = { "MAC_FOR_FILEATTR", 0, 3 },
39 kumaneko 2863 [CCS_MAC_FOR_ARGV0] = { "MAC_FOR_ARGV0", 0, 3 },
40     [CCS_MAC_FOR_ENV] = { "MAC_FOR_ENV", 0, 3 },
41     [CCS_MAC_FOR_NETWORK] = { "MAC_FOR_NETWORK", 0, 3 },
42     [CCS_MAC_FOR_SIGNAL] = { "MAC_FOR_SIGNAL", 0, 3 },
43     [CCS_MAC_FOR_NAMESPACE] = { "MAC_FOR_NAMESPACE", 0, 3 },
44     [CCS_RESTRICT_AUTOBIND] = { "RESTRICT_AUTOBIND", 0, 1 },
45     [CCS_MAX_ACCEPT_ENTRY]
46     = { "MAX_ACCEPT_ENTRY", CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY, INT_MAX },
47     #ifdef CONFIG_CCSECURITY_AUDIT
48     [CCS_MAX_GRANT_LOG]
49     = { "MAX_GRANT_LOG", CONFIG_CCSECURITY_MAX_GRANT_LOG, INT_MAX },
50     [CCS_MAX_REJECT_LOG]
51     = { "MAX_REJECT_LOG", CONFIG_CCSECURITY_MAX_REJECT_LOG, INT_MAX },
52     #endif
53     [CCS_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
54     [CCS_SLEEP_PERIOD]
55     = { "SLEEP_PERIOD", 0, 3000 }, /* in 0.1 second */
56     };
57    
58     /* Permit policy management by non-root user? */
59     static bool ccs_manage_by_non_root;
60    
61     /**
62     * ccs_quiet_setup - Set CCS_VERBOSE=0 by default.
63     *
64     * @str: Unused.
65     *
66     * Returns 0.
67     */
68     static int __init ccs_quiet_setup(char *str)
69     {
70     ccs_control_array[CCS_VERBOSE].current_value = 0;
71     return 0;
72     }
73    
74     __setup("CCS_QUIET", ccs_quiet_setup);
75    
76     /**
77     * ccs_io_printf - Transactional printf() to "struct ccs_io_buffer" structure.
78     *
79     * @head: Pointer to "struct ccs_io_buffer".
80     * @fmt: The printf()'s format string, followed by parameters.
81     *
82     * Returns true on success, false otherwise.
83     *
84     * The snprintf() will truncate, but ccs_io_printf() won't.
85     */
86     bool ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
87     {
88     va_list args;
89     int len;
90     int pos = head->read_avail;
91     int size = head->readbuf_size - pos;
92     if (size <= 0)
93     return false;
94     va_start(args, fmt);
95     len = vsnprintf(head->read_buf + pos, size, fmt, args);
96     va_end(args);
97     if (pos + len >= head->readbuf_size)
98     return false;
99     head->read_avail += len;
100     return true;
101     }
102    
103     /**
104     * ccs_find_or_assign_new_profile - Create a new profile.
105     *
106     * @profile: Profile number to create.
107     *
108     * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
109     */
110     struct ccs_profile *ccs_find_or_assign_new_profile(const unsigned int
111     profile)
112     {
113     struct ccs_profile *ptr;
114     struct ccs_profile *entry;
115     int i;
116     if (profile >= MAX_PROFILES)
117     return NULL;
118     ptr = ccs_profile_ptr[profile];
119     if (ptr)
120     return ptr;
121     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
122     mutex_lock(&ccs_policy_lock);
123     ptr = ccs_profile_ptr[profile];
124     if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
125     ptr = entry;
126     for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++)
127     ptr->value[i] = ccs_control_array[i].current_value;
128     /*
129     * Needn't to initialize "ptr->capability_value"
130     * because they are always 0.
131     */
132     mb(); /* Avoid out-of-order execution. */
133     ccs_profile_ptr[profile] = ptr;
134     entry = NULL;
135     }
136     mutex_unlock(&ccs_policy_lock);
137     kfree(entry);
138     return ptr;
139     }
140    
141     /**
142     * ccs_write_profile - Write profile table.
143     *
144     * @head: Pointer to "struct ccs_io_buffer".
145     *
146     * Returns 0 on success, negative value otherwise.
147     */
148     static int ccs_write_profile(struct ccs_io_buffer *head)
149     {
150     char *data = head->write_buf;
151     unsigned int i;
152     unsigned int value;
153     char *cp;
154     struct ccs_profile *ccs_profile;
155     i = simple_strtoul(data, &cp, 10);
156     if (data != cp) {
157     if (*cp != '-')
158     return -EINVAL;
159     data = cp + 1;
160     }
161     ccs_profile = ccs_find_or_assign_new_profile(i);
162     if (!ccs_profile)
163     return -EINVAL;
164     cp = strchr(data, '=');
165     if (!cp)
166     return -EINVAL;
167     *cp = '\0';
168     if (!strcmp(data, "COMMENT")) {
169     const struct ccs_path_info *new_comment
170     = ccs_get_name(cp + 1);
171     const struct ccs_path_info *old_comment;
172     /* Protect reader from ccs_put_name(). */
173     /***** CRITICAL SECTION START *****/
174     spin_lock(&ccs_profile_comment_lock);
175     old_comment = ccs_profile->comment;
176     ccs_profile->comment = new_comment;
177     spin_unlock(&ccs_profile_comment_lock);
178     /***** CRITICAL SECTION END *****/
179     ccs_put_name(old_comment);
180     ccs_profile_entry_used[0] = true;
181     return 0;
182     }
183     if (ccs_str_starts(&data, KEYWORD_MAC_FOR_CAPABILITY)) {
184     if (sscanf(cp + 1, "%u", &value) != 1) {
185     for (i = 0; i < 4; i++) {
186     if (strcmp(cp + 1, ccs_mode_4[i]))
187     continue;
188     value = i;
189     break;
190     }
191     if (i == 4)
192     return -EINVAL;
193     }
194     if (value > 3)
195     value = 3;
196     for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) {
197     if (strcmp(data, ccs_capability_control_keyword[i]))
198     continue;
199     ccs_profile->capability_value[i] = value;
200     ccs_profile_entry_used[i + 1 + CCS_MAX_CONTROL_INDEX]
201     = true;
202     return 0;
203     }
204     return -EINVAL;
205     }
206     for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) {
207     if (strcmp(data, ccs_control_array[i].keyword))
208     continue;
209     if (sscanf(cp + 1, "%u", &value) != 1) {
210     int j;
211     const char **modes;
212     switch (i) {
213     case CCS_RESTRICT_AUTOBIND:
214     case CCS_VERBOSE:
215     modes = ccs_mode_2;
216     break;
217     default:
218     modes = ccs_mode_4;
219     break;
220     }
221     for (j = 0; j < 4; j++) {
222     if (strcmp(cp + 1, modes[j]))
223     continue;
224     value = j;
225     break;
226     }
227     if (j == 4)
228     return -EINVAL;
229     } else if (value > ccs_control_array[i].max_value) {
230     value = ccs_control_array[i].max_value;
231     }
232     ccs_profile->value[i] = value;
233     ccs_profile_entry_used[i + 1] = true;
234     return 0;
235     }
236     return -EINVAL;
237     }
238    
239     /**
240     * ccs_read_profile - Read profile table.
241     *
242     * @head: Pointer to "struct ccs_io_buffer".
243     *
244     * Returns 0.
245     */
246     static int ccs_read_profile(struct ccs_io_buffer *head)
247     {
248     static const int ccs_total
249     = CCS_MAX_CONTROL_INDEX + CCS_MAX_CAPABILITY_INDEX + 1;
250     int step;
251     if (head->read_eof)
252     return 0;
253     for (step = head->read_step; step < MAX_PROFILES * ccs_total; step++) {
254     const u8 index = step / ccs_total;
255     u8 type = step % ccs_total;
256     const struct ccs_profile *ccs_profile = ccs_profile_ptr[index];
257     head->read_step = step;
258     if (!ccs_profile)
259     continue;
260     if (!ccs_profile_entry_used[type])
261     continue;
262     if (!type) { /* Print profile' comment tag. */
263     bool done;
264     /***** CRITICAL SECTION START *****/
265     spin_lock(&ccs_profile_comment_lock);
266     done = ccs_io_printf(head, "%u-COMMENT=%s\n",
267     index, ccs_profile->comment ?
268     ccs_profile->comment->name : "");
269     spin_unlock(&ccs_profile_comment_lock);
270     /***** CRITICAL SECTION END *****/
271     if (!done)
272     break;
273     continue;
274     }
275     type--;
276     if (type >= CCS_MAX_CONTROL_INDEX) {
277     const int i = type - CCS_MAX_CONTROL_INDEX;
278     const u8 value = ccs_profile->capability_value[i];
279     if (!ccs_io_printf(head,
280     "%u-" KEYWORD_MAC_FOR_CAPABILITY
281     "%s=%s\n", index,
282     ccs_capability_control_keyword[i],
283     ccs_mode_4[value]))
284     break;
285     } else {
286     const unsigned int value = ccs_profile->value[type];
287     const char **modes = NULL;
288     const char *keyword = ccs_control_array[type].keyword;
289     switch (ccs_control_array[type].max_value) {
290     case 3:
291     modes = ccs_mode_4;
292     break;
293     case 1:
294     modes = ccs_mode_2;
295     break;
296     }
297     if (modes) {
298     if (!ccs_io_printf(head, "%u-%s=%s\n", index,
299     keyword, modes[value]))
300     break;
301     } else {
302     if (!ccs_io_printf(head, "%u-%s=%u\n", index,
303     keyword, value))
304     break;
305     }
306     }
307     }
308     if (step == MAX_PROFILES * ccs_total)
309     head->read_eof = true;
310     return 0;
311     }
312    
313     /* The list for "struct ccs_policy_manager_entry". */
314     LIST_HEAD(ccs_policy_manager_list);
315    
316     /**
317     * ccs_update_manager_entry - Add a manager entry.
318     *
319     * @manager: The path to manager or the domainnamme.
320     * @is_delete: True if it is a delete request.
321     *
322     * Returns 0 on success, negative value otherwise.
323     */
324     static int ccs_update_manager_entry(const char *manager, const bool is_delete)
325     {
326     struct ccs_policy_manager_entry *entry = NULL;
327     struct ccs_policy_manager_entry *ptr;
328     const struct ccs_path_info *saved_manager;
329     int error = is_delete ? -ENOENT : -ENOMEM;
330     bool is_domain = false;
331     if (ccs_is_domain_def(manager)) {
332     if (!ccs_is_correct_domain(manager))
333     return -EINVAL;
334     is_domain = true;
335     } else {
336     if (!ccs_is_correct_path(manager, 1, -1, -1))
337     return -EINVAL;
338     }
339     saved_manager = ccs_get_name(manager);
340     if (!saved_manager)
341     return -ENOMEM;
342     if (!is_delete)
343     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
344     mutex_lock(&ccs_policy_lock);
345     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
346     if (ptr->manager != saved_manager)
347     continue;
348     ptr->is_deleted = is_delete;
349     error = 0;
350     break;
351     }
352     if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
353     entry->manager = saved_manager;
354     saved_manager = NULL;
355     entry->is_domain = is_domain;
356     list_add_tail_rcu(&entry->list, &ccs_policy_manager_list);
357     entry = NULL;
358     error = 0;
359     }
360     mutex_unlock(&ccs_policy_lock);
361     ccs_put_name(saved_manager);
362     kfree(entry);
363     return error;
364     }
365    
366     /**
367     * ccs_write_manager_policy - Write manager policy.
368     *
369     * @head: Pointer to "struct ccs_io_buffer".
370     *
371     * Returns 0 on success, negative value otherwise.
372     */
373     static int ccs_write_manager_policy(struct ccs_io_buffer *head)
374     {
375     char *data = head->write_buf;
376     bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
377     if (!strcmp(data, "manage_by_non_root")) {
378     ccs_manage_by_non_root = !is_delete;
379     return 0;
380     }
381     return ccs_update_manager_entry(data, is_delete);
382     }
383    
384     /**
385     * ccs_read_manager_policy - Read manager policy.
386     *
387     * @head: Pointer to "struct ccs_io_buffer".
388     *
389     * Returns 0.
390     *
391     * Caller holds ccs_read_lock().
392     */
393     static int ccs_read_manager_policy(struct ccs_io_buffer *head)
394     {
395     struct list_head *pos;
396     ccs_check_read_lock();
397     if (head->read_eof)
398     return 0;
399     list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) {
400     struct ccs_policy_manager_entry *ptr;
401     ptr = list_entry(pos, struct ccs_policy_manager_entry, list);
402     if (ptr->is_deleted)
403     continue;
404     if (!ccs_io_printf(head, "%s\n", ptr->manager->name))
405     return 0;
406     }
407     head->read_eof = true;
408     return 0;
409     }
410    
411     /**
412     * ccs_is_policy_manager - Check whether the current process is a policy manager.
413     *
414     * Returns true if the current process is permitted to modify policy
415     * via /proc/ccs/ interface.
416     *
417     * Caller holds ccs_read_lock().
418     */
419     static bool ccs_is_policy_manager(void)
420     {
421     struct ccs_policy_manager_entry *ptr;
422     const char *exe;
423     struct task_struct *task = current;
424     const struct ccs_path_info *domainname
425     = ccs_current_domain()->domainname;
426     bool found = false;
427     ccs_check_read_lock();
428     if (!ccs_policy_loaded)
429     return true;
430     if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER)
431     return true;
432     if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
433     return false;
434     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
435     if (!ptr->is_deleted && ptr->is_domain
436     && !ccs_pathcmp(domainname, ptr->manager)) {
437     /* Set manager flag. */
438     task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
439     return true;
440     }
441     }
442     exe = ccs_get_exe();
443     if (!exe)
444     return false;
445     list_for_each_entry_rcu(ptr, &ccs_policy_manager_list, list) {
446     if (!ptr->is_deleted && !ptr->is_domain
447     && !strcmp(exe, ptr->manager->name)) {
448     found = true;
449     /* Set manager flag. */
450     task->ccs_flags |= CCS_TASK_IS_POLICY_MANAGER;
451     break;
452     }
453     }
454     if (!found) { /* Reduce error messages. */
455     static pid_t ccs_last_pid;
456     const pid_t pid = current->pid;
457     if (ccs_last_pid != pid) {
458     printk(KERN_WARNING "%s ( %s ) is not permitted to "
459     "update policies.\n", domainname->name, exe);
460     ccs_last_pid = pid;
461     }
462     }
463     kfree(exe);
464     return found;
465     }
466    
467     /**
468     * ccs_find_condition_part - Find condition part from the statement.
469     *
470     * @data: String to parse.
471     *
472     * Returns pointer to the condition part if it was found in the statement,
473     * NULL otherwise.
474     */
475     static char *ccs_find_condition_part(char *data)
476     {
477     char *cp = strstr(data, " if ");
478     if (cp) {
479     while (1) {
480     char *cp2 = strstr(cp + 3, " if ");
481     if (!cp2)
482     break;
483     cp = cp2;
484     }
485     *cp++ = '\0';
486     } else {
487     cp = strstr(data, " ; set ");
488     if (cp)
489     *cp++ = '\0';
490     }
491     return cp;
492     }
493    
494     /**
495     * ccs_is_select_one - Parse select command.
496     *
497     * @head: Pointer to "struct ccs_io_buffer".
498     * @data: String to parse.
499     *
500     * Returns true on success, false otherwise.
501     *
502     * Caller holds ccs_read_lock().
503     */
504     static bool ccs_is_select_one(struct ccs_io_buffer *head, const char *data)
505     {
506     unsigned int pid;
507     struct ccs_domain_info *domain = NULL;
508     ccs_check_read_lock();
509     if (!strcmp(data, "allow_execute")) {
510     head->read_execute_only = true;
511     return true;
512     }
513     if (sscanf(data, "pid=%u", &pid) == 1) {
514     struct task_struct *p;
515     /***** CRITICAL SECTION START *****/
516     read_lock(&tasklist_lock);
517     p = find_task_by_pid(pid);
518     if (p)
519     domain = ccs_task_domain(p);
520     read_unlock(&tasklist_lock);
521     /***** CRITICAL SECTION END *****/
522     } else if (!strncmp(data, "domain=", 7)) {
523     if (ccs_is_domain_def(data + 7))
524     domain = ccs_find_domain(data + 7);
525     } else
526     return false;
527     head->write_var1 = domain;
528     /* Accessing read_buf is safe because head->io_sem is held. */
529     if (!head->read_buf)
530     return true; /* Do nothing if open(O_WRONLY). */
531     head->read_avail = 0;
532     ccs_io_printf(head, "# select %s\n", data);
533     head->read_single_domain = true;
534     head->read_eof = !domain;
535     if (domain) {
536     struct ccs_domain_info *d;
537     head->read_var1 = NULL;
538     list_for_each_entry_rcu(d, &ccs_domain_list, list) {
539     if (d == domain)
540     break;
541     head->read_var1 = &d->list;
542     }
543     head->read_var2 = NULL;
544     head->read_bit = 0;
545     head->read_step = 0;
546     if (domain->is_deleted)
547     ccs_io_printf(head, "# This is a deleted domain.\n");
548     }
549     return true;
550     }
551    
552     /**
553     * ccs_write_domain_policy - Write domain policy.
554     *
555     * @head: Pointer to "struct ccs_io_buffer".
556     *
557     * Returns 0 on success, negative value otherwise.
558     */
559     static int ccs_write_domain_policy(struct ccs_io_buffer *head)
560     {
561     char *data = head->write_buf;
562     struct ccs_domain_info *domain = head->write_var1;
563     bool is_delete = false;
564     bool is_select = false;
565     unsigned int profile;
566     struct ccs_condition *cond = NULL;
567     char *cp;
568     int error;
569     if (ccs_str_starts(&data, KEYWORD_DELETE))
570     is_delete = true;
571     else if (ccs_str_starts(&data, KEYWORD_SELECT))
572     is_select = true;
573     if (is_select && ccs_is_select_one(head, data))
574     return 0;
575     /* Don't allow updating policies by non manager programs. */
576     if (!ccs_is_policy_manager())
577     return -EPERM;
578     if (ccs_is_domain_def(data)) {
579     domain = NULL;
580     if (is_delete)
581     ccs_delete_domain(data);
582     else if (is_select)
583     domain = ccs_find_domain(data);
584     else
585     domain = ccs_find_or_assign_new_domain(data, 0);
586     head->write_var1 = domain;
587     return 0;
588     }
589     if (!domain)
590     return -EINVAL;
591    
592     if (sscanf(data, KEYWORD_USE_PROFILE "%u", &profile) == 1
593     && profile < MAX_PROFILES) {
594     if (ccs_profile_ptr[profile] || !ccs_policy_loaded)
595     domain->profile = (u8) profile;
596     return 0;
597     }
598     if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
599     domain->ignore_global_allow_read = !is_delete;
600     return 0;
601     }
602     if (!strcmp(data, KEYWORD_IGNORE_GLOBAL_ALLOW_ENV)) {
603     domain->ignore_global_allow_env = !is_delete;
604     return 0;
605     }
606     cp = ccs_find_condition_part(data);
607     if (cp) {
608     cond = ccs_get_condition(cp);
609     if (!cond)
610     return -EINVAL;
611     }
612     if (ccs_str_starts(&data, KEYWORD_ALLOW_CAPABILITY))
613     error = ccs_write_capability_policy(data, domain, cond,
614     is_delete);
615     else if (ccs_str_starts(&data, KEYWORD_ALLOW_NETWORK))
616     error = ccs_write_network_policy(data, domain, cond, is_delete);
617     else if (ccs_str_starts(&data, KEYWORD_ALLOW_SIGNAL))
618     error = ccs_write_signal_policy(data, domain, cond, is_delete);
619     else if (ccs_str_starts(&data, KEYWORD_ALLOW_ARGV0))
620     error = ccs_write_argv0_policy(data, domain, cond, is_delete);
621     else if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
622     error = ccs_write_env_policy(data, domain, cond, is_delete);
623     else if (ccs_str_starts(&data, KEYWORD_ALLOW_MOUNT))
624     error = ccs_write_mount_policy(data, domain, cond, is_delete);
625     else if (ccs_str_starts(&data, KEYWORD_ALLOW_UNMOUNT))
626     error = ccs_write_umount_policy(data, domain, cond, is_delete);
627     else if (ccs_str_starts(&data, KEYWORD_ALLOW_CHROOT))
628     error = ccs_write_chroot_policy(data, domain, cond, is_delete);
629     else if (ccs_str_starts(&data, KEYWORD_ALLOW_PIVOT_ROOT))
630     error = ccs_write_pivot_root_policy(data, domain, cond,
631     is_delete);
632     else
633     error = ccs_write_file_policy(data, domain, cond, is_delete);
634     if (cond)
635     ccs_put_condition(cond);
636     return error;
637     }
638    
639     static bool ccs_print_name_union(struct ccs_io_buffer *head, bool is_group,
640     union ccs_name_union *group)
641     {
642     const int pos = head->read_avail;
643     if (pos && head->read_buf[pos - 1] == ' ')
644     head->read_avail--;
645     if (is_group)
646 kumaneko 2870 return ccs_io_printf(head, " @%s",
647     group->group->group_name->name);
648 kumaneko 2863 return ccs_io_printf(head, " %s", group->filename->name);
649     }
650    
651     static bool ccs_print_number_union(struct ccs_io_buffer *head, bool is_group,
652     union ccs_number_union *group)
653     {
654     unsigned int min;
655     unsigned int max;
656     if (is_group)
657 kumaneko 2870 return ccs_io_printf(head, " @%s",
658     group->group->group_name->name);
659 kumaneko 2863 min = group->value.min;
660     max = group->value.max;
661     if (min == max)
662     return ccs_io_printf(head, " %u", min);
663     return ccs_io_printf(head, " %u-%u", min, max);
664     }
665    
666     /**
667     * ccs_print_single_path_acl - Print a single path ACL entry.
668     *
669     * @head: Pointer to "struct ccs_io_buffer".
670     * @ptr: Pointer to "struct ccs_single_path_acl_record".
671     * @cond: Pointer to "struct ccs_condition". May be NULL.
672     *
673     * Returns true on success, false otherwise.
674     */
675     static bool ccs_print_single_path_acl(struct ccs_io_buffer *head,
676     struct ccs_single_path_acl_record *ptr,
677     const struct ccs_condition *cond)
678     {
679     int pos;
680     u8 bit;
681     const u16 perm = ptr->perm;
682     for (bit = head->read_bit; bit < MAX_SINGLE_PATH_OPERATION; bit++) {
683     const char *msg;
684     if (!(perm & (1 << bit)))
685     continue;
686     if (head->read_execute_only && bit != TYPE_EXECUTE_ACL)
687     continue;
688     /* Print "read/write" instead of "read" and "write". */
689     if ((bit == TYPE_READ_ACL || bit == TYPE_WRITE_ACL)
690     && (perm & (1 << TYPE_READ_WRITE_ACL)))
691     continue;
692     msg = ccs_sp2keyword(bit);
693     pos = head->read_avail;
694     if (!ccs_io_printf(head, "allow_%s", msg) ||
695     !ccs_print_name_union(head, ptr->name_is_group,
696     &ptr->name) ||
697     !ccs_print_condition(head, cond))
698     goto out;
699     }
700     head->read_bit = 0;
701     return true;
702     out:
703     head->read_bit = bit;
704     head->read_avail = pos;
705     return false;
706     }
707    
708     /**
709     * ccs_print_mkdev_acl - Print a mkdev ACL entry.
710     *
711     * @head: Pointer to "struct ccs_io_buffer".
712     * @ptr: Pointer to "struct ccs_mkdev_acl_record".
713     * @cond: Pointer to "struct ccs_condition". May be NULL.
714     *
715     * Returns true on success, false otherwise.
716     */
717     static bool ccs_print_mkdev_acl(struct ccs_io_buffer *head,
718     struct ccs_mkdev_acl_record *ptr,
719     const struct ccs_condition *cond)
720     {
721     int pos;
722     u8 bit;
723     const u16 perm = ptr->perm;
724     for (bit = head->read_bit; bit < MAX_MKDEV_OPERATION; bit++) {
725     const char *msg;
726     if (!(perm & (1 << bit)))
727     continue;
728     msg = ccs_mkdev2keyword(bit);
729     pos = head->read_avail;
730     if (!ccs_io_printf(head, "allow_%s", msg) ||
731     !ccs_print_name_union(head, ptr->name_is_group,
732     &ptr->name) ||
733     !ccs_print_number_union(head, ptr->major_is_group,
734     &ptr->major) ||
735     !ccs_print_number_union(head, ptr->minor_is_group,
736     &ptr->minor) ||
737     !ccs_print_condition(head, cond))
738     goto out;
739     }
740     head->read_bit = 0;
741     return true;
742     out:
743     head->read_bit = bit;
744     head->read_avail = pos;
745     return false;
746     }
747    
748     /**
749     * ccs_print_double_path_acl - Print a double path ACL entry.
750     *
751     * @head: Pointer to "struct ccs_io_buffer".
752     * @ptr: Pointer to "struct ccs_double_path_acl_record".
753     * @cond: Pointer to "struct ccs_condition". May be NULL.
754     *
755     * Returns true on success, false otherwise.
756     */
757     static bool ccs_print_double_path_acl(struct ccs_io_buffer *head,
758     struct ccs_double_path_acl_record *ptr,
759     const struct ccs_condition *cond)
760     {
761     int pos;
762     u8 bit;
763     const u8 perm = ptr->perm;
764     for (bit = head->read_bit; bit < MAX_DOUBLE_PATH_OPERATION; bit++) {
765     const char *msg;
766     if (!(perm & (1 << bit)))
767     continue;
768     msg = ccs_dp2keyword(bit);
769     pos = head->read_avail;
770     if (!ccs_io_printf(head, "allow_%s", msg) ||
771     !ccs_print_name_union(head, ptr->name1_is_group,
772     &ptr->name1) ||
773     !ccs_print_name_union(head, ptr->name2_is_group,
774     &ptr->name2) ||
775     !ccs_print_condition(head, cond))
776     goto out;
777     }
778     head->read_bit = 0;
779     return true;
780     out:
781     head->read_bit = bit;
782     head->read_avail = pos;
783     return false;
784     }
785    
786     /**
787 kumaneko 2871 * ccs_print_path_number_acl - Print an ioctl/chmod/chown/chgrp ACL entry.
788 kumaneko 2863 *
789     * @head: Pointer to "struct ccs_io_buffer".
790 kumaneko 2871 * @ptr: Pointer to "struct ccs_path_number_acl_record".
791 kumaneko 2863 * @cond: Pointer to "struct ccs_condition". May be NULL.
792     *
793     * Returns true on success, false otherwise.
794     */
795 kumaneko 2871 static bool ccs_print_path_number_acl(struct ccs_io_buffer *head,
796     struct ccs_path_number_acl_record *ptr,
797     const struct ccs_condition *cond)
798 kumaneko 2863 {
799 kumaneko 2871 int pos;
800     u8 bit;
801     const u8 perm = ptr->perm;
802     for (bit = head->read_bit; bit < MAX_PATH_NUMBER_OPERATION; bit++) {
803     const char *msg;
804     if (!(perm & (1 << bit)))
805     continue;
806     msg = ccs_path_number2keyword(bit);
807     pos = head->read_avail;
808     if (!ccs_io_printf(head, "allow_%s", msg) ||
809     !ccs_print_name_union(head, ptr->name_is_group,
810     &ptr->name) ||
811     !ccs_print_number_union(head, ptr->number_is_group,
812     &ptr->number) ||
813     !ccs_print_condition(head, cond))
814     goto out;
815     }
816     head->read_bit = 0;
817 kumaneko 2863 return true;
818     out:
819 kumaneko 2871 head->read_bit = bit;
820 kumaneko 2863 head->read_avail = pos;
821     return false;
822     }
823    
824     /**
825     * ccs_print_argv0_acl - Print an argv[0] ACL entry.
826     *
827     * @head: Pointer to "struct ccs_io_buffer".
828     * @ptr: Pointer to "struct ccs_argv0_acl_record".
829     * @cond: Pointer to "struct ccs_condition". May be NULL.
830     *
831     * Returns true on success, false otherwise.
832     */
833     static bool ccs_print_argv0_acl(struct ccs_io_buffer *head,
834     struct ccs_argv0_acl_record *ptr,
835     const struct ccs_condition *cond)
836     {
837     int pos = head->read_avail;
838     if (!ccs_io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s",
839     ptr->filename->name, ptr->argv0->name))
840     goto out;
841     if (!ccs_print_condition(head, cond))
842     goto out;
843     return true;
844     out:
845     head->read_avail = pos;
846     return false;
847     }
848    
849     /**
850     * ccs_print_env_acl - Print an evironment variable name's ACL entry.
851     *
852     * @head: Pointer to "struct ccs_io_buffer".
853     * @ptr: Pointer to "struct ccs_env_acl_record".
854     * @cond: Pointer to "struct ccs_condition". May be NULL.
855     *
856     * Returns true on success, false otherwise.
857     */
858     static bool ccs_print_env_acl(struct ccs_io_buffer *head,
859     struct ccs_env_acl_record *ptr,
860     const struct ccs_condition *cond)
861     {
862     int pos = head->read_avail;
863     if (!ccs_io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr->env->name))
864     goto out;
865     if (!ccs_print_condition(head, cond))
866     goto out;
867     return true;
868     out:
869     head->read_avail = pos;
870     return false;
871     }
872    
873     /**
874     * ccs_print_capability_acl - Print a capability ACL entry.
875     *
876     * @head: Pointer to "struct ccs_io_buffer".
877     * @ptr: Pointer to "struct ccs_capability_acl_record".
878     * @cond: Pointer to "struct ccs_condition". May be NULL.
879     *
880     * Returns true on success, false otherwise.
881     */
882     static bool ccs_print_capability_acl(struct ccs_io_buffer *head,
883     struct ccs_capability_acl_record *ptr,
884     const struct ccs_condition *cond)
885     {
886     int pos = head->read_avail;
887     if (!ccs_io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s",
888     ccs_cap2keyword(ptr->operation)))
889     goto out;
890     if (!ccs_print_condition(head, cond))
891     goto out;
892     return true;
893     out:
894     head->read_avail = pos;
895     return false;
896     }
897    
898     /**
899     * ccs_print_ipv4_entry - Print IPv4 address of a network ACL entry.
900     *
901     * @head: Pointer to "struct ccs_io_buffer".
902     * @ptr: Pointer to "struct ccs_ip_network_acl_record".
903     *
904     * Returns true on success, false otherwise.
905     */
906     static bool ccs_print_ipv4_entry(struct ccs_io_buffer *head,
907     struct ccs_ip_network_acl_record *ptr)
908     {
909     const u32 min_address = ptr->address.ipv4.min;
910     const u32 max_address = ptr->address.ipv4.max;
911     if (!ccs_io_printf(head, "%u.%u.%u.%u", HIPQUAD(min_address)))
912     return false;
913     if (min_address != max_address
914     && !ccs_io_printf(head, "-%u.%u.%u.%u", HIPQUAD(max_address)))
915     return false;
916     return true;
917     }
918    
919     /**
920     * ccs_print_ipv6_entry - Print IPv6 address of a network ACL entry.
921     *
922     * @head: Pointer to "struct ccs_io_buffer".
923     * @ptr: Pointer to "struct ccs_ip_network_acl_record".
924     *
925     * Returns true on success, false otherwise.
926     */
927     static bool ccs_print_ipv6_entry(struct ccs_io_buffer *head,
928     struct ccs_ip_network_acl_record *ptr)
929     {
930     char buf[64];
931     const struct in6_addr *min_address = ptr->address.ipv6.min;
932     const struct in6_addr *max_address = ptr->address.ipv6.max;
933     ccs_print_ipv6(buf, sizeof(buf), min_address);
934     if (!ccs_io_printf(head, "%s", buf))
935     return false;
936     if (min_address != max_address) {
937     ccs_print_ipv6(buf, sizeof(buf), max_address);
938     if (!ccs_io_printf(head, "-%s", buf))
939     return false;
940     }
941     return true;
942     }
943    
944     /**
945     * ccs_print_network_acl - Print a network ACL entry.
946     *
947     * @head: Pointer to "struct ccs_io_buffer".
948     * @ptr: Pointer to "struct ccs_ip_network_acl_record".
949     * @cond: Pointer to "struct ccs_condition". May be NULL.
950     *
951     * Returns true on success, false otherwise.
952     */
953     static bool ccs_print_network_acl(struct ccs_io_buffer *head,
954     struct ccs_ip_network_acl_record *ptr,
955     const struct ccs_condition *cond)
956     {
957     int pos = head->read_avail;
958     if (!ccs_io_printf(head, KEYWORD_ALLOW_NETWORK "%s ",
959     ccs_net2keyword(ptr->operation_type)))
960     goto out;
961     switch (ptr->record_type) {
962     case IP_RECORD_TYPE_ADDRESS_GROUP:
963     if (!ccs_io_printf(head, "@%s",
964     ptr->address.group->group_name->name))
965     goto out;
966     break;
967     case IP_RECORD_TYPE_IPv4:
968     if (!ccs_print_ipv4_entry(head, ptr))
969     goto out;
970     break;
971     case IP_RECORD_TYPE_IPv6:
972     if (!ccs_print_ipv6_entry(head, ptr))
973     goto out;
974     break;
975     }
976     if (!ccs_print_number_union(head, ptr->port_is_group, &ptr->port) ||
977     !ccs_print_condition(head, cond))
978     goto out;
979     return true;
980     out:
981     head->read_avail = pos;
982     return false;
983     }
984    
985     /**
986     * ccs_print_signal_acl - Print a signal ACL entry.
987     *
988     * @head: Pointer to "struct ccs_io_buffer".
989     * @ptr: Pointer to "struct signale_acl_record".
990     * @cond: Pointer to "struct ccs_condition". May be NULL.
991     *
992     * Returns true on success, false otherwise.
993     */
994     static bool ccs_print_signal_acl(struct ccs_io_buffer *head,
995     struct ccs_signal_acl_record *ptr,
996     const struct ccs_condition *cond)
997     {
998     int pos = head->read_avail;
999     if (!ccs_io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s",
1000     ptr->sig, ptr->domainname->name))
1001     goto out;
1002     if (!ccs_print_condition(head, cond))
1003     goto out;
1004     return true;
1005     out:
1006     head->read_avail = pos;
1007     return false;
1008     }
1009    
1010     /**
1011     * ccs_print_execute_handler_record - Print an execute handler ACL entry.
1012     *
1013     * @head: Pointer to "struct ccs_io_buffer".
1014     * @keyword: Name of the keyword.
1015     * @ptr: Pointer to "struct ccs_execute_handler_record".
1016     *
1017     * Returns true on success, false otherwise.
1018     */
1019     static bool ccs_print_execute_handler_record(struct ccs_io_buffer *head,
1020     const char *keyword,
1021     struct ccs_execute_handler_record *
1022     ptr)
1023     {
1024     return ccs_io_printf(head, "%s %s\n", keyword, ptr->handler->name);
1025     }
1026    
1027     /**
1028     * ccs_print_mount_acl - Print a mount ACL entry.
1029     *
1030     * @head: Pointer to "struct ccs_io_buffer".
1031     * @ptr: Pointer to "struct ccs_mount_acl_record".
1032     * @cond: Pointer to "struct ccs_condition". May be NULL.
1033     *
1034     * Returns true on success, false otherwise.
1035     */
1036     static bool ccs_print_mount_acl(struct ccs_io_buffer *head,
1037     struct ccs_mount_acl_record *ptr,
1038     const struct ccs_condition *cond)
1039     {
1040     int pos = head->read_avail;
1041     if (!ccs_io_printf(head, KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
1042     ptr->dev_name->name, ptr->dir_name->name,
1043     ptr->fs_type->name, ptr->flags))
1044     goto out;
1045     if (!ccs_print_condition(head, cond))
1046     goto out;
1047     return true;
1048     out:
1049     head->read_avail = pos;
1050     return false;
1051     }
1052    
1053     /**
1054     * ccs_print_umount_acl - Print a mount ACL entry.
1055     *
1056     * @head: Pointer to "struct ccs_io_buffer".
1057     * @ptr: Pointer to "struct ccs_umount_acl_record".
1058     * @cond: Pointer to "struct ccs_condition". May be NULL.
1059     *
1060     * Returns true on success, false otherwise.
1061     */
1062     static bool ccs_print_umount_acl(struct ccs_io_buffer *head,
1063     struct ccs_umount_acl_record *ptr,
1064     const struct ccs_condition *cond)
1065     {
1066     int pos = head->read_avail;
1067     if (!ccs_io_printf(head, KEYWORD_ALLOW_UNMOUNT "%s\n",
1068     ptr->dir->name))
1069     goto out;
1070     if (!ccs_print_condition(head, cond))
1071     goto out;
1072     return true;
1073     out:
1074     head->read_avail = pos;
1075     return false;
1076     }
1077    
1078     /**
1079     * ccs_print_chroot_acl - Print a chroot ACL entry.
1080     *
1081     * @head: Pointer to "struct ccs_io_buffer".
1082     * @ptr: Pointer to "struct ccs_chroot_acl_record".
1083     * @cond: Pointer to "struct ccs_condition". May be NULL.
1084     *
1085     * Returns true on success, false otherwise.
1086     */
1087     static bool ccs_print_chroot_acl(struct ccs_io_buffer *head,
1088     struct ccs_chroot_acl_record *ptr,
1089     const struct ccs_condition *cond)
1090     {
1091     int pos = head->read_avail;
1092     if (!ccs_io_printf(head, KEYWORD_ALLOW_CHROOT "%s\n",
1093     ptr->dir->name))
1094     goto out;
1095     if (!ccs_print_condition(head, cond))
1096     goto out;
1097     return true;
1098     out:
1099     head->read_avail = pos;
1100     return false;
1101     }
1102    
1103     /**
1104     * ccs_print_pivot_root_acl - Print a pivot_root ACL entry.
1105     *
1106     * @head: Pointer to "struct ccs_io_buffer".
1107     * @ptr: Pointer to "struct ccs_pivot_root_acl_record".
1108     * @cond: Pointer to "struct ccs_condition". May be NULL.
1109     *
1110     * Returns true on success, false otherwise.
1111     */
1112     static bool ccs_print_pivot_root_acl(struct ccs_io_buffer *head,
1113     struct ccs_pivot_root_acl_record *ptr,
1114     const struct ccs_condition *cond)
1115     {
1116     int pos = head->read_avail;
1117     if (!ccs_io_printf(head, KEYWORD_ALLOW_PIVOT_ROOT "%s %s\n",
1118     ptr->new_root->name, ptr->old_root->name))
1119     goto out;
1120     if (!ccs_print_condition(head, cond))
1121     goto out;
1122     return true;
1123     out:
1124     head->read_avail = pos;
1125     return false;
1126     }
1127    
1128     /**
1129     * ccs_print_entry - Print an ACL entry.
1130     *
1131     * @head: Pointer to "struct ccs_io_buffer".
1132     * @ptr: Pointer to an ACL entry.
1133     *
1134     * Returns true on success, false otherwise.
1135     */
1136     static bool ccs_print_entry(struct ccs_io_buffer *head,
1137     struct ccs_acl_info *ptr)
1138     {
1139     const struct ccs_condition *cond = ptr->cond;
1140     const u8 acl_type = ccs_acl_type2(ptr);
1141     if (acl_type & ACL_DELETED)
1142     return true;
1143     if (acl_type == TYPE_SINGLE_PATH_ACL) {
1144     struct ccs_single_path_acl_record *acl
1145     = container_of(ptr, struct ccs_single_path_acl_record,
1146     head);
1147     return ccs_print_single_path_acl(head, acl, cond);
1148     }
1149     if (acl_type == TYPE_EXECUTE_HANDLER) {
1150     struct ccs_execute_handler_record *acl
1151     = container_of(ptr, struct ccs_execute_handler_record,
1152     head);
1153     const char *keyword = KEYWORD_EXECUTE_HANDLER;
1154     return ccs_print_execute_handler_record(head, keyword, acl);
1155     }
1156     if (acl_type == TYPE_DENIED_EXECUTE_HANDLER) {
1157     struct ccs_execute_handler_record *acl
1158     = container_of(ptr, struct ccs_execute_handler_record,
1159     head);
1160     const char *keyword = KEYWORD_DENIED_EXECUTE_HANDLER;
1161     return ccs_print_execute_handler_record(head, keyword, acl);
1162     }
1163     if (head->read_execute_only)
1164     return true;
1165     if (acl_type == TYPE_MKDEV_ACL) {
1166     struct ccs_mkdev_acl_record *acl
1167     = container_of(ptr, struct ccs_mkdev_acl_record, head);
1168     return ccs_print_mkdev_acl(head, acl, cond);
1169     }
1170     if (acl_type == TYPE_DOUBLE_PATH_ACL) {
1171     struct ccs_double_path_acl_record *acl
1172     = container_of(ptr, struct ccs_double_path_acl_record,
1173     head);
1174     return ccs_print_double_path_acl(head, acl, cond);
1175     }
1176 kumaneko 2871 if (acl_type == TYPE_PATH_NUMBER_ACL) {
1177     struct ccs_path_number_acl_record *acl
1178     = container_of(ptr, struct ccs_path_number_acl_record,
1179     head);
1180     return ccs_print_path_number_acl(head, acl, cond);
1181 kumaneko 2863 }
1182     if (acl_type == TYPE_ARGV0_ACL) {
1183     struct ccs_argv0_acl_record *acl
1184     = container_of(ptr, struct ccs_argv0_acl_record, head);
1185     return ccs_print_argv0_acl(head, acl, cond);
1186     }
1187     if (acl_type == TYPE_ENV_ACL) {
1188     struct ccs_env_acl_record *acl
1189     = container_of(ptr, struct ccs_env_acl_record, head);
1190     return ccs_print_env_acl(head, acl, cond);
1191     }
1192     if (acl_type == TYPE_CAPABILITY_ACL) {
1193     struct ccs_capability_acl_record *acl
1194     = container_of(ptr, struct ccs_capability_acl_record,
1195     head);
1196     return ccs_print_capability_acl(head, acl, cond);
1197     }
1198     if (acl_type == TYPE_IP_NETWORK_ACL) {
1199     struct ccs_ip_network_acl_record *acl
1200     = container_of(ptr, struct ccs_ip_network_acl_record,
1201     head);
1202     return ccs_print_network_acl(head, acl, cond);
1203     }
1204     if (acl_type == TYPE_SIGNAL_ACL) {
1205     struct ccs_signal_acl_record *acl
1206     = container_of(ptr, struct ccs_signal_acl_record, head);
1207     return ccs_print_signal_acl(head, acl, cond);
1208     }
1209     if (acl_type == TYPE_MOUNT_ACL) {
1210     struct ccs_mount_acl_record *acl
1211     = container_of(ptr, struct ccs_mount_acl_record, head);
1212     return ccs_print_mount_acl(head, acl, cond);
1213     }
1214     if (acl_type == TYPE_UMOUNT_ACL) {
1215     struct ccs_umount_acl_record *acl
1216     = container_of(ptr, struct ccs_umount_acl_record, head);
1217     return ccs_print_umount_acl(head, acl, cond);
1218     }
1219     if (acl_type == TYPE_CHROOT_ACL) {
1220     struct ccs_chroot_acl_record *acl
1221     = container_of(ptr, struct ccs_chroot_acl_record, head);
1222     return ccs_print_chroot_acl(head, acl, cond);
1223     }
1224     if (acl_type == TYPE_PIVOT_ROOT_ACL) {
1225     struct ccs_pivot_root_acl_record *acl
1226     = container_of(ptr, struct ccs_pivot_root_acl_record,
1227     head);
1228     return ccs_print_pivot_root_acl(head, acl, cond);
1229     }
1230     /* Workaround for gcc 3.2.2's inline bug. */
1231     if (acl_type & ACL_DELETED)
1232     return true;
1233     BUG(); /* This must not happen. */
1234     return false;
1235     }
1236    
1237     /**
1238     * ccs_read_domain_policy - Read domain policy.
1239     *
1240     * @head: Pointer to "struct ccs_io_buffer".
1241     *
1242     * Returns 0.
1243     *
1244     * Caller holds ccs_read_lock().
1245     */
1246     static int ccs_read_domain_policy(struct ccs_io_buffer *head)
1247     {
1248     struct list_head *dpos;
1249     struct list_head *apos;
1250     ccs_check_read_lock();
1251     if (head->read_eof)
1252     return 0;
1253     if (head->read_step == 0)
1254     head->read_step = 1;
1255     list_for_each_cookie(dpos, head->read_var1, &ccs_domain_list) {
1256     struct ccs_domain_info *domain;
1257     const char *quota_exceeded = "";
1258     const char *transition_failed = "";
1259     const char *ignore_global_allow_read = "";
1260     const char *ignore_global_allow_env = "";
1261     domain = list_entry(dpos, struct ccs_domain_info, list);
1262     if (head->read_step != 1)
1263     goto acl_loop;
1264     if (domain->is_deleted && !head->read_single_domain)
1265     continue;
1266     /* Print domainname and flags. */
1267     if (domain->quota_warned)
1268     quota_exceeded = "quota_exceeded\n";
1269     if (domain->domain_transition_failed)
1270     transition_failed = "transition_failed\n";
1271     if (domain->ignore_global_allow_read)
1272     ignore_global_allow_read
1273     = KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1274     if (domain->ignore_global_allow_env)
1275     ignore_global_allow_env
1276     = KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "\n";
1277     if (!ccs_io_printf(head, "%s\n" KEYWORD_USE_PROFILE "%u\n"
1278     "%s%s%s%s\n", domain->domainname->name,
1279     domain->profile, quota_exceeded,
1280     transition_failed,
1281     ignore_global_allow_read,
1282     ignore_global_allow_env))
1283     return 0;
1284     head->read_step = 2;
1285     acl_loop:
1286     if (head->read_step == 3)
1287     goto tail_mark;
1288     /* Print ACL entries in the domain. */
1289     list_for_each_cookie(apos, head->read_var2,
1290     &domain->acl_info_list) {
1291     struct ccs_acl_info *ptr
1292     = list_entry(apos, struct ccs_acl_info, list);
1293     if (!ccs_print_entry(head, ptr))
1294     return 0;
1295     }
1296     head->read_step = 3;
1297     tail_mark:
1298     if (!ccs_io_printf(head, "\n"))
1299     return 0;
1300     head->read_step = 1;
1301     if (head->read_single_domain)
1302     break;
1303     }
1304     head->read_eof = true;
1305     return 0;
1306     }
1307    
1308     /**
1309     * ccs_write_domain_profile - Assign profile for specified domain.
1310     *
1311     * @head: Pointer to "struct ccs_io_buffer".
1312     *
1313     * Returns 0 on success, -EINVAL otherwise.
1314     *
1315     * This is equivalent to doing
1316     *
1317     * ( echo "select " $domainname; echo "use_profile " $profile ) |
1318     * /usr/lib/ccs/loadpolicy -d
1319     *
1320     * Caller holds ccs_read_lock().
1321     */
1322     static int ccs_write_domain_profile(struct ccs_io_buffer *head)
1323     {
1324     char *data = head->write_buf;
1325     char *cp = strchr(data, ' ');
1326     struct ccs_domain_info *domain;
1327     unsigned int profile;
1328     ccs_check_read_lock();
1329     if (!cp)
1330     return -EINVAL;
1331     *cp = '\0';
1332     profile = simple_strtoul(data, NULL, 10);
1333     if (profile >= MAX_PROFILES)
1334     return -EINVAL;
1335     domain = ccs_find_domain(cp + 1);
1336     if (domain && (ccs_profile_ptr[profile] || !ccs_policy_loaded))
1337     domain->profile = (u8) profile;
1338     return 0;
1339     }
1340    
1341     /**
1342     * ccs_read_domain_profile - Read only domainname and profile.
1343     *
1344     * @head: Pointer to "struct ccs_io_buffer".
1345     *
1346     * Returns list of profile number and domainname pairs.
1347     *
1348     * This is equivalent to doing
1349     *
1350     * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
1351     * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1352     * domainname = $0; } else if ( $1 == "use_profile" ) {
1353     * print $2 " " domainname; domainname = ""; } } ; '
1354     *
1355     * Caller holds ccs_read_lock().
1356     */
1357     static int ccs_read_domain_profile(struct ccs_io_buffer *head)
1358     {
1359     struct list_head *pos;
1360     ccs_check_read_lock();
1361     if (head->read_eof)
1362     return 0;
1363     list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) {
1364     struct ccs_domain_info *domain;
1365     domain = list_entry(pos, struct ccs_domain_info, list);
1366     if (domain->is_deleted)
1367     continue;
1368     if (!ccs_io_printf(head, "%u %s\n", domain->profile,
1369     domain->domainname->name))
1370     return 0;
1371     }
1372     head->read_eof = true;
1373     return 0;
1374     }
1375    
1376     /**
1377     * ccs_write_pid: Specify PID to obtain domainname.
1378     *
1379     * @head: Pointer to "struct ccs_io_buffer".
1380     *
1381     * Returns 0.
1382     */
1383     static int ccs_write_pid(struct ccs_io_buffer *head)
1384     {
1385     head->read_eof = false;
1386     return 0;
1387     }
1388    
1389     /**
1390     * ccs_read_pid - Read information of a process.
1391     *
1392     * @head: Pointer to "struct ccs_io_buffer".
1393     *
1394     * Returns the domainname which the specified PID is in or
1395     * process information of the specified PID on success,
1396     * empty string otherwise.
1397     *
1398     * Caller holds ccs_read_lock().
1399     */
1400     static int ccs_read_pid(struct ccs_io_buffer *head)
1401     {
1402     char *buf = head->write_buf;
1403     bool task_info = false;
1404     unsigned int pid;
1405     struct task_struct *p;
1406     struct ccs_domain_info *domain = NULL;
1407     u32 ccs_flags = 0;
1408     ccs_check_read_lock();
1409     /* Accessing write_buf is safe because head->io_sem is held. */
1410     if (!buf)
1411     goto done; /* Do nothing if open(O_RDONLY). */
1412     if (head->read_avail || head->read_eof)
1413     goto done;
1414     head->read_eof = true;
1415     if (ccs_str_starts(&buf, "info "))
1416     task_info = true;
1417     pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1418     /***** CRITICAL SECTION START *****/
1419     read_lock(&tasklist_lock);
1420     p = find_task_by_pid(pid);
1421     if (p) {
1422     domain = ccs_task_domain(p);
1423     ccs_flags = p->ccs_flags;
1424     }
1425     read_unlock(&tasklist_lock);
1426     /***** CRITICAL SECTION END *****/
1427     if (!domain)
1428     goto done;
1429     if (!task_info)
1430     ccs_io_printf(head, "%u %u %s", pid, domain->profile,
1431     domain->domainname->name);
1432     else
1433     ccs_io_printf(head, "%u manager=%s execute_handler=%s "
1434     "state[0]=%u state[1]=%u state[2]=%u", pid,
1435     ccs_flags & CCS_TASK_IS_POLICY_MANAGER ?
1436     "yes" : "no",
1437     ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ?
1438     "yes" : "no",
1439     (u8) (ccs_flags >> 24),
1440     (u8) (ccs_flags >> 16),
1441     (u8) (ccs_flags >> 8));
1442     done:
1443     return 0;
1444     }
1445    
1446     /**
1447     * ccs_write_exception_policy - Write exception policy.
1448     *
1449     * @head: Pointer to "struct ccs_io_buffer".
1450     *
1451     * Returns 0 on success, negative value otherwise.
1452     */
1453     static int ccs_write_exception_policy(struct ccs_io_buffer *head)
1454     {
1455     char *data = head->write_buf;
1456     bool is_delete = ccs_str_starts(&data, KEYWORD_DELETE);
1457     if (ccs_str_starts(&data, KEYWORD_KEEP_DOMAIN))
1458     return ccs_write_domain_keeper_policy(data, false, is_delete);
1459     if (ccs_str_starts(&data, KEYWORD_NO_KEEP_DOMAIN))
1460     return ccs_write_domain_keeper_policy(data, true, is_delete);
1461     if (ccs_str_starts(&data, KEYWORD_INITIALIZE_DOMAIN))
1462     return ccs_write_domain_initializer_policy(data, false,
1463     is_delete);
1464     if (ccs_str_starts(&data, KEYWORD_NO_INITIALIZE_DOMAIN))
1465     return ccs_write_domain_initializer_policy(data, true,
1466     is_delete);
1467     if (ccs_str_starts(&data, KEYWORD_AGGREGATOR))
1468     return ccs_write_aggregator_policy(data, is_delete);
1469     if (ccs_str_starts(&data, KEYWORD_ALLOW_READ))
1470     return ccs_write_globally_readable_policy(data, is_delete);
1471     if (ccs_str_starts(&data, KEYWORD_ALLOW_ENV))
1472     return ccs_write_globally_usable_env_policy(data, is_delete);
1473     if (ccs_str_starts(&data, KEYWORD_FILE_PATTERN))
1474     return ccs_write_pattern_policy(data, is_delete);
1475     if (ccs_str_starts(&data, KEYWORD_PATH_GROUP))
1476     return ccs_write_path_group_policy(data, is_delete);
1477     if (ccs_str_starts(&data, KEYWORD_NUMBER_GROUP))
1478     return ccs_write_number_group_policy(data, is_delete);
1479     if (ccs_str_starts(&data, KEYWORD_DENY_REWRITE))
1480     return ccs_write_no_rewrite_policy(data, is_delete);
1481     if (ccs_str_starts(&data, KEYWORD_ADDRESS_GROUP))
1482     return ccs_write_address_group_policy(data, is_delete);
1483     if (ccs_str_starts(&data, KEYWORD_DENY_AUTOBIND))
1484     return ccs_write_reserved_port_policy(data, is_delete);
1485     return -EINVAL;
1486     }
1487    
1488     /**
1489     * ccs_read_exception_policy - Read exception policy.
1490     *
1491     * @head: Pointer to "struct ccs_io_buffer".
1492     *
1493     * Returns 0 on success, -EINVAL otherwise.
1494     *
1495     * Caller holds ccs_read_lock().
1496     */
1497     static int ccs_read_exception_policy(struct ccs_io_buffer *head)
1498     {
1499     ccs_check_read_lock();
1500     if (!head->read_eof) {
1501     switch (head->read_step) {
1502     case 0:
1503     head->read_var2 = NULL;
1504     head->read_step = 1;
1505     case 1:
1506     if (!ccs_read_domain_keeper_policy(head))
1507     break;
1508     head->read_var2 = NULL;
1509     head->read_step = 2;
1510     case 2:
1511     if (!ccs_read_globally_readable_policy(head))
1512     break;
1513     head->read_var2 = NULL;
1514     head->read_step = 3;
1515     case 3:
1516     if (!ccs_read_globally_usable_env_policy(head))
1517     break;
1518     head->read_var2 = NULL;
1519     head->read_step = 4;
1520     case 4:
1521     if (!ccs_read_domain_initializer_policy(head))
1522     break;
1523     head->read_var2 = NULL;
1524     head->read_step = 6;
1525     case 6:
1526     if (!ccs_read_aggregator_policy(head))
1527     break;
1528     head->read_var2 = NULL;
1529     head->read_step = 7;
1530     case 7:
1531     if (!ccs_read_file_pattern(head))
1532     break;
1533     head->read_var2 = NULL;
1534     head->read_step = 8;
1535     case 8:
1536     if (!ccs_read_no_rewrite_policy(head))
1537     break;
1538     head->read_var2 = NULL;
1539     head->read_step = 9;
1540     case 9:
1541     if (!ccs_read_path_group_policy(head))
1542     break;
1543     head->read_var1 = NULL;
1544     head->read_var2 = NULL;
1545     head->read_step = 10;
1546     case 10:
1547     if (!ccs_read_number_group_policy(head))
1548     break;
1549     head->read_var1 = NULL;
1550     head->read_var2 = NULL;
1551     head->read_step = 11;
1552     case 11:
1553     if (!ccs_read_address_group_policy(head))
1554     break;
1555     head->read_var2 = NULL;
1556     head->read_step = 12;
1557     case 12:
1558     if (!ccs_read_reserved_port_policy(head))
1559     break;
1560     head->read_eof = true;
1561     break;
1562     default:
1563     return -EINVAL;
1564     }
1565     }
1566     return 0;
1567     }
1568    
1569     /* Wait queue for ccs_query_list. */
1570     static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1571    
1572     /* Lock for manipulating ccs_query_list. */
1573     static DEFINE_SPINLOCK(ccs_query_list_lock);
1574    
1575     /* Structure for query. */
1576     struct ccs_query_entry {
1577     struct list_head list;
1578     char *query;
1579     int query_len;
1580     unsigned int serial;
1581     int timer;
1582     int answer;
1583     };
1584    
1585     /* The list for "struct ccs_query_entry". */
1586     static LIST_HEAD(ccs_query_list);
1587    
1588     /* Number of "struct file" referring /proc/ccs/query interface. */
1589     static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1590    
1591     /**
1592     * ccs_check_supervisor - Ask for the supervisor's decision.
1593     *
1594     * @r: Pointer to "struct ccs_request_info".
1595     * @fmt: The printf()'s format string, followed by parameters.
1596     *
1597     * Returns 0 if the supervisor decided to permit the access request which
1598     * violated the policy in enforcing mode, 1 if the supervisor decided to
1599     * retry the access request which violated the policy in enforcing mode,
1600     * -EPERM otherwise.
1601     */
1602     int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...)
1603     {
1604     va_list args;
1605     int error = -EPERM;
1606     int pos;
1607     int len;
1608     static unsigned int ccs_serial;
1609     struct ccs_query_entry *ccs_query_entry = NULL;
1610     bool quota_exceeded = false;
1611     char *header;
1612     if (!r->domain)
1613     r->domain = ccs_current_domain();
1614     if (!atomic_read(&ccs_query_observers)) {
1615     int i;
1616     if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
1617     return -EPERM;
1618     for (i = 0; i < ccs_check_flags(r->domain, CCS_SLEEP_PERIOD);
1619     i++) {
1620     set_current_state(TASK_INTERRUPTIBLE);
1621     schedule_timeout(HZ / 10);
1622     }
1623     return -EPERM;
1624     }
1625     va_start(args, fmt);
1626     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
1627     va_end(args);
1628     header = ccs_init_audit_log(&len, r);
1629     if (!header)
1630     goto out;
1631     ccs_query_entry = kzalloc(sizeof(*ccs_query_entry), GFP_KERNEL);
1632     if (!ccs_query_entry)
1633     goto out;
1634     ccs_query_entry->query = kzalloc(len, GFP_KERNEL);
1635     if (!ccs_query_entry->query)
1636     goto out;
1637     INIT_LIST_HEAD(&ccs_query_entry->list);
1638     /***** CRITICAL SECTION START *****/
1639     spin_lock(&ccs_query_list_lock);
1640     if (ccs_quota_for_query && ccs_query_memory_size + len +
1641     sizeof(*ccs_query_entry) >= ccs_quota_for_query) {
1642     quota_exceeded = true;
1643     } else {
1644     ccs_query_memory_size += len + sizeof(*ccs_query_entry);
1645     ccs_query_entry->serial = ccs_serial++;
1646     }
1647     spin_unlock(&ccs_query_list_lock);
1648     /***** CRITICAL SECTION END *****/
1649     if (quota_exceeded)
1650     goto out;
1651     pos = snprintf(ccs_query_entry->query, len - 1, "Q%u-%hu\n%s",
1652     ccs_query_entry->serial, r->retry, header);
1653     kfree(header);
1654     header = NULL;
1655     va_start(args, fmt);
1656     vsnprintf(ccs_query_entry->query + pos, len - 1 - pos, fmt, args);
1657     ccs_query_entry->query_len = strlen(ccs_query_entry->query) + 1;
1658     va_end(args);
1659     /***** CRITICAL SECTION START *****/
1660     spin_lock(&ccs_query_list_lock);
1661     list_add_tail(&ccs_query_entry->list, &ccs_query_list);
1662     spin_unlock(&ccs_query_list_lock);
1663     /***** CRITICAL SECTION END *****/
1664     /* Give 10 seconds for supervisor's opinion. */
1665     for (ccs_query_entry->timer = 0;
1666     atomic_read(&ccs_query_observers) && ccs_query_entry->timer < 100;
1667     ccs_query_entry->timer++) {
1668     wake_up(&ccs_query_wait);
1669     set_current_state(TASK_INTERRUPTIBLE);
1670     schedule_timeout(HZ / 10);
1671     if (ccs_query_entry->answer)
1672     break;
1673     }
1674     /***** CRITICAL SECTION START *****/
1675     spin_lock(&ccs_query_list_lock);
1676     list_del(&ccs_query_entry->list);
1677     ccs_query_memory_size -= len + sizeof(*ccs_query_entry);
1678     spin_unlock(&ccs_query_list_lock);
1679     /***** CRITICAL SECTION END *****/
1680     switch (ccs_query_entry->answer) {
1681     case 3: /* Asked to retry by administrator. */
1682     error = 1;
1683     r->retry++;
1684     break;
1685     case 1:
1686     /* Granted by administrator. */
1687     error = 0;
1688     break;
1689     case 0:
1690     /* Timed out. */
1691     break;
1692     default:
1693     /* Rejected by administrator. */
1694     break;
1695     }
1696     out:
1697     if (ccs_query_entry)
1698     kfree(ccs_query_entry->query);
1699     kfree(ccs_query_entry);
1700     kfree(header);
1701     return error;
1702     }
1703    
1704     /**
1705     * ccs_poll_query - poll() for /proc/ccs/query.
1706     *
1707     * @file: Pointer to "struct file".
1708     * @wait: Pointer to "poll_table".
1709     *
1710     * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
1711     *
1712     * Waits for access requests which violated policy in enforcing mode.
1713     */
1714     static int ccs_poll_query(struct file *file, poll_table *wait)
1715     {
1716     struct list_head *tmp;
1717     bool found = false;
1718     u8 i;
1719     for (i = 0; i < 2; i++) {
1720     /***** CRITICAL SECTION START *****/
1721     spin_lock(&ccs_query_list_lock);
1722     list_for_each(tmp, &ccs_query_list) {
1723     struct ccs_query_entry *ptr
1724     = list_entry(tmp, struct ccs_query_entry, list);
1725     if (ptr->answer)
1726     continue;
1727     found = true;
1728     break;
1729     }
1730     spin_unlock(&ccs_query_list_lock);
1731     /***** CRITICAL SECTION END *****/
1732     if (found)
1733     return POLLIN | POLLRDNORM;
1734     if (i)
1735     break;
1736     poll_wait(file, &ccs_query_wait, wait);
1737     }
1738     return 0;
1739     }
1740    
1741     /**
1742     * ccs_read_query - Read access requests which violated policy in enforcing mode.
1743     *
1744     * @head: Pointer to "struct ccs_io_buffer".
1745     *
1746     * Returns 0.
1747     */
1748     static int ccs_read_query(struct ccs_io_buffer *head)
1749     {
1750     struct list_head *tmp;
1751     int pos = 0;
1752     int len = 0;
1753     char *buf;
1754     if (head->read_avail)
1755     return 0;
1756     if (head->read_buf) {
1757     kfree(head->read_buf);
1758     head->read_buf = NULL;
1759     head->readbuf_size = 0;
1760     }
1761     /***** CRITICAL SECTION START *****/
1762     spin_lock(&ccs_query_list_lock);
1763     list_for_each(tmp, &ccs_query_list) {
1764     struct ccs_query_entry *ptr
1765     = list_entry(tmp, struct ccs_query_entry, list);
1766     if (ptr->answer)
1767     continue;
1768     if (pos++ != head->read_step)
1769     continue;
1770     len = ptr->query_len;
1771     break;
1772     }
1773     spin_unlock(&ccs_query_list_lock);
1774     /***** CRITICAL SECTION END *****/
1775     if (!len) {
1776     head->read_step = 0;
1777     return 0;
1778     }
1779     buf = kzalloc(len, GFP_KERNEL);
1780     if (!buf)
1781     return 0;
1782     pos = 0;
1783     /***** CRITICAL SECTION START *****/
1784     spin_lock(&ccs_query_list_lock);
1785     list_for_each(tmp, &ccs_query_list) {
1786     struct ccs_query_entry *ptr
1787     = list_entry(tmp, struct ccs_query_entry, list);
1788     if (ptr->answer)
1789     continue;
1790     if (pos++ != head->read_step)
1791     continue;
1792     /*
1793     * Some query can be skipped because ccs_query_list
1794     * can change, but I don't care.
1795     */
1796     if (len == ptr->query_len)
1797     memmove(buf, ptr->query, len);
1798     break;
1799     }
1800     spin_unlock(&ccs_query_list_lock);
1801     /***** CRITICAL SECTION END *****/
1802     if (buf[0]) {
1803     head->read_avail = len;
1804     head->readbuf_size = head->read_avail;
1805     head->read_buf = buf;
1806     head->read_step++;
1807     } else {
1808     kfree(buf);
1809     }
1810     return 0;
1811     }
1812    
1813     /**
1814     * ccs_write_answer - Write the supervisor's decision.
1815     *
1816     * @head: Pointer to "struct ccs_io_buffer".
1817     *
1818     * Returns 0 on success, -EINVAL otherwise.
1819     */
1820     static int ccs_write_answer(struct ccs_io_buffer *head)
1821     {
1822     char *data = head->write_buf;
1823     struct list_head *tmp;
1824     unsigned int serial;
1825     unsigned int answer;
1826     /***** CRITICAL SECTION START *****/
1827     spin_lock(&ccs_query_list_lock);
1828     list_for_each(tmp, &ccs_query_list) {
1829     struct ccs_query_entry *ptr
1830     = list_entry(tmp, struct ccs_query_entry, list);
1831     ptr->timer = 0;
1832     }
1833     spin_unlock(&ccs_query_list_lock);
1834     /***** CRITICAL SECTION END *****/
1835     if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
1836     return -EINVAL;
1837     /***** CRITICAL SECTION START *****/
1838     spin_lock(&ccs_query_list_lock);
1839     list_for_each(tmp, &ccs_query_list) {
1840     struct ccs_query_entry *ptr
1841     = list_entry(tmp, struct ccs_query_entry, list);
1842     if (ptr->serial != serial)
1843     continue;
1844     if (!ptr->answer)
1845     ptr->answer = answer;
1846     break;
1847     }
1848     spin_unlock(&ccs_query_list_lock);
1849     /***** CRITICAL SECTION END *****/
1850     return 0;
1851     }
1852    
1853     /**
1854     * ccs_read_version: Get version.
1855     *
1856     * @head: Pointer to "struct ccs_io_buffer".
1857     *
1858     * Returns version information.
1859     */
1860     static int ccs_read_version(struct ccs_io_buffer *head)
1861     {
1862     if (!head->read_eof) {
1863     ccs_io_printf(head, "1.7.0-pre");
1864     head->read_eof = true;
1865     }
1866     return 0;
1867     }
1868    
1869     /**
1870     * ccs_read_self_domain - Get the current process's domainname.
1871     *
1872     * @head: Pointer to "struct ccs_io_buffer".
1873     *
1874     * Returns the current process's domainname.
1875     */
1876     static int ccs_read_self_domain(struct ccs_io_buffer *head)
1877     {
1878     if (!head->read_eof) {
1879     /*
1880     * ccs_current_domain()->domainname != NULL
1881     * because every process belongs to a domain and
1882     * the domain's name cannot be NULL.
1883     */
1884     ccs_io_printf(head, "%s",
1885     ccs_current_domain()->domainname->name);
1886     head->read_eof = true;
1887     }
1888     return 0;
1889     }
1890    
1891     /**
1892     * ccs_open_control - open() for /proc/ccs/ interface.
1893     *
1894     * @type: Type of interface.
1895     * @file: Pointer to "struct file".
1896     *
1897     * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
1898     */
1899     int ccs_open_control(const u8 type, struct file *file)
1900     {
1901     struct ccs_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
1902     if (!head)
1903     return -ENOMEM;
1904     mutex_init(&head->io_sem);
1905     head->type = type;
1906     switch (type) {
1907     case CCS_DOMAINPOLICY: /* /proc/ccs/domain_policy */
1908     head->write = ccs_write_domain_policy;
1909     head->read = ccs_read_domain_policy;
1910     break;
1911     case CCS_EXCEPTIONPOLICY: /* /proc/ccs/exception_policy */
1912     head->write = ccs_write_exception_policy;
1913     head->read = ccs_read_exception_policy;
1914     break;
1915     #ifdef CONFIG_CCSECURITY_AUDIT
1916     case CCS_GRANTLOG: /* /proc/ccs/grant_log */
1917     head->poll = ccs_poll_grant_log;
1918     head->read = ccs_read_grant_log;
1919     break;
1920     case CCS_REJECTLOG: /* /proc/ccs/reject_log */
1921     head->poll = ccs_poll_reject_log;
1922     head->read = ccs_read_reject_log;
1923     break;
1924     #endif
1925     case CCS_SELFDOMAIN: /* /proc/ccs/self_domain */
1926     head->read = ccs_read_self_domain;
1927     break;
1928     case CCS_DOMAIN_STATUS: /* /proc/ccs/.domain_status */
1929     head->write = ccs_write_domain_profile;
1930     head->read = ccs_read_domain_profile;
1931     break;
1932     case CCS_EXECUTE_HANDLER: /* /proc/ccs/.execute_handler */
1933     /* Allow execute_handler to read process's status. */
1934     if (!(current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER)) {
1935     kfree(head);
1936     return -EPERM;
1937     }
1938     /* fall through */
1939     case CCS_PROCESS_STATUS: /* /proc/ccs/.process_status */
1940     head->write = ccs_write_pid;
1941     head->read = ccs_read_pid;
1942     break;
1943     case CCS_VERSION: /* /proc/ccs/version */
1944     head->read = ccs_read_version;
1945     head->readbuf_size = 128;
1946     break;
1947     case CCS_MEMINFO: /* /proc/ccs/meminfo */
1948     head->write = ccs_write_memory_quota;
1949     head->read = ccs_read_memory_counter;
1950     head->readbuf_size = 512;
1951     break;
1952     case CCS_PROFILE: /* /proc/ccs/profile */
1953     head->write = ccs_write_profile;
1954     head->read = ccs_read_profile;
1955     break;
1956     case CCS_QUERY: /* /proc/ccs/query */
1957     head->poll = ccs_poll_query;
1958     head->write = ccs_write_answer;
1959     head->read = ccs_read_query;
1960     break;
1961     case CCS_MANAGER: /* /proc/ccs/manager */
1962     head->write = ccs_write_manager_policy;
1963     head->read = ccs_read_manager_policy;
1964     break;
1965     }
1966     if (!(file->f_mode & FMODE_READ)) {
1967     /*
1968     * No need to allocate read_buf since it is not opened
1969     * for reading.
1970     */
1971     head->read = NULL;
1972     head->poll = NULL;
1973     } else if (type != CCS_QUERY &&
1974     type != CCS_GRANTLOG && type != CCS_REJECTLOG) {
1975     /*
1976     * Don't allocate buffer for reading if the file is one of
1977     * /proc/ccs/grant_log , /proc/ccs/reject_log , /proc/ccs/query.
1978     */
1979     if (!head->readbuf_size)
1980     head->readbuf_size = 4096 * 2;
1981     head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
1982     if (!head->read_buf) {
1983     kfree(head);
1984     return -ENOMEM;
1985     }
1986     }
1987     if (!(file->f_mode & FMODE_WRITE)) {
1988     /*
1989     * No need to allocate write_buf since it is not opened
1990     * for writing.
1991     */
1992     head->write = NULL;
1993     } else if (head->write) {
1994     head->writebuf_size = 4096 * 2;
1995     head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
1996     if (!head->write_buf) {
1997     kfree(head->read_buf);
1998     kfree(head);
1999     return -ENOMEM;
2000     }
2001     }
2002     if (type != CCS_QUERY &&
2003     type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2004     head->reader_idx = ccs_read_lock();
2005     file->private_data = head;
2006     /*
2007     * Call the handler now if the file is /proc/ccs/self_domain
2008     * so that the user can use "cat < /proc/ccs/self_domain" to
2009     * know the current process's domainname.
2010     */
2011     if (type == CCS_SELFDOMAIN)
2012     ccs_read_control(file, NULL, 0);
2013     /*
2014     * If the file is /proc/ccs/query , increment the observer counter.
2015     * The obserber counter is used by ccs_check_supervisor() to see if
2016     * there is some process monitoring /proc/ccs/query.
2017     */
2018     else if (type == CCS_QUERY)
2019     atomic_inc(&ccs_query_observers);
2020     return 0;
2021     }
2022    
2023     /**
2024     * ccs_poll_control - poll() for /proc/ccs/ interface.
2025     *
2026     * @file: Pointer to "struct file".
2027     * @wait: Pointer to "poll_table".
2028     *
2029     * Waits for read readiness.
2030     * /proc/ccs/query is handled by /usr/lib/ccs/ccs-queryd and
2031     * /proc/ccs/grant_log and /proc/ccs/reject_log are handled by
2032     * /usr/lib/ccs/ccs-auditd.
2033     */
2034     int ccs_poll_control(struct file *file, poll_table *wait)
2035     {
2036     struct ccs_io_buffer *head = file->private_data;
2037     if (!head->poll)
2038     return -ENOSYS;
2039     return head->poll(file, wait);
2040     }
2041    
2042     /**
2043     * ccs_read_control - read() for /proc/ccs/ interface.
2044     *
2045     * @file: Pointer to "struct file".
2046     * @buffer: Poiner to buffer to write to.
2047     * @buffer_len: Size of @buffer.
2048     *
2049     * Returns bytes read on success, negative value otherwise.
2050     */
2051     int ccs_read_control(struct file *file, char __user *buffer,
2052     const int buffer_len)
2053     {
2054     int len = 0;
2055     struct ccs_io_buffer *head = file->private_data;
2056     char *cp;
2057     if (!head->read)
2058     return -ENOSYS;
2059     if (!access_ok(VERIFY_WRITE, buffer, buffer_len))
2060     return -EFAULT;
2061     if (mutex_lock_interruptible(&head->io_sem))
2062     return -EINTR;
2063     /* Call the policy handler. */
2064     len = head->read(head);
2065     if (len < 0)
2066     goto out;
2067     /* Write to buffer. */
2068     len = head->read_avail;
2069     if (len > buffer_len)
2070     len = buffer_len;
2071     if (!len)
2072     goto out;
2073     /* head->read_buf changes by some functions. */
2074     cp = head->read_buf;
2075     if (copy_to_user(buffer, cp, len)) {
2076     len = -EFAULT;
2077     goto out;
2078     }
2079     head->read_avail -= len;
2080     memmove(cp, cp + len, head->read_avail);
2081     out:
2082     mutex_unlock(&head->io_sem);
2083     return len;
2084     }
2085    
2086     /**
2087     * ccs_write_control - write() for /proc/ccs/ interface.
2088     *
2089     * @file: Pointer to "struct file".
2090     * @buffer: Pointer to buffer to read from.
2091     * @buffer_len: Size of @buffer.
2092     *
2093     * Returns @buffer_len on success, negative value otherwise.
2094     */
2095     int ccs_write_control(struct file *file, const char __user *buffer,
2096     const int buffer_len)
2097     {
2098     struct ccs_io_buffer *head = file->private_data;
2099     int error = buffer_len;
2100     int avail_len = buffer_len;
2101     char *cp0 = head->write_buf;
2102     if (!head->write)
2103     return -ENOSYS;
2104     if (!access_ok(VERIFY_READ, buffer, buffer_len))
2105     return -EFAULT;
2106     /* Don't allow updating policies by non manager programs. */
2107     if (head->write != ccs_write_pid &&
2108     head->write != ccs_write_domain_policy &&
2109     !ccs_is_policy_manager())
2110     return -EPERM;
2111     if (mutex_lock_interruptible(&head->io_sem))
2112     return -EINTR;
2113     /* Read a line and dispatch it to the policy handler. */
2114     while (avail_len > 0) {
2115     char c;
2116     if (head->write_avail >= head->writebuf_size - 1) {
2117     error = -ENOMEM;
2118     break;
2119     } else if (get_user(c, buffer)) {
2120     error = -EFAULT;
2121     break;
2122     }
2123     buffer++;
2124     avail_len--;
2125     cp0[head->write_avail++] = c;
2126     if (c != '\n')
2127     continue;
2128     cp0[head->write_avail - 1] = '\0';
2129     head->write_avail = 0;
2130     ccs_normalize_line(cp0);
2131     head->write(head);
2132     }
2133     mutex_unlock(&head->io_sem);
2134     return error;
2135     }
2136    
2137     /**
2138     * ccs_close_control - close() for /proc/ccs/ interface.
2139     *
2140     * @file: Pointer to "struct file".
2141     *
2142     * Releases memory and returns 0.
2143     */
2144     int ccs_close_control(struct file *file)
2145     {
2146     struct ccs_io_buffer *head = file->private_data;
2147     const bool is_write = head->write_buf != NULL;
2148     const u8 type = head->type;
2149     /*
2150     * If the file is /proc/ccs/query , decrement the observer counter.
2151     */
2152     if (type == CCS_QUERY)
2153     atomic_dec(&ccs_query_observers);
2154     if (type != CCS_QUERY &&
2155     type != CCS_GRANTLOG && type != CCS_REJECTLOG)
2156     ccs_read_unlock(head->reader_idx);
2157     /* Release memory used for policy I/O. */
2158     kfree(head->read_buf);
2159     head->read_buf = NULL;
2160     kfree(head->write_buf);
2161     head->write_buf = NULL;
2162     kfree(head);
2163     head = NULL;
2164     file->private_data = NULL;
2165     if (is_write)
2166     ccs_run_gc();
2167     return 0;
2168     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26