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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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