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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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