~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/ccsecurity/policy_io.c

Version: ~ [ linux-5.8 ] ~ [ linux-5.7.14 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.57 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.138 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.193 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.232 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.232 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * security/ccsecurity/policy_io.c
  3  *
  4  * Copyright (C) 2005-2012  NTT DATA CORPORATION
  5  *
  6  * Version: 1.8.6   2019/08/20
  7  */
  8 
  9 #include "internal.h"
 10 
 11 /***** SECTION1: Constants definition *****/
 12 
 13 /* Define this to enable debug mode. */
 14 /* #define DEBUG_CONDITION */
 15 
 16 #ifdef DEBUG_CONDITION
 17 #define dprintk printk
 18 #else
 19 #define dprintk(...) do { } while (0)
 20 #endif
 21 
 22 /* Mapping table from "enum ccs_mac_index" to "enum ccs_mac_category_index". */
 23 static const u8 ccs_index2category[CCS_MAX_MAC_INDEX] = {
 24         /* CONFIG::file group */
 25         [CCS_MAC_FILE_EXECUTE]    = CCS_MAC_CATEGORY_FILE,
 26         [CCS_MAC_FILE_OPEN]       = CCS_MAC_CATEGORY_FILE,
 27         [CCS_MAC_FILE_CREATE]     = CCS_MAC_CATEGORY_FILE,
 28         [CCS_MAC_FILE_UNLINK]     = CCS_MAC_CATEGORY_FILE,
 29 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
 30         [CCS_MAC_FILE_GETATTR]    = CCS_MAC_CATEGORY_FILE,
 31 #endif
 32         [CCS_MAC_FILE_MKDIR]      = CCS_MAC_CATEGORY_FILE,
 33         [CCS_MAC_FILE_RMDIR]      = CCS_MAC_CATEGORY_FILE,
 34         [CCS_MAC_FILE_MKFIFO]     = CCS_MAC_CATEGORY_FILE,
 35         [CCS_MAC_FILE_MKSOCK]     = CCS_MAC_CATEGORY_FILE,
 36         [CCS_MAC_FILE_TRUNCATE]   = CCS_MAC_CATEGORY_FILE,
 37         [CCS_MAC_FILE_SYMLINK]    = CCS_MAC_CATEGORY_FILE,
 38         [CCS_MAC_FILE_MKBLOCK]    = CCS_MAC_CATEGORY_FILE,
 39         [CCS_MAC_FILE_MKCHAR]     = CCS_MAC_CATEGORY_FILE,
 40         [CCS_MAC_FILE_LINK]       = CCS_MAC_CATEGORY_FILE,
 41         [CCS_MAC_FILE_RENAME]     = CCS_MAC_CATEGORY_FILE,
 42         [CCS_MAC_FILE_CHMOD]      = CCS_MAC_CATEGORY_FILE,
 43         [CCS_MAC_FILE_CHOWN]      = CCS_MAC_CATEGORY_FILE,
 44         [CCS_MAC_FILE_CHGRP]      = CCS_MAC_CATEGORY_FILE,
 45         [CCS_MAC_FILE_IOCTL]      = CCS_MAC_CATEGORY_FILE,
 46         [CCS_MAC_FILE_CHROOT]     = CCS_MAC_CATEGORY_FILE,
 47         [CCS_MAC_FILE_MOUNT]      = CCS_MAC_CATEGORY_FILE,
 48         [CCS_MAC_FILE_UMOUNT]     = CCS_MAC_CATEGORY_FILE,
 49         [CCS_MAC_FILE_PIVOT_ROOT] = CCS_MAC_CATEGORY_FILE,
 50 #ifdef CONFIG_CCSECURITY_MISC
 51         /* CONFIG::misc group */
 52         [CCS_MAC_ENVIRON]         = CCS_MAC_CATEGORY_MISC,
 53 #endif
 54 #ifdef CONFIG_CCSECURITY_NETWORK
 55         /* CONFIG::network group */
 56         [CCS_MAC_NETWORK_INET_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
 57         [CCS_MAC_NETWORK_INET_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
 58         [CCS_MAC_NETWORK_INET_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
 59         [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
 60         [CCS_MAC_NETWORK_INET_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
 61         [CCS_MAC_NETWORK_INET_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
 62 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
 63         [CCS_MAC_NETWORK_INET_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
 64 #endif
 65         [CCS_MAC_NETWORK_INET_RAW_BIND]          = CCS_MAC_CATEGORY_NETWORK,
 66         [CCS_MAC_NETWORK_INET_RAW_SEND]          = CCS_MAC_CATEGORY_NETWORK,
 67 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
 68         [CCS_MAC_NETWORK_INET_RAW_RECV]          = CCS_MAC_CATEGORY_NETWORK,
 69 #endif
 70         [CCS_MAC_NETWORK_UNIX_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
 71         [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
 72         [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
 73         [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
 74         [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
 75         [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
 76 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
 77         [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
 78 #endif
 79         [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = CCS_MAC_CATEGORY_NETWORK,
 80         [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = CCS_MAC_CATEGORY_NETWORK,
 81         [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
 82         [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = CCS_MAC_CATEGORY_NETWORK,
 83 #endif
 84 #ifdef CONFIG_CCSECURITY_IPC
 85         /* CONFIG::ipc group */
 86         [CCS_MAC_SIGNAL]          = CCS_MAC_CATEGORY_IPC,
 87 #endif
 88 #ifdef CONFIG_CCSECURITY_CAPABILITY
 89         /* CONFIG::capability group */
 90         [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = CCS_MAC_CATEGORY_CAPABILITY,
 91         [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = CCS_MAC_CATEGORY_CAPABILITY,
 92         [CCS_MAC_CAPABILITY_SYS_REBOOT]        = CCS_MAC_CATEGORY_CAPABILITY,
 93         [CCS_MAC_CAPABILITY_SYS_VHANGUP]       = CCS_MAC_CATEGORY_CAPABILITY,
 94         [CCS_MAC_CAPABILITY_SYS_SETTIME]       = CCS_MAC_CATEGORY_CAPABILITY,
 95         [CCS_MAC_CAPABILITY_SYS_NICE]          = CCS_MAC_CATEGORY_CAPABILITY,
 96         [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = CCS_MAC_CATEGORY_CAPABILITY,
 97         [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY,
 98         [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = CCS_MAC_CATEGORY_CAPABILITY,
 99         [CCS_MAC_CAPABILITY_SYS_PTRACE]        = CCS_MAC_CATEGORY_CAPABILITY,
100 #endif
101 };
102 
103 /* String table for operation mode. */
104 static const char * const ccs_mode[CCS_CONFIG_MAX_MODE] = {
105         [CCS_CONFIG_DISABLED]   = "disabled",
106         [CCS_CONFIG_LEARNING]   = "learning",
107         [CCS_CONFIG_PERMISSIVE] = "permissive",
108         [CCS_CONFIG_ENFORCING]  = "enforcing"
109 };
110 
111 /* String table for /proc/ccs/profile interface. */
112 static const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX
113                                            + CCS_MAX_MAC_CATEGORY_INDEX] = {
114         /* CONFIG::file group */
115         [CCS_MAC_FILE_EXECUTE]    = "execute",
116         [CCS_MAC_FILE_OPEN]       = "open",
117         [CCS_MAC_FILE_CREATE]     = "create",
118         [CCS_MAC_FILE_UNLINK]     = "unlink",
119 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
120         [CCS_MAC_FILE_GETATTR]    = "getattr",
121 #endif
122         [CCS_MAC_FILE_MKDIR]      = "mkdir",
123         [CCS_MAC_FILE_RMDIR]      = "rmdir",
124         [CCS_MAC_FILE_MKFIFO]     = "mkfifo",
125         [CCS_MAC_FILE_MKSOCK]     = "mksock",
126         [CCS_MAC_FILE_TRUNCATE]   = "truncate",
127         [CCS_MAC_FILE_SYMLINK]    = "symlink",
128         [CCS_MAC_FILE_MKBLOCK]    = "mkblock",
129         [CCS_MAC_FILE_MKCHAR]     = "mkchar",
130         [CCS_MAC_FILE_LINK]       = "link",
131         [CCS_MAC_FILE_RENAME]     = "rename",
132         [CCS_MAC_FILE_CHMOD]      = "chmod",
133         [CCS_MAC_FILE_CHOWN]      = "chown",
134         [CCS_MAC_FILE_CHGRP]      = "chgrp",
135         [CCS_MAC_FILE_IOCTL]      = "ioctl",
136         [CCS_MAC_FILE_CHROOT]     = "chroot",
137         [CCS_MAC_FILE_MOUNT]      = "mount",
138         [CCS_MAC_FILE_UMOUNT]     = "unmount",
139         [CCS_MAC_FILE_PIVOT_ROOT] = "pivot_root",
140 #ifdef CONFIG_CCSECURITY_MISC
141         /* CONFIG::misc group */
142         [CCS_MAC_ENVIRON] = "env",
143 #endif
144 #ifdef CONFIG_CCSECURITY_NETWORK
145         /* CONFIG::network group */
146         [CCS_MAC_NETWORK_INET_STREAM_BIND]       = "inet_stream_bind",
147         [CCS_MAC_NETWORK_INET_STREAM_LISTEN]     = "inet_stream_listen",
148         [CCS_MAC_NETWORK_INET_STREAM_CONNECT]    = "inet_stream_connect",
149         [CCS_MAC_NETWORK_INET_STREAM_ACCEPT]     = "inet_stream_accept",
150         [CCS_MAC_NETWORK_INET_DGRAM_BIND]        = "inet_dgram_bind",
151         [CCS_MAC_NETWORK_INET_DGRAM_SEND]        = "inet_dgram_send",
152 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
153         [CCS_MAC_NETWORK_INET_DGRAM_RECV]        = "inet_dgram_recv",
154 #endif
155         [CCS_MAC_NETWORK_INET_RAW_BIND]          = "inet_raw_bind",
156         [CCS_MAC_NETWORK_INET_RAW_SEND]          = "inet_raw_send",
157 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
158         [CCS_MAC_NETWORK_INET_RAW_RECV]          = "inet_raw_recv",
159 #endif
160         [CCS_MAC_NETWORK_UNIX_STREAM_BIND]       = "unix_stream_bind",
161         [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]     = "unix_stream_listen",
162         [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]    = "unix_stream_connect",
163         [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]     = "unix_stream_accept",
164         [CCS_MAC_NETWORK_UNIX_DGRAM_BIND]        = "unix_dgram_bind",
165         [CCS_MAC_NETWORK_UNIX_DGRAM_SEND]        = "unix_dgram_send",
166 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
167         [CCS_MAC_NETWORK_UNIX_DGRAM_RECV]        = "unix_dgram_recv",
168 #endif
169         [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = "unix_seqpacket_bind",
170         [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = "unix_seqpacket_listen",
171         [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
172         [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = "unix_seqpacket_accept",
173 #endif
174 #ifdef CONFIG_CCSECURITY_IPC
175         /* CONFIG::ipc group */
176         [CCS_MAC_SIGNAL] = "signal",
177 #endif
178 #ifdef CONFIG_CCSECURITY_CAPABILITY
179         /* CONFIG::capability group */
180         [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = "use_route",
181         [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = "use_packet",
182         [CCS_MAC_CAPABILITY_SYS_REBOOT]        = "SYS_REBOOT",
183         [CCS_MAC_CAPABILITY_SYS_VHANGUP]       = "SYS_VHANGUP",
184         [CCS_MAC_CAPABILITY_SYS_SETTIME]       = "SYS_TIME",
185         [CCS_MAC_CAPABILITY_SYS_NICE]          = "SYS_NICE",
186         [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = "SYS_SETHOSTNAME",
187         [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
188         [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = "SYS_KEXEC_LOAD",
189         [CCS_MAC_CAPABILITY_SYS_PTRACE]        = "SYS_PTRACE",
190 #endif
191         /* CONFIG group */
192         [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE]       = "file",
193 #ifdef CONFIG_CCSECURITY_NETWORK
194         [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NETWORK]    = "network",
195 #endif
196 #ifdef CONFIG_CCSECURITY_MISC
197         [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_MISC]       = "misc",
198 #endif
199 #ifdef CONFIG_CCSECURITY_IPC
200         [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_IPC]        = "ipc",
201 #endif
202 #ifdef CONFIG_CCSECURITY_CAPABILITY
203         [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
204 #endif
205 };
206 
207 /* String table for path operation. */
208 static const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = {
209         [CCS_TYPE_EXECUTE]    = "execute",
210         [CCS_TYPE_READ]       = "read",
211         [CCS_TYPE_WRITE]      = "write",
212         [CCS_TYPE_APPEND]     = "append",
213         [CCS_TYPE_UNLINK]     = "unlink",
214 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
215         [CCS_TYPE_GETATTR]    = "getattr",
216 #endif
217         [CCS_TYPE_RMDIR]      = "rmdir",
218         [CCS_TYPE_TRUNCATE]   = "truncate",
219         [CCS_TYPE_SYMLINK]    = "symlink",
220         [CCS_TYPE_CHROOT]     = "chroot",
221         [CCS_TYPE_UMOUNT]     = "unmount",
222 };
223 
224 #ifdef CONFIG_CCSECURITY_NETWORK
225 
226 /* String table for socket's operation. */
227 static const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION] = {
228         [CCS_NETWORK_BIND]    = "bind",
229         [CCS_NETWORK_LISTEN]  = "listen",
230         [CCS_NETWORK_CONNECT] = "connect",
231         [CCS_NETWORK_ACCEPT]  = "accept",
232         [CCS_NETWORK_SEND]    = "send",
233 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
234         [CCS_NETWORK_RECV]    = "recv",
235 #endif
236 };
237 
238 /* String table for socket's protocols. */
239 static const char * const ccs_proto_keyword[CCS_SOCK_MAX] = {
240         [SOCK_STREAM]    = "stream",
241         [SOCK_DGRAM]     = "dgram",
242         [SOCK_RAW]       = "raw",
243         [SOCK_SEQPACKET] = "seqpacket",
244         [0] = " ", /* Dummy for avoiding NULL pointer dereference. */
245         [4] = " ", /* Dummy for avoiding NULL pointer dereference. */
246 };
247 
248 #endif
249 
250 /* String table for categories. */
251 static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = {
252         [CCS_MAC_CATEGORY_FILE]       = "file",
253 #ifdef CONFIG_CCSECURITY_NETWORK
254         [CCS_MAC_CATEGORY_NETWORK]    = "network",
255 #endif
256 #ifdef CONFIG_CCSECURITY_MISC
257         [CCS_MAC_CATEGORY_MISC]       = "misc",
258 #endif
259 #ifdef CONFIG_CCSECURITY_IPC
260         [CCS_MAC_CATEGORY_IPC]        = "ipc",
261 #endif
262 #ifdef CONFIG_CCSECURITY_CAPABILITY
263         [CCS_MAC_CATEGORY_CAPABILITY] = "capability",
264 #endif
265 };
266 
267 /* String table for conditions. */
268 static const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = {
269         [CCS_TASK_UID]             = "task.uid",
270         [CCS_TASK_EUID]            = "task.euid",
271         [CCS_TASK_SUID]            = "task.suid",
272         [CCS_TASK_FSUID]           = "task.fsuid",
273         [CCS_TASK_GID]             = "task.gid",
274         [CCS_TASK_EGID]            = "task.egid",
275         [CCS_TASK_SGID]            = "task.sgid",
276         [CCS_TASK_FSGID]           = "task.fsgid",
277         [CCS_TASK_PID]             = "task.pid",
278         [CCS_TASK_PPID]            = "task.ppid",
279         [CCS_EXEC_ARGC]            = "exec.argc",
280         [CCS_EXEC_ENVC]            = "exec.envc",
281         [CCS_TYPE_IS_SOCKET]       = "socket",
282         [CCS_TYPE_IS_SYMLINK]      = "symlink",
283         [CCS_TYPE_IS_FILE]         = "file",
284         [CCS_TYPE_IS_BLOCK_DEV]    = "block",
285         [CCS_TYPE_IS_DIRECTORY]    = "directory",
286         [CCS_TYPE_IS_CHAR_DEV]     = "char",
287         [CCS_TYPE_IS_FIFO]         = "fifo",
288         [CCS_MODE_SETUID]          = "setuid",
289         [CCS_MODE_SETGID]          = "setgid",
290         [CCS_MODE_STICKY]          = "sticky",
291         [CCS_MODE_OWNER_READ]      = "owner_read",
292         [CCS_MODE_OWNER_WRITE]     = "owner_write",
293         [CCS_MODE_OWNER_EXECUTE]   = "owner_execute",
294         [CCS_MODE_GROUP_READ]      = "group_read",
295         [CCS_MODE_GROUP_WRITE]     = "group_write",
296         [CCS_MODE_GROUP_EXECUTE]   = "group_execute",
297         [CCS_MODE_OTHERS_READ]     = "others_read",
298         [CCS_MODE_OTHERS_WRITE]    = "others_write",
299         [CCS_MODE_OTHERS_EXECUTE]  = "others_execute",
300         [CCS_TASK_TYPE]            = "task.type",
301         [CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
302         [CCS_EXEC_REALPATH]        = "exec.realpath",
303         [CCS_SYMLINK_TARGET]       = "symlink.target",
304         [CCS_PATH1_UID]            = "path1.uid",
305         [CCS_PATH1_GID]            = "path1.gid",
306         [CCS_PATH1_INO]            = "path1.ino",
307         [CCS_PATH1_MAJOR]          = "path1.major",
308         [CCS_PATH1_MINOR]          = "path1.minor",
309         [CCS_PATH1_PERM]           = "path1.perm",
310         [CCS_PATH1_TYPE]           = "path1.type",
311         [CCS_PATH1_DEV_MAJOR]      = "path1.dev_major",
312         [CCS_PATH1_DEV_MINOR]      = "path1.dev_minor",
313         [CCS_PATH2_UID]            = "path2.uid",
314         [CCS_PATH2_GID]            = "path2.gid",
315         [CCS_PATH2_INO]            = "path2.ino",
316         [CCS_PATH2_MAJOR]          = "path2.major",
317         [CCS_PATH2_MINOR]          = "path2.minor",
318         [CCS_PATH2_PERM]           = "path2.perm",
319         [CCS_PATH2_TYPE]           = "path2.type",
320         [CCS_PATH2_DEV_MAJOR]      = "path2.dev_major",
321         [CCS_PATH2_DEV_MINOR]      = "path2.dev_minor",
322         [CCS_PATH1_PARENT_UID]     = "path1.parent.uid",
323         [CCS_PATH1_PARENT_GID]     = "path1.parent.gid",
324         [CCS_PATH1_PARENT_INO]     = "path1.parent.ino",
325         [CCS_PATH1_PARENT_PERM]    = "path1.parent.perm",
326         [CCS_PATH2_PARENT_UID]     = "path2.parent.uid",
327         [CCS_PATH2_PARENT_GID]     = "path2.parent.gid",
328         [CCS_PATH2_PARENT_INO]     = "path2.parent.ino",
329         [CCS_PATH2_PARENT_PERM]    = "path2.parent.perm",
330 };
331 
332 /* String table for PREFERENCE keyword. */
333 static const char * const ccs_pref_keywords[CCS_MAX_PREF] = {
334         [CCS_PREF_MAX_AUDIT_LOG]      = "max_audit_log",
335         [CCS_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
336         [CCS_PREF_ENFORCING_PENALTY]  = "enforcing_penalty",
337 };
338 
339 /* String table for domain flags. */
340 const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
341         [CCS_DIF_QUOTA_WARNED]      = "quota_exceeded\n",
342         [CCS_DIF_TRANSITION_FAILED] = "transition_failed\n",
343 };
344 
345 /* String table for domain transition control keywords. */
346 static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
347         [CCS_TRANSITION_CONTROL_NO_RESET]      = "no_reset_domain ",
348         [CCS_TRANSITION_CONTROL_RESET]         = "reset_domain ",
349         [CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
350         [CCS_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
351         [CCS_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
352         [CCS_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
353 };
354 
355 /* String table for grouping keywords. */
356 static const char * const ccs_group_name[CCS_MAX_GROUP] = {
357         [CCS_PATH_GROUP]    = "path_group ",
358         [CCS_NUMBER_GROUP]  = "number_group ",
359 #ifdef CONFIG_CCSECURITY_NETWORK
360         [CCS_ADDRESS_GROUP] = "address_group ",
361 #endif
362 };
363 
364 /* String table for /proc/ccs/stat interface. */
365 static const char * const ccs_policy_headers[CCS_MAX_POLICY_STAT] = {
366         [CCS_STAT_POLICY_UPDATES]    = "update:",
367         [CCS_STAT_POLICY_LEARNING]   = "violation in learning mode:",
368         [CCS_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
369         [CCS_STAT_POLICY_ENFORCING]  = "violation in enforcing mode:",
370 };
371 
372 /* String table for /proc/ccs/stat interface. */
373 static const char * const ccs_memory_headers[CCS_MAX_MEMORY_STAT] = {
374         [CCS_MEMORY_POLICY]     = "policy:",
375         [CCS_MEMORY_AUDIT]      = "audit log:",
376         [CCS_MEMORY_QUERY]      = "query message:",
377 };
378 
379 /***** SECTION2: Structure definition *****/
380 
381 struct iattr;
382 
383 /* Structure for query. */
384 struct ccs_query {
385         struct list_head list;
386         struct ccs_domain_info *domain;
387         char *query;
388         size_t query_len;
389         unsigned int serial;
390         u8 timer;
391         u8 answer;
392         u8 retry;
393 };
394 
395 /* Structure for audit log. */
396 struct ccs_log {
397         struct list_head list;
398         char *log;
399         int size;
400 };
401 
402 /***** SECTION3: Prototype definition section *****/
403 
404 int ccs_audit_log(struct ccs_request_info *r);
405 struct ccs_domain_info *ccs_assign_domain(const char *domainname,
406                                           const bool transit);
407 u8 ccs_get_config(const u8 profile, const u8 index);
408 void ccs_transition_failed(const char *domainname);
409 void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...);
410 
411 static bool ccs_correct_domain(const unsigned char *domainname);
412 static bool ccs_correct_path(const char *filename);
413 static bool ccs_correct_word(const char *string);
414 static bool ccs_correct_word2(const char *string, size_t len);
415 static bool ccs_domain_def(const unsigned char *buffer);
416 static bool ccs_domain_quota_ok(struct ccs_request_info *r);
417 static bool ccs_flush(struct ccs_io_buffer *head);
418 static bool ccs_get_audit(const struct ccs_request_info *r);
419 static bool ccs_has_more_namespace(struct ccs_io_buffer *head);
420 static bool ccs_manager(void);
421 static bool ccs_namespace_jump(const char *domainname);
422 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv);
423 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp);
424 static bool ccs_parse_name_union(struct ccs_acl_param *param,
425                                  struct ccs_name_union *ptr);
426 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
427                                         struct ccs_name_union *ptr);
428 static bool ccs_parse_number_union(struct ccs_acl_param *param,
429                                    struct ccs_number_union *ptr);
430 static bool ccs_permstr(const char *string, const char *keyword);
431 static bool ccs_print_condition(struct ccs_io_buffer *head,
432                                 const struct ccs_condition *cond);
433 static bool ccs_print_entry(struct ccs_io_buffer *head,
434                             const struct ccs_acl_info *acl);
435 static bool ccs_print_group(struct ccs_io_buffer *head,
436                             const struct ccs_group *group);
437 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list);
438 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx);
439 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx);
440 static bool ccs_same_condition(const struct ccs_condition *a,
441                                const struct ccs_condition *b);
442 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data);
443 static bool ccs_set_lf(struct ccs_io_buffer *head);
444 static bool ccs_str_starts(char **src, const char *find);
445 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
446                                         struct ccs_condition *e);
447 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt,
448                           va_list args);
449 static char *ccs_print_bprm(struct linux_binprm *bprm,
450                             struct ccs_page_dump *dump);
451 static char *ccs_print_header(struct ccs_request_info *r);
452 static char *ccs_read_token(struct ccs_acl_param *param);
453 static const char *ccs_yesno(const unsigned int value);
454 static const struct ccs_path_info *ccs_get_domainname
455 (struct ccs_acl_param *param);
456 static const struct ccs_path_info *ccs_get_dqword(char *start);
457 static int __init ccs_init_module(void);
458 static int ccs_delete_domain(char *domainname);
459 static int ccs_open(struct inode *inode, struct file *file);
460 static int ccs_parse_policy(struct ccs_io_buffer *head, char *line);
461 static int ccs_release(struct inode *inode, struct file *file);
462 static int ccs_set_mode(char *name, const char *value,
463                         struct ccs_profile *profile);
464 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
465         __printf(2, 3);
466 static int ccs_truncate(char *str);
467 static int ccs_update_acl(const int size, struct ccs_acl_param *param);
468 static int ccs_update_manager_entry(const char *manager, const bool is_delete);
469 static int ccs_update_policy(const int size, struct ccs_acl_param *param);
470 static int ccs_write_acl(struct ccs_policy_namespace *ns,
471                          struct list_head *list, char *data,
472                          const bool is_delete);
473 static int ccs_write_aggregator(struct ccs_acl_param *param);
474 static int ccs_write_answer(struct ccs_io_buffer *head);
475 static int ccs_write_domain(struct ccs_io_buffer *head);
476 static int ccs_write_exception(struct ccs_io_buffer *head);
477 static int ccs_write_file(struct ccs_acl_param *param);
478 static int ccs_write_group(struct ccs_acl_param *param, const u8 type);
479 static int ccs_write_manager(struct ccs_io_buffer *head);
480 static int ccs_write_pid(struct ccs_io_buffer *head);
481 static int ccs_write_profile(struct ccs_io_buffer *head);
482 static int ccs_write_stat(struct ccs_io_buffer *head);
483 static int ccs_write_task(struct ccs_acl_param *param);
484 static int ccs_write_transition_control(struct ccs_acl_param *param,
485                                         const u8 type);
486 static s8 ccs_find_yesno(const char *string, const char *find);
487 static ssize_t ccs_read(struct file *file, char __user *buf, size_t count,
488                         loff_t *ppos);
489 static ssize_t ccs_read_self(struct file *file, char __user *buf, size_t count,
490                              loff_t *ppos);
491 static ssize_t ccs_write(struct file *file, const char __user *buf,
492                          size_t count, loff_t *ppos);
493 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry);
494 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param);
495 static struct ccs_domain_info *ccs_find_domain(const char *domainname);
496 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial);
497 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
498                                        const u8 idx);
499 static struct ccs_policy_namespace *ccs_assign_namespace
500 (const char *domainname);
501 static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
502                                                        const unsigned int len);
503 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
504                                               const unsigned int profile);
505 static struct ccs_profile *ccs_profile(const u8 profile);
506 static u8 ccs_condition_type(const char *word);
507 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3);
508 static u8 ccs_parse_ulong(unsigned long *result, char **str);
509 static unsigned int ccs_poll(struct file *file, poll_table *wait);
510 static void __init ccs_create_entry(const char *name, const umode_t mode,
511                                     struct proc_dir_entry *parent,
512                                     const u8 key);
513 static void __init ccs_load_builtin_policy(void);
514 static void __init ccs_policy_io_init(void);
515 static void __init ccs_proc_init(void);
516 static void ccs_add_entry(char *header);
517 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
518         __printf(3, 4);
519 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...);
520 static void ccs_check_profile(void);
521 static void ccs_convert_time(time_t time, struct ccs_time *stamp);
522 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns);
523 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
524         __printf(2, 3);
525 static void ccs_normalize_line(unsigned char *buffer);
526 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config);
527 static void ccs_print_name_union(struct ccs_io_buffer *head,
528                                  const struct ccs_name_union *ptr);
529 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
530                                         const struct ccs_name_union *ptr);
531 static void ccs_print_namespace(struct ccs_io_buffer *head);
532 static void ccs_print_number_union(struct ccs_io_buffer *head,
533                                    const struct ccs_number_union *ptr);
534 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
535                                            const struct ccs_number_union *ptr);
536 static void ccs_read_domain(struct ccs_io_buffer *head);
537 static void ccs_read_exception(struct ccs_io_buffer *head);
538 static void ccs_read_log(struct ccs_io_buffer *head);
539 static void ccs_read_manager(struct ccs_io_buffer *head);
540 static void ccs_read_pid(struct ccs_io_buffer *head);
541 static void ccs_read_profile(struct ccs_io_buffer *head);
542 static void ccs_read_query(struct ccs_io_buffer *head);
543 static void ccs_read_stat(struct ccs_io_buffer *head);
544 static void ccs_read_version(struct ccs_io_buffer *head);
545 static void ccs_set_group(struct ccs_io_buffer *head, const char *category);
546 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head);
547 static void ccs_set_slash(struct ccs_io_buffer *head);
548 static void ccs_set_space(struct ccs_io_buffer *head);
549 static void ccs_set_string(struct ccs_io_buffer *head, const char *string);
550 static void ccs_set_uint(unsigned int *i, const char *string,
551                          const char *find);
552 static void ccs_update_stat(const u8 index);
553 static void ccs_update_task_domain(struct ccs_request_info *r);
554 static void ccs_write_log2(struct ccs_request_info *r, int len,
555                            const char *fmt, va_list args);
556 
557 #ifdef CONFIG_CCSECURITY_PORTRESERVE
558 static bool __ccs_lport_reserved(const u16 port);
559 static int ccs_write_reserved_port(struct ccs_acl_param *param);
560 #endif
561 
562 #ifdef CONFIG_CCSECURITY_NETWORK
563 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
564                                    struct ccs_ipaddr_union *ptr);
565 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
566                           const u32 *ip);
567 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
568                           const struct in6_addr *ip);
569 static int ccs_write_inet_network(struct ccs_acl_param *param);
570 static int ccs_write_unix_network(struct ccs_acl_param *param);
571 static void ccs_print_ip(char *buf, const unsigned int size,
572                          const struct ccs_ipaddr_union *ptr);
573 #endif
574 
575 #ifdef CONFIG_CCSECURITY_CAPABILITY
576 static int ccs_write_capability(struct ccs_acl_param *param);
577 #endif
578 
579 #ifdef CONFIG_CCSECURITY_MISC
580 static int ccs_write_misc(struct ccs_acl_param *param);
581 #endif
582 
583 #ifdef CONFIG_CCSECURITY_IPC
584 static int ccs_write_ipc(struct ccs_acl_param *param);
585 #endif
586 
587 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
588 static ssize_t ccs_write_self(struct file *file, const char __user *buf,
589                               size_t count, loff_t *ppos);
590 #endif
591 
592 /***** SECTION4: Standalone functions section *****/
593 
594 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
595 
596 /**
597  * fatal_signal_pending - Check whether SIGKILL is pending or not.
598  *
599  * @p: Pointer to "struct task_struct".
600  *
601  * Returns true if SIGKILL is pending on @p, false otherwise.
602  *
603  * This is for compatibility with older kernels.
604  */
605 #define fatal_signal_pending(p) (signal_pending(p) &&                   \
606                                  sigismember(&p->pending.signal, SIGKILL))
607 
608 #endif
609 
610 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
611 
612 /**
613  * __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
614  *
615  * @wq:        The waitqueue to wait on.
616  * @condition: A C expression for the event to wait for.
617  * @ret:       Timeout, in jiffies.
618  *
619  * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
620  * signal, and the remaining jiffies otherwise if the condition evaluated to
621  * true before the timeout elapsed.
622  *
623  * This is for compatibility with older kernels.
624  */
625 #define __wait_event_interruptible_timeout(wq, condition, ret)          \
626 do {                                                                    \
627         wait_queue_t __wait;                                            \
628         init_waitqueue_entry(&__wait, current);                         \
629                                                                         \
630         add_wait_queue(&wq, &__wait);                                   \
631         for (;;) {                                                      \
632                 set_current_state(TASK_INTERRUPTIBLE);                  \
633                 if (condition)                                          \
634                         break;                                          \
635                 if (!signal_pending(current)) {                         \
636                         ret = schedule_timeout(ret);                    \
637                         if (!ret)                                       \
638                                 break;                                  \
639                         continue;                                       \
640                 }                                                       \
641                 ret = -ERESTARTSYS;                                     \
642                 break;                                                  \
643         }                                                               \
644         current->state = TASK_RUNNING;                                  \
645         remove_wait_queue(&wq, &__wait);                                \
646 } while (0)
647 
648 /**
649  * wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
650  *
651  * @wq:        The waitqueue to wait on.
652  * @condition: A C expression for the event to wait for.
653  * @timeout:   Timeout, in jiffies.
654  *
655  * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
656  * signal, and the remaining jiffies otherwise if the condition evaluated to
657  * true before the timeout elapsed.
658  *
659  * This is for compatibility with older kernels.
660  */
661 #define wait_event_interruptible_timeout(wq, condition, timeout)        \
662 ({                                                                      \
663         long __ret = timeout;                                           \
664         if (!(condition))                                               \
665                 __wait_event_interruptible_timeout(wq, condition, __ret); \
666         __ret;                                                          \
667 })
668 
669 #endif
670 
671 /**
672  * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
673  *
674  * @time:  Seconds since 1970/01/01 00:00:00.
675  * @stamp: Pointer to "struct ccs_time".
676  *
677  * Returns nothing.
678  *
679  * This function does not handle Y2038 problem.
680  */
681 static void ccs_convert_time(time_t time, struct ccs_time *stamp)
682 {
683         static const u16 ccs_eom[2][12] = {
684                 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
685                 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
686         };
687         u16 y;
688         u8 m;
689         bool r;
690         stamp->sec = time % 60;
691         time /= 60;
692         stamp->min = time % 60;
693         time /= 60;
694         stamp->hour = time % 24;
695         time /= 24;
696         for (y = 1970; ; y++) {
697                 const unsigned short days = (y & 3) ? 365 : 366;
698                 if (time < days)
699                         break;
700                 time -= days;
701         }
702         r = (y & 3) == 0;
703         for (m = 0; m < 11 && time >= ccs_eom[r][m]; m++);
704         if (m)
705                 time -= ccs_eom[r][m - 1];
706         stamp->year = y;
707         stamp->month = ++m;
708         stamp->day = ++time;
709 }
710 
711 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
712 #if !defined(RHEL_VERSION) || RHEL_VERSION != 3
713 
714 /**
715  * PDE - Get "struct proc_dir_entry".
716  *
717  * @inode: Pointer to "struct inode".
718  *
719  * Returns pointer to "struct proc_dir_entry".
720  *
721  * This is for compatibility with older kernels.
722  */
723 static inline struct proc_dir_entry *PDE(const struct inode *inode)
724 {
725         return (struct proc_dir_entry *) inode->u.generic_ip;
726 }
727 
728 #endif
729 #endif
730 
731 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
732 
733 /**
734  * proc_notify_change - Update inode's attributes and reflect to the dentry.
735  *
736  * @dentry: Pointer to "struct dentry".
737  * @iattr:  Pointer to "struct iattr".
738  *
739  * Returns 0 on success, negative value otherwise.
740  *
741  * The 2.4 kernels don't allow chmod()/chown() for files in /proc,
742  * while the 2.6 kernels allow.
743  * To permit management of /proc/ccs/ interface by non-root user,
744  * I modified to allow chmod()/chown() of /proc/ccs/ interface like 2.6 kernels
745  * by adding "struct inode_operations"->setattr hook.
746  */
747 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
748 {
749         struct inode *inode = dentry->d_inode;
750         struct proc_dir_entry *de = PDE(inode);
751         int error;
752 
753         error = inode_change_ok(inode, iattr);
754         if (error)
755                 goto out;
756 
757         error = inode_setattr(inode, iattr);
758         if (error)
759                 goto out;
760 
761         de->uid = inode->i_uid;
762         de->gid = inode->i_gid;
763         de->mode = inode->i_mode;
764 out:
765         return error;
766 }
767 
768 #endif
769 
770 #ifdef CONFIG_CCSECURITY_NETWORK
771 
772 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && defined(CONFIG_NET)
773 #define ccs_in4_pton in4_pton
774 #define ccs_in6_pton in6_pton
775 #else
776 /*
777  * Routines for parsing IPv4 or IPv6 address.
778  * These are copied from lib/hexdump.c net/core/utils.c .
779  */
780 #include <linux/ctype.h>
781 
782 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
783 static int hex_to_bin(char ch)
784 {
785         if ((ch >= '') && (ch <= '9'))
786                 return ch - '';
787         ch = tolower(ch);
788         if ((ch >= 'a') && (ch <= 'f'))
789                 return ch - 'a' + 10;
790         return -1;
791 }
792 #endif
793 
794 #define IN6PTON_XDIGIT          0x00010000
795 #define IN6PTON_DIGIT           0x00020000
796 #define IN6PTON_COLON_MASK      0x00700000
797 #define IN6PTON_COLON_1         0x00100000      /* single : requested */
798 #define IN6PTON_COLON_2         0x00200000      /* second : requested */
799 #define IN6PTON_COLON_1_2       0x00400000      /* :: requested */
800 #define IN6PTON_DOT             0x00800000      /* . */
801 #define IN6PTON_DELIM           0x10000000
802 #define IN6PTON_NULL            0x20000000      /* first/tail */
803 #define IN6PTON_UNKNOWN         0x40000000
804 
805 static inline int xdigit2bin(char c, int delim)
806 {
807         int val;
808 
809         if (c == delim || c == '\0')
810                 return IN6PTON_DELIM;
811         if (c == ':')
812                 return IN6PTON_COLON_MASK;
813         if (c == '.')
814                 return IN6PTON_DOT;
815 
816         val = hex_to_bin(c);
817         if (val >= 0)
818                 return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
819 
820         if (delim == -1)
821                 return IN6PTON_DELIM;
822         return IN6PTON_UNKNOWN;
823 }
824 
825 static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim,
826                         const char **end)
827 {
828         const char *s;
829         u8 *d;
830         u8 dbuf[4];
831         int ret = 0;
832         int i;
833         int w = 0;
834 
835         if (srclen < 0)
836                 srclen = strlen(src);
837         s = src;
838         d = dbuf;
839         i = 0;
840         while (1) {
841                 int c;
842                 c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
843                 if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM |
844                            IN6PTON_COLON_MASK)))
845                         goto out;
846                 if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
847                         if (w == 0)
848                                 goto out;
849                         *d++ = w & 0xff;
850                         w = 0;
851                         i++;
852                         if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
853                                 if (i != 4)
854                                         goto out;
855                                 break;
856                         }
857                         goto cont;
858                 }
859                 w = (w * 10) + c;
860                 if ((w & 0xffff) > 255)
861                         goto out;
862 cont:
863                 if (i >= 4)
864                         goto out;
865                 s++;
866                 srclen--;
867         }
868         ret = 1;
869         memcpy(dst, dbuf, sizeof(dbuf));
870 out:
871         if (end)
872                 *end = s;
873         return ret;
874 }
875 
876 static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim,
877                         const char **end)
878 {
879         const char *s, *tok = NULL;
880         u8 *d, *dc = NULL;
881         u8 dbuf[16];
882         int ret = 0;
883         int i;
884         int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
885         int w = 0;
886 
887         memset(dbuf, 0, sizeof(dbuf));
888 
889         s = src;
890         d = dbuf;
891         if (srclen < 0)
892                 srclen = strlen(src);
893 
894         while (1) {
895                 int c;
896 
897                 c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
898                 if (!(c & state))
899                         goto out;
900                 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
901                         /* process one 16-bit word */
902                         if (!(state & IN6PTON_NULL)) {
903                                 *d++ = (w >> 8) & 0xff;
904                                 *d++ = w & 0xff;
905                         }
906                         w = 0;
907                         if (c & IN6PTON_DELIM) {
908                                 /* We've processed last word */
909                                 break;
910                         }
911                         /*
912                          * COLON_1 => XDIGIT
913                          * COLON_2 => XDIGIT|DELIM
914                          * COLON_1_2 => COLON_2
915                          */
916                         switch (state & IN6PTON_COLON_MASK) {
917                         case IN6PTON_COLON_2:
918                                 dc = d;
919                                 state = IN6PTON_XDIGIT | IN6PTON_DELIM;
920                                 if (dc - dbuf >= sizeof(dbuf))
921                                         state |= IN6PTON_NULL;
922                                 break;
923                         case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
924                                 state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
925                                 break;
926                         case IN6PTON_COLON_1:
927                                 state = IN6PTON_XDIGIT;
928                                 break;
929                         case IN6PTON_COLON_1_2:
930                                 state = IN6PTON_COLON_2;
931                                 break;
932                         default:
933                                 state = 0;
934                         }
935                         tok = s + 1;
936                         goto cont;
937                 }
938 
939                 if (c & IN6PTON_DOT) {
940                         ret = ccs_in4_pton(tok ? tok : s, srclen +
941                                            (int)(s - tok), d, delim, &s);
942                         if (ret > 0) {
943                                 d += 4;
944                                 break;
945                         }
946                         goto out;
947                 }
948 
949                 w = (w << 4) | (0xff & c);
950                 state = IN6PTON_COLON_1 | IN6PTON_DELIM;
951                 if (!(w & 0xf000))
952                         state |= IN6PTON_XDIGIT;
953                 if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
954                         state |= IN6PTON_COLON_1_2;
955                         state &= ~IN6PTON_DELIM;
956                 }
957                 if (d + 2 >= dbuf + sizeof(dbuf))
958                         state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
959 cont:
960                 if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
961                     d + 4 == dbuf + sizeof(dbuf))
962                         state |= IN6PTON_DOT;
963                 if (d >= dbuf + sizeof(dbuf))
964                         state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
965                 s++;
966                 srclen--;
967         }
968 
969         i = 15; d--;
970 
971         if (dc) {
972                 while (d >= dc)
973                         dst[i--] = *d--;
974                 while (i >= dc - dbuf)
975                         dst[i--] = 0;
976                 while (i >= 0)
977                         dst[i--] = *d--;
978         } else
979                 memcpy(dst, dbuf, sizeof(dbuf));
980 
981         ret = 1;
982 out:
983         if (end)
984                 *end = s;
985         return ret;
986 }
987 #endif
988 
989 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
990 
991 /*
992  * Routines for printing IPv4 or IPv6 address.
993  * These are copied from include/linux/kernel.h include/net/ipv6.h
994  * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified.
995  */
996 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
997 #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5 || !defined(RHEL_MINOR) || RHEL_MINOR < 9
998 static const char hex_asc[] = "0123456789abcdef";
999 #define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
1000 #define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
1001 
1002 static inline char *pack_hex_byte(char *buf, u8 byte)
1003 {
1004         *buf++ = hex_asc_hi(byte);
1005         *buf++ = hex_asc_lo(byte);
1006         return buf;
1007 }
1008 #endif
1009 #endif
1010 
1011 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
1012 static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
1013 {
1014         return (a->s6_addr32[0] | a->s6_addr32[1] |
1015                 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
1016 }
1017 #endif
1018 
1019 static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
1020 {
1021         return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
1022 }
1023 
1024 static char *ip4_string(char *p, const u8 *addr)
1025 {
1026         /*
1027          * Since this function is called outside vsnprintf(), I can use
1028          * sprintf() here.
1029          */
1030         return p +
1031                 sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
1032 }
1033 
1034 static char *ip6_compressed_string(char *p, const char *addr)
1035 {
1036         int i, j, range;
1037         unsigned char zerolength[8];
1038         int longest = 1;
1039         int colonpos = -1;
1040         u16 word;
1041         u8 hi, lo;
1042         bool needcolon = false;
1043         bool useIPv4;
1044         struct in6_addr in6;
1045 
1046         memcpy(&in6, addr, sizeof(struct in6_addr));
1047 
1048         useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
1049 
1050         memset(zerolength, 0, sizeof(zerolength));
1051 
1052         if (useIPv4)
1053                 range = 6;
1054         else
1055                 range = 8;
1056 
1057         /* find position of longest 0 run */
1058         for (i = 0; i < range; i++) {
1059                 for (j = i; j < range; j++) {
1060                         if (in6.s6_addr16[j] != 0)
1061                                 break;
1062                         zerolength[i]++;
1063                 }
1064         }
1065         for (i = 0; i < range; i++) {
1066                 if (zerolength[i] > longest) {
1067                         longest = zerolength[i];
1068                         colonpos = i;
1069                 }
1070         }
1071         if (longest == 1)               /* don't compress a single 0 */
1072                 colonpos = -1;
1073 
1074         /* emit address */
1075         for (i = 0; i < range; i++) {
1076                 if (i == colonpos) {
1077                         if (needcolon || i == 0)
1078                                 *p++ = ':';
1079                         *p++ = ':';
1080                         needcolon = false;
1081                         i += longest - 1;
1082                         continue;
1083                 }
1084                 if (needcolon) {
1085                         *p++ = ':';
1086                         needcolon = false;
1087                 }
1088                 /* hex u16 without leading 0s */
1089                 word = ntohs(in6.s6_addr16[i]);
1090                 hi = word >> 8;
1091                 lo = word & 0xff;
1092                 if (hi) {
1093                         if (hi > 0x0f)
1094                                 p = pack_hex_byte(p, hi);
1095                         else
1096                                 *p++ = hex_asc_lo(hi);
1097                         p = pack_hex_byte(p, lo);
1098                 } else if (lo > 0x0f)
1099                         p = pack_hex_byte(p, lo);
1100                 else
1101                         *p++ = hex_asc_lo(lo);
1102                 needcolon = true;
1103         }
1104 
1105         if (useIPv4) {
1106                 if (needcolon)
1107                         *p++ = ':';
1108                 p = ip4_string(p, &in6.s6_addr[12]);
1109         }
1110         *p = '\0';
1111 
1112         return p;
1113 }
1114 #endif
1115 
1116 /**
1117  * ccs_print_ipv4 - Print an IPv4 address.
1118  *
1119  * @buffer:     Buffer to write to.
1120  * @buffer_len: Size of @buffer.
1121  * @ip:         Pointer to "u32 in network byte order".
1122  *
1123  * Returns written length.
1124  */
1125 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
1126                           const u32 *ip)
1127 {
1128 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1129         return snprintf(buffer, buffer_len, "%pI4", ip);
1130 #else
1131         char addr[sizeof("255.255.255.255")];
1132         ip4_string(addr, (const u8 *) ip);
1133         return snprintf(buffer, buffer_len, "%s", addr);
1134 #endif
1135 }
1136 
1137 /**
1138  * ccs_print_ipv6 - Print an IPv6 address.
1139  *
1140  * @buffer:     Buffer to write to.
1141  * @buffer_len: Size of @buffer.
1142  * @ip:         Pointer to "struct in6_addr".
1143  *
1144  * Returns written length.
1145  */
1146 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
1147                           const struct in6_addr *ip)
1148 {
1149 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1150         return snprintf(buffer, buffer_len, "%pI6c", ip);
1151 #else
1152         char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
1153         ip6_compressed_string(addr, (const u8 *) ip);
1154         return snprintf(buffer, buffer_len, "%s", addr);
1155 #endif
1156 }
1157 
1158 /**
1159  * ccs_print_ip - Print an IP address.
1160  *
1161  * @buf:  Buffer to write to.
1162  * @size: Size of @buf.
1163  * @ptr:  Pointer to "struct ipaddr_union".
1164  *
1165  * Returns nothing.
1166  */
1167 static void ccs_print_ip(char *buf, const unsigned int size,
1168                          const struct ccs_ipaddr_union *ptr)
1169 {
1170         int len;
1171         if (ptr->is_ipv6)
1172                 len = ccs_print_ipv6(buf, size, &ptr->ip[0]);
1173         else
1174                 len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]);
1175         if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2)
1176                 return;
1177         buf[len++] = '-';
1178         if (ptr->is_ipv6)
1179                 ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]);
1180         else
1181                 ccs_print_ipv4(buf + len, size - len,
1182                                &ptr->ip[1].s6_addr32[0]);
1183 }
1184 
1185 #endif
1186 
1187 /***** SECTION5: Variables definition section *****/
1188 
1189 /* Permit policy management by non-root user? */
1190 static bool ccs_manage_by_non_root;
1191 
1192 /* Lock for protecting policy. */
1193 DEFINE_MUTEX(ccs_policy_lock);
1194 
1195 /* Has /sbin/init started? */
1196 bool ccs_policy_loaded;
1197 
1198 /* List of namespaces. */
1199 LIST_HEAD(ccs_namespace_list);
1200 /* True if namespace other than ccs_kernel_namespace is defined. */
1201 static bool ccs_namespace_enabled;
1202 
1203 /* Initial namespace.*/
1204 static struct ccs_policy_namespace ccs_kernel_namespace;
1205 
1206 /* List of "struct ccs_condition". */
1207 LIST_HEAD(ccs_condition_list);
1208 
1209 #ifdef CONFIG_CCSECURITY_PORTRESERVE
1210 /* Bitmap for reserved local port numbers.*/
1211 static u8 ccs_reserved_port_map[8192];
1212 #endif
1213 
1214 /* Wait queue for kernel -> userspace notification. */
1215 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1216 /* Wait queue for userspace -> kernel notification. */
1217 static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait);
1218 
1219 /* The list for "struct ccs_query". */
1220 static LIST_HEAD(ccs_query_list);
1221 
1222 /* Lock for manipulating ccs_query_list. */
1223 static DEFINE_SPINLOCK(ccs_query_list_lock);
1224 
1225 /* Number of "struct file" referring /proc/ccs/query interface. */
1226 static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1227 
1228 /* Wait queue for /proc/ccs/audit. */
1229 static DECLARE_WAIT_QUEUE_HEAD(ccs_log_wait);
1230 
1231 /* The list for "struct ccs_log". */
1232 static LIST_HEAD(ccs_log);
1233 
1234 /* Lock for "struct list_head ccs_log". */
1235 static DEFINE_SPINLOCK(ccs_log_lock);
1236 
1237 /* Length of "stuct list_head ccs_log". */
1238 static unsigned int ccs_log_count;
1239 
1240 /* Timestamp counter for last updated. */
1241 static unsigned int ccs_stat_updated[CCS_MAX_POLICY_STAT];
1242 
1243 /* Counter for number of updates. */
1244 static unsigned int ccs_stat_modified[CCS_MAX_POLICY_STAT];
1245 
1246 /* Operations for /proc/ccs/self_domain interface. */
1247 static
1248 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1249 const
1250 #endif
1251 struct file_operations ccs_self_operations = {
1252 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1253         .write = ccs_write_self,
1254 #endif
1255         .read  = ccs_read_self,
1256 };
1257 
1258 /* Operations for /proc/ccs/ interface. */
1259 static
1260 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1261 const
1262 #endif
1263 struct file_operations ccs_operations = {
1264         .open    = ccs_open,
1265         .release = ccs_release,
1266         .poll    = ccs_poll,
1267         .read    = ccs_read,
1268         .write   = ccs_write,
1269 };
1270 
1271 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
1272 
1273 /* The inode operations for /proc/ccs/ directory. */
1274 static struct inode_operations ccs_dir_inode_operations;
1275 
1276 /* The inode operations for files under /proc/ccs/ directory. */
1277 static struct inode_operations ccs_file_inode_operations;
1278 
1279 #endif
1280 
1281 /***** SECTION6: Dependent functions section *****/
1282 
1283 /**
1284  * list_for_each_cookie - iterate over a list with cookie.
1285  *
1286  * @pos:  Pointer to "struct list_head".
1287  * @head: Pointer to "struct list_head".
1288  */
1289 #define list_for_each_cookie(pos, head)                                 \
1290         for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \
1291              pos != (head); pos = srcu_dereference(pos->next, &ccs_ss))
1292 
1293 /**
1294  * ccs_read_token - Read a word from a line.
1295  *
1296  * @param: Pointer to "struct ccs_acl_param".
1297  *
1298  * Returns a word on success, "" otherwise.
1299  *
1300  * To allow the caller to skip NULL check, this function returns "" rather than
1301  * NULL if there is no more words to read.
1302  */
1303 static char *ccs_read_token(struct ccs_acl_param *param)
1304 {
1305         char *pos = param->data;
1306         char *del = strchr(pos, ' ');
1307         if (del)
1308                 *del++ = '\0';
1309         else
1310                 del = pos + strlen(pos);
1311         param->data = del;
1312         return pos;
1313 }
1314 
1315 /**
1316  * ccs_make_byte - Make byte value from three octal characters.
1317  *
1318  * @c1: The first character.
1319  * @c2: The second character.
1320  * @c3: The third character.
1321  *
1322  * Returns byte value.
1323  */
1324 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
1325 {
1326         return ((c1 - '') << 6) + ((c2 - '') << 3) + (c3 - '');
1327 }
1328 
1329 /**
1330  * ccs_correct_word2 - Check whether the given string follows the naming rules.
1331  *
1332  * @string: The byte sequence to check. Not '\0'-terminated.
1333  * @len:    Length of @string.
1334  *
1335  * Returns true if @string follows the naming rules, false otherwise.
1336  */
1337 static bool ccs_correct_word2(const char *string, size_t len)
1338 {
1339         u8 recursion = 20;
1340         const char *const start = string;
1341         bool in_repetition = false;
1342         if (!len)
1343                 goto out;
1344         while (len--) {
1345                 unsigned char c = *string++;
1346                 if (c == '\\') {
1347                         if (!len--)
1348                                 goto out;
1349                         c = *string++;
1350                         if (c >= '' && c <= '3') {
1351                                 unsigned char d;
1352                                 unsigned char e;
1353                                 if (!len-- || !len--)
1354                                         goto out;
1355                                 d = *string++;
1356                                 e = *string++;
1357                                 if (d < '' || d > '7' || e < '' || e > '7')
1358                                         goto out;
1359                                 c = ccs_make_byte(c, d, e);
1360                                 if (c <= ' ' || c >= 127)
1361                                         continue;
1362                                 goto out;
1363                         }
1364                         switch (c) {
1365                         case '\\':  /* "\\" */
1366                         case '+':   /* "\+" */
1367                         case '?':   /* "\?" */
1368                         case 'x':   /* "\x" */
1369                         case 'a':   /* "\a" */
1370                         case '-':   /* "\-" */
1371                                 continue;
1372                         }
1373                         if (!recursion--)
1374                                 goto out;
1375                         switch (c) {
1376                         case '*':   /* "\*" */
1377                         case '@':   /* "\@" */
1378                         case '$':   /* "\$" */
1379                         case 'X':   /* "\X" */
1380                         case 'A':   /* "\A" */
1381                                 continue;
1382                         case '{':   /* "/\{" */
1383                                 if (string - 3 < start || *(string - 3) != '/')
1384                                         goto out;
1385                                 in_repetition = true;
1386                                 continue;
1387                         case '}':   /* "\}/" */
1388                                 if (*string != '/')
1389                                         goto out;
1390                                 if (!in_repetition)
1391                                         goto out;
1392                                 in_repetition = false;
1393                                 continue;
1394                         }
1395                         goto out;
1396                 } else if (in_repetition && c == '/') {
1397                         goto out;
1398                 } else if (c <= ' ' || c >= 127) {
1399                         goto out;
1400                 }
1401         }
1402         if (in_repetition)
1403                 goto out;
1404         return true;
1405 out:
1406         return false;
1407 }
1408 
1409 /**
1410  * ccs_correct_word - Check whether the given string follows the naming rules.
1411  *
1412  * @string: The string to check.
1413  *
1414  * Returns true if @string follows the naming rules, false otherwise.
1415  */
1416 static bool ccs_correct_word(const char *string)
1417 {
1418         return ccs_correct_word2(string, strlen(string));
1419 }
1420 
1421 /**
1422  * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group".
1423  *
1424  * @param: Pointer to "struct ccs_acl_param".
1425  * @idx:   Index number.
1426  *
1427  * Returns pointer to "struct ccs_group" on success, NULL otherwise.
1428  */
1429 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
1430                                        const u8 idx)
1431 {
1432         struct ccs_group e = { };
1433         struct ccs_group *group = NULL;
1434         struct list_head *list;
1435         const char *group_name = ccs_read_token(param);
1436         bool found = false;
1437         if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
1438                 return NULL;
1439         e.group_name = ccs_get_name(group_name);
1440         if (!e.group_name)
1441                 return NULL;
1442         if (mutex_lock_interruptible(&ccs_policy_lock))
1443                 goto out;
1444         list = &param->ns->group_list[idx];
1445         list_for_each_entry(group, list, head.list) {
1446                 if (e.group_name != group->group_name ||
1447                     atomic_read(&group->head.users) == CCS_GC_IN_PROGRESS)
1448                         continue;
1449                 atomic_inc(&group->head.users);
1450                 found = true;
1451                 break;
1452         }
1453         if (!found) {
1454                 struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e));
1455                 if (entry) {
1456                         INIT_LIST_HEAD(&entry->member_list);
1457                         atomic_set(&entry->head.users, 1);
1458                         list_add_tail_rcu(&entry->head.list, list);
1459                         group = entry;
1460                         found = true;
1461                 }
1462         }
1463         mutex_unlock(&ccs_policy_lock);
1464 out:
1465         ccs_put_name(e.group_name);
1466         return found ? group : NULL;
1467 }
1468 
1469 /**
1470  * ccs_parse_name_union - Parse a ccs_name_union.
1471  *
1472  * @param: Pointer to "struct ccs_acl_param".
1473  * @ptr:   Pointer to "struct ccs_name_union".
1474  *
1475  * Returns true on success, false otherwise.
1476  */
1477 static bool ccs_parse_name_union(struct ccs_acl_param *param,
1478                                  struct ccs_name_union *ptr)
1479 {
1480         char *filename;
1481         if (param->data[0] == '@') {
1482                 param->data++;
1483                 ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
1484                 return ptr->group != NULL;
1485         }
1486         filename = ccs_read_token(param);
1487         if (!ccs_correct_word(filename))
1488                 return false;
1489         ptr->filename = ccs_get_name(filename);
1490         return ptr->filename != NULL;
1491 }
1492 
1493 /**
1494  * ccs_parse_ulong - Parse an "unsigned long" value.
1495  *
1496  * @result: Pointer to "unsigned long".
1497  * @str:    Pointer to string to parse.
1498  *
1499  * Returns one of values in "enum ccs_value_type".
1500  *
1501  * The @src is updated to point the first character after the value
1502  * on success.
1503  */
1504 static u8 ccs_parse_ulong(unsigned long *result, char **str)
1505 {
1506         const char *cp = *str;
1507         char *ep;
1508         int base = 10;
1509         if (*cp == '') {
1510                 char c = *(cp + 1);
1511                 if (c == 'x' || c == 'X') {
1512                         base = 16;
1513                         cp += 2;
1514                 } else if (c >= '' && c <= '7') {
1515                         base = 8;
1516                         cp++;
1517                 }
1518         }
1519         *result = simple_strtoul(cp, &ep, base);
1520         if (cp == ep)
1521                 return CCS_VALUE_TYPE_INVALID;
1522         *str = ep;
1523         switch (base) {
1524         case 16:
1525                 return CCS_VALUE_TYPE_HEXADECIMAL;
1526         case 8:
1527                 return CCS_VALUE_TYPE_OCTAL;
1528         default:
1529                 return CCS_VALUE_TYPE_DECIMAL;
1530         }
1531 }
1532 
1533 /**
1534  * ccs_parse_number_union - Parse a ccs_number_union.
1535  *
1536  * @param: Pointer to "struct ccs_acl_param".
1537  * @ptr:   Pointer to "struct ccs_number_union".
1538  *
1539  * Returns true on success, false otherwise.
1540  */
1541 static bool ccs_parse_number_union(struct ccs_acl_param *param,
1542                                    struct ccs_number_union *ptr)
1543 {
1544         char *data;
1545         u8 type;
1546         unsigned long v;
1547         memset(ptr, 0, sizeof(*ptr));
1548         if (param->data[0] == '@') {
1549                 param->data++;
1550                 ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
1551                 return ptr->group != NULL;
1552         }
1553         data = ccs_read_token(param);
1554         type = ccs_parse_ulong(&v, &data);
1555         if (type == CCS_VALUE_TYPE_INVALID)
1556                 return false;
1557         ptr->values[0] = v;
1558         ptr->value_type[0] = type;
1559         if (!*data) {
1560                 ptr->values[1] = v;
1561                 ptr->value_type[1] = type;
1562                 return true;
1563         }
1564         if (*data++ != '-')
1565                 return false;
1566         type = ccs_parse_ulong(&v, &data);
1567         if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
1568                 return false;
1569         ptr->values[1] = v;
1570         ptr->value_type[1] = type;
1571         return true;
1572 }
1573 
1574 #ifdef CONFIG_CCSECURITY_NETWORK
1575 
1576 /**
1577  * ccs_parse_ipaddr_union - Parse an IP address.
1578  *
1579  * @param: Pointer to "struct ccs_acl_param".
1580  * @ptr:   Pointer to "struct ccs_ipaddr_union".
1581  *
1582  * Returns true on success, false otherwise.
1583  */
1584 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
1585                                    struct ccs_ipaddr_union *ptr)
1586 {
1587         u8 * const min = ptr->ip[0].in6_u.u6_addr8;
1588         u8 * const max = ptr->ip[1].in6_u.u6_addr8;
1589         char *address = ccs_read_token(param);
1590         const char *end;
1591         if (!strchr(address, ':') &&
1592             ccs_in4_pton(address, -1, min, '-', &end) > 0) {
1593                 ptr->is_ipv6 = false;
1594                 if (!*end)
1595                         ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
1596                 else if (*end++ != '-' ||
1597                          ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
1598                         return false;
1599                 return true;
1600         }
1601         if (ccs_in6_pton(address, -1, min, '-', &end) > 0) {
1602                 ptr->is_ipv6 = true;
1603                 if (!*end)
1604                         memmove(max, min, sizeof(u16) * 8);
1605                 else if (*end++ != '-' ||
1606                          ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
1607                         return false;
1608                 return true;
1609         }
1610         return false;
1611 }
1612 
1613 #endif
1614 
1615 /**
1616  * ccs_get_dqword - ccs_get_name() for a quoted string.
1617  *
1618  * @start: String to save.
1619  *
1620  * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
1621  */
1622 static const struct ccs_path_info *ccs_get_dqword(char *start)
1623 {
1624         char *cp = start + strlen(start) - 1;
1625         if (cp == start || *start++ != '"' || *cp != '"')
1626                 return NULL;
1627         *cp = '\0';
1628         if (*start && !ccs_correct_word(start))
1629                 return NULL;
1630         return ccs_get_name(start);
1631 }
1632 
1633 /**
1634  * ccs_parse_name_union_quoted - Parse a quoted word.
1635  *
1636  * @param: Pointer to "struct ccs_acl_param".
1637  * @ptr:   Pointer to "struct ccs_name_union".
1638  *
1639  * Returns true on success, false otherwise.
1640  */
1641 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
1642                                         struct ccs_name_union *ptr)
1643 {
1644         char *filename = param->data;
1645         if (*filename == '@')
1646                 return ccs_parse_name_union(param, ptr);
1647         ptr->filename = ccs_get_dqword(filename);
1648         return ptr->filename != NULL;
1649 }
1650 
1651 /**
1652  * ccs_parse_argv - Parse an argv[] condition part.
1653  *
1654  * @left:  Lefthand value.
1655  * @right: Righthand value.
1656  * @argv:  Pointer to "struct ccs_argv".
1657  *
1658  * Returns true on success, false otherwise.
1659  */
1660 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
1661 {
1662         if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL ||
1663             *left++ != ']' || *left)
1664                 return false;
1665         argv->value = ccs_get_dqword(right);
1666         return argv->value != NULL;
1667 }
1668 
1669 /**
1670  * ccs_parse_envp - Parse an envp[] condition part.
1671  *
1672  * @left:  Lefthand value.
1673  * @right: Righthand value.
1674  * @envp:  Pointer to "struct ccs_envp".
1675  *
1676  * Returns true on success, false otherwise.
1677  */
1678 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
1679 {
1680         const struct ccs_path_info *name;
1681         const struct ccs_path_info *value;
1682         char *cp = left + strlen(left) - 1;
1683         if (*cp-- != ']' || *cp != '"')
1684                 goto out;
1685         *cp = '\0';
1686         if (!ccs_correct_word(left))
1687                 goto out;
1688         name = ccs_get_name(left);
1689         if (!name)
1690                 goto out;
1691         if (!strcmp(right, "NULL")) {
1692                 value = NULL;
1693         } else {
1694                 value = ccs_get_dqword(right);
1695                 if (!value) {
1696                         ccs_put_name(name);
1697                         goto out;
1698                 }
1699         }
1700         envp->name = name;
1701         envp->value = value;
1702         return true;
1703 out:
1704         return false;
1705 }
1706 
1707 /**
1708  * ccs_same_condition - Check for duplicated "struct ccs_condition" entry.
1709  *
1710  * @a: Pointer to "struct ccs_condition".
1711  * @b: Pointer to "struct ccs_condition".
1712  *
1713  * Returns true if @a == @b, false otherwise.
1714  */
1715 static bool ccs_same_condition(const struct ccs_condition *a,
1716                                const struct ccs_condition *b)
1717 {
1718         return a->size == b->size && a->condc == b->condc &&
1719                 a->numbers_count == b->numbers_count &&
1720                 a->names_count == b->names_count &&
1721                 a->argc == b->argc && a->envc == b->envc &&
1722                 a->grant_log == b->grant_log &&
1723                 a->exec_transit == b->exec_transit && a->transit == b->transit
1724                 && !memcmp(a + 1, b + 1, a->size - sizeof(*a));
1725 }
1726 
1727 /**
1728  * ccs_condition_type - Get condition type.
1729  *
1730  * @word: Keyword string.
1731  *
1732  * Returns one of values in "enum ccs_conditions_index" on success,
1733  * CCS_MAX_CONDITION_KEYWORD otherwise.
1734  */
1735 static u8 ccs_condition_type(const char *word)
1736 {
1737         u8 i;
1738         for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) {
1739                 if (!strcmp(word, ccs_condition_keyword[i]))
1740                         break;
1741         }
1742         return i;
1743 }
1744 
1745 /**
1746  * ccs_commit_condition - Commit "struct ccs_condition".
1747  *
1748  * @entry: Pointer to "struct ccs_condition".
1749  *
1750  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
1751  *
1752  * This function merges duplicated entries. This function returns NULL if
1753  * @entry is not duplicated but memory quota for policy has exceeded.
1754  */
1755 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry)
1756 {
1757         struct ccs_condition *ptr;
1758         bool found = false;
1759         if (mutex_lock_interruptible(&ccs_policy_lock)) {
1760                 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
1761                 ptr = NULL;
1762                 found = true;
1763                 goto out;
1764         }
1765         list_for_each_entry(ptr, &ccs_condition_list, head.list) {
1766                 if (!ccs_same_condition(ptr, entry) ||
1767                     atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS)
1768                         continue;
1769                 /* Same entry found. Share this entry. */
1770                 atomic_inc(&ptr->head.users);
1771                 found = true;
1772                 break;
1773         }
1774         if (!found) {
1775                 if (ccs_memory_ok(entry, entry->size)) {
1776                         atomic_set(&entry->head.users, 1);
1777                         list_add(&entry->head.list, &ccs_condition_list);
1778                 } else {
1779                         found = true;
1780                         ptr = NULL;
1781                 }
1782         }
1783         mutex_unlock(&ccs_policy_lock);
1784 out:
1785         if (found) {
1786                 ccs_del_condition(&entry->head.list);
1787                 kfree(entry);
1788                 entry = ptr;
1789         }
1790         return entry;
1791 }
1792 
1793 /**
1794  * ccs_correct_path - Check whether the given pathname follows the naming rules.
1795  *
1796  * @filename: The pathname to check.
1797  *
1798  * Returns true if @filename follows the naming rules, false otherwise.
1799  */
1800 static bool ccs_correct_path(const char *filename)
1801 {
1802         return *filename == '/' && ccs_correct_word(filename);
1803 }
1804 
1805 /**
1806  * ccs_domain_def - Check whether the given token can be a domainname.
1807  *
1808  * @buffer: The token to check.
1809  *
1810  * Returns true if @buffer possibly be a domainname, false otherwise.
1811  */
1812 static bool ccs_domain_def(const unsigned char *buffer)
1813 {
1814         const unsigned char *cp;
1815         int len;
1816         if (*buffer != '<')
1817                 return false;
1818         cp = strchr(buffer, ' ');
1819         if (!cp)
1820                 len = strlen(buffer);
1821         else
1822                 len = cp - buffer;
1823         if (buffer[len - 1] != '>' || !ccs_correct_word2(buffer + 1, len - 2))
1824                 return false;
1825         return true;
1826 }
1827 
1828 /**
1829  * ccs_correct_domain - Check whether the given domainname follows the naming rules.
1830  *
1831  * @domainname: The domainname to check.
1832  *
1833  * Returns true if @domainname follows the naming rules, false otherwise.
1834  */
1835 static bool ccs_correct_domain(const unsigned char *domainname)
1836 {
1837         if (!domainname || !ccs_domain_def(domainname))
1838                 return false;
1839         domainname = strchr(domainname, ' ');
1840         if (!domainname++)
1841                 return true;
1842         while (1) {
1843                 const unsigned char *cp = strchr(domainname, ' ');
1844                 if (!cp)
1845                         break;
1846                 if (*domainname != '/' ||
1847                     !ccs_correct_word2(domainname, cp - domainname))
1848                         return false;
1849                 domainname = cp + 1;
1850         }
1851         return ccs_correct_path(domainname);
1852 }
1853 
1854 /**
1855  * ccs_normalize_line - Format string.
1856  *
1857  * @buffer: The line to normalize.
1858  *
1859  * Returns nothing.
1860  *
1861  * Leading and trailing whitespaces are removed.
1862  * Multiple whitespaces are packed into single space.
1863  */
1864 static void ccs_normalize_line(unsigned char *buffer)
1865 {
1866         unsigned char *sp = buffer;
1867         unsigned char *dp = buffer;
1868         bool first = true;
1869         while (*sp && (*sp <= ' ' || *sp >= 127))
1870                 sp++;
1871         while (*sp) {
1872                 if (!first)
1873                         *dp++ = ' ';
1874                 first = false;
1875                 while (*sp > ' ' && *sp < 127)
1876                         *dp++ = *sp++;
1877                 while (*sp && (*sp <= ' ' || *sp >= 127))
1878                         sp++;
1879         }
1880         *dp = '\0';
1881 }
1882 
1883 /**
1884  * ccs_get_domainname - Read a domainname from a line.
1885  *
1886  * @param: Pointer to "struct ccs_acl_param".
1887  *
1888  * Returns a domainname on success, NULL otherwise.
1889  */
1890 static const struct ccs_path_info *ccs_get_domainname
1891 (struct ccs_acl_param *param)
1892 {
1893         char *start = param->data;
1894         char *pos = start;
1895         while (*pos) {
1896                 if (*pos++ != ' ' || *pos++ == '/')
1897                         continue;
1898                 pos -= 2;
1899                 *pos++ = '\0';
1900                 break;
1901         }
1902         param->data = pos;
1903         if (ccs_correct_domain(start))
1904                 return ccs_get_name(start);
1905         return NULL;
1906 }
1907 
1908 /**
1909  * ccs_get_transit_preference - Parse domain transition preference for execve().
1910  *
1911  * @param: Pointer to "struct ccs_acl_param".
1912  * @e:     Pointer to "struct ccs_condition".
1913  *
1914  * Returns the condition string part.
1915  */
1916 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
1917                                         struct ccs_condition *e)
1918 {
1919         char * const pos = param->data;
1920         bool flag;
1921         if (*pos == '<') {
1922                 e->transit = ccs_get_domainname(param);
1923                 goto done;
1924         }
1925         {
1926                 char *cp = strchr(pos, ' ');
1927                 if (cp)
1928                         *cp = '\0';
1929                 flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
1930                         !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
1931                         !strcmp(pos, "child") || !strcmp(pos, "parent");
1932                 if (cp)
1933                         *cp = ' ';
1934         }
1935         if (!flag)
1936                 return pos;
1937         e->transit = ccs_get_name(ccs_read_token(param));
1938 done:
1939         if (e->transit) {
1940                 e->exec_transit = true;
1941                 return param->data;
1942         }
1943         /*
1944          * Return a bad read-only condition string that will let
1945          * ccs_get_condition() return NULL.
1946          */
1947         return "/";
1948 }
1949 
1950 /**
1951  * ccs_get_condition - Parse condition part.
1952  *
1953  * @param: Pointer to "struct ccs_acl_param".
1954  *
1955  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
1956  */
1957 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param)
1958 {
1959         struct ccs_condition *entry = NULL;
1960         struct ccs_condition_element *condp = NULL;
1961         struct ccs_number_union *numbers_p = NULL;
1962         struct ccs_name_union *names_p = NULL;
1963         struct ccs_argv *argv = NULL;
1964         struct ccs_envp *envp = NULL;
1965         struct ccs_condition e = { };
1966         char * const start_of_string = ccs_get_transit_preference(param, &e);
1967         char * const end_of_string = start_of_string + strlen(start_of_string);
1968         char *pos;
1969 rerun:
1970         pos = start_of_string;
1971         while (1) {
1972                 u8 left = -1;
1973                 u8 right = -1;
1974                 char *left_word = pos;
1975                 char *cp;
1976                 char *right_word;
1977                 bool is_not;
1978                 if (!*left_word)
1979                         break;
1980                 /*
1981                  * Since left-hand condition does not allow use of "path_group"
1982                  * or "number_group" and environment variable's names do not
1983                  * accept '=', it is guaranteed that the original line consists
1984                  * of one or more repetition of $left$operator$right blocks
1985                  * where "$left is free from '=' and ' '" and "$operator is
1986                  * either '=' or '!='" and "$right is free from ' '".
1987                  * Therefore, we can reconstruct the original line at the end
1988                  * of dry run even if we overwrite $operator with '\0'.
1989                  */
1990                 cp = strchr(pos, ' ');
1991                 if (cp) {
1992                         *cp = '\0'; /* Will restore later. */
1993                         pos = cp + 1;
1994                 } else {
1995                         pos = "";
1996                 }
1997                 right_word = strchr(left_word, '=');
1998                 if (!right_word || right_word == left_word)
1999                         goto out;
2000                 is_not = *(right_word - 1) == '!';
2001                 if (is_not)
2002                         *(right_word++ - 1) = '\0'; /* Will restore later. */
2003                 else if (*(right_word + 1) != '=')
2004                         *right_word++ = '\0'; /* Will restore later. */
2005                 else
2006                         goto out;
2007                 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
2008                         is_not ? "!" : "", right_word);
2009                 if (!strcmp(left_word, "grant_log")) {
2010                         if (entry) {
2011                                 if (is_not ||
2012                                     entry->grant_log != CCS_GRANTLOG_AUTO)
2013                                         goto out;
2014                                 else if (!strcmp(right_word, "yes"))
2015                                         entry->grant_log = CCS_GRANTLOG_YES;
2016                                 else if (!strcmp(right_word, "no"))
2017                                         entry->grant_log = CCS_GRANTLOG_NO;
2018                                 else
2019                                         goto out;
2020                         }
2021                         continue;
2022                 }
2023                 if (!strcmp(left_word, "auto_domain_transition")) {
2024                         if (entry) {
2025                                 if (is_not || entry->transit)
2026                                         goto out;
2027                                 entry->transit = ccs_get_dqword(right_word);
2028                                 if (!entry->transit ||
2029                                     (entry->transit->name[0] != '/' &&
2030                                      !ccs_domain_def(entry->transit->name)))
2031                                         goto out;
2032                         }
2033                         continue;
2034                 }
2035                 if (!strncmp(left_word, "exec.argv[", 10)) {
2036                         if (!argv) {
2037                                 e.argc++;
2038                                 e.condc++;
2039                         } else {
2040                                 e.argc--;
2041                                 e.condc--;
2042                                 left = CCS_ARGV_ENTRY;
2043                                 argv->is_not = is_not;
2044                                 if (!ccs_parse_argv(left_word + 10,
2045                                                     right_word, argv++))
2046                                         goto out;
2047                         }
2048                         goto store_value;
2049                 }
2050                 if (!strncmp(left_word, "exec.envp[\"", 11)) {
2051                         if (!envp) {
2052                                 e.envc++;
2053                                 e.condc++;
2054                         } else {
2055                                 e.envc--;
2056                                 e.condc--;
2057                                 left = CCS_ENVP_ENTRY;
2058                                 envp->is_not = is_not;
2059                                 if (!ccs_parse_envp(left_word + 11,
2060                                                     right_word, envp++))
2061                                         goto out;
2062                         }
2063                         goto store_value;
2064                 }
2065                 left = ccs_condition_type(left_word);
2066                 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
2067                         left);
2068                 if (left == CCS_MAX_CONDITION_KEYWORD) {
2069                         if (!numbers_p) {
2070                                 e.numbers_count++;
2071                         } else {
2072                                 e.numbers_count--;
2073                                 left = CCS_NUMBER_UNION;
2074                                 param->data = left_word;
2075                                 if (*left_word == '@' ||
2076                                     !ccs_parse_number_union(param,
2077                                                             numbers_p++))
2078                                         goto out;
2079                         }
2080                 }
2081                 if (!condp)
2082                         e.condc++;
2083                 else
2084                         e.condc--;
2085                 if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
2086                         if (!names_p) {
2087                                 e.names_count++;
2088                         } else {
2089                                 e.names_count--;
2090                                 right = CCS_NAME_UNION;
2091                                 param->data = right_word;
2092                                 if (!ccs_parse_name_union_quoted(param,
2093                                                                  names_p++))
2094                                         goto out;
2095                         }
2096                         goto store_value;
2097                 }
2098                 right = ccs_condition_type(right_word);
2099                 if (right == CCS_MAX_CONDITION_KEYWORD) {
2100                         if (!numbers_p) {
2101                                 e.numbers_count++;
2102                         } else {
2103                                 e.numbers_count--;
2104                                 right = CCS_NUMBER_UNION;
2105                                 param->data = right_word;
2106                                 if (!ccs_parse_number_union(param,
2107                                                             numbers_p++))
2108                                         goto out;
2109                         }
2110                 }
2111 store_value:
2112                 if (!condp) {
2113                         dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
2114                                 "match=%u\n", __LINE__, left, right, !is_not);
2115                         continue;
2116                 }
2117                 condp->left = left;
2118                 condp->right = right;
2119                 condp->equals = !is_not;
2120                 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
2121                         __LINE__, condp->left, condp->right,
2122                         condp->equals);
2123                 condp++;
2124         }
2125         dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
2126                 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
2127                 e.envc);
2128         if (entry) {
2129                 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
2130                        e.condc);
2131                 return ccs_commit_condition(entry);
2132         }
2133         e.size = sizeof(*entry)
2134                 + e.condc * sizeof(struct ccs_condition_element)
2135                 + e.numbers_count * sizeof(struct ccs_number_union)
2136                 + e.names_count * sizeof(struct ccs_name_union)
2137                 + e.argc * sizeof(struct ccs_argv)
2138                 + e.envc * sizeof(struct ccs_envp);
2139         entry = kzalloc(e.size, CCS_GFP_FLAGS);
2140         if (!entry)
2141                 goto out2;
2142         *entry = e;
2143         e.transit = NULL;
2144         condp = (struct ccs_condition_element *) (entry + 1);
2145         numbers_p = (struct ccs_number_union *) (condp + e.condc);
2146         names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
2147         argv = (struct ccs_argv *) (names_p + e.names_count);
2148         envp = (struct ccs_envp *) (argv + e.argc);
2149         {
2150                 bool flag = false;
2151                 for (pos = start_of_string; pos < end_of_string; pos++) {
2152                         if (*pos)
2153                                 continue;
2154                         if (flag) /* Restore " ". */
2155                                 *pos = ' ';
2156                         else if (*(pos + 1) == '=') /* Restore "!=". */
2157                                 *pos = '!';
2158                         else /* Restore "=". */
2159                                 *pos = '=';
2160                         flag = !flag;
2161                 }
2162         }
2163         goto rerun;
2164 out:
2165         dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
2166         if (entry) {
2167                 ccs_del_condition(&entry->head.list);
2168                 kfree(entry);
2169         }
2170 out2:
2171         ccs_put_name(e.transit);
2172         return NULL;
2173 }
2174 
2175 /**
2176  * ccs_yesno - Return "yes" or "no".
2177  *
2178  * @value: Bool value.
2179  *
2180  * Returns "yes" if @value is not 0, "no" otherwise.
2181  */
2182 static const char *ccs_yesno(const unsigned int value)
2183 {
2184         return value ? "yes" : "no";
2185 }
2186 
2187 /**
2188  * ccs_addprintf - strncat()-like-snprintf().
2189  *
2190  * @buffer: Buffer to write to. Must be '\0'-terminated.
2191  * @len:    Size of @buffer.
2192  * @fmt:    The printf()'s format string, followed by parameters.
2193  *
2194  * Returns nothing.
2195  */
2196 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
2197 {
2198         va_list args;
2199         const int pos = strlen(buffer);
2200         va_start(args, fmt);
2201         vsnprintf(buffer + pos, len - pos - 1, fmt, args);
2202         va_end(args);
2203 }
2204 
2205 /**
2206  * ccs_flush - Flush queued string to userspace's buffer.
2207  *
2208  * @head: Pointer to "struct ccs_io_buffer".
2209  *
2210  * Returns true if all data was flushed, false otherwise.
2211  */
2212 static bool ccs_flush(struct ccs_io_buffer *head)
2213 {
2214         while (head->r.w_pos) {
2215                 const char *w = head->r.w[0];
2216                 size_t len = strlen(w);
2217                 if (len) {
2218                         if (len > head->read_user_buf_avail)
2219                                 len = head->read_user_buf_avail;
2220                         if (!len)
2221                                 return false;
2222                         if (copy_to_user(head->read_user_buf, w, len))
2223                                 return false;
2224                         head->read_user_buf_avail -= len;
2225                         head->read_user_buf += len;
2226                         w += len;
2227                 }
2228                 head->r.w[0] = w;
2229                 if (*w)
2230                         return false;
2231                 /* Add '\0' for audit logs and query. */
2232                 if (head->type == CCS_AUDIT || head->type == CCS_QUERY) {
2233                         if (!head->read_user_buf_avail ||
2234                             copy_to_user(head->read_user_buf, "", 1))
2235                                 return false;
2236                         head->read_user_buf_avail--;
2237                         head->read_user_buf++;
2238                 }
2239                 head->r.w_pos--;
2240                 for (len = 0; len < head->r.w_pos; len++)
2241                         head->r.w[len] = head->r.w[len + 1];
2242         }
2243         head->r.avail = 0;
2244         return true;
2245 }
2246 
2247 /**
2248  * ccs_set_string - Queue string to "struct ccs_io_buffer" structure.
2249  *
2250  * @head:   Pointer to "struct ccs_io_buffer".
2251  * @string: String to print.
2252  *
2253  * Returns nothing.
2254  *
2255  * Note that @string has to be kept valid until @head is kfree()d.
2256  * This means that char[] allocated on stack memory cannot be passed to
2257  * this function. Use ccs_io_printf() for char[] allocated on stack memory.
2258  */
2259 static void ccs_set_string(struct ccs_io_buffer *head, const char *string)
2260 {
2261         if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) {
2262                 head->r.w[head->r.w_pos++] = string;
2263                 ccs_flush(head);
2264         } else
2265                 printk(KERN_WARNING "Too many words in a line.\n");
2266 }
2267 
2268 /**
2269  * ccs_io_printf - printf() to "struct ccs_io_buffer" structure.
2270  *
2271  * @head: Pointer to "struct ccs_io_buffer".
2272  * @fmt:  The printf()'s format string, followed by parameters.
2273  *
2274  * Returns nothing.
2275  */
2276 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
2277 {
2278         va_list args;
2279         size_t len;
2280         size_t pos = head->r.avail;
2281         int size = head->readbuf_size - pos;
2282         if (size <= 0)
2283                 return;
2284         va_start(args, fmt);
2285         len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
2286         va_end(args);
2287         if (pos + len >= head->readbuf_size) {
2288                 printk(KERN_WARNING "Too many words in a line.\n");
2289                 return;
2290         }
2291         head->r.avail += len;
2292         ccs_set_string(head, head->read_buf + pos);
2293 }
2294 
2295 /**
2296  * ccs_set_space - Put a space to "struct ccs_io_buffer" structure.
2297  *
2298  * @head: Pointer to "struct ccs_io_buffer".
2299  *
2300  * Returns nothing.
2301  */
2302 static void ccs_set_space(struct ccs_io_buffer *head)
2303 {
2304         ccs_set_string(head, " ");
2305 }
2306 
2307 /**
2308  * ccs_set_lf - Put a line feed to "struct ccs_io_buffer" structure.
2309  *
2310  * @head: Pointer to "struct ccs_io_buffer".
2311  *
2312  * Returns true if all data was flushed, false otherwise.
2313  */
2314 static bool ccs_set_lf(struct ccs_io_buffer *head)
2315 {
2316         ccs_set_string(head, "\n");
2317         return !head->r.w_pos;
2318 }
2319 
2320 /**
2321  * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure.
2322  *
2323  * @head: Pointer to "struct ccs_io_buffer".
2324  *
2325  * Returns nothing.
2326  */
2327 static void ccs_set_slash(struct ccs_io_buffer *head)
2328 {
2329         ccs_set_string(head, "/");
2330 }
2331 
2332 /**
2333  * ccs_init_policy_namespace - Initialize namespace.
2334  *
2335  * @ns: Pointer to "struct ccs_policy_namespace".
2336  *
2337  * Returns nothing.
2338  */
2339 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
2340 {
2341         unsigned int idx;
2342         for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++)
2343                 INIT_LIST_HEAD(&ns->acl_group[idx]);
2344         for (idx = 0; idx < CCS_MAX_GROUP; idx++)
2345                 INIT_LIST_HEAD(&ns->group_list[idx]);
2346         for (idx = 0; idx < CCS_MAX_POLICY; idx++)
2347                 INIT_LIST_HEAD(&ns->policy_list[idx]);
2348         ns->profile_version = 20150505;
2349         ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
2350         list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list);
2351 }
2352 
2353 /**
2354  * ccs_print_namespace - Print namespace header.
2355  *
2356  * @head: Pointer to "struct ccs_io_buffer".
2357  *
2358  * Returns nothing.
2359  */
2360 static void ccs_print_namespace(struct ccs_io_buffer *head)
2361 {
2362         if (!ccs_namespace_enabled)
2363                 return;
2364         ccs_set_string(head,
2365                        container_of(head->r.ns, struct ccs_policy_namespace,
2366                                     namespace_list)->name);
2367         ccs_set_space(head);
2368 }
2369 
2370 /**
2371  * ccs_assign_profile - Create a new profile.
2372  *
2373  * @ns:      Pointer to "struct ccs_policy_namespace".
2374  * @profile: Profile number to create.
2375  *
2376  * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
2377  */
2378 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
2379                                               const unsigned int profile)
2380 {
2381         struct ccs_profile *ptr;
2382         struct ccs_profile *entry;
2383         if (profile >= CCS_MAX_PROFILES)
2384                 return NULL;
2385         ptr = ns->profile_ptr[profile];
2386         if (ptr)
2387                 return ptr;
2388         entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
2389         if (mutex_lock_interruptible(&ccs_policy_lock))
2390                 goto out;
2391         ptr = ns->profile_ptr[profile];
2392         if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
2393                 ptr = entry;
2394                 ptr->default_config = CCS_CONFIG_DISABLED |
2395                         CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
2396                 memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
2397                        sizeof(ptr->config));
2398                 ptr->pref[CCS_PREF_MAX_AUDIT_LOG] =
2399                         CONFIG_CCSECURITY_MAX_AUDIT_LOG;
2400                 ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] =
2401                         CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY;
2402                 mb(); /* Avoid out-of-order execution. */
2403                 ns->profile_ptr[profile] = ptr;
2404                 entry = NULL;
2405         }
2406         mutex_unlock(&ccs_policy_lock);
2407 out:
2408         kfree(entry);
2409         return ptr;
2410 }
2411 
2412 /**
2413  * ccs_check_profile - Check all profiles currently assigned to domains are defined.
2414  *
2415  * Returns nothing.
2416  */
2417 static void ccs_check_profile(void)
2418 {
2419         struct ccs_domain_info *domain;
2420         const int idx = ccs_read_lock();
2421         ccs_policy_loaded = true;
2422         printk(KERN_INFO "CCSecurity: 1.8.6   2019/08/20\n");
2423         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
2424                 const u8 profile = domain->profile;
2425                 struct ccs_policy_namespace *ns = domain->ns;
2426                 if (ns->profile_version == 20100903) {
2427                         static bool done;
2428                         if (!done)
2429                                 printk(KERN_INFO "Converting profile version "
2430                                        "from %u to %u.\n", 20100903, 20150505);
2431                         done = true;
2432                         ns->profile_version = 20150505;
2433                 }
2434                 if (ns->profile_version != 20150505)
2435                         printk(KERN_ERR
2436                                "Profile version %u is not supported.\n",
2437                                ns->profile_version);
2438                 else if (!ns->profile_ptr[profile])
2439                         printk(KERN_ERR
2440                                "Profile %u (used by '%s') is not defined.\n",
2441                                profile, domain->domainname->name);
2442                 else
2443                         continue;
2444                 printk(KERN_ERR
2445                        "Userland tools for TOMOYO 1.8 must be installed and "
2446                        "policy must be initialized.\n");
2447                 printk(KERN_ERR "Please see https://tomoyo.osdn.jp/1.8/ "
2448                        "for more information.\n");
2449                 panic("STOP!");
2450         }
2451         ccs_read_unlock(idx);
2452         printk(KERN_INFO "Mandatory Access Control activated.\n");
2453 }
2454 
2455 /**
2456  * ccs_profile - Find a profile.
2457  *
2458  * @profile: Profile number to find.
2459  *
2460  * Returns pointer to "struct ccs_profile".
2461  */
2462 static struct ccs_profile *ccs_profile(const u8 profile)
2463 {
2464         static struct ccs_profile ccs_null_profile;
2465         struct ccs_profile *ptr = ccs_current_namespace()->
2466                 profile_ptr[profile];
2467         if (!ptr)
2468                 ptr = &ccs_null_profile;
2469         return ptr;
2470 }
2471 
2472 /**
2473  * ccs_get_config - Get config for specified profile's specified functionality.
2474  *
2475  * @profile: Profile number.
2476  * @index:   Index number of functionality.
2477  *
2478  * Returns config.
2479  *
2480  * First, check for CONFIG::category::functionality.
2481  * If CONFIG::category::functionality is set to use default, then check
2482  * CONFIG::category. If CONFIG::category is set to use default, then use
2483  * CONFIG. CONFIG cannot be set to use default.
2484  */
2485 u8 ccs_get_config(const u8 profile, const u8 index)
2486 {
2487         u8 config;
2488         const struct ccs_profile *p;
2489         if (!ccs_policy_loaded)
2490                 return CCS_CONFIG_DISABLED;
2491         p = ccs_profile(profile);
2492         config = p->config[index];
2493         if (config == CCS_CONFIG_USE_DEFAULT)
2494                 config = p->config[ccs_index2category[index]
2495                                    + CCS_MAX_MAC_INDEX];
2496         if (config == CCS_CONFIG_USE_DEFAULT)
2497                 config = p->default_config;
2498         return config;
2499 }
2500 
2501 /**
2502  * ccs_find_yesno - Find values for specified keyword.
2503  *
2504  * @string: String to check.
2505  * @find:   Name of keyword.
2506  *
2507  * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
2508  */
2509 static s8 ccs_find_yesno(const char *string, const char *find)
2510 {
2511         const char *cp = strstr(string, find);
2512         if (cp) {
2513                 cp += strlen(find);
2514                 if (!strncmp(cp, "=yes", 4))
2515                         return 1;
2516                 else if (!strncmp(cp, "=no", 3))
2517                         return 0;
2518         }
2519         return -1;
2520 }
2521 
2522 /**
2523  * ccs_set_uint - Set value for specified preference.
2524  *
2525  * @i:      Pointer to "unsigned int".
2526  * @string: String to check.
2527  * @find:   Name of keyword.
2528  *
2529  * Returns nothing.
2530  */
2531 static void ccs_set_uint(unsigned int *i, const char *string, const char *find)
2532 {
2533         const char *cp = strstr(string, find);
2534         if (cp)
2535                 sscanf(cp + strlen(find), "=%u", i);
2536 }
2537 
2538 /**
2539  * ccs_str_starts - Check whether the given string starts with the given keyword.
2540  *
2541  * @src:  Pointer to pointer to the string.
2542  * @find: Pointer to the keyword.
2543  *
2544  * Returns true if @src starts with @find, false otherwise.
2545  *
2546  * The @src is updated to point the first character after the @find
2547  * if @src starts with @find.
2548  */
2549 static bool ccs_str_starts(char **src, const char *find)
2550 {
2551         const int len = strlen(find);
2552         char *tmp = *src;
2553         if (strncmp(tmp, find, len))
2554                 return false;
2555         tmp += len;
2556         *src = tmp;
2557         return true;
2558 }
2559 
2560 /**
2561  * ccs_print_group - Print group's name.
2562  *
2563  * @head:  Pointer to "struct ccs_io_buffer".
2564  * @group: Pointer to "struct ccsgroup". Maybe NULL.
2565  *
2566  * Returns true if @group is not NULL. false otherwise.
2567  */
2568 static bool ccs_print_group(struct ccs_io_buffer *head,
2569                             const struct ccs_group *group)
2570 {
2571         if (group) {
2572                 ccs_set_string(head, "@");
2573                 ccs_set_string(head, group->group_name->name);
2574                 return true;
2575         }
2576         return false;
2577 }
2578 
2579 /**
2580  * ccs_set_mode - Set mode for specified profile.
2581  *
2582  * @name:    Name of functionality.
2583  * @value:   Mode for @name.
2584  * @profile: Pointer to "struct ccs_profile".
2585  *
2586  * Returns 0 on success, negative value otherwise.
2587  */
2588 static int ccs_set_mode(char *name, const char *value,
2589                         struct ccs_profile *profile)
2590 {
2591         u8 i;
2592         u8 config;
2593         if (!strcmp(name, "CONFIG")) {
2594                 i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
2595                 config = profile->default_config;
2596         } else if (ccs_str_starts(&name, "CONFIG::")) {
2597                 config = 0;
2598                 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
2599                      i++) {
2600                         int len = 0;
2601                         if (i < CCS_MAX_MAC_INDEX) {
2602                                 const u8 c = ccs_index2category[i];
2603                                 const char *category =
2604                                         ccs_category_keywords[c];
2605                                 len = strlen(category);
2606                                 if (strncmp(name, category, len) ||
2607                                     name[len++] != ':' || name[len++] != ':')
2608                                         continue;
2609                         }
2610                         if (strcmp(name + len, ccs_mac_keywords[i]))
2611                                 continue;
2612                         config = profile->config[i];
2613                         break;
2614                 }
2615                 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
2616                         return -EINVAL;
2617         } else {
2618                 return -EINVAL;
2619         }
2620         if (strstr(value, "use_default")) {
2621                 config = CCS_CONFIG_USE_DEFAULT;
2622         } else {
2623                 u8 mode;
2624                 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
2625                         if (strstr(value, ccs_mode[mode]))
2626                                 /*
2627                                  * Update lower 3 bits in order to distinguish
2628                                  * 'config' from 'CCS_CONFIG_USE_DEAFULT'.
2629                                  */
2630                                 config = (config & ~7) | mode;
2631                 if (config != CCS_CONFIG_USE_DEFAULT) {
2632                         switch (ccs_find_yesno(value, "grant_log")) {
2633                         case 1:
2634                                 config |= CCS_CONFIG_WANT_GRANT_LOG;
2635                                 break;
2636                         case 0:
2637                                 config &= ~CCS_CONFIG_WANT_GRANT_LOG;
2638                                 break;
2639                         }
2640                         switch (ccs_find_yesno(value, "reject_log")) {
2641                         case 1:
2642                                 config |= CCS_CONFIG_WANT_REJECT_LOG;
2643                                 break;
2644                         case 0:
2645                                 config &= ~CCS_CONFIG_WANT_REJECT_LOG;
2646                                 break;
2647                         }
2648                 }
2649         }
2650         if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
2651                 profile->config[i] = config;
2652         else if (config != CCS_CONFIG_USE_DEFAULT)
2653                 profile->default_config = config;
2654         return 0;
2655 }
2656 
2657 /**
2658  * ccs_write_profile - Write profile table.
2659  *
2660  * @head: Pointer to "struct ccs_io_buffer".
2661  *
2662  * Returns 0 on success, negative value otherwise.
2663  */
2664 static int ccs_write_profile(struct ccs_io_buffer *head)
2665 {
2666         char *data = head->write_buf;
2667         unsigned int i;
2668         char *cp;
2669         struct ccs_profile *profile;
2670         if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
2671             == 1)
2672                 return 0;
2673         i = simple_strtoul(data, &cp, 10);
2674         if (*cp != '-')
2675                 return -EINVAL;
2676         data = cp + 1;
2677         profile = ccs_assign_profile(head->w.ns, i);
2678         if (!profile)
2679                 return -EINVAL;
2680         cp = strchr(data, '=');
2681         if (!cp)
2682                 return -EINVAL;
2683         *cp++ = '\0';
2684         if (!strcmp(data, "COMMENT")) {
2685                 static DEFINE_SPINLOCK(lock);
2686                 const struct ccs_path_info *new_comment = ccs_get_name(cp);
2687                 const struct ccs_path_info *old_comment;
2688                 if (!new_comment)
2689                         return -ENOMEM;
2690                 spin_lock(&lock);
2691                 old_comment = profile->comment;
2692                 profile->comment = new_comment;
2693                 spin_unlock(&lock);
2694                 ccs_put_name(old_comment);
2695                 return 0;
2696         }
2697         if (!strcmp(data, "PREFERENCE")) {
2698                 for (i = 0; i < CCS_MAX_PREF; i++)
2699                         ccs_set_uint(&profile->pref[i], cp,
2700                                      ccs_pref_keywords[i]);
2701                 return 0;
2702         }
2703         return ccs_set_mode(data, cp, profile);
2704 }
2705 
2706 /**
2707  * ccs_print_config - Print mode for specified functionality.
2708  *
2709  * @head:   Pointer to "struct ccs_io_buffer".
2710  * @config: Mode for that functionality.
2711  *
2712  * Returns nothing.
2713  *
2714  * Caller prints functionality's name.
2715  */
2716 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)
2717 {
2718         ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
2719                       ccs_mode[config & 3],
2720                       ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
2721                       ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));
2722 }
2723 
2724 /**
2725  * ccs_read_profile - Read profile table.
2726  *
2727  * @head: Pointer to "struct ccs_io_buffer".
2728  *
2729  * Returns nothing.
2730  */
2731 static void ccs_read_profile(struct ccs_io_buffer *head)
2732 {
2733         u8 index;
2734         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
2735                                                        namespace_list);
2736         const struct ccs_profile *profile;
2737         if (head->r.eof)
2738                 return;
2739 next:
2740         index = head->r.index;
2741         profile = ns->profile_ptr[index];
2742         switch (head->r.step) {
2743         case 0:
2744                 ccs_print_namespace(head);
2745                 ccs_io_printf(head, "PROFILE_VERSION=%u\n",
2746                               ns->profile_version);
2747                 head->r.step++;
2748                 break;
2749         case 1:
2750                 for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++)
2751                         if (ns->profile_ptr[head->r.index])
2752                                 break;
2753                 if (head->r.index == CCS_MAX_PROFILES) {
2754                         head->r.eof = true;
2755                         return;
2756                 }
2757                 head->r.step++;
2758                 break;
2759         case 2:
2760                 {
2761                         u8 i;
2762                         const struct ccs_path_info *comment = profile->comment;
2763                         ccs_print_namespace(head);
2764                         ccs_io_printf(head, "%u-COMMENT=", index);
2765                         ccs_set_string(head, comment ? comment->name : "");
2766                         ccs_set_lf(head);
2767                         ccs_print_namespace(head);
2768                         ccs_io_printf(head, "%u-PREFERENCE={ ", index);
2769                         for (i = 0; i < CCS_MAX_PREF; i++)
2770                                 ccs_io_printf(head, "%s=%u ",
2771                                               ccs_pref_keywords[i],
2772                                               profile->pref[i]);
2773                         ccs_set_string(head, "}\n");
2774                         head->r.step++;
2775                 }
2776                 break;
2777         case 3:
2778                 {
2779                         ccs_print_namespace(head);
2780                         ccs_io_printf(head, "%u-%s", index, "CONFIG");
2781                         ccs_print_config(head, profile->default_config);
2782                         head->r.bit = 0;
2783                         head->r.step++;
2784                 }
2785                 break;
2786         case 4:
2787                 for ( ; head->r.bit < CCS_MAX_MAC_INDEX
2788                               + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
2789                         const u8 i = head->r.bit;
2790                         const u8 config = profile->config[i];
2791                         if (config == CCS_CONFIG_USE_DEFAULT)
2792                                 continue;
2793                         ccs_print_namespace(head);
2794                         if (i < CCS_MAX_MAC_INDEX)
2795                                 ccs_io_printf(head, "%u-CONFIG::%s::%s", index,
2796                                               ccs_category_keywords
2797                                               [ccs_index2category[i]],
2798                                               ccs_mac_keywords[i]);
2799                         else
2800                                 ccs_io_printf(head, "%u-CONFIG::%s", index,
2801                                               ccs_mac_keywords[i]);
2802                         ccs_print_config(head, config);
2803                         head->r.bit++;
2804                         break;
2805                 }
2806                 if (head->r.bit == CCS_MAX_MAC_INDEX
2807                     + CCS_MAX_MAC_CATEGORY_INDEX) {
2808                         head->r.index++;
2809                         head->r.step = 1;
2810                 }
2811                 break;
2812         }
2813         if (ccs_flush(head))
2814                 goto next;
2815 }
2816 
2817 /**
2818  * ccs_update_policy - Update an entry for exception policy.
2819  *
2820  * @size:  Size of new entry in bytes.
2821  * @param: Pointer to "struct ccs_acl_param".
2822  *
2823  * Returns 0 on success, negative value otherwise.
2824  *
2825  * Caller holds ccs_read_lock().
2826  */
2827 static int ccs_update_policy(const int size, struct ccs_acl_param *param)
2828 {
2829         struct ccs_acl_head *new_entry = &param->e.acl_head;
2830         int error = param->is_delete ? -ENOENT : -ENOMEM;
2831         struct ccs_acl_head *entry;
2832         struct list_head *list = param->list;
2833         BUG_ON(size < sizeof(*entry));
2834         if (mutex_lock_interruptible(&ccs_policy_lock))
2835                 return -ENOMEM;
2836         list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
2837                 if (entry->is_deleted == CCS_GC_IN_PROGRESS)
2838                         continue;
2839                 if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
2840                         continue;
2841                 entry->is_deleted = param->is_delete;
2842                 error = 0;
2843                 break;
2844         }
2845         if (error && !param->is_delete) {
2846                 entry = ccs_commit_ok(new_entry, size);
2847                 if (entry) {
2848                         list_add_tail_rcu(&entry->list, list);
2849                         error = 0;
2850                 }
2851         }
2852         mutex_unlock(&ccs_policy_lock);
2853         return error;
2854 }
2855 
2856 /**
2857  * ccs_update_manager_entry - Add a manager entry.
2858  *
2859  * @manager:   The path to manager or the domainnamme.
2860  * @is_delete: True if it is a delete request.
2861  *
2862  * Returns 0 on success, negative value otherwise.
2863  */
2864 static int ccs_update_manager_entry(const char *manager,
2865                                     const bool is_delete)
2866 {
2867         struct ccs_acl_param param = {
2868                 /* .ns = &ccs_kernel_namespace, */
2869                 .is_delete = is_delete,
2870                 .list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER],
2871         };
2872         struct ccs_manager *e = &param.e.manager;
2873         int error = is_delete ? -ENOENT : -ENOMEM;
2874         /* Forced zero clear for using memcmp() at ccs_update_policy(). */
2875         memset(&param.e, 0, sizeof(param.e));
2876         if (!ccs_correct_domain(manager) && !ccs_correct_word(manager))
2877                 return -EINVAL;
2878         e->manager = ccs_get_name(manager);
2879         if (e->manager) {
2880                 error = ccs_update_policy(sizeof(*e), &param);
2881                 ccs_put_name(e->manager);
2882         }
2883         return error;
2884 }
2885 
2886 /**
2887  * ccs_write_manager - Write manager policy.
2888  *
2889  * @head: Pointer to "struct ccs_io_buffer".
2890  *
2891  * Returns 0 on success, negative value otherwise.
2892  */
2893 static int ccs_write_manager(struct ccs_io_buffer *head)
2894 {
2895         const char *data = head->write_buf;
2896         if (!strcmp(data, "manage_by_non_root")) {
2897                 ccs_manage_by_non_root = !head->w.is_delete;
2898                 return 0;
2899         }
2900         return ccs_update_manager_entry(data, head->w.is_delete);
2901 }
2902 
2903 /**
2904  * ccs_read_manager - Read manager policy.
2905  *
2906  * @head: Pointer to "struct ccs_io_buffer".
2907  *
2908  * Returns nothing.
2909  *
2910  * Caller holds ccs_read_lock().
2911  */
2912 static void ccs_read_manager(struct ccs_io_buffer *head)
2913 {
2914         if (head->r.eof)
2915                 return;
2916         list_for_each_cookie(head->r.acl, &ccs_kernel_namespace.
2917                              policy_list[CCS_ID_MANAGER]) {
2918                 struct ccs_manager *ptr =
2919                         list_entry(head->r.acl, typeof(*ptr), head.list);
2920                 if (ptr->head.is_deleted)
2921                         continue;
2922                 if (!ccs_flush(head))
2923                         return;
2924                 ccs_set_string(head, ptr->manager->name);
2925                 ccs_set_lf(head);
2926         }
2927         head->r.eof = true;
2928 }
2929 
2930 /**
2931  * ccs_manager - Check whether the current process is a policy manager.
2932  *
2933  * Returns true if the current process is permitted to modify policy
2934  * via /proc/ccs/ interface.
2935  *
2936  * Caller holds ccs_read_lock().
2937  */
2938 static bool ccs_manager(void)
2939 {
2940         struct ccs_manager *ptr;
2941         struct ccs_path_info exe;
2942         struct ccs_security *task = ccs_current_security();
2943         const struct ccs_path_info *domainname
2944                 = ccs_current_domain()->domainname;
2945         bool found = false;
2946         if (!ccs_policy_loaded)
2947                 return true;
2948         if (task->ccs_flags & CCS_TASK_IS_MANAGER)
2949                 return true;
2950         if (!ccs_manage_by_non_root &&
2951             (!uid_eq(current_uid(), GLOBAL_ROOT_UID) ||
2952              !uid_eq(current_euid(), GLOBAL_ROOT_UID)))
2953                 return false;
2954         exe.name = ccs_get_exe();
2955         if (!exe.name)
2956                 return false;
2957         ccs_fill_path_info(&exe);
2958         list_for_each_entry_srcu(ptr, &ccs_kernel_namespace.
2959                                  policy_list[CCS_ID_MANAGER], head.list,
2960                                  &ccs_ss) {
2961                 if (ptr->head.is_deleted)
2962                         continue;
2963                 if (ccs_pathcmp(domainname, ptr->manager) &&
2964                     ccs_pathcmp(&exe, ptr->manager))
2965                         continue;
2966                 /* Set manager flag. */
2967                 task->ccs_flags |= CCS_TASK_IS_MANAGER;
2968                 found = true;
2969                 break;
2970         }
2971         if (!found) { /* Reduce error messages. */
2972                 static pid_t ccs_last_pid;
2973                 const pid_t pid = current->pid;
2974                 if (ccs_last_pid != pid) {
2975                         printk(KERN_WARNING "%s ( %s ) is not permitted to "
2976                                "update policies.\n", domainname->name,
2977                                exe.name);
2978                         ccs_last_pid = pid;
2979                 }
2980         }
2981         kfree(exe.name);
2982         return found;
2983 }
2984 
2985 /**
2986  * ccs_find_domain - Find a domain by the given name.
2987  *
2988  * @domainname: The domainname to find.
2989  *
2990  * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
2991  *
2992  * Caller holds ccs_read_lock().
2993  */
2994 static struct ccs_domain_info *ccs_find_domain(const char *domainname)
2995 {
2996         struct ccs_domain_info *domain;
2997         struct ccs_path_info name;
2998         name.name = domainname;
2999         ccs_fill_path_info(&name);
3000         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
3001                 if (!domain->is_deleted &&
3002                     !ccs_pathcmp(&name, domain->domainname))
3003                         return domain;
3004         }
3005         return NULL;
3006 }
3007 
3008 /**
3009  * ccs_select_domain - Parse select command.
3010  *
3011  * @head: Pointer to "struct ccs_io_buffer".
3012  * @data: String to parse.
3013  *
3014  * Returns true on success, false otherwise.
3015  *
3016  * Caller holds ccs_read_lock().
3017  */
3018 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data)
3019 {
3020         unsigned int pid;
3021         struct ccs_domain_info *domain = NULL;
3022         bool global_pid = false;
3023         if (strncmp(data, "select ", 7))
3024                 return false;
3025         data += 7;
3026         if (sscanf(data, "pid=%u", &pid) == 1 ||
3027             (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
3028                 struct task_struct *p;
3029                 ccs_tasklist_lock();
3030 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
3031                 if (global_pid)
3032                         p = ccsecurity_exports.find_task_by_pid_ns(pid,
3033                                                                &init_pid_ns);
3034                 else
3035                         p = ccsecurity_exports.find_task_by_vpid(pid);
3036 #else
3037                 p = find_task_by_pid(pid);
3038 #endif
3039                 if (p)
3040                         domain = ccs_task_domain(p);
3041                 ccs_tasklist_unlock();
3042         } else if (!strncmp(data, "domain=", 7)) {
3043                 if (*(data + 7) == '<')
3044                         domain = ccs_find_domain(data + 7);
3045         } else if (sscanf(data, "Q=%u", &pid) == 1) {
3046                 domain = ccs_find_domain_by_qid(pid);
3047         } else
3048                 return false;
3049         head->w.domain = domain;
3050         /* Accessing read_buf is safe because head->io_sem is held. */
3051         if (!head->read_buf)
3052                 return true; /* Do nothing if open(O_WRONLY). */
3053         memset(&head->r, 0, sizeof(head->r));
3054         head->r.print_this_domain_only = true;
3055         if (domain)
3056                 head->r.domain = &domain->list;
3057         else
3058                 head->r.eof = true;
3059         ccs_io_printf(head, "# select %s\n", data);
3060         if (domain && domain->is_deleted)
3061                 ccs_set_string(head, "# This is a deleted domain.\n");
3062         return true;
3063 }
3064 
3065 /**
3066  * ccs_update_acl - Update "struct ccs_acl_info" entry.
3067  *
3068  * @size:  Size of new entry in bytes.
3069  * @param: Pointer to "struct ccs_acl_param".
3070  *
3071  * Returns 0 on success, negative value otherwise.
3072  *
3073  * Caller holds ccs_read_lock().
3074  */
3075 static int ccs_update_acl(const int size, struct ccs_acl_param *param)
3076 {
3077         struct ccs_acl_info *new_entry = &param->e.acl_info;
3078         const bool is_delete = param->is_delete;
3079         int error = is_delete ? -ENOENT : -ENOMEM;
3080         struct ccs_acl_info *entry;
3081         struct list_head * const list = param->list;
3082         BUG_ON(size < sizeof(*entry));
3083         if (param->data[0]) {
3084                 new_entry->cond = ccs_get_condition(param);
3085                 if (!new_entry->cond)
3086                         return -EINVAL;
3087                 /*
3088                  * Domain transition preference is allowed for only
3089                  * "file execute"/"task auto_execute_handler"/
3090                  * "task denied_auto_execute_handler" entries.
3091                  */
3092                 if (new_entry->cond->exec_transit &&
3093                     !(new_entry->type == CCS_TYPE_PATH_ACL &&
3094                       new_entry->perm == 1 << CCS_TYPE_EXECUTE)
3095 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3096                     && new_entry->type != CCS_TYPE_AUTO_EXECUTE_HANDLER &&
3097                     new_entry->type != CCS_TYPE_DENIED_EXECUTE_HANDLER
3098 #endif
3099                     )
3100                         return -EINVAL;
3101         }
3102         if (mutex_lock_interruptible(&ccs_policy_lock))
3103                 return -ENOMEM;
3104         list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
3105                 if (entry->is_deleted == CCS_GC_IN_PROGRESS)
3106                         continue;
3107                 if (entry->type != new_entry->type ||
3108                     entry->cond != new_entry->cond ||
3109                     memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
3110                         continue;
3111                 if (is_delete)
3112                         entry->perm &= ~new_entry->perm;
3113                 else
3114                         entry->perm |= new_entry->perm;
3115                 entry->is_deleted = !entry->perm;
3116                 error = 0;
3117                 break;
3118         }
3119         if (error && !is_delete) {
3120                 entry = ccs_commit_ok(new_entry, size);
3121                 if (entry) {
3122                         list_add_tail_rcu(&entry->list, list);
3123                         error = 0;
3124                 }
3125         }
3126         mutex_unlock(&ccs_policy_lock);
3127         return error;
3128 }
3129 
3130 /**
3131  * ccs_permstr - Find permission keywords.
3132  *
3133  * @string: String representation for permissions in foo/bar/buz format.
3134  * @keyword: Keyword to find from @string/
3135  *
3136  * Returns true if @keyword was found in @string, false otherwise.
3137  *
3138  * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
3139  */
3140 static bool ccs_permstr(const char *string, const char *keyword)
3141 {
3142         const char *cp = strstr(string, keyword);
3143         if (cp)
3144                 return cp == string || *(cp - 1) == '/';
3145         return false;
3146 }
3147 
3148 /**
3149  * ccs_write_task - Update task related list.
3150  *
3151  * @param: Pointer to "struct ccs_acl_param".
3152  *
3153  * Returns 0 on success, negative value otherwise.
3154  *
3155  * Caller holds ccs_read_lock().
3156  */
3157 static int ccs_write_task(struct ccs_acl_param *param)
3158 {
3159         int error;
3160         const bool is_auto = ccs_str_starts(&param->data,
3161                                             "auto_domain_transition ");
3162         if (!is_auto && !ccs_str_starts(&param->data,
3163                                         "manual_domain_transition ")) {
3164 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3165                 struct ccs_handler_acl *e = &param->e.handler_acl;
3166                 char *handler;
3167                 if (ccs_str_starts(&param->data, "auto_execute_handler "))
3168                         e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
3169                 else if (ccs_str_starts(&param->data,
3170                                         "denied_execute_handler "))
3171                         e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
3172                 else
3173                         return -EINVAL;
3174                 handler = ccs_read_token(param);
3175                 if (!ccs_correct_path(handler))
3176                         return -EINVAL;
3177                 e->handler = ccs_get_name(handler);
3178                 if (!e->handler)
3179                         return -ENOMEM;
3180                 if (e->handler->is_patterned)
3181                         return -EINVAL; /* No patterns allowed. */
3182                 return ccs_update_acl(sizeof(*e), param);
3183 #else
3184                 error = -EINVAL;
3185 #endif
3186         } else {
3187 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
3188                 struct ccs_task_acl *e = &param->e.task_acl;
3189                 e->head.type = is_auto ?
3190                         CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL;
3191                 e->domainname = ccs_get_domainname(param);
3192                 if (!e->domainname)
3193                         return -EINVAL;
3194                 return ccs_update_acl(sizeof(*e), param);
3195 #else
3196                 error = -EINVAL;
3197 #endif
3198         }
3199         return error;
3200 }
3201 
3202 #ifdef CONFIG_CCSECURITY_NETWORK
3203 
3204 /**
3205  * ccs_write_inet_network - Write "struct ccs_inet_acl" list.
3206  *
3207  * @param: Pointer to "struct ccs_acl_param".
3208  *
3209  * Returns 0 on success, negative value otherwise.
3210  *
3211  * Caller holds ccs_read_lock().
3212  */
3213 static int ccs_write_inet_network(struct ccs_acl_param *param)
3214 {
3215         struct ccs_inet_acl *e = &param->e.inet_acl;
3216         u8 type;
3217         const char *protocol = ccs_read_token(param);
3218         const char *operation = ccs_read_token(param);
3219         e->head.type = CCS_TYPE_INET_ACL;
3220         for (type = 0; type < CCS_SOCK_MAX; type++)
3221                 if (!strcmp(protocol, ccs_proto_keyword[type]))
3222                         break;
3223         if (type == CCS_SOCK_MAX)
3224                 return -EINVAL;
3225         e->protocol = type;
3226         e->head.perm = 0;
3227         for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
3228                 if (ccs_permstr(operation, ccs_socket_keyword[type]))
3229                         e->head.perm |= 1 << type;
3230         if (!e->head.perm)
3231                 return -EINVAL;
3232         if (param->data[0] == '@') {
3233                 param->data++;
3234                 e->address.group = ccs_get_group(param, CCS_ADDRESS_GROUP);
3235                 if (!e->address.group)
3236                         return -ENOMEM;
3237         } else {
3238                 if (!ccs_parse_ipaddr_union(param, &e->address))
3239                         return -EINVAL;
3240         }
3241         if (!ccs_parse_number_union(param, &e->port) ||
3242             e->port.values[1] > 65535)
3243                 return -EINVAL;
3244         return ccs_update_acl(sizeof(*e), param);
3245 }
3246 
3247 /**
3248  * ccs_write_unix_network - Write "struct ccs_unix_acl" list.
3249  *
3250  * @param: Pointer to "struct ccs_acl_param".
3251  *
3252  * Returns 0 on success, negative value otherwise.
3253  */
3254 static int ccs_write_unix_network(struct ccs_acl_param *param)
3255 {
3256         struct ccs_unix_acl *e = &param->e.unix_acl;
3257         u8 type;
3258         const char *protocol = ccs_read_token(param);
3259         const char *operation = ccs_read_token(param);
3260         e->head.type = CCS_TYPE_UNIX_ACL;
3261         for (type = 0; type < CCS_SOCK_MAX; type++)
3262                 if (!strcmp(protocol, ccs_proto_keyword[type]))
3263                         break;
3264         if (type == CCS_SOCK_MAX)
3265                 return -EINVAL;
3266         e->protocol = type;
3267         e->head.perm = 0;
3268         for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
3269                 if (ccs_permstr(operation, ccs_socket_keyword[type]))
3270                         e->head.perm |= 1 << type;
3271         if (!e->head.perm)
3272                 return -EINVAL;
3273         if (!ccs_parse_name_union(param, &e->name))
3274                 return -EINVAL;
3275         return ccs_update_acl(sizeof(*e), param);
3276 }
3277 
3278 #endif
3279 
3280 /**
3281  * ccs_write_file - Update file related list.
3282  *
3283  * @param: Pointer to "struct ccs_acl_param".
3284  *
3285  * Returns 0 on success, negative value otherwise.
3286  *
3287  * Caller holds ccs_read_lock().
3288  */
3289 static int ccs_write_file(struct ccs_acl_param *param)
3290 {
3291         u16 perm = 0;
3292         u8 type;
3293         const char *operation = ccs_read_token(param);
3294         for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
3295                 if (ccs_permstr(operation, ccs_path_keyword[type]))
3296                         perm |= 1 << type;
3297         if (perm) {
3298                 struct ccs_path_acl *e = &param->e.path_acl;
3299                 e->head.type = CCS_TYPE_PATH_ACL;
3300                 e->head.perm = perm;
3301                 if (!ccs_parse_name_union(param, &e->name))
3302                         return -EINVAL;
3303                 return ccs_update_acl(sizeof(*e), param);
3304         }
3305         for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++)
3306                 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]]))
3307                         perm |= 1 << type;
3308         if (perm) {
3309                 struct ccs_path2_acl *e = &param->e.path2_acl;
3310                 e->head.type = CCS_TYPE_PATH2_ACL;
3311                 e->head.perm = perm;
3312                 if (!ccs_parse_name_union(param, &e->name1) ||
3313                     !ccs_parse_name_union(param, &e->name2))
3314                         return -EINVAL;
3315                 return ccs_update_acl(sizeof(*e), param);
3316         }
3317         for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++)
3318                 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]]))
3319                         perm |= 1 << type;
3320         if (perm) {
3321                 struct ccs_path_number_acl *e = &param->e.path_number_acl;
3322                 e->head.type = CCS_TYPE_PATH_NUMBER_ACL;
3323                 e->head.perm = perm;
3324                 if (!ccs_parse_name_union(param, &e->name) ||
3325                     !ccs_parse_number_union(param, &e->number))
3326                         return -EINVAL;
3327                 return ccs_update_acl(sizeof(*e), param);
3328         }
3329         for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++)
3330                 if (ccs_permstr(operation,
3331                                 ccs_mac_keywords[ccs_pnnn2mac[type]]))
3332                         perm |= 1 << type;
3333         if (perm) {
3334                 struct ccs_mkdev_acl *e = &param->e.mkdev_acl;
3335                 e->head.type = CCS_TYPE_MKDEV_ACL;
3336                 e->head.perm = perm;
3337                 if (!ccs_parse_name_union(param, &e->name) ||
3338                     !ccs_parse_number_union(param, &e->mode) ||
3339                     !ccs_parse_number_union(param, &e->major) ||
3340                     !ccs_parse_number_union(param, &e->minor))
3341                         return -EINVAL;
3342                 return ccs_update_acl(sizeof(*e), param);
3343         }
3344         if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) {
3345                 struct ccs_mount_acl *e = &param->e.mount_acl;
3346                 e->head.type = CCS_TYPE_MOUNT_ACL;
3347                 if (!ccs_parse_name_union(param, &e->dev_name) ||
3348                     !ccs_parse_name_union(param, &e->dir_name) ||
3349                     !ccs_parse_name_union(param, &e->fs_type) ||
3350                     !ccs_parse_number_union(param, &e->flags))
3351                         return -EINVAL;
3352                 return ccs_update_acl(sizeof(*e), param);
3353         }
3354         return -EINVAL;
3355 }
3356 
3357 #ifdef CONFIG_CCSECURITY_MISC
3358 
3359 /**
3360  * ccs_write_misc - Update environment variable list.
3361  *
3362  * @param: Pointer to "struct ccs_acl_param".
3363  *
3364  * Returns 0 on success, negative value otherwise.
3365  */
3366 static int ccs_write_misc(struct ccs_acl_param *param)
3367 {
3368         if (ccs_str_starts(&param->data, "env ")) {
3369                 struct ccs_env_acl *e = &param->e.env_acl;
3370                 const char *data = ccs_read_token(param);
3371                 e->head.type = CCS_TYPE_ENV_ACL;
3372                 if (!ccs_correct_word(data) || strchr(data, '='))
3373                         return -EINVAL;
3374                 e->env = ccs_get_name(data);
3375                 if (!e->env)
3376                         return -ENOMEM;
3377                 return ccs_update_acl(sizeof(*e), param);
3378         }
3379         return -EINVAL;
3380 }
3381 
3382 #endif
3383 
3384 #ifdef CONFIG_CCSECURITY_IPC
3385 
3386 /**
3387  * ccs_write_ipc - Update "struct ccs_signal_acl" list.
3388  *
3389  * @param: Pointer to "struct ccs_acl_param".
3390  *
3391  * Returns 0 on success, negative value otherwise.
3392  */
3393 static int ccs_write_ipc(struct ccs_acl_param *param)
3394 {
3395         struct ccs_signal_acl *e = &param->e.signal_acl;
3396         e->head.type = CCS_TYPE_SIGNAL_ACL;
3397         if (!ccs_parse_number_union(param, &e->sig))
3398                 return -EINVAL;
3399         e->domainname = ccs_get_domainname(param);
3400         if (!e->domainname)
3401                 return -EINVAL;
3402         return ccs_update_acl(sizeof(*e), param);
3403 }
3404 
3405 #endif
3406 
3407 #ifdef CONFIG_CCSECURITY_CAPABILITY
3408 
3409 /**
3410  * ccs_write_capability - Write "struct ccs_capability_acl" list.
3411  *
3412  * @param: Pointer to "struct ccs_acl_param".
3413  *
3414  * Returns 0 on success, negative value otherwise.
3415  *
3416  * Caller holds ccs_read_lock().
3417  */
3418 static int ccs_write_capability(struct ccs_acl_param *param)
3419 {
3420         struct ccs_capability_acl *e = &param->e.capability_acl;
3421         const char *operation = ccs_read_token(param);
3422         u8 type;
3423         e->head.type = CCS_TYPE_CAPABILITY_ACL;
3424         for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) {
3425                 if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]]))
3426                         continue;
3427                 e->operation = type;
3428                 return ccs_update_acl(sizeof(*e), param);
3429         }
3430         return -EINVAL;
3431 }
3432 
3433 #endif
3434 
3435 /**
3436  * ccs_write_acl - Write "struct ccs_acl_info" list.
3437  *
3438  * @ns:        Pointer to "struct ccs_policy_namespace".
3439  * @list:      Pointer to "struct list_head".
3440  * @data:      Policy to be interpreted.
3441  * @is_delete: True if it is a delete request.
3442  *
3443  * Returns 0 on success, negative value otherwise.
3444  *
3445  * Caller holds ccs_read_lock().
3446  */
3447 static int ccs_write_acl(struct ccs_policy_namespace *ns,
3448                          struct list_head *list, char *data,
3449                          const bool is_delete)
3450 {
3451         struct ccs_acl_param param = {
3452                 .ns = ns,
3453                 .list = list,
3454                 .data = data,
3455                 .is_delete = is_delete,
3456         };
3457         static const struct {
3458                 const char *keyword;
3459                 int (*write) (struct ccs_acl_param *);
3460         } ccs_callback[] = {
3461                 { "file ", ccs_write_file },
3462 #ifdef CONFIG_CCSECURITY_NETWORK
3463                 { "network inet ", ccs_write_inet_network },
3464                 { "network unix ", ccs_write_unix_network },
3465 #endif
3466 #ifdef CONFIG_CCSECURITY_MISC
3467                 { "misc ", ccs_write_misc },
3468 #endif
3469 #ifdef CONFIG_CCSECURITY_CAPABILITY
3470                 { "capability ", ccs_write_capability },
3471 #endif
3472 #ifdef CONFIG_CCSECURITY_IPC
3473                 { "ipc signal ", ccs_write_ipc },
3474 #endif
3475                 { "task ", ccs_write_task },
3476         };
3477         u8 i;
3478         /* Forced zero clear for using memcmp() at ccs_update_acl(). */
3479         memset(&param.e, 0, sizeof(param.e));
3480         param.e.acl_info.perm = 1;
3481         for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
3482                 int error;
3483                 if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
3484                         continue;
3485                 error = ccs_callback[i].write(&param);
3486                 ccs_del_acl(&param.e.acl_info.list);
3487                 return error;
3488         }
3489         return -EINVAL;
3490 }
3491 
3492 /**
3493  * ccs_delete_domain - Delete a domain.
3494  *
3495  * @domainname: The name of domain.
3496  *
3497  * Returns 0.
3498  */
3499 static int ccs_delete_domain(char *domainname)
3500 {
3501         struct ccs_domain_info *domain;
3502         struct ccs_path_info name;
3503         name.name = domainname;
3504         ccs_fill_path_info(&name);
3505         if (mutex_lock_interruptible(&ccs_policy_lock))
3506                 return 0;
3507         /* Is there an active domain? */
3508         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
3509                 /* Never delete ccs_kernel_domain. */
3510                 if (domain == &ccs_kernel_domain)
3511                         continue;
3512                 if (domain->is_deleted ||
3513                     ccs_pathcmp(domain->domainname, &name))
3514                         continue;
3515                 domain->is_deleted = true;
3516                 break;
3517         }
3518         mutex_unlock(&ccs_policy_lock);
3519         return 0;
3520 }
3521 
3522 /**
3523  * ccs_write_domain - Write domain policy.
3524  *
3525  * @head: Pointer to "struct ccs_io_buffer".
3526  *
3527  * Returns 0 on success, negative value otherwise.
3528  *
3529  * Caller holds ccs_read_lock().
3530  */
3531 static int ccs_write_domain(struct ccs_io_buffer *head)
3532 {
3533         char *data = head->write_buf;
3534         struct ccs_policy_namespace *ns;
3535         struct ccs_domain_info *domain = head->w.domain;
3536         const bool is_delete = head->w.is_delete;
3537         const bool is_select = !is_delete && ccs_str_starts(&data, "select ");
3538         unsigned int idx;
3539         if (*data == '<') {
3540                 domain = NULL;
3541                 if (is_delete)
3542                         ccs_delete_domain(data);
3543                 else if (is_select)
3544                         domain = ccs_find_domain(data);
3545                 else
3546                         domain = ccs_assign_domain(data, false);
3547                 head->w.domain = domain;
3548                 return 0;
3549         }
3550         if (!domain)
3551                 return -EINVAL;
3552         ns = domain->ns;
3553         if (sscanf(data, "use_profile %u\n", &idx) == 1 &&
3554             idx < CCS_MAX_PROFILES) {
3555                 if (!ccs_policy_loaded || ns->profile_ptr[(u8) idx])
3556                         if (!is_delete)
3557                                 domain->profile = (u8) idx;
3558                 return 0;
3559         }
3560         if (sscanf(data, "use_group %u\n", &idx) == 1 &&
3561             idx < CCS_MAX_ACL_GROUPS) {
3562                 if (!is_delete)
3563                         set_bit(idx, domain->group);
3564                 else
3565                         clear_bit(idx, domain->group);
3566                 return 0;
3567         }
3568         for (idx = 0; idx < CCS_MAX_DOMAIN_INFO_FLAGS; idx++) {
3569                 const char *cp = ccs_dif[idx];
3570                 if (strncmp(data, cp, strlen(cp) - 1))
3571                         continue;
3572                 domain->flags[idx] = !is_delete;
3573                 return 0;
3574         }
3575         return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete);
3576 }
3577 
3578 /**
3579  * ccs_print_name_union - Print a ccs_name_union.
3580  *
3581  * @head: Pointer to "struct ccs_io_buffer".
3582  * @ptr:  Pointer to "struct ccs_name_union".
3583  *
3584  * Returns nothing.
3585  */
3586 static void ccs_print_name_union(struct ccs_io_buffer *head,
3587                                  const struct ccs_name_union *ptr)
3588 {
3589         ccs_set_space(head);
3590         if (!ccs_print_group(head, ptr->group))
3591                 ccs_set_string(head, ptr->filename->name);
3592 }
3593 
3594 /**
3595  * ccs_print_name_union_quoted - Print a ccs_name_union with a quote.
3596  *
3597  * @head: Pointer to "struct ccs_io_buffer".
3598  * @ptr:  Pointer to "struct ccs_name_union".
3599  *
3600  * Returns nothing.
3601  */
3602 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
3603                                         const struct ccs_name_union *ptr)
3604 {
3605         if (!ccs_print_group(head, ptr->group)) {
3606                 ccs_set_string(head, "\"");
3607                 ccs_set_string(head, ptr->filename->name);
3608                 ccs_set_string(head, "\"");
3609         }
3610 }
3611 
3612 /**
3613  * ccs_print_number_union_nospace - Print a ccs_number_union without a space.
3614  *
3615  * @head: Pointer to "struct ccs_io_buffer".
3616  * @ptr:  Pointer to "struct ccs_number_union".
3617  *
3618  * Returns nothing.
3619  */
3620 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
3621                                            const struct ccs_number_union *ptr)
3622 {
3623         if (!ccs_print_group(head, ptr->group)) {
3624                 int i;
3625                 unsigned long min = ptr->values[0];
3626                 const unsigned long max = ptr->values[1];
3627                 u8 min_type = ptr->value_type[0];
3628                 const u8 max_type = ptr->value_type[1];
3629                 char buffer[128];
3630                 buffer[0] = '\0';
3631                 for (i = 0; i < 2; i++) {
3632                         switch (min_type) {
3633                         case CCS_VALUE_TYPE_HEXADECIMAL:
3634                                 ccs_addprintf(buffer, sizeof(buffer), "0x%lX",
3635                                               min);
3636                                 break;
3637                         case CCS_VALUE_TYPE_OCTAL:
3638                                 ccs_addprintf(buffer, sizeof(buffer), "0%lo",
3639                                               min);
3640                                 break;
3641                         default:
3642                                 ccs_addprintf(buffer, sizeof(buffer), "%lu",
3643                                               min);
3644                                 break;
3645                         }
3646                         if (min == max && min_type == max_type)
3647                                 break;
3648                         ccs_addprintf(buffer, sizeof(buffer), "-");
3649                         min_type = max_type;
3650                         min = max;
3651                 }
3652                 ccs_io_printf(head, "%s", buffer);
3653         }
3654 }
3655 
3656 /**
3657  * ccs_print_number_union - Print a ccs_number_union.
3658  *
3659  * @head: Pointer to "struct ccs_io_buffer".
3660  * @ptr:  Pointer to "struct ccs_number_union".
3661  *
3662  * Returns nothing.
3663  */
3664 static void ccs_print_number_union(struct ccs_io_buffer *head,
3665                                    const struct ccs_number_union *ptr)
3666 {
3667         ccs_set_space(head);
3668         ccs_print_number_union_nospace(head, ptr);
3669 }
3670 
3671 /**
3672  * ccs_print_condition - Print condition part.
3673  *
3674  * @head: Pointer to "struct ccs_io_buffer".
3675  * @cond: Pointer to "struct ccs_condition".
3676  *
3677  * Returns true on success, false otherwise.
3678  */
3679 static bool ccs_print_condition(struct ccs_io_buffer *head,
3680                                 const struct ccs_condition *cond)
3681 {
3682         switch (head->r.cond_step) {
3683         case 0:
3684                 head->r.cond_index = 0;
3685                 head->r.cond_step++;
3686                 if (cond->transit && cond->exec_transit) {
3687                         ccs_set_space(head);
3688                         ccs_set_string(head, cond->transit->name);
3689                 }
3690                 /* fall through */
3691         case 1:
3692                 {
3693                         const u16 condc = cond->condc;
3694                         const struct ccs_condition_element *condp =
3695                                 (typeof(condp)) (cond + 1);
3696                         const struct ccs_number_union *numbers_p =
3697                                 (typeof(numbers_p)) (condp + condc);
3698                         const struct ccs_name_union *names_p =
3699                                 (typeof(names_p))
3700                                 (numbers_p + cond->numbers_count);
3701                         const struct ccs_argv *argv =
3702                                 (typeof(argv)) (names_p + cond->names_count);
3703                         const struct ccs_envp *envp =
3704                                 (typeof(envp)) (argv + cond->argc);
3705                         u16 skip;
3706                         for (skip = 0; skip < head->r.cond_index; skip++) {
3707                                 const u8 left = condp->left;
3708                                 const u8 right = condp->right;
3709                                 condp++;
3710                                 switch (left) {
3711                                 case CCS_ARGV_ENTRY:
3712                                         argv++;
3713                                         continue;
3714                                 case CCS_ENVP_ENTRY:
3715                                         envp++;
3716                                         continue;
3717                                 case CCS_NUMBER_UNION:
3718                                         numbers_p++;
3719                                         break;
3720                                 }
3721                                 switch (right) {
3722                                 case CCS_NAME_UNION:
3723                                         names_p++;
3724                                         break;
3725                                 case CCS_NUMBER_UNION:
3726                                         numbers_p++;
3727                                         break;
3728                                 }
3729                         }
3730                         while (head->r.cond_index < condc) {
3731                                 const u8 match = condp->equals;
3732                                 const u8 left = condp->left;
3733                                 const u8 right = condp->right;
3734                                 if (!ccs_flush(head))
3735                                         return false;
3736                                 condp++;
3737                                 head->r.cond_index++;
3738                                 ccs_set_space(head);
3739                                 switch (left) {
3740                                 case CCS_ARGV_ENTRY:
3741                                         ccs_io_printf(head,
3742                                                       "exec.argv[%lu]%s=\"",
3743                                                       argv->index,
3744                                                       argv->is_not ? "!" : "");
3745                                         ccs_set_string(head,
3746                                                        argv->value->name);
3747                                         ccs_set_string(head, "\"");
3748                                         argv++;
3749                                         continue;
3750                                 case CCS_ENVP_ENTRY:
3751                                         ccs_set_string(head, "exec.envp[\"");
3752                                         ccs_set_string(head, envp->name->name);
3753                                         ccs_io_printf(head, "\"]%s=",
3754                                                       envp->is_not ? "!" : "");
3755                                         if (envp->value) {
3756                                                 ccs_set_string(head, "\"");
3757                                                 ccs_set_string(head, envp->
3758                                                                value->name);
3759                                                 ccs_set_string(head, "\"");
3760                                         } else {
3761                                                 ccs_set_string(head, "NULL");
3762                                         }
3763                                         envp++;
3764                                         continue;
3765                                 case CCS_NUMBER_UNION:
3766                                         ccs_print_number_union_nospace
3767                                                 (head, numbers_p++);
3768                                         break;
3769                                 default:
3770                                         ccs_set_string(head,
3771                                                ccs_condition_keyword[left]);
3772                                         break;
3773                                 }
3774                                 ccs_set_string(head, match ? "=" : "!=");
3775                                 switch (right) {
3776                                 case CCS_NAME_UNION:
3777                                         ccs_print_name_union_quoted
3778                                                 (head, names_p++);
3779                                         break;
3780                                 case CCS_NUMBER_UNION:
3781                                         ccs_print_number_union_nospace
3782                                                 (head, numbers_p++);
3783                                         break;
3784                                 default:
3785                                         ccs_set_string(head,
3786                                                ccs_condition_keyword[right]);
3787                                         break;
3788                                 }
3789                         }
3790                 }
3791                 head->r.cond_step++;
3792                 /* fall through */
3793         case 2:
3794                 if (!ccs_flush(head))
3795                         break;
3796                 head->r.cond_step++;
3797                 /* fall through */
3798         case 3:
3799                 if (cond->grant_log != CCS_GRANTLOG_AUTO)
3800                         ccs_io_printf(head, " grant_log=%s",
3801                                       ccs_yesno(cond->grant_log ==
3802                                                 CCS_GRANTLOG_YES));
3803                 if (cond->transit && !cond->exec_transit) {
3804                         const char *name = cond->transit->name;
3805                         ccs_set_string(head, " auto_domain_transition=\"");
3806                         ccs_set_string(head, name);
3807                         ccs_set_string(head, "\"");
3808                 }
3809                 ccs_set_lf(head);
3810                 return true;
3811         }
3812         return false;
3813 }
3814 
3815 /**
3816  * ccs_set_group - Print "acl_group " header keyword and category name.
3817  *
3818  * @head:     Pointer to "struct ccs_io_buffer".
3819  * @category: Category name.
3820  *
3821  * Returns nothing.
3822  */
3823 static void ccs_set_group(struct ccs_io_buffer *head, const char *category)
3824 {
3825         if (head->type == CCS_EXCEPTION_POLICY) {
3826                 ccs_print_namespace(head);
3827                 ccs_io_printf(head, "acl_group %u ", head->r.acl_group_index);
3828         }
3829         ccs_set_string(head, category);
3830 }
3831 
3832 /**
3833  * ccs_print_entry - Print an ACL entry.
3834  *
3835  * @head: Pointer to "struct ccs_io_buffer".
3836  * @acl:  Pointer to an ACL entry.
3837  *
3838  * Returns true on success, false otherwise.
3839  */
3840 static bool ccs_print_entry(struct ccs_io_buffer *head,
3841                             const struct ccs_acl_info *acl)
3842 {
3843         const u8 acl_type = acl->type;
3844         const bool may_trigger_transition = acl->cond && acl->cond->transit;
3845         bool first = true;
3846         u8 bit;
3847         if (head->r.print_cond_part)
3848                 goto print_cond_part;
3849         if (acl->is_deleted)
3850                 return true;
3851         if (!ccs_flush(head))
3852                 return false;
3853         else if (acl_type == CCS_TYPE_PATH_ACL) {
3854                 struct ccs_path_acl *ptr
3855                         = container_of(acl, typeof(*ptr), head);
3856                 for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
3857                         if (!(acl->perm & (1 << bit)))
3858                                 continue;
3859                         if (head->r.print_transition_related_only &&
3860                             bit != CCS_TYPE_EXECUTE && !may_trigger_transition)
3861                                 continue;
3862                         if (first) {
3863                                 ccs_set_group(head, "file ");
3864                                 first = false;
3865                         } else {
3866                                 ccs_set_slash(head);
3867                         }
3868                         ccs_set_string(head, ccs_path_keyword[bit]);
3869                 }
3870                 if (first)
3871                         return true;
3872                 ccs_print_name_union(head, &ptr->name);
3873 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3874         } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
3875                    acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
3876                 struct ccs_handler_acl *ptr
3877                         = container_of(acl, typeof(*ptr), head);
3878                 ccs_set_group(head, "task ");
3879                 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
3880                                ? "auto_execute_handler " :
3881                                "denied_execute_handler ");
3882                 ccs_set_string(head, ptr->handler->name);
3883 #endif
3884 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
3885         } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
3886                    acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
3887                 struct ccs_task_acl *ptr =
3888                         container_of(acl, typeof(*ptr), head);
3889                 ccs_set_group(head, "task ");
3890                 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ?
3891                                "auto_domain_transition " :
3892                                "manual_domain_transition ");
3893                 ccs_set_string(head, ptr->domainname->name);
3894 #endif
3895         } else if (head->r.print_transition_related_only &&
3896                    !may_trigger_transition) {
3897                 return true;
3898         } else if (acl_type == CCS_TYPE_MKDEV_ACL) {
3899                 struct ccs_mkdev_acl *ptr =
3900                         container_of(acl, typeof(*ptr), head);
3901                 for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) {
3902                         if (!(acl->perm & (1 << bit)))
3903                                 continue;
3904                         if (first) {
3905                                 ccs_set_group(head, "file ");
3906                                 first = false;
3907                         } else {
3908                                 ccs_set_slash(head);
3909                         }
3910                         ccs_set_string(head, ccs_mac_keywords
3911                                        [ccs_pnnn2mac[bit]]);
3912                 }
3913                 if (first)
3914                         return true;
3915                 ccs_print_name_union(head, &ptr->name);
3916                 ccs_print_number_union(head, &ptr->mode);
3917                 ccs_print_number_union(head, &ptr->major);
3918                 ccs_print_number_union(head, &ptr->minor);
3919         } else if (acl_type == CCS_TYPE_PATH2_ACL) {
3920                 struct ccs_path2_acl *ptr =
3921                         container_of(acl, typeof(*ptr), head);
3922                 for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) {
3923                         if (!(acl->perm & (1 << bit)))
3924                                 continue;
3925                         if (first) {
3926                                 ccs_set_group(head, "file ");
3927                                 first = false;
3928                         } else {
3929                                 ccs_set_slash(head);
3930                         }
3931                         ccs_set_string(head, ccs_mac_keywords
3932                                        [ccs_pp2mac[bit]]);
3933                 }
3934                 if (first)
3935                         return true;
3936                 ccs_print_name_union(head, &ptr->name1);
3937                 ccs_print_name_union(head, &ptr->name2);
3938         } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
3939                 struct ccs_path_number_acl *ptr =
3940                         container_of(acl, typeof(*ptr), head);
3941                 for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) {
3942                         if (!(acl->perm & (1 << bit)))
3943                                 continue;
3944                         if (first) {
3945                                 ccs_set_group(head, "file ");
3946                                 first = false;
3947                         } else {
3948                                 ccs_set_slash(head);
3949                         }
3950                         ccs_set_string(head, ccs_mac_keywords
3951                                        [ccs_pn2mac[bit]]);
3952                 }
3953                 if (first)
3954                         return true;
3955                 ccs_print_name_union(head, &ptr->name);
3956                 ccs_print_number_union(head, &ptr->number);
3957 #ifdef CONFIG_CCSECURITY_MISC
3958         } else if (acl_type == CCS_TYPE_ENV_ACL) {
3959                 struct ccs_env_acl *ptr =
3960                         container_of(acl, typeof(*ptr), head);
3961                 ccs_set_group(head, "misc env ");
3962                 ccs_set_string(head, ptr->env->name);
3963 #endif
3964 #ifdef CONFIG_CCSECURITY_CAPABILITY
3965         } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
3966                 struct ccs_capability_acl *ptr =
3967                         container_of(acl, typeof(*ptr), head);
3968                 ccs_set_group(head, "capability ");
3969                 ccs_set_string(head, ccs_mac_keywords
3970                                [ccs_c2mac[ptr->operation]]);
3971 #endif
3972 #ifdef CONFIG_CCSECURITY_NETWORK
3973         } else if (acl_type == CCS_TYPE_INET_ACL) {
3974                 struct ccs_inet_acl *ptr =
3975                         container_of(acl, typeof(*ptr), head);
3976                 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
3977                         if (!(acl->perm & (1 << bit)))
3978                                 continue;
3979                         if (first) {
3980                                 ccs_set_group(head, "network inet ");
3981                                 ccs_set_string(head, ccs_proto_keyword
3982                                                [ptr->protocol]);
3983                                 ccs_set_space(head);
3984                                 first = false;
3985                         } else {
3986                                 ccs_set_slash(head);
3987                         }
3988                         ccs_set_string(head, ccs_socket_keyword[bit]);
3989                 }
3990                 if (first)
3991                         return true;
3992                 ccs_set_space(head);
3993                 if (!ccs_print_group(head, ptr->address.group)) {
3994                         char buf[128];
3995                         ccs_print_ip(buf, sizeof(buf), &ptr->address);
3996                         ccs_io_printf(head, "%s", buf);
3997                 }
3998                 ccs_print_number_union(head, &ptr->port);
3999         } else if (acl_type == CCS_TYPE_UNIX_ACL) {
4000                 struct ccs_unix_acl *ptr =
4001                         container_of(acl, typeof(*ptr), head);
4002                 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
4003                         if (!(acl->perm & (1 << bit)))
4004                                 continue;
4005                         if (first) {
4006                                 ccs_set_group(head, "network unix ");
4007                                 ccs_set_string(head, ccs_proto_keyword
4008                                                [ptr->protocol]);
4009                                 ccs_set_space(head);
4010                                 first = false;
4011                         } else {
4012                                 ccs_set_slash(head);
4013                         }
4014                         ccs_set_string(head, ccs_socket_keyword[bit]);
4015                 }
4016                 if (first)
4017                         return true;
4018                 ccs_print_name_union(head, &ptr->name);
4019 #endif
4020 #ifdef CONFIG_CCSECURITY_IPC
4021         } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
4022                 struct ccs_signal_acl *ptr =
4023                         container_of(acl, typeof(*ptr), head);
4024                 ccs_set_group(head, "ipc signal ");
4025                 ccs_print_number_union_nospace(head, &ptr->sig);
4026                 ccs_set_space(head);
4027                 ccs_set_string(head, ptr->domainname->name);
4028 #endif
4029         } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
4030                 struct ccs_mount_acl *ptr =
4031                         container_of(acl, typeof(*ptr), head);
4032                 ccs_set_group(head, "file mount");
4033                 ccs_print_name_union(head, &ptr->dev_name);
4034                 ccs_print_name_union(head, &ptr->dir_name);
4035                 ccs_print_name_union(head, &ptr->fs_type);
4036                 ccs_print_number_union(head, &ptr->flags);
4037         }
4038         if (acl->cond) {
4039                 head->r.print_cond_part = true;
4040                 head->r.cond_step = 0;
4041                 if (!ccs_flush(head))
4042                         return false;
4043 print_cond_part:
4044                 if (!ccs_print_condition(head, acl->cond))
4045                         return false;
4046                 head->r.print_cond_part = false;
4047         } else {
4048                 ccs_set_lf(head);
4049         }
4050         return true;
4051 }
4052 
4053 /**
4054  * ccs_read_acl - Read "struct ccs_acl_info" list.
4055  *
4056  * @head: Pointer to "struct ccs_io_buffer".
4057  * @list: Pointer to "struct list_head".
4058  *
4059  * Returns true on success, false otherwise.
4060  *
4061  * Caller holds ccs_read_lock().
4062  */
4063 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list)
4064 {
4065         list_for_each_cookie(head->r.acl, list) {
4066                 struct ccs_acl_info *ptr =
4067                         list_entry(head->r.acl, typeof(*ptr), list);
4068                 if (!ccs_print_entry(head, ptr))
4069                         return false;
4070         }
4071         head->r.acl = NULL;
4072         return true;
4073 }
4074 
4075 /**
4076  * ccs_read_domain - Read domain policy.
4077  *
4078  * @head: Pointer to "struct ccs_io_buffer".
4079  *
4080  * Returns nothing.
4081  *
4082  * Caller holds ccs_read_lock().
4083  */
4084 static void ccs_read_domain(struct ccs_io_buffer *head)
4085 {
4086         if (head->r.eof)
4087                 return;
4088         list_for_each_cookie(head->r.domain, &ccs_domain_list) {
4089                 struct ccs_domain_info *domain =
4090                         list_entry(head->r.domain, typeof(*domain), list);
4091                 switch (head->r.step) {
4092                         u8 i;
4093                 case 0:
4094                         if (domain->is_deleted &&
4095                             !head->r.print_this_domain_only)
4096                                 continue;
4097                         /* Print domainname and flags. */
4098                         ccs_set_string(head, domain->domainname->name);
4099                         ccs_set_lf(head);
4100                         ccs_io_printf(head, "use_profile %u\n",
4101                                       domain->profile);
4102                         for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
4103                                 if (domain->flags[i])
4104                                         ccs_set_string(head, ccs_dif[i]);
4105                         head->r.index = 0;
4106                         head->r.step++;
4107                         /* fall through */
4108                 case 1:
4109                         while (head->r.index < CCS_MAX_ACL_GROUPS) {
4110                                 i = head->r.index++;
4111                                 if (!test_bit(i, domain->group))
4112                                         continue;
4113                                 ccs_io_printf(head, "use_group %u\n", i);
4114                                 if (!ccs_flush(head))
4115                                         return;
4116                         }
4117                         head->r.index = 0;
4118                         head->r.step++;
4119                         ccs_set_lf(head);
4120                         /* fall through */
4121                 case 2:
4122                         if (!ccs_read_acl(head, &domain->acl_info_list))
4123                                 return;
4124                         head->r.step++;
4125                         if (!ccs_set_lf(head))
4126                                 return;
4127                         /* fall through */
4128                 case 3:
4129                         head->r.step = 0;
4130                         if (head->r.print_this_domain_only)
4131                                 goto done;
4132                 }
4133         }
4134 done:
4135         head->r.eof = true;
4136 }
4137 
4138 /**
4139  * ccs_write_pid - Specify PID to obtain domainname.
4140  *
4141  * @head: Pointer to "struct ccs_io_buffer".
4142  *
4143  * Returns 0.
4144  */
4145 static int ccs_write_pid(struct ccs_io_buffer *head)
4146 {
4147         head->r.eof = false;
4148         return 0;
4149 }
4150 
4151 /**
4152  * ccs_read_pid - Read information of a process.
4153  *
4154  * @head: Pointer to "struct ccs_io_buffer".
4155  *
4156  * Returns the domainname which the specified PID is in or
4157  * process information of the specified PID on success,
4158  * empty string otherwise.
4159  *
4160  * Caller holds ccs_read_lock().
4161  */
4162 static void ccs_read_pid(struct ccs_io_buffer *head)
4163 {
4164         char *buf = head->write_buf;
4165         bool task_info = false;
4166         bool global_pid = false;
4167         unsigned int pid;
4168         struct task_struct *p;
4169         struct ccs_domain_info *domain = NULL;
4170         u32 ccs_flags = 0;
4171         /* Accessing write_buf is safe because head->io_sem is held. */
4172         if (!buf) {
4173                 head->r.eof = true;
4174                 return; /* Do nothing if open(O_RDONLY). */
4175         }
4176         if (head->r.w_pos || head->r.eof)
4177                 return;
4178         head->r.eof = true;
4179         if (ccs_str_starts(&buf, "info "))
4180                 task_info = true;
4181         if (ccs_str_starts(&buf, "global-pid "))
4182                 global_pid = true;
4183         pid = (unsigned int) simple_strtoul(buf, NULL, 10);
4184         ccs_tasklist_lock();
4185 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
4186         if (global_pid)
4187                 p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns);
4188         else
4189                 p = ccsecurity_exports.find_task_by_vpid(pid);
4190 #else
4191         p = find_task_by_pid(pid);
4192 #endif
4193         if (p) {
4194                 domain = ccs_task_domain(p);
4195                 ccs_flags = ccs_task_flags(p);
4196         }
4197         ccs_tasklist_unlock();
4198         if (!domain)
4199                 return;
4200         if (!task_info) {
4201                 ccs_io_printf(head, "%u %u ", pid, domain->profile);
4202                 ccs_set_string(head, domain->domainname->name);
4203         } else {
4204                 ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid,
4205                               ccs_yesno(ccs_flags &
4206                                         CCS_TASK_IS_MANAGER),
4207                               ccs_yesno(ccs_flags &
4208                                         CCS_TASK_IS_EXECUTE_HANDLER));
4209         }
4210 }
4211 
4212 /**
4213  * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
4214  *
4215  * @param: Pointer to "struct ccs_acl_param".
4216  * @type:  Type of this group.
4217  *
4218  * Returns 0 on success, negative value otherwise.
4219  */
4220 static int ccs_write_group(struct ccs_acl_param *param, const u8 type)
4221 {
4222         struct ccs_group *group = ccs_get_group(param, type);
4223         int error = -EINVAL;
4224         if (!group)
4225                 return -ENOMEM;
4226         param->list = &group->member_list;
4227         if (type == CCS_PATH_GROUP) {
4228                 struct ccs_path_group *e = &param->e.path_group;
4229                 e->member_name = ccs_get_name(ccs_read_token(param));
4230                 if (!e->member_name) {
4231                         error = -ENOMEM;
4232                         goto out;
4233                 }
4234                 error = ccs_update_policy(sizeof(*e), param);
4235                 ccs_put_name(e->member_name);
4236         } else if (type == CCS_NUMBER_GROUP) {
4237                 struct ccs_number_group *e = &param->e.number_group;
4238                 if (param->data[0] == '@' ||
4239                     !ccs_parse_number_union(param, &e->number))
4240                         goto out;
4241                 error = ccs_update_policy(sizeof(*e), param);
4242 #ifdef CONFIG_CCSECURITY_NETWORK
4243         } else {
4244                 struct ccs_address_group *e = &param->e.address_group;
4245                 if (param->data[0] == '@' ||
4246                     !ccs_parse_ipaddr_union(param, &e->address))
4247                         goto out;
4248                 error = ccs_update_policy(sizeof(*e), param);
4249 #endif
4250         }
4251 out:
4252         ccs_put_group(group);
4253         return error;
4254 }
4255 
4256 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4257 /**
4258  * ccs_lport_reserved - Check whether local port is reserved or not.
4259  *
4260  * @port: Port number.
4261  *
4262  * Returns true if local port is reserved, false otherwise.
4263  */
4264 static bool __ccs_lport_reserved(const u16 port)
4265 {
4266         return ccs_reserved_port_map[port >> 3] & (1 << (port & 7))
4267                 ? true : false;
4268 }
4269 
4270 /**
4271  * ccs_write_reserved_port - Update "struct ccs_reserved" list.
4272  *
4273  * @param: Pointer to "struct ccs_acl_param".
4274  *
4275  * Returns 0 on success, negative value otherwise.
4276  *
4277  * Caller holds ccs_read_lock().
4278  */
4279 static int ccs_write_reserved_port(struct ccs_acl_param *param)
4280 {
4281         struct ccs_reserved *e = &param->e.reserved;
4282         struct ccs_policy_namespace *ns = param->ns;
4283         int error;
4284         u8 *tmp;
4285         if (param->data[0] == '@' ||
4286             !ccs_parse_number_union(param, &e->port) ||
4287             e->port.values[1] > 65535 || param->data[0])
4288                 return -EINVAL;
4289         param->list = &ns->policy_list[CCS_ID_RESERVEDPORT];
4290         error = ccs_update_policy(sizeof(*e), param);
4291         if (error)
4292                 return error;
4293         tmp = kzalloc(sizeof(ccs_reserved_port_map), CCS_GFP_FLAGS);
4294         if (!tmp)
4295                 return -ENOMEM;
4296         list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list,
4297                                  &ccs_ss) {
4298                 struct ccs_reserved *ptr;
4299                 struct list_head *list = &ns->policy_list[CCS_ID_RESERVEDPORT];
4300                 list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
4301                         unsigned int port;
4302                         if (ptr->head.is_deleted)
4303                                 continue;
4304                         for (port = ptr->port.values[0];
4305                              port <= ptr->port.values[1]; port++)
4306                                 tmp[port >> 3] |= 1 << (port & 7);
4307                 }
4308         }
4309         memmove(ccs_reserved_port_map, tmp, sizeof(ccs_reserved_port_map));
4310         kfree(tmp);
4311         /*
4312          * Since this feature is no-op by default, we don't need to register
4313          * this callback hook unless the first entry is added.
4314          */
4315         ccsecurity_ops.lport_reserved = __ccs_lport_reserved;
4316         return 0;
4317 }
4318 #endif
4319 
4320 /**
4321  * ccs_write_aggregator - Write "struct ccs_aggregator" list.
4322  *
4323  * @param: Pointer to "struct ccs_acl_param".
4324  *
4325  * Returns 0 on success, negative value otherwise.
4326  */
4327 static int ccs_write_aggregator(struct ccs_acl_param *param)
4328 {
4329         struct ccs_aggregator *e = &param->e.aggregator;
4330         int error = param->is_delete ? -ENOENT : -ENOMEM;
4331         const char *original_name = ccs_read_token(param);
4332         const char *aggregated_name = ccs_read_token(param);
4333         if (!ccs_correct_word(original_name) ||
4334             !ccs_correct_path(aggregated_name))
4335                 return -EINVAL;
4336         e->original_name = ccs_get_name(original_name);
4337         e->aggregated_name = ccs_get_name(aggregated_name);
4338         if (!e->original_name || !e->aggregated_name ||
4339             e->aggregated_name->is_patterned) /* No patterns allowed. */
4340                 goto out;
4341         param->list = &param->ns->policy_list[CCS_ID_AGGREGATOR];
4342         error = ccs_update_policy(sizeof(*e), param);
4343 out:
4344         ccs_put_name(e->original_name);
4345         ccs_put_name(e->aggregated_name);
4346         return error;
4347 }
4348 
4349 /**
4350  * ccs_write_transition_control - Write "struct ccs_transition_control" list.
4351  *
4352  * @param: Pointer to "struct ccs_acl_param".
4353  * @type:  Type of this entry.
4354  *
4355  * Returns 0 on success, negative value otherwise.
4356  */
4357 static int ccs_write_transition_control(struct ccs_acl_param *param,
4358                                         const u8 type)
4359 {
4360         struct ccs_transition_control *e = &param->e.transition_control;
4361         int error = param->is_delete ? -ENOENT : -ENOMEM;
4362         char *program = param->data;
4363         char *domainname = strstr(program, " from ");
4364         e->type = type;
4365         if (domainname) {
4366                 *domainname = '\0';
4367                 domainname += 6;
4368         } else if (type == CCS_TRANSITION_CONTROL_NO_KEEP ||
4369                    type == CCS_TRANSITION_CONTROL_KEEP) {
4370                 domainname = program;
4371                 program = NULL;
4372         }
4373         if (program && strcmp(program, "any")) {
4374                 if (!ccs_correct_path(program))
4375                         return -EINVAL;
4376                 e->program = ccs_get_name(program);
4377                 if (!e->program)
4378                         goto out;
4379         }
4380         if (domainname && strcmp(domainname, "any")) {
4381                 if (!ccs_correct_domain(domainname)) {
4382                         if (!ccs_correct_path(domainname))
4383                                 goto out;
4384                         e->is_last_name = true;
4385                 }
4386                 e->domainname = ccs_get_name(domainname);
4387                 if (!e->domainname)
4388                         goto out;
4389         }
4390         param->list = &param->ns->policy_list[CCS_ID_TRANSITION_CONTROL];
4391         error = ccs_update_policy(sizeof(*e), param);
4392 out:
4393         ccs_put_name(e->domainname);
4394         ccs_put_name(e->program);
4395         return error;
4396 }
4397 
4398 /**
4399  * ccs_write_exception - Write exception policy.
4400  *
4401  * @head: Pointer to "struct ccs_io_buffer".
4402  *
4403  * Returns 0 on success, negative value otherwise.
4404  */
4405 static int ccs_write_exception(struct ccs_io_buffer *head)
4406 {
4407         const bool is_delete = head->w.is_delete;
4408         struct ccs_acl_param param = {
4409                 .ns = head->w.ns,
4410                 .is_delete = is_delete,
4411                 .data = head->write_buf,
4412         };
4413         u8 i;
4414         /* Forced zero clear for using memcmp() at ccs_update_policy(). */
4415         memset(&param.e, 0, sizeof(param.e));
4416         if (ccs_str_starts(&param.data, "aggregator "))
4417                 return ccs_write_aggregator(&param);
4418 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4419         if (ccs_str_starts(&param.data, "deny_autobind "))
4420                 return ccs_write_reserved_port(&param);
4421 #endif
4422         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
4423                 if (ccs_str_starts(&param.data, ccs_transition_type[i]))
4424                         return ccs_write_transition_control(&param, i);
4425         for (i = 0; i < CCS_MAX_GROUP; i++)
4426                 if (ccs_str_starts(&param.data, ccs_group_name[i]))
4427                         return ccs_write_group(&param, i);
4428         if (ccs_str_starts(&param.data, "acl_group ")) {
4429                 unsigned int group;
4430                 char *data;
4431                 group = simple_strtoul(param.data, &data, 10);
4432                 if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ')
4433                         return ccs_write_acl(head->w.ns,
4434                                              &head->w.ns->acl_group[group],
4435                                              data, is_delete);
4436         }
4437         return -EINVAL;
4438 }
4439 
4440 /**
4441  * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
4442  *
4443  * @head: Pointer to "struct ccs_io_buffer".
4444  * @idx:  Index number.
4445  *
4446  * Returns true on success, false otherwise.
4447  *
4448  * Caller holds ccs_read_lock().
4449  */
4450 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
4451 {
4452         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4453                                                        namespace_list);
4454         struct list_head *list = &ns->group_list[idx];
4455         list_for_each_cookie(head->r.group, list) {
4456                 struct ccs_group *group =
4457                         list_entry(head->r.group, typeof(*group), head.list);
4458                 list_for_each_cookie(head->r.acl, &group->member_list) {
4459                         struct ccs_acl_head *ptr =
4460                                 list_entry(head->r.acl, typeof(*ptr), list);
4461                         if (ptr->is_deleted)
4462                                 continue;
4463                         if (!ccs_flush(head))
4464                                 return false;
4465                         ccs_print_namespace(head);
4466                         ccs_set_string(head, ccs_group_name[idx]);
4467                         ccs_set_string(head, group->group_name->name);
4468                         if (idx == CCS_PATH_GROUP) {
4469                                 ccs_set_space(head);
4470                                 ccs_set_string(head, container_of
4471                                                (ptr, struct ccs_path_group,
4472                                                 head)->member_name->name);
4473                         } else if (idx == CCS_NUMBER_GROUP) {
4474                                 ccs_print_number_union(head, &container_of
4475                                                (ptr, struct ccs_number_group,
4476                                                 head)->number);
4477 #ifdef CONFIG_CCSECURITY_NETWORK
4478                         } else if (idx == CCS_ADDRESS_GROUP) {
4479                                 char buffer[128];
4480                                 struct ccs_address_group *member =
4481                                         container_of(ptr, typeof(*member),
4482                                                      head);
4483                                 ccs_print_ip(buffer, sizeof(buffer),
4484                                              &member->address);
4485                                 ccs_io_printf(head, " %s", buffer);
4486 #endif
4487                         }
4488                         ccs_set_lf(head);
4489                 }
4490                 head->r.acl = NULL;
4491         }
4492         head->r.group = NULL;
4493         return true;
4494 }
4495 
4496 /**
4497  * ccs_read_policy - Read "struct ccs_..._entry" list.
4498  *
4499  * @head: Pointer to "struct ccs_io_buffer".
4500  * @idx:  Index number.
4501  *
4502  * Returns true on success, false otherwise.
4503  *
4504  * Caller holds ccs_read_lock().
4505  */
4506 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
4507 {
4508         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4509                                                        namespace_list);
4510         struct list_head *list = &ns->policy_list[idx];
4511         list_for_each_cookie(head->r.acl, list) {
4512                 struct ccs_acl_head *acl =
4513                         container_of(head->r.acl, typeof(*acl), list);
4514                 if (acl->is_deleted)
4515                         continue;
4516                 if (head->r.print_transition_related_only &&
4517                     idx != CCS_ID_TRANSITION_CONTROL)
4518                         continue;
4519                 if (!ccs_flush(head))
4520                         return false;
4521                 switch (idx) {
4522                 case CCS_ID_TRANSITION_CONTROL:
4523                         {
4524                                 struct ccs_transition_control *ptr =
4525                                         container_of(acl, typeof(*ptr), head);
4526                                 ccs_print_namespace(head);
4527                                 ccs_set_string(head,
4528                                                ccs_transition_type[ptr->type]);
4529                                 ccs_set_string(head, ptr->program ?
4530                                                ptr->program->name : "any");
4531                                 ccs_set_string(head, " from ");
4532                                 ccs_set_string(head, ptr->domainname ?
4533                                                ptr->domainname->name : "any");
4534                         }
4535                         break;
4536                 case CCS_ID_AGGREGATOR:
4537                         {
4538                                 struct ccs_aggregator *ptr =
4539                                         container_of(acl, typeof(*ptr), head);
4540                                 ccs_print_namespace(head);
4541                                 ccs_set_string(head, "aggregator ");
4542                                 ccs_set_string(head, ptr->original_name->name);
4543                                 ccs_set_space(head);
4544                                 ccs_set_string(head,
4545                                                ptr->aggregated_name->name);
4546                         }
4547                         break;
4548 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4549                 case CCS_ID_RESERVEDPORT:
4550                         {
4551                                 struct ccs_reserved *ptr =
4552                                         container_of(acl, typeof(*ptr), head);
4553                                 ccs_print_namespace(head);
4554                                 ccs_set_string(head, "deny_autobind ");
4555                                 ccs_print_number_union_nospace(head,
4556                                                                &ptr->port);
4557                         }
4558                         break;
4559 #endif
4560                 default:
4561                         continue;
4562                 }
4563                 ccs_set_lf(head);
4564         }
4565         head->r.acl = NULL;
4566         return true;
4567 }
4568 
4569 /**
4570  * ccs_read_exception - Read exception policy.
4571  *
4572  * @head: Pointer to "struct ccs_io_buffer".
4573  *
4574  * Returns nothing.
4575  *
4576  * Caller holds ccs_read_lock().
4577  */
4578 static void ccs_read_exception(struct ccs_io_buffer *head)
4579 {
4580         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4581                                                        namespace_list);
4582         if (head->r.eof)
4583                 return;
4584         while (head->r.step < CCS_MAX_POLICY &&
4585                ccs_read_policy(head, head->r.step))
4586                 head->r.step++;
4587         if (head->r.step < CCS_MAX_POLICY)
4588                 return;
4589         while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
4590                ccs_read_group(head, head->r.step - CCS_MAX_POLICY))
4591                 head->r.step++;
4592         if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
4593                 return;
4594         while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
4595                + CCS_MAX_ACL_GROUPS) {
4596                 head->r.acl_group_index =
4597                         head->r.step - CCS_MAX_POLICY - CCS_MAX_GROUP;
4598                 if (!ccs_read_acl(head, &ns->acl_group
4599                                   [head->r.acl_group_index]))
4600                         return;
4601                 head->r.step++;
4602         }
4603         head->r.eof = true;
4604 }
4605 
4606 /**
4607  * ccs_truncate - Truncate a line.
4608  *
4609  * @str: String to truncate.
4610  *
4611  * Returns length of truncated @str.
4612  */
4613 static int ccs_truncate(char *str)
4614 {
4615         char *start = str;
4616         while (*(unsigned char *) str > (unsigned char) ' ')
4617                 str++;
4618         *str = '\0';
4619         return strlen(start) + 1;
4620 }
4621 
4622 /**
4623  * ccs_add_entry - Add an ACL to current thread's domain. Used by learning mode.
4624  *
4625  * @header: Lines containing ACL.
4626  *
4627  * Returns nothing.
4628  */
4629 static void ccs_add_entry(char *header)
4630 {
4631         char *buffer;
4632         char *realpath = NULL;
4633         char *argv0 = NULL;
4634         char *symlink = NULL;
4635 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4636         char *handler;
4637 #endif
4638         char *cp = strchr(header, '\n');
4639         int len;
4640         if (!cp)
4641                 return;
4642         cp = strchr(cp + 1, '\n');
4643         if (!cp)
4644                 return;
4645         *cp++ = '\0';
4646         len = strlen(cp) + 1;
4647         /* strstr() will return NULL if ordering is wrong. */
4648         if (*cp == 'f') {
4649                 argv0 = strstr(header, " argv[]={ \"");
4650                 if (argv0) {
4651                         argv0 += 10;
4652                         len += ccs_truncate(argv0) + 14;
4653                 }
4654                 realpath = strstr(header, " exec={ realpath=\"");
4655                 if (realpath) {
4656                         realpath += 8;
4657                         len += ccs_truncate(realpath) + 6;
4658                 }
4659                 symlink = strstr(header, " symlink.target=\"");
4660                 if (symlink)
4661                         len += ccs_truncate(symlink + 1) + 1;
4662         }
4663 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4664         handler = strstr(header, "type=execute_handler");
4665         if (handler)
4666                 len += ccs_truncate(handler) + 6;
4667 #endif
4668         buffer = kmalloc(len, CCS_GFP_FLAGS);
4669         if (!buffer)
4670                 return;
4671         snprintf(buffer, len - 1, "%s", cp);
4672 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4673         if (handler)
4674                 ccs_addprintf(buffer, len, " task.%s", handler);
4675 #endif
4676         if (realpath)
4677                 ccs_addprintf(buffer, len, " exec.%s", realpath);
4678         if (argv0)
4679                 ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
4680         if (symlink)
4681                 ccs_addprintf(buffer, len, "%s", symlink);
4682         ccs_normalize_line(buffer);
4683         {
4684                 struct ccs_domain_info *domain = ccs_current_domain();
4685                 if (!ccs_write_acl(domain->ns, &domain->acl_info_list,
4686                                    buffer, false))
4687                         ccs_update_stat(CCS_STAT_POLICY_UPDATES);
4688         }
4689         kfree(buffer);
4690 }
4691 
4692 /**
4693  * ccs_domain_quota_ok - Check for domain's quota.
4694  *
4695  * @r: Pointer to "struct ccs_request_info".
4696  *
4697  * Returns true if the domain is not exceeded quota, false otherwise.
4698  *
4699  * Caller holds ccs_read_lock().
4700  */
4701 static bool ccs_domain_quota_ok(struct ccs_request_info *r)
4702 {
4703         unsigned int count = 0;
4704         struct ccs_domain_info * const domain = ccs_current_domain();
4705         struct ccs_acl_info *ptr;
4706         if (r->mode != CCS_CONFIG_LEARNING)
4707                 return false;
4708         if (!domain)
4709                 return true;
4710         list_for_each_entry_srcu(ptr, &domain->acl_info_list, list, &ccs_ss) {
4711                 u16 perm;
4712                 u8 i;
4713                 if (ptr->is_deleted)
4714                         continue;
4715                 switch (ptr->type) {
4716                 case CCS_TYPE_PATH_ACL:
4717                 case CCS_TYPE_PATH2_ACL:
4718                 case CCS_TYPE_PATH_NUMBER_ACL:
4719                 case CCS_TYPE_MKDEV_ACL:
4720 #ifdef CONFIG_CCSECURITY_NETWORK
4721                 case CCS_TYPE_INET_ACL:
4722                 case CCS_TYPE_UNIX_ACL:
4723 #endif
4724                         perm = ptr->perm;
4725                         break;
4726 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4727                 case CCS_TYPE_AUTO_EXECUTE_HANDLER:
4728                 case CCS_TYPE_DENIED_EXECUTE_HANDLER:
4729 #endif
4730 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
4731                 case CCS_TYPE_AUTO_TASK_ACL:
4732                 case CCS_TYPE_MANUAL_TASK_ACL:
4733 #endif
4734                         perm = 0;
4735                         break;
4736                 default:
4737                         perm = 1;
4738                 }
4739                 for (i = 0; i < 16; i++)
4740                         if (perm & (1 << i))
4741                                 count++;
4742         }
4743         if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY])
4744                 return true;
4745         if (!domain->flags[CCS_DIF_QUOTA_WARNED]) {
4746                 domain->flags[CCS_DIF_QUOTA_WARNED] = true;
4747                 /* r->granted = false; */
4748                 ccs_write_log(r, "%s", ccs_dif[CCS_DIF_QUOTA_WARNED]);
4749                 printk(KERN_WARNING "WARNING: "
4750                        "Domain '%s' has too many ACLs to hold. "
4751                        "Stopped learning mode.\n", domain->domainname->name);
4752         }
4753         return false;
4754 }
4755 
4756 /**
4757  * ccs_supervisor - Ask for the supervisor's decision.
4758  *
4759  * @r:   Pointer to "struct ccs_request_info".
4760  * @fmt: The printf()'s format string, followed by parameters.
4761  *
4762  * Returns 0 if the supervisor decided to permit the access request which
4763  * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
4764  * decided to retry the access request which violated the policy in enforcing
4765  * mode, 0 if it is not in enforcing mode, -EPERM otherwise.
4766  */
4767 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
4768 {
4769         va_list args;
4770         int error;
4771         int len;
4772         static unsigned int ccs_serial;
4773         struct ccs_query entry = { };
4774         bool quota_exceeded = false;
4775         va_start(args, fmt);
4776         len = vsnprintf((char *) &len, 1, fmt, args) + 1;
4777         va_end(args);
4778         /* Write /proc/ccs/audit. */
4779         va_start(args, fmt);
4780         ccs_write_log2(r, len, fmt, args);
4781         va_end(args);
4782         /* Nothing more to do if granted. */
4783         if (r->granted)
4784                 return 0;
4785         if (r->mode)
4786                 ccs_update_stat(r->mode);
4787         switch (r->mode) {
4788                 int i;
4789                 struct ccs_profile *p;
4790         case CCS_CONFIG_ENFORCING:
4791                 error = -EPERM;
4792                 if (atomic_read(&ccs_query_observers))
4793                         break;
4794                 if (r->dont_sleep_on_enforce_error)
4795                         goto out;
4796                 p = ccs_profile(r->profile);
4797                 /* Check enforcing_penalty parameter. */
4798                 for (i = 0; i < p->pref[CCS_PREF_ENFORCING_PENALTY]; i++) {
4799                         set_current_state(TASK_INTERRUPTIBLE);
4800                         schedule_timeout(HZ / 10);
4801                 }
4802                 goto out;
4803         case CCS_CONFIG_LEARNING:
4804                 error = 0;
4805                 /* Check max_learning_entry parameter. */
4806                 if (ccs_domain_quota_ok(r))
4807                         break;
4808                 /* fall through */
4809         default:
4810                 return 0;
4811         }
4812         /* Get message. */
4813         va_start(args, fmt);
4814         entry.query = ccs_init_log(r, len, fmt, args);
4815         va_end(args);
4816         if (!entry.query)
4817                 goto out;
4818         entry.query_len = strlen(entry.query) + 1;
4819         if (!error) {
4820                 ccs_add_entry(entry.query);
4821                 goto out;
4822         }
4823         len = ccs_round2(entry.query_len);
4824         entry.domain = ccs_current_domain();
4825         spin_lock(&ccs_query_list_lock);
4826         if (ccs_memory_quota[CCS_MEMORY_QUERY] &&
4827             ccs_memory_used[CCS_MEMORY_QUERY] + len
4828             >= ccs_memory_quota[CCS_MEMORY_QUERY]) {
4829                 quota_exceeded = true;
4830         } else {
4831                 entry.serial = ccs_serial++;
4832                 entry.retry = r->retry;
4833                 ccs_memory_used[CCS_MEMORY_QUERY] += len;
4834                 list_add_tail(&entry.list, &ccs_query_list);
4835         }
4836         spin_unlock(&ccs_query_list_lock);
4837         if (quota_exceeded)
4838                 goto out;
4839         /* Give 10 seconds for supervisor's opinion. */
4840         while (entry.timer < 10) {
4841                 wake_up_all(&ccs_query_wait);
4842                 if (wait_event_interruptible_timeout
4843                     (ccs_answer_wait, entry.answer ||
4844                      !atomic_read(&ccs_query_observers), HZ))
4845                         break;
4846                 else
4847                         entry.timer++;
4848         }
4849         spin_lock(&ccs_query_list_lock);
4850         list_del(&entry.list);
4851         ccs_memory_used[CCS_MEMORY_QUERY] -= len;
4852         spin_unlock(&ccs_query_list_lock);
4853         switch (entry.answer) {
4854         case 3: /* Asked to retry by administrator. */
4855                 error = CCS_RETRY_REQUEST;
4856                 r->retry++;
4857                 break;
4858         case 1:
4859                 /* Granted by administrator. */
4860                 error = 0;
4861                 break;
4862         default:
4863                 /* Timed out or rejected by administrator. */
4864                 break;
4865         }
4866 out:
4867         kfree(entry.query);
4868         return error;
4869 }
4870 
4871 /**
4872  * ccs_audit_log - Audit permission check log.
4873  *
4874  * @r: Pointer to "struct ccs_request_info".
4875  *
4876  * Returns return value of ccs_supervisor().
4877  */
4878 int ccs_audit_log(struct ccs_request_info *r)
4879 {
4880         switch (r->param_type) {
4881                 u8 type;
4882                 char buf[48];
4883 #ifdef CONFIG_CCSECURITY_NETWORK
4884                 const u32 *address;
4885 #endif
4886         case CCS_TYPE_PATH_ACL:
4887                 return ccs_supervisor(r, "file %s %s\n", ccs_path_keyword
4888                                       [r->param.path.operation],
4889                                       r->param.path.filename->name);
4890         case CCS_TYPE_PATH2_ACL:
4891                 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
4892                                       [ccs_pp2mac[r->param.path2.operation]],
4893                                       r->param.path2.filename1->name,
4894                                       r->param.path2.filename2->name);
4895         case CCS_TYPE_PATH_NUMBER_ACL:
4896                 type = r->param.path_number.operation;
4897                 switch (type) {
4898                 case CCS_TYPE_CREATE:
4899                 case CCS_TYPE_MKDIR:
4900                 case CCS_TYPE_MKFIFO:
4901                 case CCS_TYPE_MKSOCK:
4902                 case CCS_TYPE_CHMOD:
4903                         snprintf(buf, sizeof(buf), "0%lo",
4904                                  r->param.path_number.number);
4905                         break;
4906                 case CCS_TYPE_IOCTL:
4907                         snprintf(buf, sizeof(buf), "0x%lX",
4908                                  r->param.path_number.number);
4909                         break;
4910                 default:
4911                         snprintf(buf, sizeof(buf), "%lu",
4912                                  r->param.path_number.number);
4913                         break;
4914                 }
4915                 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
4916                                       [ccs_pn2mac[type]],
4917                                       r->param.path_number.filename->name,
4918                                       buf);
4919         case CCS_TYPE_MKDEV_ACL:
4920                 return ccs_supervisor(r, "file %s %s 0%o %u %u\n",
4921                                       ccs_mac_keywords
4922                                       [ccs_pnnn2mac[r->param.mkdev.operation]],
4923                                       r->param.mkdev.filename->name,
4924                                       r->param.mkdev.mode,
4925                                       r->param.mkdev.major,
4926                                       r->param.mkdev.minor);
4927         case CCS_TYPE_MOUNT_ACL:
4928                 return ccs_supervisor(r, "file mount %s %s %s 0x%lX\n",
4929                                       r->param.mount.dev->name,
4930                                       r->param.mount.dir->name,
4931                                       r->param.mount.type->name,
4932                                       r->param.mount.flags);
4933 #ifdef CONFIG_CCSECURITY_MISC
4934         case CCS_TYPE_ENV_ACL:
4935                 return ccs_supervisor(r, "misc env %s\n",
4936                                       r->param.environ.name->name);
4937 #endif
4938 #ifdef CONFIG_CCSECURITY_CAPABILITY
4939         case CCS_TYPE_CAPABILITY_ACL:
4940                 return ccs_supervisor(r, "capability %s\n", ccs_mac_keywords
4941                                       [ccs_c2mac[r->param.capability.
4942                                                  operation]]);
4943 #endif
4944 #ifdef CONFIG_CCSECURITY_NETWORK
4945         case CCS_TYPE_INET_ACL:
4946                 address = r->param.inet_network.address;
4947                 if (r->param.inet_network.is_ipv6)
4948                         ccs_print_ipv6(buf, sizeof(buf),
4949                                        (const struct in6_addr *) address);
4950                 else
4951                         ccs_print_ipv4(buf, sizeof(buf), address);
4952                 return ccs_supervisor(r, "network inet %s %s %s %u\n",
4953                                       ccs_proto_keyword[r->param.inet_network.
4954                                                         protocol],
4955                                       ccs_socket_keyword[r->param.inet_network.
4956                                                          operation],
4957                                       buf, r->param.inet_network.port);
4958         case CCS_TYPE_UNIX_ACL:
4959                 return ccs_supervisor(r, "network unix %s %s %s\n",
4960                                       ccs_proto_keyword[r->param.
4961                                                         unix_network.protocol],
4962                                       ccs_socket_keyword[r->param.unix_network.
4963                                                          operation],
4964                                       r->param.unix_network.address->name);
4965 #endif
4966 #ifdef CONFIG_CCSECURITY_IPC
4967         case CCS_TYPE_SIGNAL_ACL:
4968                 return ccs_supervisor(r, "ipc signal %d %s\n",
4969                                       r->param.signal.sig,
4970                                       r->param.signal.dest_pattern);
4971 #endif
4972         }
4973         return 0;
4974 }
4975 
4976 /**
4977  * ccs_find_domain_by_qid - Get domain by query id.
4978  *
4979  * @serial: Query ID assigned by ccs_supervisor().
4980  *
4981  * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
4982  */
4983 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial)
4984 {
4985         struct ccs_query *ptr;
4986         struct ccs_domain_info *domain = NULL;
4987         spin_lock(&ccs_query_list_lock);
4988         list_for_each_entry(ptr, &ccs_query_list, list) {
4989                 if (ptr->serial != serial)
4990                         continue;
4991                 domain = ptr->domain;
4992                 break;
4993         }
4994         spin_unlock(&ccs_query_list_lock);
4995         return domain;
4996 }
4997 
4998 /**
4999  * ccs_read_query - Read access requests which violated policy in enforcing mode.
5000  *
5001  * @head: Pointer to "struct ccs_io_buffer".
5002  *
5003  * Returns nothing.
5004  */
5005 static void ccs_read_query(struct ccs_io_buffer *head)
5006 {
5007         struct list_head *tmp;
5008         unsigned int pos = 0;
5009         size_t len = 0;
5010         char *buf;
5011         if (head->r.w_pos)
5012                 return;
5013         kfree(head->read_buf);
5014         head->read_buf = NULL;
5015         spin_lock(&ccs_query_list_lock);
5016         list_for_each(tmp, &ccs_query_list) {
5017                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5018                 if (pos++ != head->r.query_index)
5019                         continue;
5020                 len = ptr->query_len;
5021                 break;
5022         }
5023         spin_unlock(&ccs_query_list_lock);
5024         if (!len) {
5025                 head->r.query_index = 0;
5026                 return;
5027         }
5028         buf = kzalloc(len + 32, CCS_GFP_FLAGS);
5029         if (!buf)
5030                 return;
5031         pos = 0;
5032         spin_lock(&ccs_query_list_lock);
5033         list_for_each(tmp, &ccs_query_list) {
5034                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5035                 if (pos++ != head->r.query_index)
5036                         continue;
5037                 /*
5038                  * Some query can be skipped because ccs_query_list
5039                  * can change, but I don't care.
5040                  */
5041                 if (len == ptr->query_len)
5042                         snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
5043                                  ptr->retry, ptr->query);
5044                 break;
5045         }
5046         spin_unlock(&ccs_query_list_lock);
5047         if (buf[0]) {
5048                 head->read_buf = buf;
5049                 head->r.w[head->r.w_pos++] = buf;
5050                 head->r.query_index++;
5051         } else {
5052                 kfree(buf);
5053         }
5054 }
5055 
5056 /**
5057  * ccs_write_answer - Write the supervisor's decision.
5058  *
5059  * @head: Pointer to "struct ccs_io_buffer".
5060  *
5061  * Returns 0 on success, -EINVAL otherwise.
5062  */
5063 static int ccs_write_answer(struct ccs_io_buffer *head)
5064 {
5065         char *data = head->write_buf;
5066         struct list_head *tmp;
5067         unsigned int serial;
5068         unsigned int answer;
5069         spin_lock(&ccs_query_list_lock);
5070         list_for_each(tmp, &ccs_query_list) {
5071                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5072                 ptr->timer = 0;
5073         }
5074         spin_unlock(&ccs_query_list_lock);
5075         if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
5076                 return -EINVAL;
5077         spin_lock(&ccs_query_list_lock);
5078         list_for_each(tmp, &ccs_query_list) {
5079                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5080                 if (ptr->serial != serial)
5081                         continue;
5082                 ptr->answer = (u8) answer;
5083                 /* Remove from ccs_query_list. */
5084                 if (ptr->answer) {
5085                         list_del(&ptr->list);
5086                         INIT_LIST_HEAD(&ptr->list);
5087                 }
5088                 break;
5089         }
5090         spin_unlock(&ccs_query_list_lock);
5091         wake_up_all(&ccs_answer_wait);
5092         return 0;
5093 }
5094 
5095 /**
5096  * ccs_read_version - Get version.
5097  *
5098  * @head: Pointer to "struct ccs_io_buffer".
5099  *
5100  * Returns nothing.
5101  */
5102 static void ccs_read_version(struct ccs_io_buffer *head)
5103 {
5104         if (head->r.eof)
5105                 return;
5106         ccs_set_string(head, "1.8.6");
5107         head->r.eof = true;
5108 }
5109 
5110 /**
5111  * ccs_update_stat - Update statistic counters.
5112  *
5113  * @index: Index for policy type.
5114  *
5115  * Returns nothing.
5116  */
5117 static void ccs_update_stat(const u8 index)
5118 {
5119 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
5120         struct timeval tv;
5121         do_gettimeofday(&tv);
5122         /*
5123          * I don't use atomic operations because race condition is not fatal.
5124          */
5125         ccs_stat_updated[index]++;
5126         ccs_stat_modified[index] = tv.tv_sec;
5127 #else
5128         /*
5129          * I don't use atomic operations because race condition is not fatal.
5130          */
5131         ccs_stat_updated[index]++;
5132         ccs_stat_modified[index] = get_seconds();
5133 #endif
5134 }
5135 
5136 /**
5137  * ccs_read_stat - Read statistic data.
5138  *
5139  * @head: Pointer to "struct ccs_io_buffer".
5140  *
5141  * Returns nothing.
5142  */
5143 static void ccs_read_stat(struct ccs_io_buffer *head)
5144 {
5145         u8 i;
5146         unsigned int total = 0;
5147         if (head->r.eof)
5148                 return;
5149         for (i = 0; i < CCS_MAX_POLICY_STAT; i++) {
5150                 ccs_io_printf(head, "Policy %-30s %10u", ccs_policy_headers[i],
5151                               ccs_stat_updated[i]);
5152                 if (ccs_stat_modified[i]) {
5153                         struct ccs_time stamp;
5154                         ccs_convert_time(ccs_stat_modified[i], &stamp);
5155                         ccs_io_printf(head, " (Last: %04u/%02u/%02u "
5156                                       "%02u:%02u:%02u)",
5157                                       stamp.year, stamp.month, stamp.day,
5158                                       stamp.hour, stamp.min, stamp.sec);
5159                 }
5160                 ccs_set_lf(head);
5161         }
5162         for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) {
5163                 unsigned int used = ccs_memory_used[i];
5164                 total += used;
5165                 ccs_io_printf(head, "Memory used by %-22s %10u",
5166                               ccs_memory_headers[i], used);
5167                 used = ccs_memory_quota[i];
5168                 if (used)
5169                         ccs_io_printf(head, " (Quota: %10u)", used);
5170                 ccs_set_lf(head);
5171         }
5172         ccs_io_printf(head, "Total memory used:                    %10u\n",
5173                       total);
5174         head->r.eof = true;
5175 }
5176 
5177 /**
5178  * ccs_write_stat - Set memory quota.
5179  *
5180  * @head: Pointer to "struct ccs_io_buffer".
5181  *
5182  * Returns 0.
5183  */
5184 static int ccs_write_stat(struct ccs_io_buffer *head)
5185 {
5186         char *data = head->write_buf;
5187         u8 i;
5188         if (ccs_str_starts(&data, "Memory used by "))
5189                 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++)
5190                         if (ccs_str_starts(&data, ccs_memory_headers[i])) {
5191                                 if (*data == ' ')
5192                                         data++;
5193                                 ccs_memory_quota[i] =
5194                                         simple_strtoul(data, NULL, 10);
5195                         }
5196         return 0;
5197 }
5198 
5199 /**
5200  * ccs_print_bprm - Print "struct linux_binprm" for auditing.
5201  *
5202  * @bprm: Pointer to "struct linux_binprm".
5203  * @dump: Pointer to "struct ccs_page_dump".
5204  *
5205  * Returns the contents of @bprm on success, NULL otherwise.
5206  *
5207  * This function uses kzalloc(), so caller must kfree() if this function
5208  * didn't return NULL.
5209  */
5210 static char *ccs_print_bprm(struct linux_binprm *bprm,
5211                             struct ccs_page_dump *dump)
5212 {
5213         static const int ccs_buffer_len = 4096 * 2;
5214         char *buffer = kzalloc(ccs_buffer_len, CCS_GFP_FLAGS);
5215         char *cp;
5216         char *last_start;
5217         int len;
5218         unsigned long pos = bprm->p;
5219         int offset = pos % PAGE_SIZE;
5220         int argv_count = bprm->argc;
5221         int envp_count = bprm->envc;
5222         bool truncated = false;
5223         if (!buffer)
5224                 return NULL;
5225         len = snprintf(buffer, ccs_buffer_len - 1, "argv[]={ ");
5226         cp = buffer + len;
5227         if (!argv_count) {
5228                 memmove(cp, "} envp[]={ ", 11);
5229                 cp += 11;
5230         }
5231         last_start = cp;
5232         while (argv_count || envp_count) {
5233                 if (!ccs_dump_page(bprm, pos, dump))
5234                         goto out;
5235                 pos += PAGE_SIZE - offset;
5236                 /* Read. */
5237                 while (offset < PAGE_SIZE) {
5238                         const char *kaddr = dump->data;
5239                         const unsigned char c = kaddr[offset++];
5240                         if (cp == last_start)
5241                                 *cp++ = '"';
5242                         if (cp >= buffer + ccs_buffer_len - 32) {
5243                                 /* Reserve some room for "..." string. */
5244                                 truncated = true;
5245                         } else if (c == '\\') {
5246                                 *cp++ = '\\';
5247                                 *cp++ = '\\';
5248                         } else if (c > ' ' && c < 127) {
5249                                 *cp++ = c;
5250                         } else if (!c) {
5251                                 *cp++ = '"';
5252                                 *cp++ = ' ';
5253                                 last_start = cp;
5254                         } else {
5255                                 *cp++ = '\\';
5256                                 *cp++ = (c >> 6) + '';
5257                                 *cp++ = ((c >> 3) & 7) + '';
5258                                 *cp++ = (c & 7) + '';
5259                         }
5260                         if (c)
5261                                 continue;
5262                         if (argv_count) {
5263                                 if (--argv_count == 0) {
5264                                         if (truncated) {
5265                                                 cp = last_start;
5266                                                 memmove(cp, "... ", 4);
5267                                                 cp += 4;
5268                                         }
5269