Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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