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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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