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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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