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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3949 - (hide annotations) (download) (as text)
Sun Sep 5 11:50:03 2010 UTC (13 years, 8 months ago) by kumaneko
Original Path: trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c
File MIME type: text/x-csrc
File size: 68292 byte(s)


1 kumaneko 2863 /*
2 kumaneko 2864 * security/ccsecurity/policy_io.c
3 kumaneko 2863 *
4 kumaneko 3441 * Copyright (C) 2005-2010 NTT DATA CORPORATION
5 kumaneko 2863 *
6 kumaneko 3935 * Version: 1.8.0-pre 2010/09/01
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     #ifdef CONFIG_CCSECURITY_AUDIT
17     .preference.audit_max_grant_log = CONFIG_CCSECURITY_MAX_GRANT_LOG,
18     .preference.audit_max_reject_log = CONFIG_CCSECURITY_MAX_REJECT_LOG,
19     #endif
20 kumaneko 3064 .preference.audit_task_info = true,
21     .preference.audit_path_info = true,
22 kumaneko 2962 .preference.enforcing_penalty = 0,
23     .preference.learning_max_entry = CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY,
24     .preference.learning_exec_realpath = true,
25     .preference.learning_exec_argv0 = true,
26     .preference.learning_symlink_target = true,
27     };
28    
29 kumaneko 3945 /* Profile version. Currently only 20100903 is defined. */
30 kumaneko 3158 static unsigned int ccs_profile_version;
31    
32 kumaneko 2958 /* Profile table. Memory is allocated as needed. */
33     static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
34    
35 kumaneko 2948 /* String table for functionality that takes 4 modes. */
36 kumaneko 3781 const char *ccs_mode[CCS_CONFIG_MAX_MODE] = {
37 kumaneko 3748 [CCS_CONFIG_DISABLED] = "disabled",
38     [CCS_CONFIG_LEARNING] = "learning",
39     [CCS_CONFIG_PERMISSIVE] = "permissive",
40     [CCS_CONFIG_ENFORCING] = "enforcing"
41 kumaneko 2863 };
42 kumaneko 2915
43 kumaneko 2948 /* String table for /proc/ccs/profile */
44 kumaneko 2918 static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX +
45 kumaneko 2943 CCS_MAX_CAPABILITY_INDEX +
46     CCS_MAX_MAC_CATEGORY_INDEX] = {
47     [CCS_MAC_FILE_EXECUTE]
48     = "file::execute",
49     [CCS_MAC_FILE_OPEN]
50     = "file::open",
51     [CCS_MAC_FILE_CREATE]
52     = "file::create",
53     [CCS_MAC_FILE_UNLINK]
54     = "file::unlink",
55     [CCS_MAC_FILE_MKDIR]
56     = "file::mkdir",
57     [CCS_MAC_FILE_RMDIR]
58     = "file::rmdir",
59     [CCS_MAC_FILE_MKFIFO]
60     = "file::mkfifo",
61     [CCS_MAC_FILE_MKSOCK]
62     = "file::mksock",
63     [CCS_MAC_FILE_TRUNCATE]
64     = "file::truncate",
65     [CCS_MAC_FILE_SYMLINK]
66     = "file::symlink",
67     [CCS_MAC_FILE_MKBLOCK]
68     = "file::mkblock",
69     [CCS_MAC_FILE_MKCHAR]
70     = "file::mkchar",
71     [CCS_MAC_FILE_LINK]
72     = "file::link",
73     [CCS_MAC_FILE_RENAME]
74     = "file::rename",
75     [CCS_MAC_FILE_CHMOD]
76     = "file::chmod",
77     [CCS_MAC_FILE_CHOWN]
78     = "file::chown",
79     [CCS_MAC_FILE_CHGRP]
80     = "file::chgrp",
81     [CCS_MAC_FILE_IOCTL]
82     = "file::ioctl",
83     [CCS_MAC_FILE_CHROOT]
84     = "file::chroot",
85     [CCS_MAC_FILE_MOUNT]
86     = "file::mount",
87     [CCS_MAC_FILE_UMOUNT]
88     = "file::umount",
89     [CCS_MAC_FILE_PIVOT_ROOT]
90     = "file::pivot_root",
91     [CCS_MAC_ENVIRON]
92     = "misc::env",
93 kumaneko 3927 [CCS_MAC_NETWORK_INET_STREAM_BIND]
94     = "network::inet_stream_bind",
95     [CCS_MAC_NETWORK_INET_STREAM_LISTEN]
96     = "network::inet_stream_listen",
97     [CCS_MAC_NETWORK_INET_STREAM_CONNECT]
98     = "network::inet_stream_connect",
99     [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]
100     = "network::inet_stream_accept",
101     [CCS_MAC_NETWORK_INET_DGRAM_BIND]
102     = "network::inet_dgram_bind",
103     [CCS_MAC_NETWORK_INET_DGRAM_SEND]
104     = "network::inet_dgram_send",
105     [CCS_MAC_NETWORK_INET_DGRAM_RECV]
106     = "network::inet_dgram_recv",
107 kumaneko 3911 [CCS_MAC_NETWORK_INET_RAW_BIND]
108 kumaneko 2943 = "network::inet_raw_bind",
109 kumaneko 3911 [CCS_MAC_NETWORK_INET_RAW_SEND]
110 kumaneko 3843 = "network::inet_raw_send",
111 kumaneko 3911 [CCS_MAC_NETWORK_INET_RAW_RECV]
112 kumaneko 3843 = "network::inet_raw_recv",
113 kumaneko 3911 [CCS_MAC_NETWORK_UNIX_STREAM_BIND]
114     = "network::unix_stream_bind",
115     [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]
116     = "network::unix_stream_listen",
117     [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]
118     = "network::unix_stream_connect",
119 kumaneko 3912 [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]
120     = "network::unix_stream_accept",
121 kumaneko 3911 [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]
122     = "network::unix_dgram_bind",
123     [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]
124     = "network::unix_dgram_send",
125 kumaneko 3912 [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]
126     = "network::unix_dgram_recv",
127 kumaneko 3911 [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]
128     = "network::unix_seqpacket_bind",
129     [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]
130     = "network::unix_seqpacket_listen",
131     [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT]
132     = "network::unix_seqpacket_connect",
133 kumaneko 3912 [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]
134     = "network::unix_seqpacket_accept",
135 kumaneko 2943 [CCS_MAC_SIGNAL]
136     = "ipc::signal",
137     [CCS_MAX_MAC_INDEX + CCS_USE_ROUTE_SOCKET]
138     = "capability::use_route",
139     [CCS_MAX_MAC_INDEX + CCS_USE_PACKET_SOCKET]
140     = "capability::use_packet",
141     [CCS_MAX_MAC_INDEX + CCS_SYS_REBOOT]
142     = "capability::SYS_REBOOT",
143     [CCS_MAX_MAC_INDEX + CCS_SYS_VHANGUP]
144     = "capability::SYS_VHANGUP",
145     [CCS_MAX_MAC_INDEX + CCS_SYS_SETTIME]
146     = "capability::SYS_TIME",
147     [CCS_MAX_MAC_INDEX + CCS_SYS_NICE]
148     = "capability::SYS_NICE",
149     [CCS_MAX_MAC_INDEX + CCS_SYS_SETHOSTNAME]
150     = "capability::SYS_SETHOSTNAME",
151     [CCS_MAX_MAC_INDEX + CCS_USE_KERNEL_MODULE]
152     = "capability::use_kernel_module",
153     [CCS_MAX_MAC_INDEX + CCS_SYS_KEXEC_LOAD]
154     = "capability::SYS_KEXEC_LOAD",
155     [CCS_MAX_MAC_INDEX + CCS_SYS_PTRACE]
156     = "capability::SYS_PTRACE",
157     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
158     + CCS_MAC_CATEGORY_FILE] = "file",
159     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
160     + CCS_MAC_CATEGORY_NETWORK] = "network",
161     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
162     + CCS_MAC_CATEGORY_MISC] = "misc",
163     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
164     + CCS_MAC_CATEGORY_IPC] = "ipc",
165     [CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
166     + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
167 kumaneko 2915 };
168    
169 kumaneko 2863 /* Permit policy management by non-root user? */
170     static bool ccs_manage_by_non_root;
171    
172     /**
173 kumaneko 2918 * ccs_cap2keyword - Convert capability operation to capability name.
174     *
175     * @operation: The capability index.
176     *
177     * Returns the name of the specified capability's name.
178     */
179     const char *ccs_cap2keyword(const u8 operation)
180     {
181     return operation < CCS_MAX_CAPABILITY_INDEX
182 kumaneko 2943 ? ccs_mac_keywords[CCS_MAX_MAC_INDEX + operation] + 12 : NULL;
183 kumaneko 2918 }
184    
185     /**
186 kumaneko 2958 * ccs_yesno - Return "yes" or "no".
187 kumaneko 2863 *
188 kumaneko 2958 * @value: Bool value.
189 kumaneko 2863 */
190 kumaneko 2958 static const char *ccs_yesno(const unsigned int value)
191 kumaneko 2863 {
192 kumaneko 2958 return value ? "yes" : "no";
193 kumaneko 2863 }
194    
195 kumaneko 3780 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
196     {
197     va_list args;
198     const int pos = strlen(buffer);
199     va_start(args, fmt);
200     vsnprintf(buffer + pos, len - pos - 1, fmt, args);
201     va_end(args);
202     }
203    
204 kumaneko 2863 /**
205 kumaneko 3780 * ccs_flush - Flush queued string to userspace's buffer.
206 kumaneko 2863 *
207 kumaneko 3780 * @head: Pointer to "struct ccs_io_buffer".
208 kumaneko 2863 *
209 kumaneko 3780 * Returns true if all data was flushed, false otherwise.
210     */
211     static bool ccs_flush(struct ccs_io_buffer *head)
212     {
213     while (head->r.w_pos) {
214     const char *w = head->r.w[0];
215     int len = strlen(w);
216     if (len) {
217     if (len > head->read_user_buf_avail)
218     len = head->read_user_buf_avail;
219     if (!len)
220     return false;
221     if (copy_to_user(head->read_user_buf, w, len))
222     return false;
223     head->read_user_buf_avail -= len;
224     head->read_user_buf += len;
225     w += len;
226     }
227     if (*w) {
228     head->r.w[0] = w;
229     return false;
230     }
231     /* Add '\0' for audit logs and query. */
232     if (head->poll) {
233     if (!head->read_user_buf_avail ||
234     copy_to_user(head->read_user_buf, "", 1))
235     return false;
236     head->read_user_buf_avail--;
237     head->read_user_buf++;
238     }
239     head->r.w_pos--;
240     for (len = 0; len < head->r.w_pos; len++)
241     head->r.w[len] = head->r.w[len + 1];
242     }
243     head->r.avail = 0;
244     return true;
245     }
246    
247     /**
248     * ccs_set_string - Queue string to "struct ccs_io_buffer" structure.
249 kumaneko 2863 *
250 kumaneko 3780 * @head: Pointer to "struct ccs_io_buffer".
251     * @string: String to print.
252     *
253     * Note that @string has to be kept valid until @head is kfree()d.
254     * This means that char[] allocated on stack memory cannot be passed to
255     * this function. Use ccs_io_printf() for char[] allocated on stack memory.
256 kumaneko 2863 */
257 kumaneko 3780 static void ccs_set_string(struct ccs_io_buffer *head, const char *string)
258 kumaneko 2863 {
259 kumaneko 3780 if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) {
260     head->r.w[head->r.w_pos++] = string;
261     ccs_flush(head);
262     } else
263 kumaneko 3829 printk(KERN_WARNING "Too many words in a line.\n");
264 kumaneko 3780 }
265    
266     /**
267     * ccs_io_printf - printf() to "struct ccs_io_buffer" structure.
268     *
269     * @head: Pointer to "struct ccs_io_buffer".
270     * @fmt: The printf()'s format string, followed by parameters.
271     */
272     void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
273     {
274 kumaneko 2863 va_list args;
275     int len;
276 kumaneko 3780 int pos = head->r.avail;
277 kumaneko 2863 int size = head->readbuf_size - pos;
278     if (size <= 0)
279 kumaneko 3780 return;
280 kumaneko 2863 va_start(args, fmt);
281 kumaneko 3780 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
282 kumaneko 2863 va_end(args);
283 kumaneko 3780 if (pos + len >= head->readbuf_size) {
284 kumaneko 3829 printk(KERN_WARNING "Too many words in a line.\n");
285 kumaneko 3780 return;
286     }
287     head->r.avail += len;
288     ccs_set_string(head, head->read_buf + pos);
289 kumaneko 2863 }
290    
291 kumaneko 3780 static void ccs_set_space(struct ccs_io_buffer *head)
292     {
293     ccs_set_string(head, " ");
294     }
295    
296     static bool ccs_set_lf(struct ccs_io_buffer *head)
297     {
298     ccs_set_string(head, "\n");
299     return !head->r.w_pos;
300     }
301    
302 kumaneko 2863 /**
303 kumaneko 3694 * ccs_assign_profile - Create a new profile.
304 kumaneko 2863 *
305     * @profile: Profile number to create.
306     *
307     * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
308     */
309 kumaneko 3694 static struct ccs_profile *ccs_assign_profile(const unsigned int profile)
310 kumaneko 2863 {
311     struct ccs_profile *ptr;
312     struct ccs_profile *entry;
313 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
314 kumaneko 2863 return NULL;
315     ptr = ccs_profile_ptr[profile];
316     if (ptr)
317     return ptr;
318 kumaneko 3512 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
319 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
320     goto out;
321 kumaneko 2863 ptr = ccs_profile_ptr[profile];
322     if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
323     ptr = entry;
324 kumaneko 2958 ptr->default_config = CCS_CONFIG_DISABLED |
325 kumaneko 3870 CCS_CONFIG_VERBOSE |
326 kumaneko 2958 CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
327     memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
328 kumaneko 2943 sizeof(ptr->config));
329 kumaneko 2863 mb(); /* Avoid out-of-order execution. */
330     ccs_profile_ptr[profile] = ptr;
331     entry = NULL;
332     }
333     mutex_unlock(&ccs_policy_lock);
334 kumaneko 3534 out:
335 kumaneko 2863 kfree(entry);
336     return ptr;
337     }
338    
339     /**
340 kumaneko 2991 * ccs_check_profile - Check all profiles currently assigned to domains are defined.
341     */
342 kumaneko 3502 static void ccs_check_profile(void)
343 kumaneko 2991 {
344     struct ccs_domain_info *domain;
345 kumaneko 3535 const int idx = ccs_read_lock();
346 kumaneko 2991 ccs_policy_loaded = true;
347     list_for_each_entry_rcu(domain, &ccs_domain_list, list) {
348     const u8 profile = domain->profile;
349     if (ccs_profile_ptr[profile])
350     continue;
351     panic("Profile %u (used by '%s') not defined.\n",
352     profile, domain->domainname->name);
353     }
354 kumaneko 3535 ccs_read_unlock(idx);
355 kumaneko 3945 if (ccs_profile_version != 20100903)
356 kumaneko 3158 panic("Profile version %u is not supported.\n",
357     ccs_profile_version);
358 kumaneko 3935 printk(KERN_INFO "CCSecurity: 1.8.0-pre 2010/09/01\n");
359 kumaneko 3502 printk(KERN_INFO "Mandatory Access Control activated.\n");
360 kumaneko 2991 }
361    
362     /**
363 kumaneko 2958 * ccs_profile - Find a profile.
364     *
365     * @profile: Profile number to find.
366     *
367 kumaneko 2991 * Returns pointer to "struct ccs_profile".
368 kumaneko 2958 */
369     struct ccs_profile *ccs_profile(const u8 profile)
370     {
371 kumaneko 2974 struct ccs_profile *ptr = ccs_profile_ptr[profile];
372 kumaneko 2962 if (!ccs_policy_loaded)
373     return &ccs_default_profile;
374 kumaneko 2974 BUG_ON(!ptr);
375     return ptr;
376 kumaneko 2958 }
377    
378 kumaneko 3747 static s8 ccs_find_yesno(const char *string, const char *find)
379 kumaneko 2863 {
380 kumaneko 3747 const char *cp = strstr(string, find);
381     if (cp) {
382     cp += strlen(find);
383 kumaneko 3758 if (!strncmp(cp, "=yes", 4))
384 kumaneko 3747 return 1;
385 kumaneko 3758 else if (!strncmp(cp, "=no", 3))
386 kumaneko 3747 return 0;
387 kumaneko 2863 }
388 kumaneko 3747 return -1;
389     }
390    
391     static void ccs_set_bool(bool *b, const char *string, const char *find)
392     {
393     switch (ccs_find_yesno(string, find)) {
394     case 1:
395     *b = true;
396     break;
397     case 0:
398     *b = false;
399     break;
400     }
401     }
402    
403     static void ccs_set_uint(unsigned int *i, const char *string, const char *find)
404     {
405     const char *cp = strstr(string, find);
406     if (cp)
407     sscanf(cp + strlen(find), "=%u", i);
408     }
409    
410 kumaneko 3758 static void ccs_set_pref(const char *name, const char *value,
411 kumaneko 3870 struct ccs_profile *profile)
412 kumaneko 3747 {
413 kumaneko 3758 if (!strcmp(name, "audit")) {
414 kumaneko 3069 #ifdef CONFIG_CCSECURITY_AUDIT
415 kumaneko 3758 ccs_set_uint(&profile->preference.audit_max_grant_log, value,
416 kumaneko 3747 "max_grant_log");
417 kumaneko 3758 ccs_set_uint(&profile->preference.audit_max_reject_log, value,
418 kumaneko 3747 "max_reject_log");
419 kumaneko 3069 #endif
420 kumaneko 3758 ccs_set_bool(&profile->preference.audit_task_info, value,
421 kumaneko 3747 "task_info");
422 kumaneko 3758 ccs_set_bool(&profile->preference.audit_path_info, value,
423 kumaneko 3747 "path_info");
424     return;
425 kumaneko 2863 }
426 kumaneko 3758 if (!strcmp(name, "enforcing")) {
427     ccs_set_uint(&profile->preference.enforcing_penalty, value,
428 kumaneko 3747 "penalty");
429 kumaneko 3870 return;
430 kumaneko 2958 }
431 kumaneko 3758 if (!strcmp(name, "learning")) {
432     ccs_set_uint(&profile->preference.learning_max_entry, value,
433 kumaneko 3747 "max_entry");
434 kumaneko 3758 ccs_set_bool(&profile->preference.learning_exec_realpath,
435     value, "exec.realpath");
436     ccs_set_bool(&profile->preference.learning_exec_argv0, value,
437 kumaneko 3747 "exec.argv0");
438 kumaneko 3758 ccs_set_bool(&profile->preference.learning_symlink_target,
439     value, "symlink.target");
440 kumaneko 3870 return;
441 kumaneko 2958 }
442 kumaneko 3747 }
443    
444 kumaneko 3870 static int ccs_set_mode(char *name, const char *value,
445 kumaneko 3758 struct ccs_profile *profile)
446 kumaneko 3747 {
447     u8 i;
448     u8 config;
449 kumaneko 3758 if (!strcmp(name, "CONFIG")) {
450 kumaneko 2958 i = CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
451     + CCS_MAX_MAC_CATEGORY_INDEX;
452     config = profile->default_config;
453 kumaneko 3758 } else if (ccs_str_starts(&name, "CONFIG::")) {
454 kumaneko 2958 config = 0;
455 kumaneko 2943 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
456     + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
457 kumaneko 3758 if (strcmp(name, ccs_mac_keywords[i]))
458 kumaneko 2943 continue;
459 kumaneko 2958 config = profile->config[i];
460 kumaneko 2943 break;
461     }
462 kumaneko 2958 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
463     + CCS_MAX_MAC_CATEGORY_INDEX)
464     return -EINVAL;
465     } else {
466     return -EINVAL;
467     }
468 kumaneko 3870 if (strstr(value, "use_default")) {
469 kumaneko 2958 config = CCS_CONFIG_USE_DEFAULT;
470     } else {
471 kumaneko 3747 u8 mode;
472 kumaneko 3758 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
473     if (strstr(value, ccs_mode[mode]))
474 kumaneko 2958 /*
475     * Update lower 3 bits in order to distinguish
476     * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
477     */
478     config = (config & ~7) | mode;
479 kumaneko 3870 if (config != CCS_CONFIG_USE_DEFAULT) {
480     switch (ccs_find_yesno(value, "verbose")) {
481     case 1:
482     config |= CCS_CONFIG_VERBOSE;
483     break;
484     case 0:
485     config &= ~CCS_CONFIG_VERBOSE;
486     break;
487     }
488 kumaneko 2959 #ifdef CONFIG_CCSECURITY_AUDIT
489 kumaneko 3758 switch (ccs_find_yesno(value, "grant_log")) {
490 kumaneko 3747 case 1:
491 kumaneko 2958 config |= CCS_CONFIG_WANT_GRANT_LOG;
492 kumaneko 3747 break;
493     case 0:
494 kumaneko 2958 config &= ~CCS_CONFIG_WANT_GRANT_LOG;
495 kumaneko 3747 break;
496     }
497 kumaneko 3758 switch (ccs_find_yesno(value, "reject_log")) {
498 kumaneko 3747 case 1:
499 kumaneko 2958 config |= CCS_CONFIG_WANT_REJECT_LOG;
500 kumaneko 3747 break;
501     case 0:
502 kumaneko 2958 config &= ~CCS_CONFIG_WANT_REJECT_LOG;
503 kumaneko 3747 break;
504     }
505 kumaneko 3870 #endif
506 kumaneko 2958 }
507     }
508     if (i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
509     + CCS_MAX_MAC_CATEGORY_INDEX)
510     profile->config[i] = config;
511     else if (config != CCS_CONFIG_USE_DEFAULT)
512     profile->default_config = config;
513 kumaneko 2943 return 0;
514 kumaneko 2863 }
515    
516 kumaneko 3747 /**
517     * ccs_write_profile - Write profile table.
518     *
519     * @head: Pointer to "struct ccs_io_buffer".
520     *
521     * Returns 0 on success, negative value otherwise.
522     */
523     static int ccs_write_profile(struct ccs_io_buffer *head)
524     {
525     char *data = head->write_buf;
526 kumaneko 3781 unsigned int i;
527 kumaneko 3747 char *cp;
528     struct ccs_profile *profile;
529     if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
530     return 0;
531     i = simple_strtoul(data, &cp, 10);
532 kumaneko 3870 if (*cp != '-')
533     return -EINVAL;
534     data = cp + 1;
535     profile = ccs_assign_profile(i);
536     if (!profile)
537     return -EINVAL;
538 kumaneko 3747 cp = strchr(data, '=');
539     if (!cp)
540     return -EINVAL;
541     *cp++ = '\0';
542     if (ccs_str_starts(&data, "PREFERENCE::")) {
543 kumaneko 3870 ccs_set_pref(data, cp, profile);
544 kumaneko 3747 return 0;
545     }
546     if (!strcmp(data, "COMMENT")) {
547     const struct ccs_path_info *old_comment = profile->comment;
548     profile->comment = ccs_get_name(cp);
549     ccs_put_name(old_comment);
550     return 0;
551     }
552 kumaneko 3870 return ccs_set_mode(data, cp, profile);
553 kumaneko 3747 }
554    
555 kumaneko 3870 static void ccs_print_preference(struct ccs_io_buffer *head, const int index)
556 kumaneko 3691 {
557 kumaneko 3870 struct ccs_profile *profile = ccs_profile_ptr[index];
558     struct ccs_preference *pref = &profile->preference;
559     ccs_io_printf(head, "%u-PREFERENCE::%s={ "
560 kumaneko 3691 #ifdef CONFIG_CCSECURITY_AUDIT
561 kumaneko 3780 "max_grant_log=%u max_reject_log=%u "
562 kumaneko 3691 #endif
563 kumaneko 3870 "task_info=%s path_info=%s }\n", index,
564 kumaneko 3780 "audit",
565 kumaneko 3691 #ifdef CONFIG_CCSECURITY_AUDIT
566 kumaneko 3780 pref->audit_max_grant_log,
567     pref->audit_max_reject_log,
568 kumaneko 3691 #endif
569 kumaneko 3780 ccs_yesno(pref->audit_task_info),
570     ccs_yesno(pref->audit_path_info));
571 kumaneko 3870 ccs_io_printf(head, "%u-PREFERENCE::%s={ "
572     "max_entry=%u exec.realpath=%s "
573 kumaneko 3780 "exec.argv0=%s symlink.target=%s }\n",
574 kumaneko 3870 index, "learning",
575 kumaneko 3780 pref->learning_max_entry,
576     ccs_yesno(pref->learning_exec_realpath),
577     ccs_yesno(pref->learning_exec_argv0),
578     ccs_yesno(pref->learning_symlink_target));
579 kumaneko 3870 ccs_io_printf(head, "%u-PREFERENCE::%s={ penalty=%u }\n", index,
580     "enforcing", pref->enforcing_penalty);
581 kumaneko 3691 }
582    
583 kumaneko 3780 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)
584     {
585 kumaneko 3870 ccs_io_printf(head, "={ mode=%s verbose=%s", ccs_mode[config & 3],
586     ccs_yesno(config & CCS_CONFIG_VERBOSE));
587 kumaneko 3780 #ifdef CONFIG_CCSECURITY_AUDIT
588     ccs_io_printf(head, " grant_log=%s reject_log=%s",
589     ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
590     ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));
591     #endif
592     ccs_set_string(head, " }\n");
593     }
594    
595 kumaneko 2863 /**
596     * ccs_read_profile - Read profile table.
597     *
598     * @head: Pointer to "struct ccs_io_buffer".
599     */
600 kumaneko 2943 static void ccs_read_profile(struct ccs_io_buffer *head)
601 kumaneko 2863 {
602 kumaneko 3780 u8 index;
603     const struct ccs_profile *profile;
604     next:
605     index = head->r.index;
606     profile = ccs_profile_ptr[index];
607     switch (head->r.step) {
608     case 0:
609 kumaneko 3945 ccs_io_printf(head, "PROFILE_VERSION=%s\n", "20100903");
610 kumaneko 3780 head->r.step++;
611     break;
612     case 1:
613     for ( ; head->r.index < CCS_MAX_PROFILES;
614     head->r.index++)
615     if (ccs_profile_ptr[head->r.index])
616     break;
617     if (head->r.index == CCS_MAX_PROFILES)
618     return;
619     head->r.step++;
620     break;
621     case 2:
622     {
623     const struct ccs_path_info *comment = profile->comment;
624     ccs_io_printf(head, "%u-COMMENT=", index);
625     ccs_set_string(head, comment ? comment->name : "");
626     ccs_set_lf(head);
627     head->r.step++;
628     }
629     break;
630     case 3:
631     {
632     ccs_io_printf(head, "%u-%s", index, "CONFIG");
633     ccs_print_config(head, profile->default_config);
634     head->r.bit = 0;
635     head->r.step++;
636     }
637     break;
638     case 4:
639     for ( ; head->r.bit < CCS_MAX_MAC_INDEX
640     + CCS_MAX_CAPABILITY_INDEX
641     + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
642     const u8 i = head->r.bit;
643     const u8 config = profile->config[i];
644 kumaneko 2958 if (config == CCS_CONFIG_USE_DEFAULT)
645     continue;
646 kumaneko 3780 ccs_io_printf(head, "%u-%s%s", index, "CONFIG::",
647     ccs_mac_keywords[i]);
648     ccs_print_config(head, config);
649     head->r.bit++;
650     break;
651 kumaneko 2908 }
652 kumaneko 3780 if (head->r.bit == CCS_MAX_MAC_INDEX
653     + CCS_MAX_CAPABILITY_INDEX
654     + CCS_MAX_MAC_CATEGORY_INDEX) {
655     ccs_print_preference(head, index);
656     head->r.index++;
657     head->r.step = 1;
658     }
659 kumaneko 2958 break;
660 kumaneko 2863 }
661 kumaneko 3780 if (ccs_flush(head))
662     goto next;
663 kumaneko 2863 }
664    
665 kumaneko 3781 static bool ccs_same_manager(const struct ccs_acl_head *a,
666     const struct ccs_acl_head *b)
667 kumaneko 3689 {
668 kumaneko 3693 return container_of(a, struct ccs_manager, head)->manager
669     == container_of(b, struct ccs_manager, head)->manager;
670 kumaneko 3689 }
671 kumaneko 2863
672     /**
673     * ccs_update_manager_entry - Add a manager entry.
674     *
675     * @manager: The path to manager or the domainnamme.
676     * @is_delete: True if it is a delete request.
677     *
678     * Returns 0 on success, negative value otherwise.
679     */
680     static int ccs_update_manager_entry(const char *manager, const bool is_delete)
681     {
682 kumaneko 3693 struct ccs_manager e = { };
683 kumaneko 2863 int error = is_delete ? -ENOENT : -ENOMEM;
684 kumaneko 3693 if (ccs_domain_def(manager)) {
685     if (!ccs_correct_domain(manager))
686 kumaneko 2863 return -EINVAL;
687 kumaneko 2900 e.is_domain = true;
688 kumaneko 2863 } else {
689 kumaneko 3707 if (!ccs_correct_path(manager))
690 kumaneko 2863 return -EINVAL;
691     }
692 kumaneko 2900 e.manager = ccs_get_name(manager);
693     if (!e.manager)
694 kumaneko 3689 return error;
695     error = ccs_update_policy(&e.head, sizeof(e), is_delete,
696 kumaneko 3754 &ccs_policy_list[CCS_ID_MANAGER],
697 kumaneko 3781 ccs_same_manager);
698 kumaneko 2900 ccs_put_name(e.manager);
699 kumaneko 2863 return error;
700     }
701    
702     /**
703 kumaneko 3693 * ccs_write_manager - Write manager policy.
704 kumaneko 2863 *
705     * @head: Pointer to "struct ccs_io_buffer".
706     *
707     * Returns 0 on success, negative value otherwise.
708     */
709 kumaneko 3693 static int ccs_write_manager(struct ccs_io_buffer *head)
710 kumaneko 2863 {
711     char *data = head->write_buf;
712 kumaneko 2892 bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
713 kumaneko 2863 if (!strcmp(data, "manage_by_non_root")) {
714     ccs_manage_by_non_root = !is_delete;
715     return 0;
716     }
717     return ccs_update_manager_entry(data, is_delete);
718     }
719    
720     /**
721 kumaneko 3693 * ccs_read_manager - Read manager policy.
722 kumaneko 2863 *
723     * @head: Pointer to "struct ccs_io_buffer".
724     *
725     * Caller holds ccs_read_lock().
726     */
727 kumaneko 3693 static void ccs_read_manager(struct ccs_io_buffer *head)
728 kumaneko 2863 {
729 kumaneko 3780 if (head->r.eof)
730 kumaneko 2943 return;
731 kumaneko 3780 list_for_each_cookie(head->r.acl, &ccs_policy_list[CCS_ID_MANAGER]) {
732     struct ccs_manager *ptr =
733     list_entry(head->r.acl, typeof(*ptr), head.list);
734 kumaneko 3689 if (ptr->head.is_deleted)
735 kumaneko 2863 continue;
736 kumaneko 3780 if (!ccs_flush(head))
737 kumaneko 2943 return;
738 kumaneko 3780 ccs_set_string(head, ptr->manager->name);
739     ccs_set_lf(head);
740 kumaneko 2863 }
741 kumaneko 3780 head->r.eof = true;
742 kumaneko 2863 }
743    
744     /**
745 kumaneko 3693 * ccs_manager - Check whether the current process is a policy manager.
746 kumaneko 2863 *
747     * Returns true if the current process is permitted to modify policy
748     * via /proc/ccs/ interface.
749     *
750     * Caller holds ccs_read_lock().
751     */
752 kumaneko 3693 static bool ccs_manager(void)
753 kumaneko 2863 {
754 kumaneko 3693 struct ccs_manager *ptr;
755 kumaneko 2863 const char *exe;
756     struct task_struct *task = current;
757     const struct ccs_path_info *domainname
758     = ccs_current_domain()->domainname;
759     bool found = false;
760     if (!ccs_policy_loaded)
761     return true;
762 kumaneko 3693 if (task->ccs_flags & CCS_TASK_IS_MANAGER)
763 kumaneko 2863 return true;
764     if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
765     return false;
766     exe = ccs_get_exe();
767 kumaneko 3689 list_for_each_entry_rcu(ptr, &ccs_policy_list[CCS_ID_MANAGER],
768     head.list) {
769 kumaneko 3697 if (ptr->head.is_deleted)
770     continue;
771     if (ptr->is_domain) {
772     if (ccs_pathcmp(domainname, ptr->manager))
773     continue;
774     } else {
775     if (!exe || strcmp(exe, ptr->manager->name))
776     continue;
777 kumaneko 2863 }
778 kumaneko 3697 /* Set manager flag. */
779     task->ccs_flags |= CCS_TASK_IS_MANAGER;
780     found = true;
781     break;
782 kumaneko 2863 }
783     if (!found) { /* Reduce error messages. */
784     static pid_t ccs_last_pid;
785     const pid_t pid = current->pid;
786     if (ccs_last_pid != pid) {
787     printk(KERN_WARNING "%s ( %s ) is not permitted to "
788     "update policies.\n", domainname->name, exe);
789     ccs_last_pid = pid;
790     }
791     }
792     kfree(exe);
793     return found;
794     }
795    
796     /**
797     * ccs_find_condition_part - Find condition part from the statement.
798     *
799     * @data: String to parse.
800     *
801     * Returns pointer to the condition part if it was found in the statement,
802     * NULL otherwise.
803     */
804 kumaneko 3697 static char *ccs_find_condition_part(char *data)
805 kumaneko 2863 {
806     char *cp = strstr(data, " if ");
807 kumaneko 3924 if (cp) {
808     while (1) {
809     char *cp2 = strstr(cp + 3, " if ");
810     if (!cp2)
811     break;
812     cp = cp2;
813     }
814     *cp = '\0';
815     cp += 4;
816     }
817 kumaneko 2863 return cp;
818     }
819    
820     /**
821 kumaneko 3693 * ccs_select_one - Parse select command.
822 kumaneko 2863 *
823     * @head: Pointer to "struct ccs_io_buffer".
824     * @data: String to parse.
825     *
826     * Returns true on success, false otherwise.
827     *
828     * Caller holds ccs_read_lock().
829     */
830 kumaneko 3693 static bool ccs_select_one(struct ccs_io_buffer *head, const char *data)
831 kumaneko 2863 {
832     unsigned int pid;
833     struct ccs_domain_info *domain = NULL;
834 kumaneko 2970 bool global_pid = false;
835 kumaneko 3808 if (!strcmp(data, "execute")) {
836 kumaneko 3780 head->r.print_execute_only = true;
837 kumaneko 2863 return true;
838     }
839 kumaneko 2970 if (sscanf(data, "pid=%u", &pid) == 1 ||
840     (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
841 kumaneko 2863 struct task_struct *p;
842 kumaneko 3248 ccs_tasklist_lock();
843 kumaneko 2970 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
844     if (global_pid)
845 kumaneko 3502 p = ccsecurity_exports.find_task_by_pid_ns(pid,
846     &init_pid_ns);
847 kumaneko 2970 else
848 kumaneko 3502 p = ccsecurity_exports.find_task_by_vpid(pid);
849 kumaneko 2970 #else
850 kumaneko 2863 p = find_task_by_pid(pid);
851 kumaneko 2970 #endif
852 kumaneko 2863 if (p)
853     domain = ccs_task_domain(p);
854 kumaneko 3248 ccs_tasklist_unlock();
855 kumaneko 2863 } else if (!strncmp(data, "domain=", 7)) {
856 kumaneko 3693 if (ccs_domain_def(data + 7))
857 kumaneko 2863 domain = ccs_find_domain(data + 7);
858     } else
859     return false;
860 kumaneko 3780 head->w.domain = domain;
861 kumaneko 2863 /* Accessing read_buf is safe because head->io_sem is held. */
862     if (!head->read_buf)
863     return true; /* Do nothing if open(O_WRONLY). */
864 kumaneko 3780 memset(&head->r, 0, sizeof(head->r));
865     head->r.print_this_domain_only = true;
866 kumaneko 3892 if (domain)
867     head->r.domain = &domain->list;
868     else
869     head->r.eof = true;
870 kumaneko 2863 ccs_io_printf(head, "# select %s\n", data);
871 kumaneko 3772 if (domain && domain->is_deleted)
872 kumaneko 3780 ccs_set_string(head, "# This is a deleted domain.\n");
873 kumaneko 2863 return true;
874     }
875    
876 kumaneko 3924 static bool ccs_same_handler_acl(const struct ccs_acl_info *a,
877     const struct ccs_acl_info *b)
878     {
879     const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head);
880     const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head);
881 kumaneko 3949 return p1->handler == p2->handler;
882 kumaneko 3924 }
883    
884     static bool ccs_same_task_acl(const struct ccs_acl_info *a,
885     const struct ccs_acl_info *b)
886     {
887     const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head);
888     const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head);
889 kumaneko 3949 return p1->domainname == p2->domainname;
890 kumaneko 3924 }
891    
892     /**
893     * ccs_write_task - Update task related list.
894     *
895 kumaneko 3949 * @data: String to parse.
896     * @param: Pointer to "struct ccs_acl_param".
897 kumaneko 3924 *
898     * Returns 0 on success, negative value otherwise.
899     */
900 kumaneko 3949 static int ccs_write_task(char *data, struct ccs_acl_param *param)
901 kumaneko 3924 {
902     int error;
903     const bool is_auto = ccs_str_starts(&data, "auto_domain_transition ");
904     if (!is_auto && !ccs_str_starts(&data, "manual_domain_transition ")) {
905 kumaneko 3949 struct ccs_handler_acl e = { };
906 kumaneko 3924 if (ccs_str_starts(&data, "auto_execute_handler "))
907     e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
908     else if (ccs_str_starts(&data, "denied_execute_handler "))
909     e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
910     else
911     return -EINVAL;
912     if (!ccs_correct_path(data))
913     return -EINVAL;
914     e.handler = ccs_get_name(data);
915     if (!e.handler)
916     return -ENOMEM;
917     if (e.handler->is_patterned)
918     error = -EINVAL; /* No patterns allowed. */
919     else
920 kumaneko 3949 error = ccs_update_domain(&e.head, sizeof(e), param,
921 kumaneko 3924 ccs_same_handler_acl, NULL);
922     ccs_put_name(e.handler);
923     } else {
924     struct ccs_task_acl e = {
925     .head.type = is_auto ?
926 kumaneko 3949 CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL
927 kumaneko 3924 };
928     if (!ccs_correct_domain(data))
929     return -EINVAL;
930     e.domainname = ccs_get_name(data);
931     if (!e.domainname)
932     return -ENOMEM;
933 kumaneko 3949 error = ccs_update_domain(&e.head, sizeof(e), param,
934     ccs_same_task_acl, NULL);
935 kumaneko 3924 ccs_put_name(e.domainname);
936     }
937     return error;
938     }
939    
940 kumaneko 3693 static int ccs_write_domain2(char *data, struct ccs_domain_info *domain,
941 kumaneko 3746 const bool is_delete)
942 kumaneko 2897 {
943 kumaneko 3949 struct ccs_acl_param param = {
944     .domain = domain,
945     .is_delete = is_delete,
946     };
947 kumaneko 3692 static const struct {
948     const char *keyword;
949 kumaneko 3949 int (*write) (char *, struct ccs_acl_param *);
950 kumaneko 3924 } ccs_callback[7] = {
951     { "file ", ccs_write_file },
952 kumaneko 3911 { "network inet ", ccs_write_inet_network },
953     { "network unix ", ccs_write_unix_network },
954 kumaneko 3808 { "misc ", ccs_write_misc },
955     { "capability ", ccs_write_capability },
956     { "ipc ", ccs_write_ipc },
957 kumaneko 3924 { "task ", ccs_write_task },
958 kumaneko 3692 };
959 kumaneko 3924 int error = -EINVAL;
960 kumaneko 3746 u8 i;
961     char *cp = ccs_find_condition_part(data);
962     if (cp) {
963 kumaneko 3949 param.condition = ccs_get_condition(cp);
964     if (!param.condition)
965 kumaneko 3746 return -EINVAL;
966     }
967 kumaneko 3924 for (i = 0; i < 7; i++) {
968 kumaneko 3692 if (!ccs_str_starts(&data, ccs_callback[i].keyword))
969     continue;
970 kumaneko 3949 error = ccs_callback[i].write(data, &param);
971 kumaneko 3692 break;
972     }
973 kumaneko 3949 if (param.condition)
974     ccs_put_condition(param.condition);
975 kumaneko 3746 return error;
976 kumaneko 2897 }
977    
978 kumaneko 3747 static const char *ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
979     [CCS_DIF_QUOTA_WARNED] = CCS_KEYWORD_QUOTA_EXCEEDED "\n",
980     [CCS_DIF_TRANSITION_FAILED] = CCS_KEYWORD_TRANSITION_FAILED "\n"
981     };
982    
983 kumaneko 2863 /**
984 kumaneko 3693 * ccs_write_domain - Write domain policy.
985 kumaneko 2863 *
986     * @head: Pointer to "struct ccs_io_buffer".
987     *
988     * Returns 0 on success, negative value otherwise.
989     */
990 kumaneko 3693 static int ccs_write_domain(struct ccs_io_buffer *head)
991 kumaneko 2863 {
992     char *data = head->write_buf;
993 kumaneko 3780 struct ccs_domain_info *domain = head->w.domain;
994 kumaneko 2863 bool is_delete = false;
995     bool is_select = false;
996     unsigned int profile;
997 kumaneko 2892 if (ccs_str_starts(&data, CCS_KEYWORD_DELETE))
998 kumaneko 2863 is_delete = true;
999 kumaneko 2892 else if (ccs_str_starts(&data, CCS_KEYWORD_SELECT))
1000 kumaneko 2863 is_select = true;
1001 kumaneko 3693 if (is_select && ccs_select_one(head, data))
1002 kumaneko 2863 return 0;
1003     /* Don't allow updating policies by non manager programs. */
1004 kumaneko 3693 if (!ccs_manager())
1005 kumaneko 2863 return -EPERM;
1006 kumaneko 3693 if (ccs_domain_def(data)) {
1007 kumaneko 2863 domain = NULL;
1008     if (is_delete)
1009     ccs_delete_domain(data);
1010     else if (is_select)
1011     domain = ccs_find_domain(data);
1012     else
1013 kumaneko 3905 domain = ccs_assign_domain(data, 0, 0, false);
1014 kumaneko 3780 head->w.domain = domain;
1015 kumaneko 2863 return 0;
1016     }
1017     if (!domain)
1018     return -EINVAL;
1019    
1020 kumaneko 2892 if (sscanf(data, CCS_KEYWORD_USE_PROFILE "%u", &profile) == 1
1021     && profile < CCS_MAX_PROFILES) {
1022 kumaneko 2991 if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])
1023 kumaneko 2863 domain->profile = (u8) profile;
1024     return 0;
1025     }
1026 kumaneko 3821 if (sscanf(data, CCS_KEYWORD_USE_GROUP "%u", &profile) == 1
1027     && profile < CCS_MAX_ACL_GROUPS) {
1028     domain->group = (u8) profile;
1029     return 0;
1030     }
1031 kumaneko 3747 for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
1032     const char *cp = ccs_dif[profile];
1033     if (strncmp(data, cp, strlen(cp) - 1))
1034     continue;
1035     domain->flags[profile] = !is_delete;
1036 kumaneko 3702 return 0;
1037     }
1038 kumaneko 3746 return ccs_write_domain2(data, domain, is_delete);
1039 kumaneko 2863 }
1040    
1041 kumaneko 2948 /**
1042     * ccs_print_name_union - Print a ccs_name_union.
1043     *
1044     * @head: Pointer to "struct ccs_io_buffer".
1045     * @ptr: Pointer to "struct ccs_name_union".
1046     */
1047 kumaneko 3780 static void ccs_print_name_union(struct ccs_io_buffer *head,
1048 kumaneko 2894 const struct ccs_name_union *ptr)
1049 kumaneko 2863 {
1050 kumaneko 3780 const bool cond = head->r.print_cond_part;
1051     if (!cond)
1052     ccs_set_space(head);
1053     if (ptr->is_group) {
1054     ccs_set_string(head, "@");
1055     ccs_set_string(head, ptr->group->group_name->name);
1056     } else {
1057     if (cond)
1058     ccs_set_string(head, "\"");
1059     ccs_set_string(head, ptr->filename->name);
1060     if (cond)
1061     ccs_set_string(head, "\"");
1062     }
1063 kumaneko 2863 }
1064    
1065 kumaneko 2948 /**
1066 kumaneko 3780 * ccs_print_number_union - Print a ccs_number_union.
1067 kumaneko 2948 *
1068     * @head: Pointer to "struct ccs_io_buffer".
1069 kumaneko 3780 * @ptr: Pointer to "struct ccs_number_union".
1070 kumaneko 2948 */
1071 kumaneko 3780 static void ccs_print_number_union(struct ccs_io_buffer *head,
1072     const struct ccs_number_union *ptr)
1073 kumaneko 2863 {
1074 kumaneko 3780 if (!head->r.print_cond_part)
1075     ccs_set_space(head);
1076     if (ptr->is_group) {
1077     ccs_set_string(head, "@");
1078     ccs_set_string(head, ptr->group->group_name->name);
1079     } else {
1080     int i;
1081     unsigned long min = ptr->values[0];
1082     const unsigned long max = ptr->values[1];
1083     u8 min_type = ptr->value_type[0];
1084     const u8 max_type = ptr->value_type[1];
1085     char buffer[128];
1086     buffer[0] = '\0';
1087     for (i = 0; i < 2; i++) {
1088     switch (min_type) {
1089     case CCS_VALUE_TYPE_HEXADECIMAL:
1090     ccs_addprintf(buffer, sizeof(buffer), "0x%lX",
1091     min);
1092     break;
1093     case CCS_VALUE_TYPE_OCTAL:
1094     ccs_addprintf(buffer, sizeof(buffer), "0%lo",
1095     min);
1096     break;
1097     default:
1098     ccs_addprintf(buffer, sizeof(buffer), "%lu",
1099     min);
1100     break;
1101     }
1102     if (min == max && min_type == max_type)
1103     break;
1104     ccs_addprintf(buffer, sizeof(buffer), "-");
1105     min_type = max_type;
1106     min = max;
1107 kumaneko 3690 }
1108 kumaneko 3780 ccs_io_printf(head, "%s", buffer);
1109 kumaneko 3690 }
1110     }
1111    
1112 kumaneko 2948 /**
1113 kumaneko 2894 * ccs_print_condition - Print condition part.
1114     *
1115     * @head: Pointer to "struct ccs_io_buffer".
1116 kumaneko 3780 * @cond: Pointer to "struct ccs_condition".
1117 kumaneko 2894 *
1118     * Returns true on success, false otherwise.
1119     */
1120     static bool ccs_print_condition(struct ccs_io_buffer *head,
1121     const struct ccs_condition *cond)
1122     {
1123 kumaneko 3780 switch (head->r.cond_step) {
1124     case 0:
1125     {
1126 kumaneko 3924 ccs_set_string(head, " if");
1127 kumaneko 3780 head->r.cond_index = 0;
1128     head->r.cond_step++;
1129     }
1130     /* fall through */
1131     case 1:
1132     {
1133     const u16 condc = cond->condc;
1134     const struct ccs_condition_element *condp =
1135     (typeof(condp)) (cond + 1);
1136     const struct ccs_number_union *numbers_p =
1137     (typeof(numbers_p)) (condp + condc);
1138     const struct ccs_name_union *names_p =
1139     (typeof(names_p))
1140     (numbers_p + cond->numbers_count);
1141     const struct ccs_argv *argv =
1142     (typeof(argv)) (names_p + cond->names_count);
1143     const struct ccs_envp *envp =
1144     (typeof(envp)) (argv + cond->argc);
1145     u16 skip;
1146     for (skip = 0; skip < head->r.cond_index; skip++) {
1147     const u8 left = condp->left;
1148     const u8 right = condp->right;
1149     condp++;
1150     switch (left) {
1151     case CCS_ARGV_ENTRY:
1152     argv++;
1153     continue;
1154     case CCS_ENVP_ENTRY:
1155     envp++;
1156     continue;
1157     case CCS_NUMBER_UNION:
1158     numbers_p++;
1159     break;
1160     }
1161     switch (right) {
1162     case CCS_NAME_UNION:
1163     names_p++;
1164     break;
1165     case CCS_NUMBER_UNION:
1166     numbers_p++;
1167     break;
1168     }
1169 kumaneko 2894 }
1170 kumaneko 3780 while (head->r.cond_index < condc) {
1171     const u8 match = condp->equals;
1172     const u8 left = condp->left;
1173     const u8 right = condp->right;
1174     if (!ccs_flush(head))
1175     return false;
1176     condp++;
1177     head->r.cond_index++;
1178     ccs_set_space(head);
1179     switch (left) {
1180     case CCS_ARGV_ENTRY:
1181     ccs_io_printf(head,
1182     "exec.argv[%u]%s\"%s\"",
1183     argv->index,
1184     argv->is_not ?
1185     "!=" : "=",
1186     argv->value->name);
1187     argv++;
1188     continue;
1189     case CCS_ENVP_ENTRY:
1190     ccs_io_printf(head,
1191     "exec.envp[\"%s\"]%s",
1192     envp->name->name,
1193     envp->is_not ?
1194     "!=" : "=");
1195     if (envp->value) {
1196     ccs_set_string(head, "\"");
1197     ccs_set_string(head, envp->
1198     value->name);
1199     ccs_set_string(head, "\"");
1200     } else {
1201     ccs_set_string(head, "NULL");
1202     }
1203     envp++;
1204     continue;
1205     case CCS_NUMBER_UNION:
1206     ccs_print_number_union(head,
1207     numbers_p++);
1208     break;
1209     default:
1210     ccs_set_string(head,
1211     ccs_condition_keyword[left]);
1212     break;
1213     }
1214     ccs_set_string(head, match ? "=" : "!=");
1215     switch (right) {
1216     case CCS_NAME_UNION:
1217     ccs_print_name_union(head, names_p++);
1218     break;
1219     case CCS_NUMBER_UNION:
1220     ccs_print_number_union(head,
1221     numbers_p++);
1222     break;
1223     default:
1224     ccs_set_string(head,
1225     ccs_condition_keyword[right]);
1226     break;
1227     }
1228     }
1229 kumaneko 2894 }
1230 kumaneko 3780 head->r.cond_step++;
1231     /* fall through */
1232     case 2:
1233     if (!ccs_flush(head))
1234 kumaneko 2894 break;
1235 kumaneko 3780 head->r.cond_step++;
1236     /* fall through */
1237     case 3:
1238 kumaneko 3924 if (cond->audit)
1239     ccs_io_printf(head, " audit=%s",
1240     ccs_yesno(cond->audit == 2));
1241     if (cond->transit) {
1242     ccs_set_string(head, " auto_domain_transitition=\"");
1243     ccs_set_string(head, cond->transit->name);
1244     ccs_set_string(head, "\"");
1245 kumaneko 2894 }
1246 kumaneko 3780 ccs_set_lf(head);
1247     return true;
1248 kumaneko 2894 }
1249     return false;
1250     }
1251    
1252 kumaneko 3872 /**
1253     * ccs_fns - Find next set bit.
1254     *
1255     * @perm: 8 bits value.
1256     * @bit: First bit to find.
1257     *
1258     * Returns next set bit on success, 8 otherwise.
1259     */
1260     static u8 ccs_fns(const u8 perm, u8 bit)
1261     {
1262     for ( ; bit < 8; bit++)
1263     if (perm & (1 << bit))
1264     break;
1265     return bit;
1266     }
1267    
1268 kumaneko 3821 static void ccs_set_group(struct ccs_io_buffer *head)
1269     {
1270     if (head->type == CCS_EXCEPTIONPOLICY)
1271     ccs_io_printf(head, "acl_group %u ", head->r.group_index);
1272     }
1273    
1274 kumaneko 3780 /**
1275 kumaneko 3772 * ccs_print_entry - Print an ACL entry.
1276 kumaneko 2863 *
1277     * @head: Pointer to "struct ccs_io_buffer".
1278 kumaneko 3780 * @acl: Pointer to an ACL entry.
1279 kumaneko 2863 *
1280     * Returns true on success, false otherwise.
1281     */
1282 kumaneko 3772 static bool ccs_print_entry(struct ccs_io_buffer *head,
1283     const struct ccs_acl_info *acl)
1284 kumaneko 2863 {
1285 kumaneko 3772 const u8 acl_type = acl->type;
1286 kumaneko 3872 u8 bit;
1287 kumaneko 3780 if (head->r.print_cond_part)
1288     goto print_cond_part;
1289 kumaneko 3772 if (acl->is_deleted)
1290     return true;
1291 kumaneko 3872 next:
1292     bit = head->r.bit;
1293 kumaneko 3780 if (!ccs_flush(head))
1294     return false;
1295     else if (acl_type == CCS_TYPE_PATH_ACL) {
1296 kumaneko 3772 struct ccs_path_acl *ptr
1297     = container_of(acl, typeof(*ptr), head);
1298 kumaneko 3872 const u16 perm = ptr->perm;
1299     for ( ; bit < CCS_MAX_PATH_OPERATION; bit++) {
1300     if (!(perm & (1 << bit)))
1301     continue;
1302     if (head->r.print_execute_only &&
1303 kumaneko 3924 bit != CCS_TYPE_EXECUTE
1304     /* && bit != CCS_TYPE_TRANSIT */)
1305 kumaneko 3872 continue;
1306     break;
1307     }
1308     if (bit >= CCS_MAX_PATH_OPERATION)
1309 kumaneko 3772 goto done;
1310 kumaneko 3872 ccs_set_group(head);
1311     ccs_set_string(head, "file ");
1312     ccs_set_string(head, ccs_path_keyword[bit]);
1313 kumaneko 3780 ccs_print_name_union(head, &ptr->name);
1314 kumaneko 3924 } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
1315 kumaneko 3772 acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
1316 kumaneko 3924 struct ccs_handler_acl *ptr
1317 kumaneko 3772 = container_of(acl, typeof(*ptr), head);
1318 kumaneko 3821 ccs_set_group(head);
1319 kumaneko 3924 ccs_set_string(head, "task ");
1320     ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
1321     ? "auto_execute_handler " :
1322     "denied_execute_handler ");
1323 kumaneko 3780 ccs_set_string(head, ptr->handler->name);
1324 kumaneko 3924 } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
1325     acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
1326     struct ccs_task_acl *ptr =
1327     container_of(acl, typeof(*ptr), head);
1328     ccs_set_group(head);
1329     ccs_set_string(head, "task ");
1330     ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ?
1331     "auto_domain_transition " :
1332     "manual_domain_transition ");
1333     ccs_set_string(head, ptr->domainname->name);
1334 kumaneko 3780 } else if (head->r.print_execute_only) {
1335 kumaneko 3772 return true;
1336     } else if (acl_type == CCS_TYPE_MKDEV_ACL) {
1337 kumaneko 3780 struct ccs_mkdev_acl *ptr =
1338     container_of(acl, typeof(*ptr), head);
1339 kumaneko 3872 bit = ccs_fns(ptr->perm, bit);
1340     if (bit >= CCS_MAX_MKDEV_OPERATION)
1341 kumaneko 3772 goto done;
1342 kumaneko 3872 ccs_set_group(head);
1343     ccs_set_string(head, "file ");
1344     ccs_set_string(head, ccs_mkdev_keyword[bit]);
1345 kumaneko 3780 ccs_print_name_union(head, &ptr->name);
1346     ccs_print_number_union(head, &ptr->mode);
1347     ccs_print_number_union(head, &ptr->major);
1348     ccs_print_number_union(head, &ptr->minor);
1349 kumaneko 3772 } else if (acl_type == CCS_TYPE_PATH2_ACL) {
1350 kumaneko 3780 struct ccs_path2_acl *ptr =
1351     container_of(acl, typeof(*ptr), head);
1352 kumaneko 3872 bit = ccs_fns(ptr->perm, bit);
1353     if (bit >= CCS_MAX_PATH2_OPERATION)
1354 kumaneko 3772 goto done;
1355 kumaneko 3872 ccs_set_group(head);
1356     ccs_set_string(head, "file ");
1357     ccs_set_string(head, ccs_path2_keyword[bit]);
1358 kumaneko 3780 ccs_print_name_union(head, &ptr->name1);
1359     ccs_print_name_union(head, &ptr->name2);
1360 kumaneko 3772 } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
1361 kumaneko 3780 struct ccs_path_number_acl *ptr =
1362     container_of(acl, typeof(*ptr), head);
1363 kumaneko 3872 bit = ccs_fns(ptr->perm, bit);
1364     if (bit >= CCS_MAX_PATH_NUMBER_OPERATION)
1365 kumaneko 3772 goto done;
1366 kumaneko 3872 ccs_set_group(head);
1367     ccs_set_string(head, "file ");
1368     ccs_set_string(head, ccs_path_number_keyword[bit]);
1369 kumaneko 3780 ccs_print_name_union(head, &ptr->name);
1370     ccs_print_number_union(head, &ptr->number);
1371 kumaneko 3772 } else if (acl_type == CCS_TYPE_ENV_ACL) {
1372 kumaneko 3780 struct ccs_env_acl *ptr =
1373     container_of(acl, typeof(*ptr), head);
1374 kumaneko 3821 ccs_set_group(head);
1375 kumaneko 3808 ccs_set_string(head, "misc env ");
1376 kumaneko 3780 ccs_set_string(head, ptr->env->name);
1377 kumaneko 3772 } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
1378 kumaneko 3780 struct ccs_capability_acl *ptr =
1379     container_of(acl, typeof(*ptr), head);
1380 kumaneko 3821 ccs_set_group(head);
1381 kumaneko 3808 ccs_set_string(head, "capability ");
1382 kumaneko 3780 ccs_set_string(head, ccs_cap2keyword(ptr->operation));
1383 kumaneko 3911 } else if (acl_type == CCS_TYPE_INET_ACL) {
1384     struct ccs_inet_acl *ptr =
1385 kumaneko 3780 container_of(acl, typeof(*ptr), head);
1386 kumaneko 3872 bit = ccs_fns(ptr->perm, bit);
1387     if (bit >= CCS_MAX_NETWORK_OPERATION)
1388 kumaneko 3772 goto done;
1389 kumaneko 3872 ccs_set_group(head);
1390 kumaneko 3911 ccs_set_string(head, "network inet ");
1391 kumaneko 3927 ccs_set_string(head, ccs_proto_keyword[ptr->protocol]);
1392 kumaneko 3843 ccs_set_space(head);
1393 kumaneko 3927 ccs_set_string(head, ccs_socket_keyword[bit]);
1394 kumaneko 3872 ccs_set_space(head);
1395 kumaneko 2916 switch (ptr->address_type) {
1396 kumaneko 3780 char buf[128];
1397 kumaneko 2916 case CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP:
1398 kumaneko 3780 ccs_set_string(head, "@");
1399     ccs_set_string(head,
1400     ptr->address.group->group_name->name);
1401 kumaneko 2916 break;
1402     case CCS_IP_ADDRESS_TYPE_IPv4:
1403 kumaneko 3690 ccs_print_ipv4(buf, sizeof(buf), ptr->address.ipv4.min,
1404     ptr->address.ipv4.max);
1405 kumaneko 3780 ccs_io_printf(head, "%s", buf);
1406 kumaneko 2916 break;
1407     case CCS_IP_ADDRESS_TYPE_IPv6:
1408 kumaneko 3690 ccs_print_ipv6(buf, sizeof(buf), ptr->address.ipv6.min,
1409     ptr->address.ipv6.max);
1410 kumaneko 3780 ccs_io_printf(head, "%s", buf);
1411 kumaneko 2916 break;
1412     }
1413 kumaneko 3780 ccs_print_number_union(head, &ptr->port);
1414 kumaneko 3911 } else if (acl_type == CCS_TYPE_UNIX_ACL) {
1415     struct ccs_unix_acl *ptr =
1416     container_of(acl, typeof(*ptr), head);
1417     bit = ccs_fns(ptr->perm, bit);
1418     if (bit >= CCS_MAX_NETWORK_OPERATION)
1419     goto done;
1420     ccs_set_group(head);
1421     ccs_set_string(head, "network unix ");
1422 kumaneko 3927 ccs_set_string(head, ccs_proto_keyword[ptr->protocol]);
1423 kumaneko 3911 ccs_set_space(head);
1424 kumaneko 3927 ccs_set_string(head, ccs_socket_keyword[bit]);
1425 kumaneko 3911 ccs_print_name_union(head, &ptr->name);
1426 kumaneko 3772 } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
1427 kumaneko 3780 struct ccs_signal_acl *ptr =
1428     container_of(acl, typeof(*ptr), head);
1429 kumaneko 3821 ccs_set_group(head);
1430 kumaneko 3808 ccs_set_string(head, "ipc signal ");
1431     ccs_io_printf(head, "%u ", ptr->sig);
1432 kumaneko 3780 ccs_set_string(head, ptr->domainname->name);
1433 kumaneko 3772 } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
1434 kumaneko 3780 struct ccs_mount_acl *ptr =
1435     container_of(acl, typeof(*ptr), head);
1436 kumaneko 3821 ccs_set_group(head);
1437 kumaneko 3808 ccs_io_printf(head, "file mount");
1438 kumaneko 3780 ccs_print_name_union(head, &ptr->dev_name);
1439     ccs_print_name_union(head, &ptr->dir_name);
1440     ccs_print_name_union(head, &ptr->fs_type);
1441     ccs_print_number_union(head, &ptr->flags);
1442 kumaneko 2863 }
1443 kumaneko 3872 head->r.bit = bit + 1;
1444 kumaneko 3780 if (acl->cond) {
1445     head->r.print_cond_part = true;
1446     head->r.cond_step = 0;
1447     if (!ccs_flush(head))
1448     return false;
1449     print_cond_part:
1450     if (!ccs_print_condition(head, acl->cond))
1451     return false;
1452     head->r.print_cond_part = false;
1453     } else {
1454     ccs_set_lf(head);
1455 kumaneko 2897 }
1456 kumaneko 3872 switch (acl_type) {
1457     case CCS_TYPE_PATH_ACL:
1458     case CCS_TYPE_MKDEV_ACL:
1459     case CCS_TYPE_PATH2_ACL:
1460     case CCS_TYPE_PATH_NUMBER_ACL:
1461 kumaneko 3911 case CCS_TYPE_INET_ACL:
1462     case CCS_TYPE_UNIX_ACL:
1463 kumaneko 3872 goto next;
1464     }
1465 kumaneko 3772 done:
1466 kumaneko 3872 head->r.bit = 0;
1467 kumaneko 3747 return true;
1468 kumaneko 2863 }
1469    
1470     /**
1471 kumaneko 3697 * ccs_read_domain2 - Read domain policy.
1472     *
1473     * @head: Pointer to "struct ccs_io_buffer".
1474     * @domain: Pointer to "struct ccs_domain_info".
1475 kumaneko 3924 * @index: Index number.
1476 kumaneko 3697 *
1477     * Caller holds ccs_read_lock().
1478     *
1479     * Returns true on success, false otherwise.
1480     */
1481     static bool ccs_read_domain2(struct ccs_io_buffer *head,
1482 kumaneko 3924 struct ccs_domain_info *domain,
1483     const u8 index)
1484 kumaneko 3697 {
1485 kumaneko 3924 list_for_each_cookie(head->r.acl, &domain->acl_info_list[index]) {
1486 kumaneko 3780 struct ccs_acl_info *ptr =
1487     list_entry(head->r.acl, typeof(*ptr), list);
1488 kumaneko 3697 if (!ccs_print_entry(head, ptr))
1489     return false;
1490     }
1491 kumaneko 3780 head->r.acl = NULL;
1492 kumaneko 3697 return true;
1493     }
1494    
1495     /**
1496 kumaneko 3693 * ccs_read_domain - Read domain policy.
1497 kumaneko 2863 *
1498     * @head: Pointer to "struct ccs_io_buffer".
1499     *
1500     * Caller holds ccs_read_lock().
1501     */
1502 kumaneko 3693 static void ccs_read_domain(struct ccs_io_buffer *head)
1503 kumaneko 2863 {
1504 kumaneko 3780 if (head->r.eof)
1505 kumaneko 2943 return;
1506 kumaneko 3780 list_for_each_cookie(head->r.domain, &ccs_domain_list) {
1507 kumaneko 3697 struct ccs_domain_info *domain =
1508 kumaneko 3780 list_entry(head->r.domain, typeof(*domain), list);
1509     switch (head->r.step) {
1510 kumaneko 3747 u8 i;
1511 kumaneko 3697 case 0:
1512 kumaneko 3780 if (domain->is_deleted &&
1513     !head->r.print_this_domain_only)
1514 kumaneko 3697 continue;
1515     /* Print domainname and flags. */
1516 kumaneko 3780 ccs_set_string(head, domain->domainname->name);
1517     ccs_set_lf(head);
1518     ccs_io_printf(head, CCS_KEYWORD_USE_PROFILE "%u\n",
1519     domain->profile);
1520 kumaneko 3821 ccs_io_printf(head, CCS_KEYWORD_USE_GROUP "%u\n",
1521     domain->group);
1522 kumaneko 3747 for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
1523 kumaneko 3780 if (domain->flags[i])
1524     ccs_set_string(head, ccs_dif[i]);
1525     head->r.step++;
1526     ccs_set_lf(head);
1527 kumaneko 3697 /* fall through */
1528     case 1:
1529 kumaneko 3924 if (!ccs_read_domain2(head, domain, 0))
1530 kumaneko 3697 return;
1531 kumaneko 3780 head->r.step++;
1532 kumaneko 3924 /* fall through */
1533     case 2:
1534     if (!ccs_read_domain2(head, domain, 1))
1535     return;
1536     head->r.step++;
1537 kumaneko 3780 if (!ccs_set_lf(head))
1538     return;
1539 kumaneko 3697 /* fall through */
1540 kumaneko 3924 case 3:
1541 kumaneko 3780 head->r.step = 0;
1542     if (head->r.print_this_domain_only)
1543     goto done;
1544 kumaneko 2863 }
1545     }
1546 kumaneko 3780 done:
1547     head->r.eof = true;
1548 kumaneko 2863 }
1549    
1550     /**
1551     * ccs_write_domain_profile - Assign profile for specified domain.
1552     *
1553     * @head: Pointer to "struct ccs_io_buffer".
1554     *
1555     * Returns 0 on success, -EINVAL otherwise.
1556     *
1557     * This is equivalent to doing
1558     *
1559     * ( echo "select " $domainname; echo "use_profile " $profile ) |
1560 kumaneko 2948 * /usr/sbin/ccs-loadpolicy -d
1561 kumaneko 2863 *
1562     * Caller holds ccs_read_lock().
1563     */
1564     static int ccs_write_domain_profile(struct ccs_io_buffer *head)
1565     {
1566     char *data = head->write_buf;
1567     char *cp = strchr(data, ' ');
1568     struct ccs_domain_info *domain;
1569     unsigned int profile;
1570     if (!cp)
1571     return -EINVAL;
1572     *cp = '\0';
1573     profile = simple_strtoul(data, NULL, 10);
1574 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
1575 kumaneko 2863 return -EINVAL;
1576     domain = ccs_find_domain(cp + 1);
1577 kumaneko 2991 if (domain && (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile]))
1578 kumaneko 2863 domain->profile = (u8) profile;
1579     return 0;
1580     }
1581    
1582     /**
1583     * ccs_read_domain_profile - Read only domainname and profile.
1584     *
1585     * @head: Pointer to "struct ccs_io_buffer".
1586     *
1587     * This is equivalent to doing
1588     *
1589     * grep -A 1 '^<kernel>' /proc/ccs/domain_policy |
1590     * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1591     * domainname = $0; } else if ( $1 == "use_profile" ) {
1592     * print $2 " " domainname; domainname = ""; } } ; '
1593     *
1594     * Caller holds ccs_read_lock().
1595     */
1596 kumaneko 2943 static void ccs_read_domain_profile(struct ccs_io_buffer *head)
1597 kumaneko 2863 {
1598 kumaneko 3780 if (head->r.eof)
1599 kumaneko 2943 return;
1600 kumaneko 3780 list_for_each_cookie(head->r.domain, &ccs_domain_list) {
1601     struct ccs_domain_info *domain =
1602     list_entry(head->r.domain, typeof(*domain), list);
1603 kumaneko 2863 if (domain->is_deleted)
1604     continue;
1605 kumaneko 3780 if (!ccs_flush(head))
1606 kumaneko 2943 return;
1607 kumaneko 3780 ccs_io_printf(head, "%u ", domain->profile);
1608     ccs_set_string(head, domain->domainname->name);
1609     ccs_set_lf(head);
1610 kumaneko 2863 }
1611 kumaneko 3780 head->r.eof = true;
1612 kumaneko 2863 }
1613    
1614     /**
1615     * ccs_write_pid: Specify PID to obtain domainname.
1616     *
1617     * @head: Pointer to "struct ccs_io_buffer".
1618     *
1619     * Returns 0.
1620     */
1621     static int ccs_write_pid(struct ccs_io_buffer *head)
1622     {
1623 kumaneko 3780 head->r.eof = false;
1624 kumaneko 2863 return 0;
1625     }
1626    
1627     /**
1628     * ccs_read_pid - Read information of a process.
1629     *
1630     * @head: Pointer to "struct ccs_io_buffer".
1631     *
1632     * Returns the domainname which the specified PID is in or
1633     * process information of the specified PID on success,
1634     * empty string otherwise.
1635     *
1636     * Caller holds ccs_read_lock().
1637     */
1638 kumaneko 2943 static void ccs_read_pid(struct ccs_io_buffer *head)
1639 kumaneko 2863 {
1640     char *buf = head->write_buf;
1641     bool task_info = false;
1642 kumaneko 2970 bool global_pid = false;
1643 kumaneko 2863 unsigned int pid;
1644     struct task_struct *p;
1645     struct ccs_domain_info *domain = NULL;
1646     u32 ccs_flags = 0;
1647     /* Accessing write_buf is safe because head->io_sem is held. */
1648 kumaneko 3136 if (!buf) {
1649 kumaneko 3780 head->r.eof = true;
1650 kumaneko 2943 return; /* Do nothing if open(O_RDONLY). */
1651 kumaneko 3136 }
1652 kumaneko 3780 if (head->r.w_pos || head->r.eof)
1653 kumaneko 2943 return;
1654 kumaneko 3780 head->r.eof = true;
1655 kumaneko 2863 if (ccs_str_starts(&buf, "info "))
1656     task_info = true;
1657 kumaneko 2970 if (ccs_str_starts(&buf, "global-pid "))
1658     global_pid = true;
1659 kumaneko 2863 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1660 kumaneko 3248 ccs_tasklist_lock();
1661 kumaneko 2970 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1662     if (global_pid)
1663 kumaneko 3502 p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns);
1664 kumaneko 2970 else
1665 kumaneko 3502 p = ccsecurity_exports.find_task_by_vpid(pid);
1666 kumaneko 2970 #else
1667 kumaneko 2863 p = find_task_by_pid(pid);
1668 kumaneko 2970 #endif
1669 kumaneko 2863 if (p) {
1670     domain = ccs_task_domain(p);
1671     ccs_flags = p->ccs_flags;
1672     }
1673 kumaneko 3248 ccs_tasklist_unlock();
1674 kumaneko 2863 if (!domain)
1675 kumaneko 2943 return;
1676 kumaneko 3780 if (!task_info) {
1677     ccs_io_printf(head, "%u %u ", pid, domain->profile);
1678     ccs_set_string(head, domain->domainname->name);
1679     } else {
1680 kumaneko 3924 ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid,
1681 kumaneko 2958 ccs_yesno(ccs_flags &
1682 kumaneko 3693 CCS_TASK_IS_MANAGER),
1683 kumaneko 2958 ccs_yesno(ccs_flags &
1684 kumaneko 3924 CCS_TASK_IS_EXECUTE_HANDLER));
1685 kumaneko 3780 }
1686 kumaneko 2863 }
1687    
1688 kumaneko 3752 static const char *ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
1689     [CCS_TRANSITION_CONTROL_NO_INITIALIZE]
1690     = CCS_KEYWORD_NO_INITIALIZE_DOMAIN,
1691 kumaneko 3754 [CCS_TRANSITION_CONTROL_INITIALIZE] = CCS_KEYWORD_INITIALIZE_DOMAIN,
1692     [CCS_TRANSITION_CONTROL_NO_KEEP] = CCS_KEYWORD_NO_KEEP_DOMAIN,
1693     [CCS_TRANSITION_CONTROL_KEEP] = CCS_KEYWORD_KEEP_DOMAIN
1694 kumaneko 3752 };
1695    
1696     static const char *ccs_group_name[CCS_MAX_GROUP] = {
1697     [CCS_PATH_GROUP] = CCS_KEYWORD_PATH_GROUP,
1698     [CCS_NUMBER_GROUP] = CCS_KEYWORD_NUMBER_GROUP,
1699     [CCS_ADDRESS_GROUP] = CCS_KEYWORD_ADDRESS_GROUP
1700     };
1701    
1702 kumaneko 2863 /**
1703 kumaneko 3693 * ccs_write_exception - Write exception policy.
1704 kumaneko 2863 *
1705     * @head: Pointer to "struct ccs_io_buffer".
1706     *
1707     * Returns 0 on success, negative value otherwise.
1708     */
1709 kumaneko 3693 static int ccs_write_exception(struct ccs_io_buffer *head)
1710 kumaneko 2863 {
1711     char *data = head->write_buf;
1712 kumaneko 3691 const bool is_delete = ccs_str_starts(&data, CCS_KEYWORD_DELETE);
1713     u8 i;
1714     static const struct {
1715     const char *keyword;
1716 kumaneko 3752 int (*write) (char *, const bool);
1717 kumaneko 3808 } ccs_callback[3] = {
1718 kumaneko 3693 { CCS_KEYWORD_AGGREGATOR, ccs_write_aggregator },
1719     { CCS_KEYWORD_FILE_PATTERN, ccs_write_pattern },
1720     { CCS_KEYWORD_DENY_AUTOBIND, ccs_write_reserved_port }
1721 kumaneko 3691 };
1722 kumaneko 3808 for (i = 0; i < 3; i++)
1723 kumaneko 3691 if (ccs_str_starts(&data, ccs_callback[i].keyword))
1724 kumaneko 3752 return ccs_callback[i].write(data, is_delete);
1725 kumaneko 3781 for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
1726 kumaneko 3752 if (ccs_str_starts(&data, ccs_transition_type[i]))
1727     return ccs_write_transition_control(data, is_delete,
1728     i);
1729 kumaneko 3781 for (i = 0; i < CCS_MAX_GROUP; i++)
1730 kumaneko 3752 if (ccs_str_starts(&data, ccs_group_name[i]))
1731 kumaneko 3693 return ccs_write_group(data, is_delete, i);
1732 kumaneko 3821 if (ccs_str_starts(&data, "acl_group ")) {
1733     unsigned int group;
1734     if (sscanf(data, "%u", &group) == 1 &&
1735     group < CCS_MAX_ACL_GROUPS) {
1736     data = strchr(data, ' ');
1737     if (data)
1738     return ccs_write_domain2(data + 1,
1739     &ccs_acl_group[group],
1740     is_delete);
1741     }
1742     }
1743     return -EINVAL;
1744 kumaneko 2863 }
1745    
1746     /**
1747 kumaneko 3689 * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
1748 kumaneko 2863 *
1749     * @head: Pointer to "struct ccs_io_buffer".
1750 kumaneko 3689 * @idx: Index number.
1751 kumaneko 2863 *
1752 kumaneko 3689 * Returns true on success, false otherwise.
1753     *
1754 kumaneko 2863 * Caller holds ccs_read_lock().
1755     */
1756 kumaneko 3689 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
1757 kumaneko 2863 {
1758 kumaneko 3780 list_for_each_cookie(head->r.group, &ccs_group_list[idx]) {
1759 kumaneko 3689 struct ccs_group *group =
1760 kumaneko 3780 list_entry(head->r.group, typeof(*group), head.list);
1761     list_for_each_cookie(head->r.acl, &group->member_list) {
1762 kumaneko 3689 struct ccs_acl_head *ptr =
1763 kumaneko 3780 list_entry(head->r.acl, typeof(*ptr), list);
1764 kumaneko 3689 if (ptr->is_deleted)
1765     continue;
1766 kumaneko 3780 if (!ccs_flush(head))
1767     return false;
1768     ccs_set_string(head, ccs_group_name[idx]);
1769     ccs_set_string(head, group->group_name->name);
1770 kumaneko 3689 if (idx == CCS_PATH_GROUP) {
1771 kumaneko 3780 ccs_set_space(head);
1772     ccs_set_string(head, container_of
1773     (ptr, struct ccs_path_group,
1774     head)->member_name->name);
1775 kumaneko 3689 } else if (idx == CCS_NUMBER_GROUP) {
1776 kumaneko 3780 ccs_print_number_union(head, &container_of
1777     (ptr, struct ccs_number_group,
1778     head)->number);
1779 kumaneko 3689 } else if (idx == CCS_ADDRESS_GROUP) {
1780 kumaneko 3780 char buffer[128];
1781 kumaneko 3689 struct ccs_address_group *member =
1782     container_of(ptr, typeof(*member),
1783     head);
1784 kumaneko 3690 if (member->is_ipv6)
1785     ccs_print_ipv6(buffer, sizeof(buffer),
1786     member->min.ipv6,
1787     member->max.ipv6);
1788     else
1789     ccs_print_ipv4(buffer, sizeof(buffer),
1790     member->min.ipv4,
1791     member->max.ipv4);
1792 kumaneko 3780 ccs_io_printf(head, " %s", buffer);
1793 kumaneko 3689 }
1794 kumaneko 3780 ccs_set_lf(head);
1795 kumaneko 3689 }
1796 kumaneko 3780 head->r.acl = NULL;
1797 kumaneko 3689 }
1798 kumaneko 3780 head->r.group = NULL;
1799 kumaneko 3689 return true;
1800     }
1801    
1802     /**
1803     * ccs_read_policy - Read "struct ccs_..._entry" list.
1804     *
1805     * @head: Pointer to "struct ccs_io_buffer".
1806     * @idx: Index number.
1807     *
1808     * Returns true on success, false otherwise.
1809     *
1810     * Caller holds ccs_read_lock().
1811     */
1812     static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
1813     {
1814 kumaneko 3780 list_for_each_cookie(head->r.acl, &ccs_policy_list[idx]) {
1815     struct ccs_acl_head *acl =
1816     container_of(head->r.acl, typeof(*acl), list);
1817 kumaneko 3689 if (acl->is_deleted)
1818     continue;
1819 kumaneko 3780 if (!ccs_flush(head))
1820     return false;
1821 kumaneko 3689 switch (idx) {
1822 kumaneko 3752 case CCS_ID_TRANSITION_CONTROL:
1823 kumaneko 3689 {
1824 kumaneko 3752 struct ccs_transition_control *ptr =
1825 kumaneko 3689 container_of(acl, typeof(*ptr), head);
1826 kumaneko 3780 ccs_set_string(head,
1827     ccs_transition_type[ptr->type]);
1828     ccs_set_string(head, ptr->program ?
1829     ptr->program->name : "any");
1830     ccs_set_string(head, " from ");
1831     ccs_set_string(head, ptr->domainname ?
1832     ptr->domainname->name : "any");
1833 kumaneko 3689 }
1834 kumaneko 2863 break;
1835 kumaneko 3689 case CCS_ID_AGGREGATOR:
1836     {
1837 kumaneko 3693 struct ccs_aggregator *ptr =
1838 kumaneko 3689 container_of(acl, typeof(*ptr), head);
1839 kumaneko 3780 ccs_set_string(head, CCS_KEYWORD_AGGREGATOR);
1840     ccs_set_string(head, ptr->original_name->name);
1841     ccs_set_space(head);
1842     ccs_set_string(head,
1843     ptr->aggregated_name->name);
1844 kumaneko 3689 }
1845 kumaneko 2943 break;
1846 kumaneko 3689 case CCS_ID_PATTERN:
1847     {
1848 kumaneko 3693 struct ccs_pattern *ptr =
1849 kumaneko 3689 container_of(acl, typeof(*ptr), head);
1850 kumaneko 3780 ccs_set_string(head, CCS_KEYWORD_FILE_PATTERN);
1851     ccs_set_string(head, ptr->pattern->name);
1852 kumaneko 3689 }
1853 kumaneko 2943 break;
1854 kumaneko 3689 case CCS_ID_RESERVEDPORT:
1855     {
1856 kumaneko 3693 struct ccs_reserved *ptr =
1857 kumaneko 3689 container_of(acl, typeof(*ptr), head);
1858     const u16 min_port = ptr->min_port;
1859     const u16 max_port = ptr->max_port;
1860 kumaneko 3780 ccs_set_string(head,
1861     CCS_KEYWORD_DENY_AUTOBIND);
1862     ccs_io_printf(head, "%u", min_port);
1863     if (min_port != max_port)
1864     ccs_io_printf(head, "-%u", max_port);
1865 kumaneko 3689 }
1866 kumaneko 2943 break;
1867 kumaneko 3696 default:
1868     continue;
1869 kumaneko 3689 }
1870 kumaneko 3780 ccs_set_lf(head);
1871 kumaneko 2863 }
1872 kumaneko 3780 head->r.acl = NULL;
1873 kumaneko 3689 return true;
1874 kumaneko 2863 }
1875    
1876 kumaneko 2897 /**
1877 kumaneko 3693 * ccs_read_exception - Read exception policy.
1878 kumaneko 3689 *
1879     * @head: Pointer to "struct ccs_io_buffer".
1880     *
1881     * Caller holds ccs_read_lock().
1882     */
1883 kumaneko 3693 static void ccs_read_exception(struct ccs_io_buffer *head)
1884 kumaneko 3689 {
1885 kumaneko 3780 if (head->r.eof)
1886 kumaneko 3689 return;
1887 kumaneko 3780 while (head->r.step < CCS_MAX_POLICY &&
1888     ccs_read_policy(head, head->r.step))
1889     head->r.step++;
1890     if (head->r.step < CCS_MAX_POLICY)
1891 kumaneko 3689 return;
1892 kumaneko 3780 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
1893     ccs_read_group(head, head->r.step - CCS_MAX_POLICY))
1894     head->r.step++;
1895     if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
1896 kumaneko 3697 return;
1897 kumaneko 3821 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
1898 kumaneko 3924 + CCS_MAX_ACL_GROUPS * 2) {
1899     head->r.group_index = (head->r.step - CCS_MAX_POLICY
1900     - CCS_MAX_GROUP) / 2;
1901 kumaneko 3821 if (!ccs_read_domain2(head,
1902 kumaneko 3924 &ccs_acl_group[head->r.group_index],
1903     head->r.step & 1))
1904 kumaneko 3821 return;
1905     head->r.step++;
1906     }
1907     head->r.eof = true;
1908 kumaneko 3689 }
1909    
1910 kumaneko 2863 /* Wait queue for ccs_query_list. */
1911     static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1912    
1913     /* Lock for manipulating ccs_query_list. */
1914     static DEFINE_SPINLOCK(ccs_query_list_lock);
1915    
1916     /* Structure for query. */
1917 kumaneko 3781 struct ccs_query {
1918 kumaneko 2863 struct list_head list;
1919     char *query;
1920     int query_len;
1921     unsigned int serial;
1922     int timer;
1923     int answer;
1924     };
1925    
1926 kumaneko 3781 /* The list for "struct ccs_query". */
1927 kumaneko 2863 static LIST_HEAD(ccs_query_list);
1928    
1929     /* Number of "struct file" referring /proc/ccs/query interface. */
1930     static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1931    
1932 kumaneko 3761 static void ccs_truncate(char *str)
1933     {
1934     while (* (unsigned char *) str > (unsigned char) ' ')
1935     str++;
1936     *str = '\0';
1937     }
1938    
1939 kumaneko 2863 /**
1940 kumaneko 2922 * ccs_supervisor - Ask for the supervisor's decision.
1941 kumaneko 2863 *
1942 kumaneko 3701 * @r: Pointer to "struct ccs_request_info".
1943     * @fmt: The printf()'s format string, followed by parameters.
1944 kumaneko 2863 *
1945     * Returns 0 if the supervisor decided to permit the access request which
1946 kumaneko 3494 * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
1947     * decided to retry the access request which violated the policy in enforcing
1948     * mode, 0 if it is not in enforcing mode, -EPERM otherwise.
1949 kumaneko 2863 */
1950 kumaneko 2922 int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
1951 kumaneko 2863 {
1952     va_list args;
1953     int error = -EPERM;
1954     int pos;
1955     int len;
1956     static unsigned int ccs_serial;
1957 kumaneko 3781 struct ccs_query *entry = NULL;
1958 kumaneko 2863 bool quota_exceeded = false;
1959     char *header;
1960 kumaneko 3627 struct ccs_domain_info * const domain = ccs_current_domain();
1961 kumaneko 3746 va_start(args, fmt);
1962     len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 80;
1963     va_end(args);
1964     if (r->mode == CCS_CONFIG_LEARNING) {
1965 kumaneko 2897 char *buffer;
1966 kumaneko 3746 char *realpath = NULL;
1967     char *argv0 = NULL;
1968 kumaneko 3761 char *symlink = NULL;
1969     char *handler = NULL;
1970 kumaneko 3746 const struct ccs_preference *pref;
1971 kumaneko 2897 if (!ccs_domain_quota_ok(r))
1972     return 0;
1973 kumaneko 3761 header = ccs_init_log(&len, r);
1974     if (!header)
1975     return 0;
1976 kumaneko 3870 pref = &ccs_profile(r->profile)->preference;
1977 kumaneko 3761 /* strstr() will return NULL if ordering is wrong. */
1978 kumaneko 3746 if (r->param_type == CCS_TYPE_PATH_ACL &&
1979     r->param.path.operation == CCS_TYPE_EXECUTE) {
1980     if (pref->learning_exec_argv0) {
1981 kumaneko 3761 argv0 = strstr(header, " argv[]={ \"");
1982     if (argv0) {
1983     argv0 += 10;
1984     ccs_truncate(argv0);
1985 kumaneko 3746 }
1986     }
1987 kumaneko 3761 if (pref->learning_exec_realpath) {
1988     realpath = strstr(header,
1989     " exec={ realpath=\"");
1990     if (realpath) {
1991     realpath += 8;
1992     ccs_truncate(realpath);
1993     }
1994     }
1995     } else if (r->param_type == CCS_TYPE_PATH_ACL &&
1996     r->param.path.operation == CCS_TYPE_SYMLINK &&
1997     pref->learning_symlink_target) {
1998     symlink = strstr(header, " symlink.target=\"");
1999     if (symlink)
2000     ccs_truncate(symlink + 1);
2001 kumaneko 3746 }
2002 kumaneko 3761 handler = strstr(header, "type=execute_handler");
2003     if (handler)
2004     ccs_truncate(handler);
2005 kumaneko 3512 buffer = kmalloc(len, CCS_GFP_FLAGS);
2006 kumaneko 3746 if (buffer) {
2007     va_start(args, fmt);
2008     vsnprintf(buffer, len - 1, fmt, args);
2009     va_end(args);
2010     if (handler || realpath || argv0 || symlink) {
2011     ccs_addprintf(buffer, len, " if");
2012     if (handler)
2013 kumaneko 3761 ccs_addprintf(buffer, len, " task.%s",
2014     handler);
2015 kumaneko 3746 if (realpath)
2016 kumaneko 3761 ccs_addprintf(buffer, len, " exec.%s",
2017 kumaneko 3746 realpath);
2018     if (argv0)
2019     ccs_addprintf(buffer, len,
2020 kumaneko 3761 " exec.argv[0]=%s",
2021 kumaneko 3746 argv0);
2022     if (symlink)
2023 kumaneko 3761 ccs_addprintf(buffer, len, "%s",
2024 kumaneko 3746 symlink);
2025     }
2026     ccs_normalize_line(buffer);
2027     ccs_write_domain2(buffer, domain, false);
2028     kfree(buffer);
2029     }
2030 kumaneko 3761 kfree(header);
2031 kumaneko 2897 return 0;
2032     }
2033 kumaneko 3746 if (r->mode != CCS_CONFIG_ENFORCING)
2034     return 0;
2035 kumaneko 2863 if (!atomic_read(&ccs_query_observers)) {
2036     int i;
2037     if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR)
2038     return -EPERM;
2039 kumaneko 3870 for (i = 0; i < ccs_profile(domain->profile)->preference.
2040 kumaneko 2958 enforcing_penalty; i++) {
2041 kumaneko 2863 set_current_state(TASK_INTERRUPTIBLE);
2042     schedule_timeout(HZ / 10);
2043     }
2044     return -EPERM;
2045     }
2046 kumaneko 3694 header = ccs_init_log(&len, r);
2047 kumaneko 2863 if (!header)
2048     goto out;
2049 kumaneko 3781 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
2050     if (!entry)
2051 kumaneko 2863 goto out;
2052 kumaneko 2900 len = ccs_round2(len);
2053 kumaneko 3781 entry->query = kzalloc(len, CCS_GFP_FLAGS);
2054     if (!entry->query)
2055 kumaneko 2863 goto out;
2056     spin_lock(&ccs_query_list_lock);
2057     if (ccs_quota_for_query && ccs_query_memory_size + len +
2058 kumaneko 3781 sizeof(*entry) >= ccs_quota_for_query) {
2059 kumaneko 2863 quota_exceeded = true;
2060     } else {
2061 kumaneko 3781 ccs_query_memory_size += len + sizeof(*entry);
2062     entry->serial = ccs_serial++;
2063 kumaneko 2863 }
2064     spin_unlock(&ccs_query_list_lock);
2065     if (quota_exceeded)
2066     goto out;
2067 kumaneko 3781 pos = snprintf(entry->query, len - 1, "Q%u-%hu\n%s",
2068     entry->serial, r->retry, header);
2069 kumaneko 2863 kfree(header);
2070     header = NULL;
2071 kumaneko 3780 va_start(args, fmt);
2072 kumaneko 3781 vsnprintf(entry->query + pos, len - 1 - pos, fmt, args);
2073     entry->query_len = strlen(entry->query) + 1;
2074 kumaneko 3780 va_end(args);
2075 kumaneko 2863 spin_lock(&ccs_query_list_lock);
2076 kumaneko 3781 list_add_tail(&entry->list, &ccs_query_list);
2077 kumaneko 2863 spin_unlock(&ccs_query_list_lock);
2078     /* Give 10 seconds for supervisor's opinion. */
2079 kumaneko 3781 for (entry->timer = 0;
2080     atomic_read(&ccs_query_observers) && entry->timer < 100;
2081     entry->timer++) {
2082 kumaneko 2863 wake_up(&ccs_query_wait);
2083     set_current_state(TASK_INTERRUPTIBLE);
2084     schedule_timeout(HZ / 10);
2085 kumaneko 3781 if (entry->answer)
2086 kumaneko 2863 break;
2087     }
2088     spin_lock(&ccs_query_list_lock);
2089 kumaneko 3781 list_del(&entry->list);
2090     ccs_query_memory_size -= len + sizeof(*entry);
2091 kumaneko 2863 spin_unlock(&ccs_query_list_lock);
2092 kumaneko 3781 switch (entry->answer) {
2093 kumaneko 2863 case 3: /* Asked to retry by administrator. */
2094 kumaneko 3494 error = CCS_RETRY_REQUEST;
2095 kumaneko 2863 r->retry++;
2096     break;
2097     case 1:
2098     /* Granted by administrator. */
2099     error = 0;
2100     break;
2101     case 0:
2102     /* Timed out. */
2103     break;
2104     default:
2105     /* Rejected by administrator. */
2106     break;
2107     }
2108     out:
2109 kumaneko 3781 if (entry)
2110     kfree(entry->query);
2111     kfree(entry);
2112 kumaneko 2863 kfree(header);
2113     return error;
2114     }
2115    
2116     /**
2117     * ccs_poll_query - poll() for /proc/ccs/query.
2118     *
2119     * @file: Pointer to "struct file".
2120     * @wait: Pointer to "poll_table".
2121     *
2122     * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2123     *
2124     * Waits for access requests which violated policy in enforcing mode.
2125     */
2126     static int ccs_poll_query(struct file *file, poll_table *wait)
2127     {
2128     struct list_head *tmp;
2129     bool found = false;
2130     u8 i;
2131     for (i = 0; i < 2; i++) {
2132     spin_lock(&ccs_query_list_lock);
2133     list_for_each(tmp, &ccs_query_list) {
2134 kumaneko 3781 struct ccs_query *ptr =
2135     list_entry(tmp, typeof(*ptr), list);
2136 kumaneko 2863 if (ptr->answer)
2137     continue;
2138     found = true;
2139     break;
2140     }
2141     spin_unlock(&ccs_query_list_lock);
2142     if (found)
2143     return POLLIN | POLLRDNORM;
2144     if (i)
2145     break;
2146     poll_wait(file, &ccs_query_wait, wait);
2147     }
2148     return 0;
2149     }
2150    
2151     /**
2152     * ccs_read_query - Read access requests which violated policy in enforcing mode.
2153     *
2154     * @head: Pointer to "struct ccs_io_buffer".
2155     */
2156 kumaneko 2943 static void ccs_read_query(struct ccs_io_buffer *head)
2157 kumaneko 2863 {
2158     struct list_head *tmp;
2159     int pos = 0;
2160     int len = 0;
2161     char *buf;
2162 kumaneko 3780 if (head->r.w_pos)
2163 kumaneko 2943 return;
2164 kumaneko 2863 if (head->read_buf) {
2165     kfree(head->read_buf);
2166     head->read_buf = NULL;
2167     }
2168     spin_lock(&ccs_query_list_lock);
2169     list_for_each(tmp, &ccs_query_list) {
2170 kumaneko 3781 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
2171 kumaneko 2863 if (ptr->answer)
2172     continue;
2173 kumaneko 3780 if (pos++ != head->r.query_index)
2174 kumaneko 2863 continue;
2175     len = ptr->query_len;
2176     break;
2177     }
2178     spin_unlock(&ccs_query_list_lock);
2179     if (!len) {
2180 kumaneko 3780 head->r.query_index = 0;
2181 kumaneko 2943 return;
2182 kumaneko 2863 }
2183 kumaneko 3512 buf = kzalloc(len, CCS_GFP_FLAGS);
2184 kumaneko 2863 if (!buf)
2185 kumaneko 2943 return;
2186 kumaneko 2863 pos = 0;
2187     spin_lock(&ccs_query_list_lock);
2188     list_for_each(tmp, &ccs_query_list) {
2189 kumaneko 3781 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
2190 kumaneko 2863 if (ptr->answer)
2191     continue;
2192 kumaneko 3780 if (pos++ != head->r.query_index)
2193 kumaneko 2863 continue;
2194     /*
2195     * Some query can be skipped because ccs_query_list
2196     * can change, but I don't care.
2197     */
2198     if (len == ptr->query_len)
2199     memmove(buf, ptr->query, len);
2200     break;
2201     }
2202     spin_unlock(&ccs_query_list_lock);
2203     if (buf[0]) {
2204     head->read_buf = buf;
2205 kumaneko 3780 head->r.w[head->r.w_pos++] = buf;
2206     head->r.query_index++;
2207 kumaneko 2863 } else {
2208     kfree(buf);
2209     }
2210     }
2211    
2212     /**
2213     * ccs_write_answer - Write the supervisor's decision.
2214     *
2215     * @head: Pointer to "struct ccs_io_buffer".
2216     *
2217     * Returns 0 on success, -EINVAL otherwise.
2218     */
2219     static int ccs_write_answer(struct ccs_io_buffer *head)
2220     {
2221     char *data = head->write_buf;
2222     struct list_head *tmp;
2223     unsigned int serial;
2224     unsigned int answer;
2225     spin_lock(&ccs_query_list_lock);
2226     list_for_each(tmp, &ccs_query_list) {
2227 kumaneko 3781 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
2228 kumaneko 2863 ptr->timer = 0;
2229     }
2230     spin_unlock(&ccs_query_list_lock);
2231     if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2232     return -EINVAL;
2233     spin_lock(&ccs_query_list_lock);
2234     list_for_each(tmp, &ccs_query_list) {
2235 kumaneko 3781 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
2236 kumaneko 2863 if (ptr->serial != serial)
2237     continue;
2238     if (!ptr->answer)
2239     ptr->answer = answer;
2240     break;
2241     }
2242     spin_unlock(&ccs_query_list_lock);
2243     return 0;
2244     }
2245    
2246     /**
2247     * ccs_read_version: Get version.
2248     *
2249     * @head: Pointer to "struct ccs_io_buffer".
2250     */
2251