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

Subversion リポジトリの参照

Contents of /trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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