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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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