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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2892 - (hide annotations) (download) (as text)
Tue Aug 11 02:02:02 2009 UTC (14 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 60031 byte(s)


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

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