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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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