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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2900 - (hide annotations) (download) (as text)
Thu Aug 13 11:54:14 2009 UTC (14 years, 9 months ago) by kumaneko
Original Path: branches/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 65942 byte(s)


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

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