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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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