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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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