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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2908 - (show annotations) (download) (as text)
Sat Aug 15 07:28:22 2009 UTC (14 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 66295 byte(s)


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

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