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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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