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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5595 - (hide annotations) (download) (as text)
Sun Nov 6 02:39:15 2011 UTC (12 years, 6 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 131087 byte(s)


1 kumaneko 2863 /*
2 kumaneko 2864 * security/ccsecurity/policy_io.c
3 kumaneko 2863 *
4 kumaneko 4334 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 kumaneko 2863 *
6 kumaneko 5567 * Version: 1.8.3+ 2011/10/25
7 kumaneko 2863 */
8    
9     #include "internal.h"
10    
11 kumaneko 5594 /***** SECTION1: Constants definition *****/
12 kumaneko 4082
13 kumaneko 5594 /* Define this to enable debug mode. */
14     /* #define DEBUG_CONDITION */
15 kumaneko 4082
16 kumaneko 5594 #ifdef DEBUG_CONDITION
17     #define dprintk printk
18     #else
19     #define dprintk(...) do { } while (0)
20 kumaneko 4082 #endif
21    
22 kumaneko 4063 /* String table for operation mode. */
23 kumaneko 3968 const char * const ccs_mode[CCS_CONFIG_MAX_MODE] = {
24     [CCS_CONFIG_DISABLED] = "disabled",
25     [CCS_CONFIG_LEARNING] = "learning",
26 kumaneko 3748 [CCS_CONFIG_PERMISSIVE] = "permissive",
27 kumaneko 3968 [CCS_CONFIG_ENFORCING] = "enforcing"
28 kumaneko 2863 };
29 kumaneko 2915
30 kumaneko 4063 /* String table for /proc/ccs/profile interface. */
31 kumaneko 3968 const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX
32     + CCS_MAX_MAC_CATEGORY_INDEX] = {
33 kumaneko 4063 /* CONFIG::file group */
34 kumaneko 3968 [CCS_MAC_FILE_EXECUTE] = "execute",
35     [CCS_MAC_FILE_OPEN] = "open",
36     [CCS_MAC_FILE_CREATE] = "create",
37     [CCS_MAC_FILE_UNLINK] = "unlink",
38 kumaneko 4080 [CCS_MAC_FILE_GETATTR] = "getattr",
39 kumaneko 3968 [CCS_MAC_FILE_MKDIR] = "mkdir",
40     [CCS_MAC_FILE_RMDIR] = "rmdir",
41     [CCS_MAC_FILE_MKFIFO] = "mkfifo",
42     [CCS_MAC_FILE_MKSOCK] = "mksock",
43     [CCS_MAC_FILE_TRUNCATE] = "truncate",
44     [CCS_MAC_FILE_SYMLINK] = "symlink",
45     [CCS_MAC_FILE_MKBLOCK] = "mkblock",
46     [CCS_MAC_FILE_MKCHAR] = "mkchar",
47     [CCS_MAC_FILE_LINK] = "link",
48     [CCS_MAC_FILE_RENAME] = "rename",
49     [CCS_MAC_FILE_CHMOD] = "chmod",
50 kumaneko 4049 [CCS_MAC_FILE_CHOWN] = "chown",
51 kumaneko 3968 [CCS_MAC_FILE_CHGRP] = "chgrp",
52     [CCS_MAC_FILE_IOCTL] = "ioctl",
53     [CCS_MAC_FILE_CHROOT] = "chroot",
54     [CCS_MAC_FILE_MOUNT] = "mount",
55     [CCS_MAC_FILE_UMOUNT] = "unmount",
56     [CCS_MAC_FILE_PIVOT_ROOT] = "pivot_root",
57 kumaneko 4063 /* CONFIG::misc group */
58 kumaneko 3968 [CCS_MAC_ENVIRON] = "env",
59 kumaneko 4063 /* CONFIG::network group */
60 kumaneko 3968 [CCS_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind",
61     [CCS_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen",
62     [CCS_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect",
63     [CCS_MAC_NETWORK_INET_STREAM_ACCEPT] = "inet_stream_accept",
64     [CCS_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind",
65     [CCS_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send",
66     [CCS_MAC_NETWORK_INET_DGRAM_RECV] = "inet_dgram_recv",
67     [CCS_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind",
68     [CCS_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send",
69     [CCS_MAC_NETWORK_INET_RAW_RECV] = "inet_raw_recv",
70     [CCS_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind",
71     [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen",
72     [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect",
73     [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT] = "unix_stream_accept",
74     [CCS_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind",
75     [CCS_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send",
76     [CCS_MAC_NETWORK_UNIX_DGRAM_RECV] = "unix_dgram_recv",
77     [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
78     [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
79     [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
80     [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT] = "unix_seqpacket_accept",
81 kumaneko 4063 /* CONFIG::ipc group */
82 kumaneko 3968 [CCS_MAC_SIGNAL] = "signal",
83 kumaneko 4063 /* CONFIG::capability group */
84 kumaneko 3968 [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET] = "use_route",
85     [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = "use_packet",
86     [CCS_MAC_CAPABILITY_SYS_REBOOT] = "SYS_REBOOT",
87     [CCS_MAC_CAPABILITY_SYS_VHANGUP] = "SYS_VHANGUP",
88     [CCS_MAC_CAPABILITY_SYS_SETTIME] = "SYS_TIME",
89     [CCS_MAC_CAPABILITY_SYS_NICE] = "SYS_NICE",
90     [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME] = "SYS_SETHOSTNAME",
91     [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
92     [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD] = "SYS_KEXEC_LOAD",
93     [CCS_MAC_CAPABILITY_SYS_PTRACE] = "SYS_PTRACE",
94 kumaneko 4063 /* CONFIG group */
95 kumaneko 3968 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE] = "file",
96     [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NETWORK] = "network",
97     [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_MISC] = "misc",
98     [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_IPC] = "ipc",
99     [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
100 kumaneko 2915 };
101    
102 kumaneko 4063 /* String table for path operation. */
103 kumaneko 3968 const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = {
104     [CCS_TYPE_EXECUTE] = "execute",
105     [CCS_TYPE_READ] = "read",
106     [CCS_TYPE_WRITE] = "write",
107     [CCS_TYPE_APPEND] = "append",
108     [CCS_TYPE_UNLINK] = "unlink",
109 kumaneko 4080 [CCS_TYPE_GETATTR] = "getattr",
110 kumaneko 3968 [CCS_TYPE_RMDIR] = "rmdir",
111     [CCS_TYPE_TRUNCATE] = "truncate",
112     [CCS_TYPE_SYMLINK] = "symlink",
113     [CCS_TYPE_CHROOT] = "chroot",
114     [CCS_TYPE_UMOUNT] = "unmount",
115     };
116    
117 kumaneko 5106 /* String table for socket's operation. */
118     const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION] = {
119     [CCS_NETWORK_BIND] = "bind",
120     [CCS_NETWORK_LISTEN] = "listen",
121     [CCS_NETWORK_CONNECT] = "connect",
122     [CCS_NETWORK_ACCEPT] = "accept",
123     [CCS_NETWORK_SEND] = "send",
124     [CCS_NETWORK_RECV] = "recv",
125     };
126    
127 kumaneko 4063 /* String table for categories. */
128 kumaneko 3968 static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = {
129     [CCS_MAC_CATEGORY_FILE] = "file",
130     [CCS_MAC_CATEGORY_NETWORK] = "network",
131     [CCS_MAC_CATEGORY_MISC] = "misc",
132     [CCS_MAC_CATEGORY_IPC] = "ipc",
133     [CCS_MAC_CATEGORY_CAPABILITY] = "capability",
134     };
135    
136 kumaneko 4063 /* String table for conditions. */
137 kumaneko 3968 const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = {
138     [CCS_TASK_UID] = "task.uid",
139     [CCS_TASK_EUID] = "task.euid",
140     [CCS_TASK_SUID] = "task.suid",
141     [CCS_TASK_FSUID] = "task.fsuid",
142     [CCS_TASK_GID] = "task.gid",
143     [CCS_TASK_EGID] = "task.egid",
144     [CCS_TASK_SGID] = "task.sgid",
145     [CCS_TASK_FSGID] = "task.fsgid",
146     [CCS_TASK_PID] = "task.pid",
147     [CCS_TASK_PPID] = "task.ppid",
148     [CCS_EXEC_ARGC] = "exec.argc",
149     [CCS_EXEC_ENVC] = "exec.envc",
150     [CCS_TYPE_IS_SOCKET] = "socket",
151     [CCS_TYPE_IS_SYMLINK] = "symlink",
152     [CCS_TYPE_IS_FILE] = "file",
153     [CCS_TYPE_IS_BLOCK_DEV] = "block",
154     [CCS_TYPE_IS_DIRECTORY] = "directory",
155     [CCS_TYPE_IS_CHAR_DEV] = "char",
156     [CCS_TYPE_IS_FIFO] = "fifo",
157     [CCS_MODE_SETUID] = "setuid",
158     [CCS_MODE_SETGID] = "setgid",
159     [CCS_MODE_STICKY] = "sticky",
160     [CCS_MODE_OWNER_READ] = "owner_read",
161     [CCS_MODE_OWNER_WRITE] = "owner_write",
162     [CCS_MODE_OWNER_EXECUTE] = "owner_execute",
163     [CCS_MODE_GROUP_READ] = "group_read",
164     [CCS_MODE_GROUP_WRITE] = "group_write",
165     [CCS_MODE_GROUP_EXECUTE] = "group_execute",
166     [CCS_MODE_OTHERS_READ] = "others_read",
167     [CCS_MODE_OTHERS_WRITE] = "others_write",
168     [CCS_MODE_OTHERS_EXECUTE] = "others_execute",
169     [CCS_TASK_TYPE] = "task.type",
170     [CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
171     [CCS_EXEC_REALPATH] = "exec.realpath",
172     [CCS_SYMLINK_TARGET] = "symlink.target",
173     [CCS_PATH1_UID] = "path1.uid",
174     [CCS_PATH1_GID] = "path1.gid",
175     [CCS_PATH1_INO] = "path1.ino",
176     [CCS_PATH1_MAJOR] = "path1.major",
177     [CCS_PATH1_MINOR] = "path1.minor",
178     [CCS_PATH1_PERM] = "path1.perm",
179     [CCS_PATH1_TYPE] = "path1.type",
180     [CCS_PATH1_DEV_MAJOR] = "path1.dev_major",
181     [CCS_PATH1_DEV_MINOR] = "path1.dev_minor",
182     [CCS_PATH2_UID] = "path2.uid",
183     [CCS_PATH2_GID] = "path2.gid",
184     [CCS_PATH2_INO] = "path2.ino",
185     [CCS_PATH2_MAJOR] = "path2.major",
186     [CCS_PATH2_MINOR] = "path2.minor",
187     [CCS_PATH2_PERM] = "path2.perm",
188     [CCS_PATH2_TYPE] = "path2.type",
189     [CCS_PATH2_DEV_MAJOR] = "path2.dev_major",
190     [CCS_PATH2_DEV_MINOR] = "path2.dev_minor",
191     [CCS_PATH1_PARENT_UID] = "path1.parent.uid",
192     [CCS_PATH1_PARENT_GID] = "path1.parent.gid",
193     [CCS_PATH1_PARENT_INO] = "path1.parent.ino",
194     [CCS_PATH1_PARENT_PERM] = "path1.parent.perm",
195     [CCS_PATH2_PARENT_UID] = "path2.parent.uid",
196     [CCS_PATH2_PARENT_GID] = "path2.parent.gid",
197     [CCS_PATH2_PARENT_INO] = "path2.parent.ino",
198     [CCS_PATH2_PARENT_PERM] = "path2.parent.perm",
199     };
200    
201 kumaneko 4063 /* String table for PREFERENCE keyword. */
202 kumaneko 4049 static const char * const ccs_pref_keywords[CCS_MAX_PREF] = {
203 kumaneko 4170 [CCS_PREF_MAX_AUDIT_LOG] = "max_audit_log",
204 kumaneko 4049 [CCS_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
205     [CCS_PREF_ENFORCING_PENALTY] = "enforcing_penalty",
206     };
207    
208 kumaneko 5594 /* String table for domain flags. */
209     const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
210     [CCS_DIF_QUOTA_WARNED] = "quota_exceeded\n",
211     [CCS_DIF_TRANSITION_FAILED] = "transition_failed\n",
212     };
213    
214     /* String table for domain transition control keywords. */
215     static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
216     [CCS_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
217     [CCS_TRANSITION_CONTROL_RESET] = "reset_domain ",
218     [CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
219     [CCS_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
220     [CCS_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
221     [CCS_TRANSITION_CONTROL_KEEP] = "keep_domain ",
222     };
223    
224     /* String table for grouping keywords. */
225     static const char * const ccs_group_name[CCS_MAX_GROUP] = {
226     [CCS_PATH_GROUP] = "path_group ",
227     [CCS_NUMBER_GROUP] = "number_group ",
228     [CCS_ADDRESS_GROUP] = "address_group ",
229     };
230    
231     /* String table for /proc/ccs/stat interface. */
232     static const char * const ccs_policy_headers[CCS_MAX_POLICY_STAT] = {
233     [CCS_STAT_POLICY_UPDATES] = "update:",
234     [CCS_STAT_POLICY_LEARNING] = "violation in learning mode:",
235     [CCS_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
236     [CCS_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
237     };
238    
239     /* String table for /proc/ccs/stat interface. */
240     static const char * const ccs_memory_headers[CCS_MAX_MEMORY_STAT] = {
241     [CCS_MEMORY_POLICY] = "policy:",
242     [CCS_MEMORY_AUDIT] = "audit log:",
243     [CCS_MEMORY_QUERY] = "query message:",
244     };
245    
246     /***** SECTION2: Structure definition *****/
247    
248 kumaneko 5595 struct iattr;
249    
250 kumaneko 5594 /* Structure for query. */
251     struct ccs_query {
252     struct list_head list;
253     struct ccs_domain_info *domain;
254     char *query;
255     size_t query_len;
256     unsigned int serial;
257     u8 timer;
258     u8 answer;
259     u8 retry;
260     };
261    
262     /***** SECTION3: Prototype definition section *****/
263    
264     const char *ccs_yesno(const unsigned int value);
265 kumaneko 5595 int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...);
266     struct ccs_profile *ccs_profile(const u8 profile);
267 kumaneko 5594 void ccs_init_policy_namespace(struct ccs_policy_namespace *ns);
268     void ccs_update_stat(const u8 index);
269    
270 kumaneko 5595 static bool __ccs_lport_reserved(const u16 port);
271     static bool ccs_flush(struct ccs_io_buffer *head);
272     static bool ccs_has_more_namespace(struct ccs_io_buffer *head);
273     static bool ccs_manager(void);
274     static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv);
275     static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp);
276     static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param, struct ccs_ipaddr_union *ptr);
277 kumaneko 5594 static bool ccs_parse_name_union(struct ccs_acl_param *param, struct ccs_name_union *ptr);
278 kumaneko 5595 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param, struct ccs_name_union *ptr);
279 kumaneko 5594 static bool ccs_parse_number_union(struct ccs_acl_param *param, struct ccs_number_union *ptr);
280 kumaneko 5595 static bool ccs_print_condition(struct ccs_io_buffer *head, const struct ccs_condition *cond);
281     static bool ccs_print_entry(struct ccs_io_buffer *head, const struct ccs_acl_info *acl);
282     static bool ccs_read_domain2(struct ccs_io_buffer *head, struct list_head *list);
283     static bool ccs_read_group(struct ccs_io_buffer *head, const int idx);
284     static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx);
285     static bool ccs_same_condition(const struct ccs_condition *a, const struct ccs_condition *b);
286     static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data);
287     static bool ccs_set_lf(struct ccs_io_buffer *head);
288     static char *ccs_get_transit_preference(struct ccs_acl_param *param, struct ccs_condition *e);
289 kumaneko 5594 static const struct ccs_path_info *ccs_get_dqword(char *start);
290 kumaneko 5595 static int __init ccs_init_module(void);
291     static int ccs_delete_domain(char *domainname);
292     static int ccs_open(struct inode *inode, struct file *file);
293     static int ccs_parse_policy(struct ccs_io_buffer *head, char *line);
294     static int ccs_poll_query(struct file *file, poll_table *wait);
295     static int ccs_release(struct inode *inode, struct file *file);
296     static int ccs_set_mode(char *name, const char *value, struct ccs_profile *profile);
297     static int ccs_truncate(char *str);
298     static int ccs_update_domain(const int size, struct ccs_acl_param *param);
299     static int ccs_update_manager_entry(const char *manager, const bool is_delete);
300     static int ccs_update_policy(const int size, struct ccs_acl_param *param);
301     static int ccs_write_aggregator(struct ccs_acl_param *param);
302     static int ccs_write_answer(struct ccs_io_buffer *head);
303     static int ccs_write_capability(struct ccs_acl_param *param);
304     static int ccs_write_domain(struct ccs_io_buffer *head);
305     static int ccs_write_domain2(struct ccs_policy_namespace *ns, struct list_head *list, char *data, const bool is_delete);
306     static int ccs_write_exception(struct ccs_io_buffer *head);
307     static int ccs_write_file(struct ccs_acl_param *param);
308     static int ccs_write_group(struct ccs_acl_param *param, const u8 type);
309     static int ccs_write_inet_network(struct ccs_acl_param *param);
310     static int ccs_write_ipc(struct ccs_acl_param *param);
311     static int ccs_write_manager(struct ccs_io_buffer *head);
312     static int ccs_write_misc(struct ccs_acl_param *param);
313     static int ccs_write_pid(struct ccs_io_buffer *head);
314     static int ccs_write_profile(struct ccs_io_buffer *head);
315     static int ccs_write_reserved_port(struct ccs_acl_param *param);
316     static int ccs_write_stat(struct ccs_io_buffer *head);
317     static int ccs_write_task(struct ccs_acl_param *param);
318     static int ccs_write_transition_control(struct ccs_acl_param *param, const u8 type);
319     static int ccs_write_unix_network(struct ccs_acl_param *param);
320     static s8 ccs_find_yesno(const char *string, const char *find);
321     static ssize_t ccs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos);
322     static ssize_t ccs_read_self(struct file *file, char __user *buf, size_t count, loff_t *ppos);
323     static ssize_t ccs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
324 kumaneko 5594 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry);
325     static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param);
326 kumaneko 5595 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial);
327     static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns, const unsigned int profile);
328     static u8 ccs_condition_type(const char *word);
329     static unsigned int ccs_poll(struct file *file, poll_table *wait);
330     static void __init ccs_create_entry(const char *name, const mode_t mode, struct proc_dir_entry *parent, const u8 key);
331     static void __init ccs_load_builtin_policy(void);
332     static void __init ccs_policy_io_init(void);
333     static void __init ccs_proc_init(void);
334     static void ccs_add_entry(char *header);
335 kumaneko 5594 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...) __attribute__ ((format(printf, 3, 4)));
336     static void ccs_addprintf(char *buffer, int len, const char *fmt, ...);
337 kumaneko 5595 static void ccs_check_profile(void);
338 kumaneko 5594 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
339     static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...);
340     static void ccs_print_config(struct ccs_io_buffer *head, const u8 config);
341 kumaneko 5595 static void ccs_print_ip(char *buf, const unsigned int size, const struct ccs_ipaddr_union *ptr);
342 kumaneko 5594 static void ccs_print_name_union(struct ccs_io_buffer *head, const struct ccs_name_union *ptr);
343     static void ccs_print_name_union_quoted(struct ccs_io_buffer *head, const struct ccs_name_union *ptr);
344 kumaneko 5595 static void ccs_print_namespace(struct ccs_io_buffer *head);
345     static void ccs_print_number_union(struct ccs_io_buffer *head, const struct ccs_number_union *ptr);
346 kumaneko 5594 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head, const struct ccs_number_union *ptr);
347     static void ccs_read_domain(struct ccs_io_buffer *head);
348 kumaneko 5595 static void ccs_read_exception(struct ccs_io_buffer *head);
349     static void ccs_read_manager(struct ccs_io_buffer *head);
350 kumaneko 5594 static void ccs_read_pid(struct ccs_io_buffer *head);
351 kumaneko 5595 static void ccs_read_profile(struct ccs_io_buffer *head);
352 kumaneko 5594 static void ccs_read_query(struct ccs_io_buffer *head);
353 kumaneko 5595 static void ccs_read_stat(struct ccs_io_buffer *head);
354 kumaneko 5594 static void ccs_read_version(struct ccs_io_buffer *head);
355 kumaneko 5595 static void ccs_set_group(struct ccs_io_buffer *head, const char *category);
356 kumaneko 5594 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head);
357 kumaneko 5595 static void ccs_set_slash(struct ccs_io_buffer *head);
358     static void ccs_set_space(struct ccs_io_buffer *head);
359     static void ccs_set_string(struct ccs_io_buffer *head, const char *string);
360     static void ccs_set_uint(unsigned int *i, const char *string, const char *find);
361 kumaneko 5594
362     /***** SECTION4: Standalone functions section *****/
363    
364     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
365    
366     /**
367     * __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
368     *
369     * @wq: The waitqueue to wait on.
370     * @condition: A C expression for the event to wait for.
371     * @ret: Timeout, in jiffies.
372     *
373     * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
374     * signal, and the remaining jiffies otherwise if the condition evaluated to
375     * true before the timeout elapsed.
376     *
377     * This is for compatibility with older kernels.
378     */
379     #define __wait_event_interruptible_timeout(wq, condition, ret) \
380     do { \
381     wait_queue_t __wait; \
382     init_waitqueue_entry(&__wait, current); \
383     \
384     add_wait_queue(&wq, &__wait); \
385     for (;;) { \
386     set_current_state(TASK_INTERRUPTIBLE); \
387     if (condition) \
388     break; \
389     if (!signal_pending(current)) { \
390     ret = schedule_timeout(ret); \
391     if (!ret) \
392     break; \
393     continue; \
394     } \
395     ret = -ERESTARTSYS; \
396     break; \
397     } \
398     current->state = TASK_RUNNING; \
399     remove_wait_queue(&wq, &__wait); \
400     } while (0)
401    
402     /**
403     * wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
404     *
405     * @wq: The waitqueue to wait on.
406     * @condition: A C expression for the event to wait for.
407     * @timeout: Timeout, in jiffies.
408     *
409     * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
410     * signal, and the remaining jiffies otherwise if the condition evaluated to
411     * true before the timeout elapsed.
412     *
413     * This is for compatibility with older kernels.
414     */
415     #define wait_event_interruptible_timeout(wq, condition, timeout) \
416     ({ \
417     long __ret = timeout; \
418     if (!(condition)) \
419     __wait_event_interruptible_timeout(wq, condition, __ret); \
420     __ret; \
421     })
422    
423     #endif
424    
425 kumaneko 5595 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
426     #if !defined(RHEL_VERSION) || RHEL_VERSION != 3
427    
428     /**
429     * PDE - Get "struct proc_dir_entry".
430     *
431     * @inode: Pointer to "struct inode".
432     *
433     * Returns pointer to "struct proc_dir_entry".
434     *
435     * This is for compatibility with older kernels.
436     */
437     static inline struct proc_dir_entry *PDE(const struct inode *inode)
438     {
439     return (struct proc_dir_entry *) inode->u.generic_ip;
440     }
441    
442     #endif
443     #endif
444    
445     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
446    
447     /**
448     * proc_notify_change - Update inode's attributes and reflect to the dentry.
449     *
450     * @dentry: Pointer to "struct dentry".
451     * @iattr: Pointer to "struct iattr".
452     *
453     * Returns 0 on success, negative value otherwise.
454     *
455     * The 2.4 kernels don't allow chmod()/chown() for files in /proc,
456     * while the 2.6 kernels allow.
457     * To permit management of /proc/ccs/ interface by non-root user,
458     * I modified to allow chmod()/chown() of /proc/ccs/ interface like 2.6 kernels
459     * by adding "struct inode_operations"->setattr hook.
460     */
461     static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
462     {
463     struct inode *inode = dentry->d_inode;
464     struct proc_dir_entry *de = PDE(inode);
465     int error;
466    
467     error = inode_change_ok(inode, iattr);
468     if (error)
469     goto out;
470    
471     error = inode_setattr(inode, iattr);
472     if (error)
473     goto out;
474    
475     de->uid = inode->i_uid;
476     de->gid = inode->i_gid;
477     de->mode = inode->i_mode;
478     out:
479     return error;
480     }
481    
482     #endif
483    
484 kumaneko 5594 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && defined(CONFIG_NET)
485     #define ccs_in4_pton in4_pton
486     #define ccs_in6_pton in6_pton
487     #else
488     /*
489     * Routines for parsing IPv4 or IPv6 address.
490     * These are copied from lib/hexdump.c net/core/utils.c .
491     */
492     #include <linux/ctype.h>
493    
494     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
495     static int hex_to_bin(char ch)
496     {
497     if ((ch >= '0') && (ch <= '9'))
498     return ch - '0';
499     ch = tolower(ch);
500     if ((ch >= 'a') && (ch <= 'f'))
501     return ch - 'a' + 10;
502     return -1;
503     }
504     #endif
505    
506     #define IN6PTON_XDIGIT 0x00010000
507     #define IN6PTON_DIGIT 0x00020000
508     #define IN6PTON_COLON_MASK 0x00700000
509     #define IN6PTON_COLON_1 0x00100000 /* single : requested */
510     #define IN6PTON_COLON_2 0x00200000 /* second : requested */
511     #define IN6PTON_COLON_1_2 0x00400000 /* :: requested */
512     #define IN6PTON_DOT 0x00800000 /* . */
513     #define IN6PTON_DELIM 0x10000000
514     #define IN6PTON_NULL 0x20000000 /* first/tail */
515     #define IN6PTON_UNKNOWN 0x40000000
516    
517     static inline int xdigit2bin(char c, int delim)
518     {
519     int val;
520    
521     if (c == delim || c == '\0')
522     return IN6PTON_DELIM;
523     if (c == ':')
524     return IN6PTON_COLON_MASK;
525     if (c == '.')
526     return IN6PTON_DOT;
527    
528     val = hex_to_bin(c);
529     if (val >= 0)
530     return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
531    
532     if (delim == -1)
533     return IN6PTON_DELIM;
534     return IN6PTON_UNKNOWN;
535     }
536    
537     static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim,
538     const char **end)
539     {
540     const char *s;
541     u8 *d;
542     u8 dbuf[4];
543     int ret = 0;
544     int i;
545     int w = 0;
546    
547     if (srclen < 0)
548     srclen = strlen(src);
549     s = src;
550     d = dbuf;
551     i = 0;
552     while (1) {
553     int c;
554     c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
555     if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM |
556     IN6PTON_COLON_MASK)))
557     goto out;
558     if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
559     if (w == 0)
560     goto out;
561     *d++ = w & 0xff;
562     w = 0;
563     i++;
564     if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
565     if (i != 4)
566     goto out;
567     break;
568     }
569     goto cont;
570     }
571     w = (w * 10) + c;
572     if ((w & 0xffff) > 255)
573     goto out;
574     cont:
575     if (i >= 4)
576     goto out;
577     s++;
578     srclen--;
579     }
580     ret = 1;
581     memcpy(dst, dbuf, sizeof(dbuf));
582     out:
583     if (end)
584     *end = s;
585     return ret;
586     }
587    
588     static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim,
589     const char **end)
590     {
591     const char *s, *tok = NULL;
592     u8 *d, *dc = NULL;
593     u8 dbuf[16];
594     int ret = 0;
595     int i;
596     int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
597     int w = 0;
598    
599     memset(dbuf, 0, sizeof(dbuf));
600    
601     s = src;
602     d = dbuf;
603     if (srclen < 0)
604     srclen = strlen(src);
605    
606     while (1) {
607     int c;
608    
609     c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
610     if (!(c & state))
611     goto out;
612     if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
613     /* process one 16-bit word */
614     if (!(state & IN6PTON_NULL)) {
615     *d++ = (w >> 8) & 0xff;
616     *d++ = w & 0xff;
617     }
618     w = 0;
619     if (c & IN6PTON_DELIM) {
620     /* We've processed last word */
621     break;
622     }
623     /*
624     * COLON_1 => XDIGIT
625     * COLON_2 => XDIGIT|DELIM
626     * COLON_1_2 => COLON_2
627     */
628     switch (state & IN6PTON_COLON_MASK) {
629     case IN6PTON_COLON_2:
630     dc = d;
631     state = IN6PTON_XDIGIT | IN6PTON_DELIM;
632     if (dc - dbuf >= sizeof(dbuf))
633     state |= IN6PTON_NULL;
634     break;
635     case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
636     state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
637     break;
638     case IN6PTON_COLON_1:
639     state = IN6PTON_XDIGIT;
640     break;
641     case IN6PTON_COLON_1_2:
642     state = IN6PTON_COLON_2;
643     break;
644     default:
645     state = 0;
646     }
647     tok = s + 1;
648     goto cont;
649     }
650    
651     if (c & IN6PTON_DOT) {
652     ret = ccs_in4_pton(tok ? tok : s, srclen +
653     (int)(s - tok), d, delim, &s);
654     if (ret > 0) {
655     d += 4;
656     break;
657     }
658     goto out;
659     }
660    
661     w = (w << 4) | (0xff & c);
662     state = IN6PTON_COLON_1 | IN6PTON_DELIM;
663     if (!(w & 0xf000))
664     state |= IN6PTON_XDIGIT;
665     if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
666     state |= IN6PTON_COLON_1_2;
667     state &= ~IN6PTON_DELIM;
668     }
669     if (d + 2 >= dbuf + sizeof(dbuf))
670     state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
671     cont:
672     if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
673     d + 4 == dbuf + sizeof(dbuf))
674     state |= IN6PTON_DOT;
675     if (d >= dbuf + sizeof(dbuf))
676     state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
677     s++;
678     srclen--;
679     }
680    
681     i = 15; d--;
682    
683     if (dc) {
684     while (d >= dc)
685     dst[i--] = *d--;
686     while (i >= dc - dbuf)
687     dst[i--] = 0;
688     while (i >= 0)
689     dst[i--] = *d--;
690     } else
691     memcpy(dst, dbuf, sizeof(dbuf));
692    
693     ret = 1;
694     out:
695     if (end)
696     *end = s;
697     return ret;
698     }
699     #endif
700    
701     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
702    
703     /*
704     * Routines for printing IPv4 or IPv6 address.
705     * These are copied from include/linux/kernel.h include/net/ipv6.h
706     * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified.
707     */
708     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
709     static const char hex_asc[] = "0123456789abcdef";
710     #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
711     #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
712    
713     static inline char *pack_hex_byte(char *buf, u8 byte)
714     {
715     *buf++ = hex_asc_hi(byte);
716     *buf++ = hex_asc_lo(byte);
717     return buf;
718     }
719     #endif
720    
721     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
722     static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
723     {
724     return (a->s6_addr32[0] | a->s6_addr32[1] |
725     (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
726     }
727     #endif
728    
729     static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
730     {
731     return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
732     }
733    
734     static char *ip4_string(char *p, const u8 *addr)
735     {
736     /*
737     * Since this function is called outside vsnprintf(), I can use
738     * sprintf() here.
739     */
740     return p +
741     sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
742     }
743    
744     static char *ip6_compressed_string(char *p, const char *addr)
745     {
746     int i, j, range;
747     unsigned char zerolength[8];
748     int longest = 1;
749     int colonpos = -1;
750     u16 word;
751     u8 hi, lo;
752     bool needcolon = false;
753     bool useIPv4;
754     struct in6_addr in6;
755    
756     memcpy(&in6, addr, sizeof(struct in6_addr));
757    
758     useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
759    
760     memset(zerolength, 0, sizeof(zerolength));
761    
762     if (useIPv4)
763     range = 6;
764     else
765     range = 8;
766    
767     /* find position of longest 0 run */
768     for (i = 0; i < range; i++) {
769     for (j = i; j < range; j++) {
770     if (in6.s6_addr16[j] != 0)
771     break;
772     zerolength[i]++;
773     }
774     }
775     for (i = 0; i < range; i++) {
776     if (zerolength[i] > longest) {
777     longest = zerolength[i];
778     colonpos = i;
779     }
780     }
781     if (longest == 1) /* don't compress a single 0 */
782     colonpos = -1;
783    
784     /* emit address */
785     for (i = 0; i < range; i++) {
786     if (i == colonpos) {
787     if (needcolon || i == 0)
788     *p++ = ':';
789     *p++ = ':';
790     needcolon = false;
791     i += longest - 1;
792     continue;
793     }
794     if (needcolon) {
795     *p++ = ':';
796     needcolon = false;
797     }
798     /* hex u16 without leading 0s */
799     word = ntohs(in6.s6_addr16[i]);
800     hi = word >> 8;
801     lo = word & 0xff;
802     if (hi) {
803     if (hi > 0x0f)
804     p = pack_hex_byte(p, hi);
805     else
806     *p++ = hex_asc_lo(hi);
807     p = pack_hex_byte(p, lo);
808     } else if (lo > 0x0f)
809     p = pack_hex_byte(p, lo);
810     else
811     *p++ = hex_asc_lo(lo);
812     needcolon = true;
813     }
814    
815     if (useIPv4) {
816     if (needcolon)
817     *p++ = ':';
818     p = ip4_string(p, &in6.s6_addr[12]);
819     }
820     *p = '\0';
821    
822     return p;
823     }
824     #endif
825    
826     /**
827     * ccs_print_ipv4 - Print an IPv4 address.
828     *
829     * @buffer: Buffer to write to.
830     * @buffer_len: Size of @buffer.
831     * @ip: Pointer to "u32 in network byte order".
832     *
833     * Returns written length.
834     */
835     int ccs_print_ipv4(char *buffer, const unsigned int buffer_len, const u32 *ip)
836     {
837     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
838     return snprintf(buffer, buffer_len, "%pI4", ip);
839     #else
840     char addr[sizeof("255.255.255.255")];
841     ip4_string(addr, (const u8 *) ip);
842     return snprintf(buffer, buffer_len, "%s", addr);
843     #endif
844     }
845    
846     /**
847     * ccs_print_ipv6 - Print an IPv6 address.
848     *
849     * @buffer: Buffer to write to.
850     * @buffer_len: Size of @buffer.
851     * @ip: Pointer to "struct in6_addr".
852     *
853     * Returns written length.
854     */
855     int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
856     const struct in6_addr *ip)
857     {
858     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
859     return snprintf(buffer, buffer_len, "%pI6c", ip);
860     #else
861     char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
862     ip6_compressed_string(addr, (const u8 *) ip);
863     return snprintf(buffer, buffer_len, "%s", addr);
864     #endif
865     }
866    
867     /***** SECTION5: Variables definition section *****/
868    
869 kumaneko 2863 /* Permit policy management by non-root user? */
870     static bool ccs_manage_by_non_root;
871    
872 kumaneko 5594 /* List of namespaces. */
873     LIST_HEAD(ccs_namespace_list);
874     /* True if namespace other than ccs_kernel_namespace is defined. */
875     static bool ccs_namespace_enabled;
876    
877     /* Bitmap for reserved local port numbers.*/
878     static u8 ccs_reserved_port_map[8192];
879    
880     /* Wait queue for kernel -> userspace notification. */
881     static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
882     /* Wait queue for userspace -> kernel notification. */
883     static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait);
884    
885     /* The list for "struct ccs_query". */
886     static LIST_HEAD(ccs_query_list);
887    
888     /* Lock for manipulating ccs_query_list. */
889     static DEFINE_SPINLOCK(ccs_query_list_lock);
890    
891     /* Number of "struct file" referring /proc/ccs/query interface. */
892     static atomic_t ccs_query_observers = ATOMIC_INIT(0);
893    
894     /* Timestamp counter for last updated. */
895     static unsigned int ccs_stat_updated[CCS_MAX_POLICY_STAT];
896     /* Counter for number of updates. */
897     static unsigned int ccs_stat_modified[CCS_MAX_POLICY_STAT];
898    
899 kumaneko 5595 /* Operations for /proc/ccs/self_domain interface. */
900     static
901     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
902     const
903     #endif
904     struct file_operations ccs_self_operations = {
905     .write = ccs_write_self,
906     .read = ccs_read_self,
907     };
908    
909     /* Operations for /proc/ccs/ interface. */
910     static
911     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
912     const
913     #endif
914     struct file_operations ccs_operations = {
915     .open = ccs_open,
916     .release = ccs_release,
917     .poll = ccs_poll,
918     .read = ccs_read,
919     .write = ccs_write,
920     };
921    
922     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
923    
924     /* The inode operations for /proc/ccs/ directory. */
925     static struct inode_operations ccs_dir_inode_operations;
926    
927     /* The inode operations for files under /proc/ccs/ directory. */
928     static struct inode_operations ccs_file_inode_operations;
929    
930     #endif
931    
932    
933 kumaneko 5594 /***** SECTION6: Dependent functions section *****/
934    
935 kumaneko 2863 /**
936 kumaneko 5594 * list_for_each_cookie - iterate over a list with cookie.
937     *
938     * @pos: Pointer to "struct list_head".
939     * @head: Pointer to "struct list_head".
940     */
941     #define list_for_each_cookie(pos, head) \
942     for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \
943     pos != (head); pos = srcu_dereference(pos->next, &ccs_ss))
944    
945     /**
946     * ccs_print_ip - Print an IP address.
947     *
948     * @buf: Buffer to write to.
949     * @size: Size of @buf.
950     * @ptr: Pointer to "struct ipaddr_union".
951     *
952     * Returns nothing.
953     */
954     static void ccs_print_ip(char *buf, const unsigned int size,
955     const struct ccs_ipaddr_union *ptr)
956     {
957     int len;
958     if (ptr->is_ipv6)
959     len = ccs_print_ipv6(buf, size, &ptr->ip[0]);
960     else
961     len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]);
962     if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2)
963     return;
964     buf[len++] = '-';
965     if (ptr->is_ipv6)
966     ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]);
967     else
968     ccs_print_ipv4(buf + len, size - len,
969     &ptr->ip[1].s6_addr32[0]);
970     }
971    
972     /**
973     * ccs_parse_name_union - Parse a ccs_name_union.
974     *
975     * @param: Pointer to "struct ccs_acl_param".
976     * @ptr: Pointer to "struct ccs_name_union".
977     *
978     * Returns true on success, false otherwise.
979     */
980     static bool ccs_parse_name_union(struct ccs_acl_param *param,
981     struct ccs_name_union *ptr)
982     {
983     char *filename;
984     if (param->data[0] == '@') {
985     param->data++;
986     ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
987     return ptr->group != NULL;
988     }
989     filename = ccs_read_token(param);
990     if (!ccs_correct_word(filename))
991     return false;
992     ptr->filename = ccs_get_name(filename);
993     return ptr->filename != NULL;
994     }
995    
996     /**
997     * ccs_parse_number_union - Parse a ccs_number_union.
998     *
999     * @param: Pointer to "struct ccs_acl_param".
1000     * @ptr: Pointer to "struct ccs_number_union".
1001     *
1002     * Returns true on success, false otherwise.
1003     */
1004     static bool ccs_parse_number_union(struct ccs_acl_param *param,
1005     struct ccs_number_union *ptr)
1006     {
1007     char *data;
1008     u8 type;
1009     unsigned long v;
1010     memset(ptr, 0, sizeof(*ptr));
1011     if (param->data[0] == '@') {
1012     param->data++;
1013     ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
1014     return ptr->group != NULL;
1015     }
1016     data = ccs_read_token(param);
1017     type = ccs_parse_ulong(&v, &data);
1018     if (type == CCS_VALUE_TYPE_INVALID)
1019     return false;
1020     ptr->values[0] = v;
1021     ptr->value_type[0] = type;
1022     if (!*data) {
1023     ptr->values[1] = v;
1024     ptr->value_type[1] = type;
1025     return true;
1026     }
1027     if (*data++ != '-')
1028     return false;
1029     type = ccs_parse_ulong(&v, &data);
1030     if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
1031     return false;
1032     ptr->values[1] = v;
1033     ptr->value_type[1] = type;
1034     return true;
1035     }
1036    
1037     /**
1038     * ccs_parse_ipaddr_union - Parse an IP address.
1039     *
1040     * @param: Pointer to "struct ccs_acl_param".
1041     * @ptr: Pointer to "struct ccs_ipaddr_union".
1042     *
1043     * Returns true on success, false otherwise.
1044     */
1045     static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
1046     struct ccs_ipaddr_union *ptr)
1047     {
1048     u8 * const min = ptr->ip[0].in6_u.u6_addr8;
1049     u8 * const max = ptr->ip[1].in6_u.u6_addr8;
1050     char *address = ccs_read_token(param);
1051     const char *end;
1052     if (!strchr(address, ':') &&
1053     ccs_in4_pton(address, -1, min, '-', &end) > 0) {
1054     ptr->is_ipv6 = false;
1055     if (!*end)
1056     ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
1057     else if (*end++ != '-' ||
1058     ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
1059     return false;
1060     return true;
1061     }
1062     if (ccs_in6_pton(address, -1, min, '-', &end) > 0) {
1063     ptr->is_ipv6 = true;
1064     if (!*end)
1065     memmove(max, min, sizeof(u16) * 8);
1066     else if (*end++ != '-' ||
1067     ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
1068     return false;
1069     return true;
1070     }
1071     return false;
1072     }
1073    
1074     /**
1075     * ccs_get_dqword - ccs_get_name() for a quoted string.
1076     *
1077     * @start: String to save.
1078     *
1079     * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
1080     */
1081     static const struct ccs_path_info *ccs_get_dqword(char *start)
1082     {
1083     char *cp = start + strlen(start) - 1;
1084     if (cp == start || *start++ != '"' || *cp != '"')
1085     return NULL;
1086     *cp = '\0';
1087     if (*start && !ccs_correct_word(start))
1088     return NULL;
1089     return ccs_get_name(start);
1090     }
1091    
1092     /**
1093     * ccs_parse_name_union_quoted - Parse a quoted word.
1094     *
1095     * @param: Pointer to "struct ccs_acl_param".
1096     * @ptr: Pointer to "struct ccs_name_union".
1097     *
1098     * Returns true on success, false otherwise.
1099     */
1100     static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
1101     struct ccs_name_union *ptr)
1102     {
1103     char *filename = param->data;
1104     if (*filename == '@')
1105     return ccs_parse_name_union(param, ptr);
1106     ptr->filename = ccs_get_dqword(filename);
1107     return ptr->filename != NULL;
1108     }
1109    
1110     /**
1111     * ccs_parse_argv - Parse an argv[] condition part.
1112     *
1113     * @left: Lefthand value.
1114     * @right: Righthand value.
1115     * @argv: Pointer to "struct ccs_argv".
1116     *
1117     * Returns true on success, false otherwise.
1118     */
1119     static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
1120     {
1121     if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL ||
1122     *left++ != ']' || *left)
1123     return false;
1124     argv->value = ccs_get_dqword(right);
1125     return argv->value != NULL;
1126     }
1127    
1128     /**
1129     * ccs_parse_envp - Parse an envp[] condition part.
1130     *
1131     * @left: Lefthand value.
1132     * @right: Righthand value.
1133     * @envp: Pointer to "struct ccs_envp".
1134     *
1135     * Returns true on success, false otherwise.
1136     */
1137     static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
1138     {
1139     const struct ccs_path_info *name;
1140     const struct ccs_path_info *value;
1141     char *cp = left + strlen(left) - 1;
1142     if (*cp-- != ']' || *cp != '"')
1143     goto out;
1144     *cp = '\0';
1145     if (!ccs_correct_word(left))
1146     goto out;
1147     name = ccs_get_name(left);
1148     if (!name)
1149     goto out;
1150     if (!strcmp(right, "NULL")) {
1151     value = NULL;
1152     } else {
1153     value = ccs_get_dqword(right);
1154     if (!value) {
1155     ccs_put_name(name);
1156     goto out;
1157     }
1158     }
1159     envp->name = name;
1160     envp->value = value;
1161     return true;
1162     out:
1163     return false;
1164     }
1165    
1166     /**
1167     * ccs_same_condition - Check for duplicated "struct ccs_condition" entry.
1168     *
1169     * @a: Pointer to "struct ccs_condition".
1170     * @b: Pointer to "struct ccs_condition".
1171     *
1172     * Returns true if @a == @b, false otherwise.
1173     */
1174     static bool ccs_same_condition(const struct ccs_condition *a,
1175     const struct ccs_condition *b)
1176     {
1177     return a->size == b->size && a->condc == b->condc &&
1178     a->numbers_count == b->numbers_count &&
1179     a->names_count == b->names_count &&
1180     a->argc == b->argc && a->envc == b->envc &&
1181     a->grant_log == b->grant_log &&
1182     a->exec_transit == b->exec_transit && a->transit == b->transit
1183     && !memcmp(a + 1, b + 1, a->size - sizeof(*a));
1184     }
1185    
1186     /**
1187     * ccs_condition_type - Get condition type.
1188     *
1189     * @word: Keyword string.
1190     *
1191     * Returns one of values in "enum ccs_conditions_index" on success,
1192     * CCS_MAX_CONDITION_KEYWORD otherwise.
1193     */
1194     static u8 ccs_condition_type(const char *word)
1195     {
1196     u8 i;
1197     for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) {
1198     if (!strcmp(word, ccs_condition_keyword[i]))
1199     break;
1200     }
1201     return i;
1202     }
1203    
1204     /**
1205     * ccs_commit_condition - Commit "struct ccs_condition".
1206     *
1207     * @entry: Pointer to "struct ccs_condition".
1208     *
1209     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
1210     *
1211     * This function merges duplicated entries. This function returns NULL if
1212     * @entry is not duplicated but memory quota for policy has exceeded.
1213     */
1214     static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry)
1215     {
1216     struct ccs_condition *ptr;
1217     bool found = false;
1218     if (mutex_lock_interruptible(&ccs_policy_lock)) {
1219     dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
1220     ptr = NULL;
1221     found = true;
1222     goto out;
1223     }
1224     list_for_each_entry(ptr, &ccs_condition_list, head.list) {
1225     if (!ccs_same_condition(ptr, entry) ||
1226     atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS)
1227     continue;
1228     /* Same entry found. Share this entry. */
1229     atomic_inc(&ptr->head.users);
1230     found = true;
1231     break;
1232     }
1233     if (!found) {
1234     if (ccs_memory_ok(entry, entry->size)) {
1235     atomic_set(&entry->head.users, 1);
1236     list_add(&entry->head.list, &ccs_condition_list);
1237     } else {
1238     found = true;
1239     ptr = NULL;
1240     }
1241     }
1242     mutex_unlock(&ccs_policy_lock);
1243     out:
1244     if (found) {
1245     ccs_del_condition(&entry->head.list);
1246     kfree(entry);
1247     entry = ptr;
1248     }
1249     return entry;
1250     }
1251    
1252     /**
1253     * ccs_get_transit_preference - Parse domain transition preference for execve().
1254     *
1255     * @param: Pointer to "struct ccs_acl_param".
1256     * @e: Pointer to "struct ccs_condition".
1257     *
1258     * Returns the condition string part.
1259     */
1260     static char *ccs_get_transit_preference(struct ccs_acl_param *param,
1261     struct ccs_condition *e)
1262     {
1263     char * const pos = param->data;
1264     bool flag;
1265     if (*pos == '<') {
1266     e->transit = ccs_get_domainname(param);
1267     goto done;
1268     }
1269     {
1270     char *cp = strchr(pos, ' ');
1271     if (cp)
1272     *cp = '\0';
1273     flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
1274     !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
1275     !strcmp(pos, "child") || !strcmp(pos, "parent");
1276     if (cp)
1277     *cp = ' ';
1278     }
1279     if (!flag)
1280     return pos;
1281     e->transit = ccs_get_name(ccs_read_token(param));
1282     done:
1283     if (e->transit) {
1284     e->exec_transit = true;
1285     return param->data;
1286     }
1287     /*
1288     * Return a bad read-only condition string that will let
1289     * ccs_get_condition() return NULL.
1290     */
1291     return "/";
1292     }
1293    
1294     /**
1295     * ccs_get_condition - Parse condition part.
1296     *
1297     * @param: Pointer to "struct ccs_acl_param".
1298     *
1299     * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
1300     */
1301     struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param)
1302     {
1303     struct ccs_condition *entry = NULL;
1304     struct ccs_condition_element *condp = NULL;
1305     struct ccs_number_union *numbers_p = NULL;
1306     struct ccs_name_union *names_p = NULL;
1307     struct ccs_argv *argv = NULL;
1308     struct ccs_envp *envp = NULL;
1309     struct ccs_condition e = { };
1310     char * const start_of_string = ccs_get_transit_preference(param, &e);
1311     char * const end_of_string = start_of_string + strlen(start_of_string);
1312     char *pos;
1313     rerun:
1314     pos = start_of_string;
1315     while (1) {
1316     u8 left = -1;
1317     u8 right = -1;
1318     char *left_word = pos;
1319     char *cp;
1320     char *right_word;
1321     bool is_not;
1322     if (!*left_word)
1323     break;
1324     /*
1325     * Since left-hand condition does not allow use of "path_group"
1326     * or "number_group" and environment variable's names do not
1327     * accept '=', it is guaranteed that the original line consists
1328     * of one or more repetition of $left$operator$right blocks
1329     * where "$left is free from '=' and ' '" and "$operator is
1330     * either '=' or '!='" and "$right is free from ' '".
1331     * Therefore, we can reconstruct the original line at the end
1332     * of dry run even if we overwrite $operator with '\0'.
1333     */
1334     cp = strchr(pos, ' ');
1335     if (cp) {
1336     *cp = '\0'; /* Will restore later. */
1337     pos = cp + 1;
1338     } else {
1339     pos = "";
1340     }
1341     right_word = strchr(left_word, '=');
1342     if (!right_word || right_word == left_word)
1343     goto out;
1344     is_not = *(right_word - 1) == '!';
1345     if (is_not)
1346     *(right_word++ - 1) = '\0'; /* Will restore later. */
1347     else if (*(right_word + 1) != '=')
1348     *right_word++ = '\0'; /* Will restore later. */
1349     else
1350     goto out;
1351     dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
1352     is_not ? "!" : "", right_word);
1353     if (!strcmp(left_word, "grant_log")) {
1354     if (entry) {
1355     if (is_not ||
1356     entry->grant_log != CCS_GRANTLOG_AUTO)
1357     goto out;
1358     else if (!strcmp(right_word, "yes"))
1359     entry->grant_log = CCS_GRANTLOG_YES;
1360     else if (!strcmp(right_word, "no"))
1361     entry->grant_log = CCS_GRANTLOG_NO;
1362     else
1363     goto out;
1364     }
1365     continue;
1366     }
1367     if (!strcmp(left_word, "auto_domain_transition")) {
1368     if (entry) {
1369     if (is_not || entry->transit)
1370     goto out;
1371     entry->transit = ccs_get_dqword(right_word);
1372     if (!entry->transit ||
1373     (entry->transit->name[0] != '/' &&
1374     !ccs_domain_def(entry->transit->name)))
1375     goto out;
1376     }
1377     continue;
1378     }
1379     if (!strncmp(left_word, "exec.argv[", 10)) {
1380     if (!argv) {
1381     e.argc++;
1382     e.condc++;
1383     } else {
1384     e.argc--;
1385     e.condc--;
1386     left = CCS_ARGV_ENTRY;
1387     argv->is_not = is_not;
1388     if (!ccs_parse_argv(left_word + 10,
1389     right_word, argv++))
1390     goto out;
1391     }
1392     goto store_value;
1393     }
1394     if (!strncmp(left_word, "exec.envp[\"", 11)) {
1395     if (!envp) {
1396     e.envc++;
1397     e.condc++;
1398     } else {
1399     e.envc--;
1400     e.condc--;
1401     left = CCS_ENVP_ENTRY;
1402     envp->is_not = is_not;
1403     if (!ccs_parse_envp(left_word + 11,
1404     right_word, envp++))
1405     goto out;
1406     }
1407     goto store_value;
1408     }
1409     left = ccs_condition_type(left_word);
1410     dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
1411     left);
1412     if (left == CCS_MAX_CONDITION_KEYWORD) {
1413     if (!numbers_p) {
1414     e.numbers_count++;
1415     } else {
1416     e.numbers_count--;
1417     left = CCS_NUMBER_UNION;
1418     param->data = left_word;
1419     if (*left_word == '@' ||
1420     !ccs_parse_number_union(param,
1421     numbers_p++))
1422     goto out;
1423     }
1424     }
1425     if (!condp)
1426     e.condc++;
1427     else
1428     e.condc--;
1429     if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
1430     if (!names_p) {
1431     e.names_count++;
1432     } else {
1433     e.names_count--;
1434     right = CCS_NAME_UNION;
1435     param->data = right_word;
1436     if (!ccs_parse_name_union_quoted(param,
1437     names_p++))
1438     goto out;
1439     }
1440     goto store_value;
1441     }
1442     right = ccs_condition_type(right_word);
1443     if (right == CCS_MAX_CONDITION_KEYWORD) {
1444     if (!numbers_p) {
1445     e.numbers_count++;
1446     } else {
1447     e.numbers_count--;
1448     right = CCS_NUMBER_UNION;
1449     param->data = right_word;
1450     if (!ccs_parse_number_union(param,
1451     numbers_p++))
1452     goto out;
1453     }
1454     }
1455     store_value:
1456     if (!condp) {
1457     dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
1458     "match=%u\n", __LINE__, left, right, !is_not);
1459     continue;
1460     }
1461     condp->left = left;
1462     condp->right = right;
1463     condp->equals = !is_not;
1464     dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
1465     __LINE__, condp->left, condp->right,
1466     condp->equals);
1467     condp++;
1468     }
1469     dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
1470     __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
1471     e.envc);
1472     if (entry) {
1473     BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
1474     e.condc);
1475     return ccs_commit_condition(entry);
1476     }
1477     e.size = sizeof(*entry)
1478     + e.condc * sizeof(struct ccs_condition_element)
1479     + e.numbers_count * sizeof(struct ccs_number_union)
1480     + e.names_count * sizeof(struct ccs_name_union)
1481     + e.argc * sizeof(struct ccs_argv)
1482     + e.envc * sizeof(struct ccs_envp);
1483     entry = kzalloc(e.size, CCS_GFP_FLAGS);
1484     if (!entry)
1485     goto out2;
1486     *entry = e;
1487     e.transit = NULL;
1488     condp = (struct ccs_condition_element *) (entry + 1);
1489     numbers_p = (struct ccs_number_union *) (condp + e.condc);
1490     names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
1491     argv = (struct ccs_argv *) (names_p + e.names_count);
1492     envp = (struct ccs_envp *) (argv + e.argc);
1493     {
1494     bool flag = false;
1495     for (pos = start_of_string; pos < end_of_string; pos++) {
1496     if (*pos)
1497     continue;
1498     if (flag) /* Restore " ". */
1499     *pos = ' ';
1500     else if (*(pos + 1) == '=') /* Restore "!=". */
1501     *pos = '!';
1502     else /* Restore "=". */
1503     *pos = '=';
1504     flag = !flag;
1505     }
1506     }
1507     goto rerun;
1508     out:
1509     dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
1510     if (entry) {
1511     ccs_del_condition(&entry->head.list);
1512     kfree(entry);
1513     }
1514     out2:
1515     ccs_put_name(e.transit);
1516     return NULL;
1517     }
1518    
1519     /* Permit policy management by non-root user? */
1520     static bool ccs_manage_by_non_root;
1521    
1522     /**
1523 kumaneko 2958 * ccs_yesno - Return "yes" or "no".
1524 kumaneko 2863 *
1525 kumaneko 2958 * @value: Bool value.
1526 kumaneko 4063 *
1527     * Returns "yes" if @value is not 0, "no" otherwise.
1528 kumaneko 2863 */
1529 kumaneko 4170 const char *ccs_yesno(const unsigned int value)
1530 kumaneko 2863 {
1531 kumaneko 2958 return value ? "yes" : "no";
1532 kumaneko 2863 }
1533    
1534 kumaneko 4063 /**
1535 kumaneko 4084 * ccs_addprintf - strncat()-like-snprintf().
1536 kumaneko 4063 *
1537     * @buffer: Buffer to write to. Must be '\0'-terminated.
1538     * @len: Size of @buffer.
1539     * @fmt: The printf()'s format string, followed by parameters.
1540     *
1541     * Returns nothing.
1542     */
1543 kumaneko 4049 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
1544 kumaneko 3780 {
1545     va_list args;
1546     const int pos = strlen(buffer);
1547     va_start(args, fmt);
1548     vsnprintf(buffer + pos, len - pos - 1, fmt, args);
1549     va_end(args);
1550     }
1551    
1552 kumaneko 2863 /**
1553 kumaneko 3780 * ccs_flush - Flush queued string to userspace's buffer.
1554 kumaneko 2863 *
1555 kumaneko 4063 * @head: Pointer to "struct ccs_io_buffer".
1556 kumaneko 2863 *
1557 kumaneko 3780 * Returns true if all data was flushed, false otherwise.
1558     */
1559     static bool ccs_flush(struct ccs_io_buffer *head)
1560     {
1561     while (head->r.w_pos) {
1562     const char *w = head->r.w[0];
1563 kumaneko 4668 size_t len = strlen(w);
1564 kumaneko 3780 if (len) {
1565     if (len > head->read_user_buf_avail)
1566     len = head->read_user_buf_avail;
1567     if (!len)
1568     return false;
1569     if (copy_to_user(head->read_user_buf, w, len))
1570     return false;
1571     head->read_user_buf_avail -= len;
1572     head->read_user_buf += len;
1573     w += len;
1574     }
1575 kumaneko 4536 head->r.w[0] = w;
1576     if (*w)
1577 kumaneko 3780 return false;
1578     /* Add '\0' for audit logs and query. */
1579 kumaneko 5106 if (head->type == CCS_AUDIT || head->type == CCS_QUERY) {
1580 kumaneko 3780 if (!head->read_user_buf_avail ||
1581     copy_to_user(head->read_user_buf, "", 1))
1582     return false;
1583     head->read_user_buf_avail--;
1584     head->read_user_buf++;
1585     }
1586     head->r.w_pos--;
1587     for (len = 0; len < head->r.w_pos; len++)
1588     head->r.w[len] = head->r.w[len + 1];
1589     }
1590     head->r.avail = 0;
1591     return true;
1592     }
1593    
1594     /**
1595     * ccs_set_string - Queue string to "struct ccs_io_buffer" structure.
1596 kumaneko 2863 *
1597 kumaneko 3780 * @head: Pointer to "struct ccs_io_buffer".
1598     * @string: String to print.
1599     *
1600 kumaneko 4084 * Returns nothing.
1601     *
1602 kumaneko 3780 * Note that @string has to be kept valid until @head is kfree()d.
1603     * This means that char[] allocated on stack memory cannot be passed to
1604     * this function. Use ccs_io_printf() for char[] allocated on stack memory.
1605 kumaneko 2863 */
1606 kumaneko 3780 static void ccs_set_string(struct ccs_io_buffer *head, const char *string)
1607 kumaneko 2863 {
1608 kumaneko 3780 if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) {
1609     head->r.w[head->r.w_pos++] = string;
1610     ccs_flush(head);
1611     } else
1612 kumaneko 3829 printk(KERN_WARNING "Too many words in a line.\n");
1613 kumaneko 3780 }
1614    
1615     /**
1616     * ccs_io_printf - printf() to "struct ccs_io_buffer" structure.
1617     *
1618     * @head: Pointer to "struct ccs_io_buffer".
1619     * @fmt: The printf()'s format string, followed by parameters.
1620 kumaneko 4063 *
1621     * Returns nothing.
1622 kumaneko 3780 */
1623 kumaneko 4535 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
1624 kumaneko 3780 {
1625 kumaneko 2863 va_list args;
1626 kumaneko 4668 size_t len;
1627     size_t pos = head->r.avail;
1628 kumaneko 2863 int size = head->readbuf_size - pos;
1629     if (size <= 0)
1630 kumaneko 3780 return;
1631 kumaneko 2863 va_start(args, fmt);
1632 kumaneko 3780 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
1633 kumaneko 2863 va_end(args);
1634 kumaneko 3780 if (pos + len >= head->readbuf_size) {
1635 kumaneko 3829 printk(KERN_WARNING "Too many words in a line.\n");
1636 kumaneko 3780 return;
1637     }
1638     head->r.avail += len;
1639     ccs_set_string(head, head->read_buf + pos);
1640 kumaneko 2863 }
1641    
1642 kumaneko 4063 /**
1643     * ccs_set_space - Put a space to "struct ccs_io_buffer" structure.
1644     *
1645     * @head: Pointer to "struct ccs_io_buffer".
1646     *
1647     * Returns nothing.
1648     */
1649 kumaneko 3780 static void ccs_set_space(struct ccs_io_buffer *head)
1650     {
1651     ccs_set_string(head, " ");
1652     }
1653    
1654 kumaneko 4063 /**
1655     * ccs_set_lf - Put a line feed to "struct ccs_io_buffer" structure.
1656     *
1657     * @head: Pointer to "struct ccs_io_buffer".
1658     *
1659     * Returns nothing.
1660     */
1661 kumaneko 3780 static bool ccs_set_lf(struct ccs_io_buffer *head)
1662     {
1663     ccs_set_string(head, "\n");
1664     return !head->r.w_pos;
1665     }
1666    
1667 kumaneko 2863 /**
1668 kumaneko 4724 * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure.
1669     *
1670     * @head: Pointer to "struct ccs_io_buffer".
1671     *
1672     * Returns nothing.
1673     */
1674     static void ccs_set_slash(struct ccs_io_buffer *head)
1675     {
1676     ccs_set_string(head, "/");
1677     }
1678    
1679     /**
1680 kumaneko 5050 * ccs_init_policy_namespace - Initialize namespace.
1681     *
1682     * @ns: Pointer to "struct ccs_policy_namespace".
1683     *
1684     * Returns nothing.
1685     */
1686     void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
1687     {
1688     unsigned int idx;
1689 kumaneko 5094 for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++)
1690     INIT_LIST_HEAD(&ns->acl_group[idx]);
1691 kumaneko 5050 for (idx = 0; idx < CCS_MAX_GROUP; idx++)
1692     INIT_LIST_HEAD(&ns->group_list[idx]);
1693     for (idx = 0; idx < CCS_MAX_POLICY; idx++)
1694     INIT_LIST_HEAD(&ns->policy_list[idx]);
1695 kumaneko 5052 ns->profile_version = 20100903;
1696 kumaneko 5050 ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
1697     list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list);
1698     }
1699    
1700     /**
1701     * ccs_print_namespace - Print namespace header.
1702     *
1703     * @head: Pointer to "struct ccs_io_buffer".
1704     *
1705     * Returns nothing.
1706     */
1707     static void ccs_print_namespace(struct ccs_io_buffer *head)
1708     {
1709     if (!ccs_namespace_enabled)
1710     return;
1711     ccs_set_string(head,
1712     container_of(head->r.ns, struct ccs_policy_namespace,
1713     namespace_list)->name);
1714     ccs_set_space(head);
1715     }
1716    
1717     /**
1718 kumaneko 3694 * ccs_assign_profile - Create a new profile.
1719 kumaneko 2863 *
1720 kumaneko 5050 * @ns: Pointer to "struct ccs_policy_namespace".
1721 kumaneko 2863 * @profile: Profile number to create.
1722     *
1723     * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
1724     */
1725 kumaneko 5050 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
1726     const unsigned int profile)
1727 kumaneko 2863 {
1728     struct ccs_profile *ptr;
1729     struct ccs_profile *entry;
1730 kumaneko 2892 if (profile >= CCS_MAX_PROFILES)
1731 kumaneko 2863 return NULL;
1732 kumaneko 5050 ptr = ns->profile_ptr[profile];
1733 kumaneko 2863 if (ptr)
1734     return ptr;
1735 kumaneko 3512 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
1736 kumaneko 3534 if (mutex_lock_interruptible(&ccs_policy_lock))
1737     goto out;
1738 kumaneko 5050 ptr = ns->profile_ptr[profile];
1739 kumaneko 5487 if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
1740 kumaneko 2863 ptr = entry;
1741 kumaneko 2958 ptr->default_config = CCS_CONFIG_DISABLED |
1742     CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
1743     memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
1744 kumaneko 2943 sizeof(ptr->config));
1745 kumaneko 4170 ptr->pref[CCS_PREF_MAX_AUDIT_LOG] =
1746     CONFIG_CCSECURITY_MAX_AUDIT_LOG;
1747 kumaneko 4049 ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] =
1748     CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY;
1749 kumaneko 2863 mb(); /* Avoid out-of-order execution. */
1750 kumaneko 5050 ns->profile_ptr[profile] = ptr;
1751 kumaneko 2863 entry = NULL;
1752     }
1753     mutex_unlock(&ccs_policy_lock);
1754 kumaneko 4049 out:
1755 kumaneko 2863 kfree(entry);
1756     return ptr;
1757     }
1758    
1759     /**
1760 kumaneko 2991 * ccs_check_profile - Check all profiles currently assigned to domains are defined.
1761 kumaneko 4063 *
1762     * Returns nothing.
1763 kumaneko 2991 */
1764 kumaneko 3502 static void ccs_check_profile(void)
1765 kumaneko 2991 {
1766     struct ccs_domain_info *domain;
1767 kumaneko 3535 const int idx = ccs_read_lock();
1768 kumaneko 2991 ccs_policy_loaded = true;
1769 kumaneko 5567 printk(KERN_INFO "CCSecurity: 1.8.3+ 2011/10/25\n");
1770 kumaneko 4049 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
1771 kumaneko 2991 const u8 profile = domain->profile;
1772 kumaneko 5052 const struct ccs_policy_namespace *ns = domain->ns;
1773     if (ns->profile_version != 20100903)
1774     printk(KERN_ERR
1775     "Profile version %u is not supported.\n",
1776     ns->profile_version);
1777     else if (!ns->profile_ptr[profile])
1778     printk(KERN_ERR
1779     "Profile %u (used by '%s') is not defined.\n",
1780     profile, domain->domainname->name);
1781     else
1782 kumaneko 2991 continue;
1783 kumaneko 5052 printk(KERN_ERR
1784     "Userland tools for TOMOYO 1.8 must be installed and "
1785     "policy must be initialized.\n");
1786 kumaneko 4053 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/1.8/ "
1787     "for more information.\n");
1788 kumaneko 5052 panic("STOP!");
1789 kumaneko 2991 }
1790 kumaneko 5050 ccs_read_unlock(idx);
1791 kumaneko 3502 printk(KERN_INFO "Mandatory Access Control activated.\n");
1792 kumaneko 2991 }
1793    
1794     /**
1795 kumaneko 2958 * ccs_profile - Find a profile.
1796     *
1797     * @profile: Profile number to find.
1798     *
1799 kumaneko 2991 * Returns pointer to "struct ccs_profile".
1800 kumaneko 2958 */
1801     struct ccs_profile *ccs_profile(const u8 profile)
1802     {
1803 kumaneko 3961 static struct ccs_profile ccs_null_profile;
1804 kumaneko 5050 struct ccs_profile *ptr = ccs_current_namespace()->
1805     profile_ptr[profile];
1806 kumaneko 3961 if (!ptr)
1807     ptr = &ccs_null_profile;
1808 kumaneko 2974 return ptr;
1809 kumaneko 2958 }
1810    
1811 kumaneko 4063 /**
1812     * ccs_find_yesno - Find values for specified keyword.
1813     *
1814     * @string: String to check.
1815     * @find: Name of keyword.
1816     *
1817     * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
1818     */
1819 kumaneko 3747 static s8 ccs_find_yesno(const char *string, const char *find)
1820 kumaneko 2863 {
1821 kumaneko 3747 const char *cp = strstr(string, find);
1822     if (cp) {
1823     cp += strlen(find);
1824 kumaneko 3758 if (!strncmp(cp, "=yes", 4))
1825 kumaneko 3747 return 1;
1826 kumaneko 3758 else if (!strncmp(cp, "=no", 3))
1827 kumaneko 3747 return 0;
1828 kumaneko 2863 }
1829 kumaneko 3747 return -1;
1830     }
1831    
1832 kumaneko 4063 /**
1833     * ccs_set_uint - Set value for specified preference.
1834     *
1835     * @i: Pointer to "unsigned int".
1836     * @string: String to check.
1837     * @find: Name of keyword.
1838     *
1839     * Returns nothing.
1840     */
1841 kumaneko 3747 static void ccs_set_uint(unsigned int *i, const char *string, const char *find)
1842     {
1843     const char *cp = strstr(string, find);
1844     if (cp)
1845     sscanf(cp + strlen(find), "=%u", i);
1846     }
1847    
1848 kumaneko 4063 /**
1849     * ccs_set_mode - Set mode for specified profile.
1850     *
1851     * @name: Name of functionality.
1852     * @value: Mode for @name.
1853     * @profile: Pointer to "struct ccs_profile".
1854     *
1855     * Returns 0 on success, negative value otherwise.
1856     */
1857 kumaneko 3870 static int ccs_set_mode(char *name, const char *value,
1858 kumaneko 3758 struct ccs_profile *profile)
1859 kumaneko 3747 {
1860     u8 i;
1861     u8 config;
1862 kumaneko 3758 if (!strcmp(name, "CONFIG")) {
1863 kumaneko 3968 i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
1864 kumaneko 2958 config = profile->default_config;
1865 kumaneko 3758 } else if (ccs_str_starts(&name, "CONFIG::")) {
1866 kumaneko 2958 config = 0;
1867 kumaneko 3968 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
1868     i++) {
1869     int len = 0;
1870     if (i < CCS_MAX_MAC_INDEX) {
1871     const u8 c = ccs_index2category[i];
1872 kumaneko 4049 const char *category =
1873     ccs_category_keywords[c];
1874 kumaneko 3968 len = strlen(category);
1875     if (strncmp(name, category, len) ||
1876     name[len++] != ':' || name[len++] != ':')
1877     continue;
1878     }
1879     if (strcmp(name + len, ccs_mac_keywords[i]))
1880 kumaneko 2943 continue;
1881 kumaneko 2958 config = profile->config[i];
1882 kumaneko 2943 break;
1883     }
1884 kumaneko 3968 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
1885 kumaneko 2958 return -EINVAL;
1886     } else {
1887     return -EINVAL;
1888     }
1889 kumaneko 3870 if (strstr(value, "use_default")) {
1890 kumaneko 2958 config = CCS_CONFIG_USE_DEFAULT;
1891     } else {
1892 kumaneko 3747 u8 mode;
1893 kumaneko 3758 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
1894     if (strstr(value, ccs_mode[mode]))
1895 kumaneko 2958 /*
1896     * Update lower 3 bits in order to distinguish
1897     * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
1898     */
1899     config = (config & ~7) | mode;
1900 kumaneko 3870 if (config != CCS_CONFIG_USE_DEFAULT) {
1901 kumaneko 3758 switch (ccs_find_yesno(value, "grant_log")) {
1902 kumaneko 3747 case 1:
1903 kumaneko 2958 config |= CCS_CONFIG_WANT_GRANT_LOG;
1904 kumaneko 3747 break;
1905     case 0:
1906 kumaneko 2958 config &= ~CCS_CONFIG_WANT_GRANT_LOG;
1907 kumaneko 3747 break;
1908     }
1909 kumaneko 3758 switch (ccs_find_yesno(value, "reject_log")) {
1910 kumaneko 3747 case 1:
1911 kumaneko 2958 config |= CCS_CONFIG_WANT_REJECT_LOG;
1912 kumaneko 3747 break;
1913     case 0:
1914 kumaneko 2958 config &= ~CCS_CONFIG_WANT_REJECT_LOG;
1915 kumaneko 3747 break;
1916     }
1917 kumaneko 3968 }
1918 kumaneko 2958 }
1919 kumaneko 3968 if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
1920 kumaneko 2958 profile->config[i] = config;
1921     else if (config != CCS_CONFIG_USE_DEFAULT)
1922     profile->default_config = config;
1923 kumaneko 2943 return 0;
1924 kumaneko 2863 }
1925    
1926 kumaneko 3747 /**
1927     * ccs_write_profile - Write profile table.
1928     *
1929     * @head: Pointer to "struct ccs_io_buffer".
1930     *
1931     * Returns 0 on success, negative value otherwise.
1932     */
1933     static int ccs_write_profile(struct ccs_io_buffer *head)
1934     {
1935     char *data = head->write_buf;
1936 kumaneko 3781 unsigned int i;
1937 kumaneko 3747 char *cp;
1938     struct ccs_profile *profile;
1939 kumaneko 5052 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
1940     == 1)
1941 kumaneko 3747 return 0;
1942     i = simple_strtoul(data, &cp, 10);
1943 kumaneko 3870 if (*cp != '-')
1944     return -EINVAL;
1945     data = cp + 1;
1946 kumaneko 5050 profile = ccs_assign_profile(head->w.ns, i);
1947 kumaneko 3870 if (!profile)
1948     return -EINVAL;
1949 kumaneko 3747 cp = strchr(data, '=');
1950     if (!cp)
1951     return -EINVAL;
1952     *cp++ = '\0';
1953     if (!strcmp(data, "COMMENT")) {
1954 kumaneko 4779 static DEFINE_SPINLOCK(lock);
1955     const struct ccs_path_info *new_comment = ccs_get_name(cp);
1956     const struct ccs_path_info *old_comment;
1957     if (!new_comment)
1958     return -ENOMEM;
1959     spin_lock(&lock);
1960     old_comment = profile->comment;
1961     profile->comment = new_comment;
1962     spin_unlock(&lock);
1963 kumaneko 3747 ccs_put_name(old_comment);
1964     return 0;
1965     }
1966 kumaneko 4049 if (!strcmp(data, "PREFERENCE")) {
1967     for (i = 0; i < CCS_MAX_PREF; i++)
1968     ccs_set_uint(&profile->pref[i], cp,
1969     ccs_pref_keywords[i]);
1970     return 0;
1971     }
1972 kumaneko 3870 return ccs_set_mode(data, cp, profile);
1973 kumaneko 3747 }
1974    
1975 kumaneko 4063 /**
1976     * ccs_print_config - Print mode for specified functionality.
1977     *
1978     * @head: Pointer to "struct ccs_io_buffer".
1979     * @config: Mode for that functionality.
1980     *
1981     * Returns nothing.
1982     *
1983     * Caller prints functionality's name.
1984     */
1985 kumaneko 3780 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)
1986     {
1987 kumaneko 4049 ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
1988     ccs_mode[config & 3],
1989 kumaneko 3780 ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
1990     ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));
1991     }
1992    
1993 kumaneko 2863 /**
1994     * ccs_read_profile - Read profile table.
1995     *
1996     * @head: Pointer to "struct ccs_io_buffer".
1997 kumaneko 4084 *
1998     * Returns nothing.
1999 kumaneko 2863 */
2000 kumaneko 2943 static void ccs_read_profile(struct ccs_io_buffer *head)
2001 kumaneko 2863 {
2002 kumaneko 3780 u8 index;
2003 kumaneko 5050 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
2004     namespace_list);
2005 kumaneko 3780 const struct ccs_profile *profile;
2006 kumaneko 5050 if (head->r.eof)
2007     return;
2008 kumaneko 4049 next:
2009 kumaneko 3780 index = head->r.index;
2010 kumaneko 5050 profile = ns->profile_ptr[index];
2011 kumaneko 3780 switch (head->r.step) {
2012     case 0:
2013 kumaneko 5050 ccs_print_namespace(head);
2014 kumaneko 5134 ccs_io_printf(head, "PROFILE_VERSION=%u\n",
2015     ns->profile_version);
2016 kumaneko 3780 head->r.step++;
2017     break;
2018     case 1:
2019 kumaneko 5050 for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++)
2020     if (ns->profile_ptr[head->r.index])
2021 kumaneko 3780 break;
2022 kumaneko 5050 if (head->r.index == CCS_MAX_PROFILES) {
2023     head->r.eof = true;
2024 kumaneko 3780 return;
2025 kumaneko 5050 }
2026 kumaneko 3780 head->r.step++;
2027     break;
2028     case 2:
2029     {
2030 kumaneko 4049 u8 i;
2031 kumaneko 3780 const struct ccs_path_info *comment = profile->comment;
2032 kumaneko 5050 ccs_print_namespace(head);
2033 kumaneko 3780 ccs_io_printf(head, "%u-COMMENT=", index);
2034     ccs_set_string(head, comment ? comment->name : "");
2035     ccs_set_lf(head);
2036 kumaneko 5050 ccs_print_namespace(head);
2037 kumaneko 4049 ccs_io_printf(head, "%u-PREFERENCE={ ", index);
2038     for (i = 0; i < CCS_MAX_PREF; i++)
2039     ccs_io_printf(head, "%s=%u ",
2040     ccs_pref_keywords[i],
2041     profile->pref[i]);
2042 kumaneko 4923 ccs_set_string(head, "}\n");
2043 kumaneko 3780 head->r.step++;
2044     }
2045     break;
2046     case 3:
2047     {
2048 kumaneko 5050 ccs_print_namespace(head);
2049 kumaneko 3780 ccs_io_printf(head, "%u-%s", index, "CONFIG");
2050     ccs_print_config(head, profile->default_config);
2051     head->r.bit = 0;
2052     head->r.step++;
2053     }
2054     break;
2055     case 4:
2056     for ( ; head->r.bit < CCS_MAX_MAC_INDEX
2057     + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
2058     const u8 i = head->r.bit;
2059     const u8 config = profile->config[i];
2060 kumaneko 2958 if (config == CCS_CONFIG_USE_DEFAULT)
2061     continue;
2062 kumaneko 5050 ccs_print_namespace(head);
2063 kumaneko 3968 if (i < CCS_MAX_MAC_INDEX)
2064     ccs_io_printf(head, "%u-CONFIG::%s::%s", index,
2065     ccs_category_keywords
2066     [ccs_index2category[i]],
2067     ccs_mac_keywords[i]);
2068     else
2069     ccs_io_printf(head, "%u-CONFIG::%s", index,
2070     ccs_mac_keywords[i]);
2071 kumaneko 3780 ccs_print_config(head, config);
2072     head->r.bit++;
2073     break;
2074 kumaneko 2908 }
2075 kumaneko 3780 if (head->r.bit == CCS_MAX_MAC_INDEX
2076     + CCS_MAX_MAC_CATEGORY_INDEX) {
2077     head->r.index++;
2078     head->r.step = 1;
2079     }
2080 kumaneko 2958 break;
2081 kumaneko 2863 }
2082 kumaneko 3780 if (ccs_flush(head))
2083     goto next;
2084 kumaneko 2863 }
2085    
2086 kumaneko 4057 /**
2087 kumaneko 5594 * ccs_update_policy - Update an entry for exception policy.
2088 kumaneko 4057 *
2089 kumaneko 5594 * @size: Size of new entry in bytes.
2090     * @param: Pointer to "struct ccs_acl_param".
2091 kumaneko 4057 *
2092 kumaneko 5594 * Returns 0 on success, negative value otherwise.
2093     *
2094     * Caller holds ccs_read_lock().
2095 kumaneko 4057 */
2096 kumaneko 5594 static int ccs_update_policy(const int size, struct ccs_acl_param *param)
2097 kumaneko 3689 {
2098 kumaneko 5594 struct ccs_acl_head *new_entry = &param->e.acl_head;
2099     int error = param->is_delete ? -ENOENT : -ENOMEM;
2100     struct ccs_acl_head *entry;
2101     struct list_head *list = param->list;
2102     BUG_ON(size < sizeof(*entry));
2103     if (mutex_lock_interruptible(&ccs_policy_lock))
2104     return -ENOMEM;
2105     list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
2106     if (entry->is_deleted == CCS_GC_IN_PROGRESS)
2107     continue;
2108     if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
2109     continue;
2110     entry->is_deleted = param->is_delete;
2111     error = 0;
2112     break;
2113     }
2114     if (error && !param->is_delete) {
2115     entry = ccs_commit_ok(new_entry, size);
2116     if (entry) {
2117     list_add_tail_rcu(&entry->list, list);
2118     error = 0;
2119     }
2120     }
2121     mutex_unlock(&ccs_policy_lock);
2122     return error;
2123 kumaneko 3689 }
2124 kumaneko 2863
2125     /**
2126     * ccs_update_manager_entry - Add a manager entry.
2127     *
2128     * @manager: The path to manager or the domainnamme.
2129     * @is_delete: True if it is a delete request.
2130     *
2131     * Returns 0 on success, negative value otherwise.
2132     */
2133 kumaneko 5594 static int ccs_update_manager_entry(const char *manager,
2134     const bool is_delete)
2135 kumaneko 2863 {
2136 kumaneko 5050 struct ccs_acl_param param = {
2137     /* .ns = &ccs_kernel_namespace, */
2138     .is_delete = is_delete,
2139     .list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER],
2140     };
2141 kumaneko 5594 struct ccs_manager *e = &param.e.manager;
2142 kumaneko 2863 int error = is_delete ? -ENOENT : -ENOMEM;
2143 kumaneko 5594 /* Forced zero clear for using memcmp() at ccs_update_policy(). */
2144     memset(&param.e, 0, sizeof(param.e));
2145 kumaneko 3693 if (ccs_domain_def(manager)) {
2146     if (!ccs_correct_domain(manager))
2147 kumaneko 2863 return -EINVAL;
2148 kumaneko 5594 e->is_domain = true;
2149 kumaneko 2863 } else {
2150 kumaneko 3707 if (!ccs_correct_path(manager))
2151 kumaneko 2863 return -EINVAL;
2152     }
2153 kumaneko 5594 e->manager = ccs_get_name(manager);
2154     if (e->manager) {
2155     error = ccs_update_policy(sizeof(*e), &param);
2156     ccs_put_name(e->manager);
2157 kumaneko 5050 }
2158 kumaneko 2863 return error;
2159     }
2160    
2161     /**
2162 kumaneko 3693 * ccs_write_manager - Write manager policy.
2163 kumaneko 2863 *
2164     * @head: Pointer to "struct ccs_io_buffer".
2165     *
2166     * Returns 0 on success, negative value otherwise.
2167     */
2168 kumaneko 3693 static int ccs_write_manager(struct ccs_io_buffer *head)
2169 kumaneko 2863 {
2170 kumaneko 5050 const char *data = head->write_buf;
2171 kumaneko 2863 if (!strcmp(data, "manage_by_non_root")) {
2172 kumaneko 5050 ccs_manage_by_non_root = !head->w.is_delete;
2173 kumaneko 2863 return 0;
2174     }
2175 kumaneko 5050 return ccs_update_manager_entry(data, head->w.is_delete);
2176 kumaneko 2863 }
2177    
2178     /**
2179 kumaneko 3693 * ccs_read_manager - Read manager policy.
2180 kumaneko 2863 *
2181     * @head: Pointer to "struct ccs_io_buffer".
2182     *
2183 kumaneko 4084 * Returns nothing.
2184     *
2185 kumaneko 2863 * Caller holds ccs_read_lock().
2186     */
2187 kumaneko 3693 static void ccs_read_manager(struct ccs_io_buffer *head)
2188 kumaneko 2863 {
2189 kumaneko 3780 if (head->r.eof)
2190 kumaneko 2943 return;
2191 kumaneko 5050 list_for_each_cookie(head->r.acl, &ccs_kernel_namespace.
2192     policy_list[CCS_ID_MANAGER]) {
2193 kumaneko 3780 struct ccs_manager *ptr =
2194     list_entry(head->r.acl, typeof(*ptr), head.list);
2195 kumaneko 3689 if (ptr->head.is_deleted)
2196 kumaneko 2863 continue;
2197 kumaneko 3780 if (!ccs_flush(head))
2198 kumaneko 2943 return;
2199 kumaneko 3780 ccs_set_string(head, ptr->manager->name);
2200     ccs_set_lf(head);
2201 kumaneko 2863 }
2202 kumaneko 3780 head->r.eof = true;
2203 kumaneko 2863 }
2204    
2205     /**
2206 kumaneko 3693 * ccs_manager - Check whether the current process is a policy manager.
2207 kumaneko 2863 *
2208     * Returns true if the current process is permitted to modify policy
2209     * via /proc/ccs/ interface.
2210     *
2211     * Caller holds ccs_read_lock().
2212     */
2213 kumaneko 3693 static bool ccs_manager(void)
2214 kumaneko 2863 {
2215 kumaneko 3693 struct ccs_manager *ptr;
2216 kumaneko 2863 const char *exe;
2217 kumaneko 4049 struct ccs_security *task = ccs_current_security();
2218 kumaneko 2863 const struct ccs_path_info *domainname
2219     = ccs_current_domain()->domainname;
2220     bool found = false;
2221     if (!ccs_policy_loaded)
2222     return true;
2223 kumaneko 3693 if (task->ccs_flags & CCS_TASK_IS_MANAGER)
2224 kumaneko 2863 return true;
2225     if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
2226     return false;
2227     exe = ccs_get_exe();
2228 kumaneko 5050 list_for_each_entry_srcu(ptr, &ccs_kernel_namespace.
2229     policy_list[CCS_ID_MANAGER], head.list,
2230     &ccs_ss) {
2231 kumaneko 3697 if (ptr->head.is_deleted)
2232     continue;
2233     if (ptr->is_domain) {
2234     if (ccs_pathcmp(domainname, ptr->manager))
2235     continue;
2236     } else {
2237     if (!exe || strcmp(exe, ptr->manager->name))
2238     continue;
2239 kumaneko 2863 }
2240 kumaneko 3697 /* Set manager flag. */
2241     task->ccs_flags |= CCS_TASK_IS_MANAGER;
2242     found = true;
2243     break;
2244 kumaneko 2863 }
2245     if (!found) { /* Reduce error messages. */
2246     static pid_t ccs_last_pid;
2247     const pid_t pid = current->pid;
2248     if (ccs_last_pid != pid) {
2249     printk(KERN_WARNING "%s ( %s ) is not permitted to "
2250     "update policies.\n", domainname->name, exe);
2251     ccs_last_pid = pid;
2252     }
2253     }
2254     kfree(exe);
2255     return found;
2256     }
2257    
2258     /**
2259 kumaneko 5050 * ccs_select_domain - Parse select command.
2260 kumaneko 2863 *
2261     * @head: Pointer to "struct ccs_io_buffer".
2262     * @data: String to parse.
2263     *
2264     * Returns true on success, false otherwise.
2265     *
2266     * Caller holds ccs_read_lock().
2267     */
2268 kumaneko 5050 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data)
2269 kumaneko 2863 {
2270     unsigned int pid;
2271     struct ccs_domain_info *domain = NULL;
2272 kumaneko 2970 bool global_pid = false;
2273 kumaneko 5050 if (strncmp(data, "select ", 7))
2274     return false;
2275     data += 7;
2276 kumaneko 2970 if (sscanf(data, "pid=%u", &pid) == 1 ||
2277     (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
2278 kumaneko 2863 struct task_struct *p;
2279 kumaneko 3248 ccs_tasklist_lock();
2280 kumaneko 2970 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
2281     if (global_pid)
2282 kumaneko 3502 p = ccsecurity_exports.find_task_by_pid_ns(pid,
2283     &init_pid_ns);
2284 kumaneko 2970 else
2285 kumaneko 3502 p = ccsecurity_exports.find_task_by_vpid(pid);
2286 kumaneko 2970 #else
2287 kumaneko 2863 p = find_task_by_pid(pid);
2288 kumaneko 2970 #endif
2289 kumaneko 2863 if (p)
2290     domain = ccs_task_domain(p);
2291 kumaneko 3248 ccs_tasklist_unlock();
2292 kumaneko 2863 } else if (!strncmp(data, "domain=", 7)) {
2293 kumaneko 5050 if (*(data + 7) == '<')
2294 kumaneko 2863 domain = ccs_find_domain(data + 7);
2295 kumaneko 5559 } else if (sscanf(data, "Q=%u", &pid) == 1) {
2296     domain = ccs_find_domain_by_qid(pid);
2297 kumaneko 2863 } else
2298     return false;
2299 kumaneko 3780 head->w.domain = domain;
2300 kumaneko 2863 /* Accessing read_buf is safe because head->io_sem is held. */
2301     if (!head->read_buf)
2302     return true; /* Do nothing if open(O_WRONLY). */
2303 kumaneko 3780 memset(&head->r, 0, sizeof(head->r));
2304     head->r.print_this_domain_only = true;
2305 kumaneko 3892 if (domain)
2306     head->r.domain = &domain->list;
2307     else
2308     head->r.eof = true;
2309 kumaneko 2863 ccs_io_printf(head, "# select %s\n", data);
2310 kumaneko 3772 if (domain && domain->is_deleted)
2311 kumaneko 3780 ccs_set_string(head, "# This is a deleted domain.\n");
2312 kumaneko 2863 return true;
2313     }
2314    
2315 kumaneko 4057 /**
2316 kumaneko 5594 * ccs_update_domain - Update an entry for domain policy.
2317 kumaneko 4057 *
2318 kumaneko 5594 * @size: Size of new entry in bytes.
2319     * @param: Pointer to "struct ccs_acl_param".
2320 kumaneko 4057 *
2321 kumaneko 5594 * Returns 0 on success, negative value otherwise.
2322 kumaneko 4057 *
2323 kumaneko 5594 * Caller holds ccs_read_lock().
2324 kumaneko 4057 */
2325 kumaneko 5594 static int ccs_update_domain(const int size, struct ccs_acl_param *param)
2326 kumaneko 3924 {
2327 kumaneko 5594 struct ccs_acl_info *new_entry = &param->e.acl_info;
2328     const bool is_delete = param->is_delete;
2329     int error = is_delete ? -ENOENT : -ENOMEM;
2330     struct ccs_acl_info *entry;
2331     struct list_head * const list = param->list;
2332     BUG_ON(size < sizeof(*entry));
2333     if (param->data[0]) {
2334     new_entry->cond = ccs_get_condition(param);
2335     if (!new_entry->cond)
2336     return -EINVAL;
2337     /*
2338     * Domain transition preference is allowed for only
2339     * "file execute"/"task auto_execute_handler"/
2340     * "task denied_auto_execute_handler" entries.
2341     */
2342     if (new_entry->cond->exec_transit &&
2343     !(new_entry->type == CCS_TYPE_PATH_ACL &&
2344     new_entry->perm == 1 << CCS_TYPE_EXECUTE) &&
2345     new_entry->type != CCS_TYPE_AUTO_EXECUTE_HANDLER &&
2346     new_entry->type != CCS_TYPE_DENIED_EXECUTE_HANDLER)
2347     return -EINVAL;
2348     }
2349     if (mutex_lock_interruptible(&ccs_policy_lock))
2350     return -ENOMEM;
2351     list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
2352     if (entry->is_deleted == CCS_GC_IN_PROGRESS)