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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2962 - (show annotations) (download) (as text)
Thu Aug 27 08:48:18 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: 76869 byte(s)


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

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