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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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