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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2958 - (hide annotations) (download) (as text)
Wed Aug 26 09:43:56 2009 UTC (14 years, 8 months ago) by kumaneko
Original Path: trunk/1.7.x/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 71881 byte(s)


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