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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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