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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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