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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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