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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2961 - (hide annotations) (download) (as text)
Thu Aug 27 05:35:30 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: 73813 byte(s)


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