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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3689 - (show annotations) (download) (as text)
Sat May 22 11:00:22 2010 UTC (14 years ago) by kumaneko
File MIME type: text/x-csrc
File size: 81081 byte(s)


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

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