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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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