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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3761 - (show annotations) (download) (as text)
Sun Jun 13 14:58:41 2010 UTC (13 years, 11 months ago) by kumaneko
Original Path: branches/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 73672 byte(s)


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

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