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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2975 - (show annotations) (download) (as text)
Tue Sep 1 05:34:46 2009 UTC (14 years, 8 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: 77557 byte(s)


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

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