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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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