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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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