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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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