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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ 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.9 ] ~ [ 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.11   2024/07/15
  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 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                                                const bool pref);
496 static struct ccs_domain_info *ccs_find_domain(const char *domainname);
497 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial);
498 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
499                                        const u8 idx);
500 static struct ccs_policy_namespace *ccs_assign_namespace
501 (const char *domainname);
502 static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
503                                                        const unsigned int len);
504 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
505                                               const unsigned int profile);
506 static struct ccs_profile *ccs_profile(const u8 profile);
507 static u8 ccs_condition_type(const char *word);
508 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3);
509 static u8 ccs_parse_ulong(unsigned long *result, char **str);
510 static unsigned int ccs_poll(struct file *file, poll_table *wait);
511 static void __init ccs_create_entry(const char *name, const umode_t mode,
512                                     struct proc_dir_entry *parent,
513                                     const u8 key);
514 static void __init ccs_load_builtin_policy(void);
515 static void __init ccs_policy_io_init(void);
516 static void __init ccs_proc_init(void);
517 static void ccs_add_entry(char *header);
518 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
519         __printf(3, 4);
520 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...);
521 static void ccs_check_profile(void);
522 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
523 static void ccs_convert_time(time_t time, struct ccs_time *stamp);
524 #else
525 static void ccs_convert_time(time64_t time, struct ccs_time *stamp);
526 #endif
527 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns);
528 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
529         __printf(2, 3);
530 static void ccs_normalize_line(unsigned char *buffer);
531 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config);
532 static void ccs_print_name_union(struct ccs_io_buffer *head,
533                                  const struct ccs_name_union *ptr);
534 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
535                                         const struct ccs_name_union *ptr);
536 static void ccs_print_namespace(struct ccs_io_buffer *head);
537 static void ccs_print_number_union(struct ccs_io_buffer *head,
538                                    const struct ccs_number_union *ptr);
539 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
540                                            const struct ccs_number_union *ptr);
541 static void ccs_read_domain(struct ccs_io_buffer *head);
542 static void ccs_read_exception(struct ccs_io_buffer *head);
543 static void ccs_read_log(struct ccs_io_buffer *head);
544 static void ccs_read_manager(struct ccs_io_buffer *head);
545 static void ccs_read_pid(struct ccs_io_buffer *head);
546 static void ccs_read_profile(struct ccs_io_buffer *head);
547 static void ccs_read_query(struct ccs_io_buffer *head);
548 static void ccs_read_stat(struct ccs_io_buffer *head);
549 static void ccs_read_version(struct ccs_io_buffer *head);
550 static void ccs_set_group(struct ccs_io_buffer *head, const char *category);
551 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head);
552 static void ccs_set_slash(struct ccs_io_buffer *head);
553 static void ccs_set_space(struct ccs_io_buffer *head);
554 static void ccs_set_string(struct ccs_io_buffer *head, const char *string);
555 static void ccs_set_uint(unsigned int *i, const char *string,
556                          const char *find);
557 static void ccs_update_stat(const u8 index);
558 static void ccs_update_task_domain(struct ccs_request_info *r);
559 static void ccs_write_log2(struct ccs_request_info *r, int len,
560                            const char *fmt, va_list args);
561 
562 #ifdef CONFIG_CCSECURITY_PORTRESERVE
563 static bool __ccs_lport_reserved(const u16 port);
564 static int ccs_write_reserved_port(struct ccs_acl_param *param);
565 #endif
566 
567 #ifdef CONFIG_CCSECURITY_NETWORK
568 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
569                                    struct ccs_ipaddr_union *ptr);
570 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
571                           const u32 *ip);
572 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
573                           const struct in6_addr *ip);
574 static int ccs_write_inet_network(struct ccs_acl_param *param);
575 static int ccs_write_unix_network(struct ccs_acl_param *param);
576 static void ccs_print_ip(char *buf, const unsigned int size,
577                          const struct ccs_ipaddr_union *ptr);
578 #endif
579 
580 #ifdef CONFIG_CCSECURITY_CAPABILITY
581 static int ccs_write_capability(struct ccs_acl_param *param);
582 #endif
583 
584 #ifdef CONFIG_CCSECURITY_MISC
585 static int ccs_write_misc(struct ccs_acl_param *param);
586 #endif
587 
588 #ifdef CONFIG_CCSECURITY_IPC
589 static int ccs_write_ipc(struct ccs_acl_param *param);
590 #endif
591 
592 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
593 static ssize_t ccs_write_self(struct file *file, const char __user *buf,
594                               size_t count, loff_t *ppos);
595 #endif
596 
597 /***** SECTION4: Standalone functions section *****/
598 
599 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
600 
601 /**
602  * fatal_signal_pending - Check whether SIGKILL is pending or not.
603  *
604  * @p: Pointer to "struct task_struct".
605  *
606  * Returns true if SIGKILL is pending on @p, false otherwise.
607  *
608  * This is for compatibility with older kernels.
609  */
610 #define fatal_signal_pending(p) (signal_pending(p) &&                   \
611                                  sigismember(&p->pending.signal, SIGKILL))
612 
613 #endif
614 
615 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
616 
617 /**
618  * __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
619  *
620  * @wq:        The waitqueue to wait on.
621  * @condition: A C expression for the event to wait for.
622  * @ret:       Timeout, in jiffies.
623  *
624  * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
625  * signal, and the remaining jiffies otherwise if the condition evaluated to
626  * true before the timeout elapsed.
627  *
628  * This is for compatibility with older kernels.
629  */
630 #define __wait_event_interruptible_timeout(wq, condition, ret)          \
631 do {                                                                    \
632         wait_queue_t __wait;                                            \
633         init_waitqueue_entry(&__wait, current);                         \
634                                                                         \
635         add_wait_queue(&wq, &__wait);                                   \
636         for (;;) {                                                      \
637                 set_current_state(TASK_INTERRUPTIBLE);                  \
638                 if (condition)                                          \
639                         break;                                          \
640                 if (!signal_pending(current)) {                         \
641                         ret = schedule_timeout(ret);                    \
642                         if (!ret)                                       \
643                                 break;                                  \
644                         continue;                                       \
645                 }                                                       \
646                 ret = -ERESTARTSYS;                                     \
647                 break;                                                  \
648         }                                                               \
649         current->state = TASK_RUNNING;                                  \
650         remove_wait_queue(&wq, &__wait);                                \
651 } while (0)
652 
653 /**
654  * wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses.
655  *
656  * @wq:        The waitqueue to wait on.
657  * @condition: A C expression for the event to wait for.
658  * @timeout:   Timeout, in jiffies.
659  *
660  * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a
661  * signal, and the remaining jiffies otherwise if the condition evaluated to
662  * true before the timeout elapsed.
663  *
664  * This is for compatibility with older kernels.
665  */
666 #define wait_event_interruptible_timeout(wq, condition, timeout)        \
667 ({                                                                      \
668         long __ret = timeout;                                           \
669         if (!(condition))                                               \
670                 __wait_event_interruptible_timeout(wq, condition, __ret); \
671         __ret;                                                          \
672 })
673 
674 #endif
675 
676 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
677 /**
678  * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
679  *
680  * @time:  Seconds since 1970/01/01 00:00:00.
681  * @stamp: Pointer to "struct ccs_time".
682  *
683  * Returns nothing.
684  *
685  * This function does not handle Y2038 problem.
686  */
687 static void ccs_convert_time(time_t time, struct ccs_time *stamp)
688 {
689         static const u16 ccs_eom[2][12] = {
690                 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
691                 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
692         };
693         u16 y;
694         u8 m;
695         bool r;
696         stamp->sec = time % 60;
697         time /= 60;
698         stamp->min = time % 60;
699         time /= 60;
700         stamp->hour = time % 24;
701         time /= 24;
702         for (y = 1970; ; y++) {
703                 const unsigned short days = (y & 3) ? 365 : 366;
704                 if (time < days)
705                         break;
706                 time -= days;
707         }
708         r = (y & 3) == 0;
709         for (m = 0; m < 11 && time >= ccs_eom[r][m]; m++);
710         if (m)
711                 time -= ccs_eom[r][m - 1];
712         stamp->year = y;
713         stamp->month = ++m;
714         stamp->day = ++time;
715 }
716 #else
717 /**
718  * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
719  *
720  * @time:  Seconds since 1970/01/01 00:00:00.
721  * @stamp: Pointer to "struct ccs_time".
722  *
723  * Returns nothing.
724  */
725 static void ccs_convert_time(time64_t time, struct ccs_time *stamp)
726 {
727         struct tm tm;
728 
729         time64_to_tm(time, 0, &tm);
730         stamp->sec = tm.tm_sec;
731         stamp->min = tm.tm_min;
732         stamp->hour = tm.tm_hour;
733         stamp->day = tm.tm_mday;
734         stamp->month = tm.tm_mon + 1;
735         stamp->year = tm.tm_year + 1900;
736 }
737 #endif
738 
739 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
740 #if !defined(RHEL_VERSION) || RHEL_VERSION != 3
741 
742 /**
743  * PDE - Get "struct proc_dir_entry".
744  *
745  * @inode: Pointer to "struct inode".
746  *
747  * Returns pointer to "struct proc_dir_entry".
748  *
749  * This is for compatibility with older kernels.
750  */
751 static inline struct proc_dir_entry *PDE(const struct inode *inode)
752 {
753         return (struct proc_dir_entry *) inode->u.generic_ip;
754 }
755 
756 #endif
757 #endif
758 
759 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
760 
761 /**
762  * proc_notify_change - Update inode's attributes and reflect to the dentry.
763  *
764  * @dentry: Pointer to "struct dentry".
765  * @iattr:  Pointer to "struct iattr".
766  *
767  * Returns 0 on success, negative value otherwise.
768  *
769  * The 2.4 kernels don't allow chmod()/chown() for files in /proc,
770  * while the 2.6 kernels allow.
771  * To permit management of /proc/ccs/ interface by non-root user,
772  * I modified to allow chmod()/chown() of /proc/ccs/ interface like 2.6 kernels
773  * by adding "struct inode_operations"->setattr hook.
774  */
775 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
776 {
777         struct inode *inode = dentry->d_inode;
778         struct proc_dir_entry *de = PDE(inode);
779         int error;
780 
781         error = inode_change_ok(inode, iattr);
782         if (error)
783                 goto out;
784 
785         error = inode_setattr(inode, iattr);
786         if (error)
787                 goto out;
788 
789         de->uid = inode->i_uid;
790         de->gid = inode->i_gid;
791         de->mode = inode->i_mode;
792 out:
793         return error;
794 }
795 
796 #endif
797 
798 #ifdef CONFIG_CCSECURITY_NETWORK
799 
800 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && defined(CONFIG_NET)
801 #define ccs_in4_pton in4_pton
802 #define ccs_in6_pton in6_pton
803 #else
804 /*
805  * Routines for parsing IPv4 or IPv6 address.
806  * These are copied from lib/hexdump.c net/core/utils.c .
807  */
808 #include <linux/ctype.h>
809 
810 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
811 static int hex_to_bin(char ch)
812 {
813         if ((ch >= '') && (ch <= '9'))
814                 return ch - '';
815         ch = tolower(ch);
816         if ((ch >= 'a') && (ch <= 'f'))
817                 return ch - 'a' + 10;
818         return -1;
819 }
820 #endif
821 
822 #define IN6PTON_XDIGIT          0x00010000
823 #define IN6PTON_DIGIT           0x00020000
824 #define IN6PTON_COLON_MASK      0x00700000
825 #define IN6PTON_COLON_1         0x00100000      /* single : requested */
826 #define IN6PTON_COLON_2         0x00200000      /* second : requested */
827 #define IN6PTON_COLON_1_2       0x00400000      /* :: requested */
828 #define IN6PTON_DOT             0x00800000      /* . */
829 #define IN6PTON_DELIM           0x10000000
830 #define IN6PTON_NULL            0x20000000      /* first/tail */
831 #define IN6PTON_UNKNOWN         0x40000000
832 
833 static inline int xdigit2bin(char c, int delim)
834 {
835         int val;
836 
837         if (c == delim || c == '\0')
838                 return IN6PTON_DELIM;
839         if (c == ':')
840                 return IN6PTON_COLON_MASK;
841         if (c == '.')
842                 return IN6PTON_DOT;
843 
844         val = hex_to_bin(c);
845         if (val >= 0)
846                 return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
847 
848         if (delim == -1)
849                 return IN6PTON_DELIM;
850         return IN6PTON_UNKNOWN;
851 }
852 
853 static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim,
854                         const char **end)
855 {
856         const char *s;
857         u8 *d;
858         u8 dbuf[4];
859         int ret = 0;
860         int i;
861         int w = 0;
862 
863         if (srclen < 0)
864                 srclen = strlen(src);
865         s = src;
866         d = dbuf;
867         i = 0;
868         while (1) {
869                 int c;
870                 c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
871                 if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM |
872                            IN6PTON_COLON_MASK)))
873                         goto out;
874                 if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
875                         if (w == 0)
876                                 goto out;
877                         *d++ = w & 0xff;
878                         w = 0;
879                         i++;
880                         if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
881                                 if (i != 4)
882                                         goto out;
883                                 break;
884                         }
885                         goto cont;
886                 }
887                 w = (w * 10) + c;
888                 if ((w & 0xffff) > 255)
889                         goto out;
890 cont:
891                 if (i >= 4)
892                         goto out;
893                 s++;
894                 srclen--;
895         }
896         ret = 1;
897         memcpy(dst, dbuf, sizeof(dbuf));
898 out:
899         if (end)
900                 *end = s;
901         return ret;
902 }
903 
904 static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim,
905                         const char **end)
906 {
907         const char *s, *tok = NULL;
908         u8 *d, *dc = NULL;
909         u8 dbuf[16];
910         int ret = 0;
911         int i;
912         int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
913         int w = 0;
914 
915         memset(dbuf, 0, sizeof(dbuf));
916 
917         s = src;
918         d = dbuf;
919         if (srclen < 0)
920                 srclen = strlen(src);
921 
922         while (1) {
923                 int c;
924 
925                 c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
926                 if (!(c & state))
927                         goto out;
928                 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
929                         /* process one 16-bit word */
930                         if (!(state & IN6PTON_NULL)) {
931                                 *d++ = (w >> 8) & 0xff;
932                                 *d++ = w & 0xff;
933                         }
934                         w = 0;
935                         if (c & IN6PTON_DELIM) {
936                                 /* We've processed last word */
937                                 break;
938                         }
939                         /*
940                          * COLON_1 => XDIGIT
941                          * COLON_2 => XDIGIT|DELIM
942                          * COLON_1_2 => COLON_2
943                          */
944                         switch (state & IN6PTON_COLON_MASK) {
945                         case IN6PTON_COLON_2:
946                                 dc = d;
947                                 state = IN6PTON_XDIGIT | IN6PTON_DELIM;
948                                 if (dc - dbuf >= sizeof(dbuf))
949                                         state |= IN6PTON_NULL;
950                                 break;
951                         case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
952                                 state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
953                                 break;
954                         case IN6PTON_COLON_1:
955                                 state = IN6PTON_XDIGIT;
956                                 break;
957                         case IN6PTON_COLON_1_2:
958                                 state = IN6PTON_COLON_2;
959                                 break;
960                         default:
961                                 state = 0;
962                         }
963                         tok = s + 1;
964                         goto cont;
965                 }
966 
967                 if (c & IN6PTON_DOT) {
968                         ret = ccs_in4_pton(tok ? tok : s, srclen +
969                                            (int)(s - tok), d, delim, &s);
970                         if (ret > 0) {
971                                 d += 4;
972                                 break;
973                         }
974                         goto out;
975                 }
976 
977                 w = (w << 4) | (0xff & c);
978                 state = IN6PTON_COLON_1 | IN6PTON_DELIM;
979                 if (!(w & 0xf000))
980                         state |= IN6PTON_XDIGIT;
981                 if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
982                         state |= IN6PTON_COLON_1_2;
983                         state &= ~IN6PTON_DELIM;
984                 }
985                 if (d + 2 >= dbuf + sizeof(dbuf))
986                         state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
987 cont:
988                 if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
989                     d + 4 == dbuf + sizeof(dbuf))
990                         state |= IN6PTON_DOT;
991                 if (d >= dbuf + sizeof(dbuf))
992                         state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
993                 s++;
994                 srclen--;
995         }
996 
997         i = 15; d--;
998 
999         if (dc) {
1000                 while (d >= dc)
1001                         dst[i--] = *d--;
1002                 while (i >= dc - dbuf)
1003                         dst[i--] = 0;
1004                 while (i >= 0)
1005                         dst[i--] = *d--;
1006         } else
1007                 memcpy(dst, dbuf, sizeof(dbuf));
1008 
1009         ret = 1;
1010 out:
1011         if (end)
1012                 *end = s;
1013         return ret;
1014 }
1015 #endif
1016 
1017 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
1018 
1019 /*
1020  * Routines for printing IPv4 or IPv6 address.
1021  * These are copied from include/linux/kernel.h include/net/ipv6.h
1022  * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified.
1023  */
1024 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
1025 #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5 || !defined(RHEL_MINOR) || RHEL_MINOR < 9
1026 static const char hex_asc[] = "0123456789abcdef";
1027 #define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
1028 #define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
1029 
1030 static inline char *pack_hex_byte(char *buf, u8 byte)
1031 {
1032         *buf++ = hex_asc_hi(byte);
1033         *buf++ = hex_asc_lo(byte);
1034         return buf;
1035 }
1036 #endif
1037 #endif
1038 
1039 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
1040 static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
1041 {
1042         return (a->s6_addr32[0] | a->s6_addr32[1] |
1043                 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
1044 }
1045 #endif
1046 
1047 static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
1048 {
1049         return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
1050 }
1051 
1052 static char *ip4_string(char *p, const u8 *addr)
1053 {
1054         /*
1055          * Since this function is called outside vsnprintf(), I can use
1056          * sprintf() here.
1057          */
1058         return p +
1059                 sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
1060 }
1061 
1062 static char *ip6_compressed_string(char *p, const char *addr)
1063 {
1064         int i, j, range;
1065         unsigned char zerolength[8];
1066         int longest = 1;
1067         int colonpos = -1;
1068         u16 word;
1069         u8 hi, lo;
1070         bool needcolon = false;
1071         bool useIPv4;
1072         struct in6_addr in6;
1073 
1074         memcpy(&in6, addr, sizeof(struct in6_addr));
1075 
1076         useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
1077 
1078         memset(zerolength, 0, sizeof(zerolength));
1079 
1080         if (useIPv4)
1081                 range = 6;
1082         else
1083                 range = 8;
1084 
1085         /* find position of longest 0 run */
1086         for (i = 0; i < range; i++) {
1087                 for (j = i; j < range; j++) {
1088                         if (in6.s6_addr16[j] != 0)
1089                                 break;
1090                         zerolength[i]++;
1091                 }
1092         }
1093         for (i = 0; i < range; i++) {
1094                 if (zerolength[i] > longest) {
1095                         longest = zerolength[i];
1096                         colonpos = i;
1097                 }
1098         }
1099         if (longest == 1)               /* don't compress a single 0 */
1100                 colonpos = -1;
1101 
1102         /* emit address */
1103         for (i = 0; i < range; i++) {
1104                 if (i == colonpos) {
1105                         if (needcolon || i == 0)
1106                                 *p++ = ':';
1107                         *p++ = ':';
1108                         needcolon = false;
1109                         i += longest - 1;
1110                         continue;
1111                 }
1112                 if (needcolon) {
1113                         *p++ = ':';
1114                         needcolon = false;
1115                 }
1116                 /* hex u16 without leading 0s */
1117                 word = ntohs(in6.s6_addr16[i]);
1118                 hi = word >> 8;
1119                 lo = word & 0xff;
1120                 if (hi) {
1121                         if (hi > 0x0f)
1122                                 p = pack_hex_byte(p, hi);
1123                         else
1124                                 *p++ = hex_asc_lo(hi);
1125                         p = pack_hex_byte(p, lo);
1126                 } else if (lo > 0x0f)
1127                         p = pack_hex_byte(p, lo);
1128                 else
1129                         *p++ = hex_asc_lo(lo);
1130                 needcolon = true;
1131         }
1132 
1133         if (useIPv4) {
1134                 if (needcolon)
1135                         *p++ = ':';
1136                 p = ip4_string(p, &in6.s6_addr[12]);
1137         }
1138         *p = '\0';
1139 
1140         return p;
1141 }
1142 #endif
1143 
1144 /**
1145  * ccs_print_ipv4 - Print an IPv4 address.
1146  *
1147  * @buffer:     Buffer to write to.
1148  * @buffer_len: Size of @buffer.
1149  * @ip:         Pointer to "u32 in network byte order".
1150  *
1151  * Returns written length.
1152  */
1153 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
1154                           const u32 *ip)
1155 {
1156 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1157         return snprintf(buffer, buffer_len, "%pI4", ip);
1158 #else
1159         char addr[sizeof("255.255.255.255")];
1160         ip4_string(addr, (const u8 *) ip);
1161         return snprintf(buffer, buffer_len, "%s", addr);
1162 #endif
1163 }
1164 
1165 /**
1166  * ccs_print_ipv6 - Print an IPv6 address.
1167  *
1168  * @buffer:     Buffer to write to.
1169  * @buffer_len: Size of @buffer.
1170  * @ip:         Pointer to "struct in6_addr".
1171  *
1172  * Returns written length.
1173  */
1174 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
1175                           const struct in6_addr *ip)
1176 {
1177 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1178         return snprintf(buffer, buffer_len, "%pI6c", ip);
1179 #else
1180         char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
1181         ip6_compressed_string(addr, (const u8 *) ip);
1182         return snprintf(buffer, buffer_len, "%s", addr);
1183 #endif
1184 }
1185 
1186 /**
1187  * ccs_print_ip - Print an IP address.
1188  *
1189  * @buf:  Buffer to write to.
1190  * @size: Size of @buf.
1191  * @ptr:  Pointer to "struct ipaddr_union".
1192  *
1193  * Returns nothing.
1194  */
1195 static void ccs_print_ip(char *buf, const unsigned int size,
1196                          const struct ccs_ipaddr_union *ptr)
1197 {
1198         int len;
1199         if (ptr->is_ipv6)
1200                 len = ccs_print_ipv6(buf, size, &ptr->ip[0]);
1201         else
1202                 len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]);
1203         if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2)
1204                 return;
1205         buf[len++] = '-';
1206         if (ptr->is_ipv6)
1207                 ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]);
1208         else
1209                 ccs_print_ipv4(buf + len, size - len,
1210                                &ptr->ip[1].s6_addr32[0]);
1211 }
1212 
1213 #endif
1214 
1215 /***** SECTION5: Variables definition section *****/
1216 
1217 /* Permit policy management by non-root user? */
1218 static bool ccs_manage_by_non_root;
1219 
1220 /* Lock for protecting policy. */
1221 DEFINE_MUTEX(ccs_policy_lock);
1222 
1223 /* Has /sbin/init started? */
1224 bool ccs_policy_loaded;
1225 
1226 /* List of namespaces. */
1227 LIST_HEAD(ccs_namespace_list);
1228 /* True if namespace other than ccs_kernel_namespace is defined. */
1229 static bool ccs_namespace_enabled;
1230 
1231 /* Initial namespace.*/
1232 static struct ccs_policy_namespace ccs_kernel_namespace;
1233 
1234 /* List of "struct ccs_condition". */
1235 LIST_HEAD(ccs_condition_list);
1236 
1237 #ifdef CONFIG_CCSECURITY_PORTRESERVE
1238 /* Bitmap for reserved local port numbers.*/
1239 static u8 ccs_reserved_port_map[8192];
1240 #endif
1241 
1242 /* Wait queue for kernel -> userspace notification. */
1243 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
1244 /* Wait queue for userspace -> kernel notification. */
1245 static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait);
1246 
1247 /* The list for "struct ccs_query". */
1248 static LIST_HEAD(ccs_query_list);
1249 
1250 /* Lock for manipulating ccs_query_list. */
1251 static DEFINE_SPINLOCK(ccs_query_list_lock);
1252 
1253 /* Number of "struct file" referring /proc/ccs/query interface. */
1254 static atomic_t ccs_query_observers = ATOMIC_INIT(0);
1255 
1256 /* Wait queue for /proc/ccs/audit. */
1257 static DECLARE_WAIT_QUEUE_HEAD(ccs_log_wait);
1258 
1259 /* The list for "struct ccs_log". */
1260 static LIST_HEAD(ccs_log);
1261 
1262 /* Lock for "struct list_head ccs_log". */
1263 static DEFINE_SPINLOCK(ccs_log_lock);
1264 
1265 /* Length of "struct list_head ccs_log". */
1266 static unsigned int ccs_log_count;
1267 
1268 /* Counter for number of updates. */
1269 static atomic_t ccs_stat_updated[CCS_MAX_POLICY_STAT];
1270 
1271 /* Timestamp counter for last updated. */
1272 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
1273 static unsigned int ccs_stat_modified[CCS_MAX_POLICY_STAT];
1274 #else
1275 static time64_t ccs_stat_modified[CCS_MAX_POLICY_STAT];
1276 #endif
1277 
1278 /* Operations for /proc/ccs/self_domain interface. */
1279 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
1280 static const struct proc_ops ccs_self_operations = {
1281 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1282         .proc_write = ccs_write_self,
1283 #endif
1284         .proc_read  = ccs_read_self,
1285         .proc_lseek = default_llseek,
1286 };
1287 #else
1288 static
1289 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1290 const
1291 #endif
1292 struct file_operations ccs_self_operations = {
1293 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1294         .write = ccs_write_self,
1295 #endif
1296         .read  = ccs_read_self,
1297 };
1298 #endif
1299 
1300 /* Operations for /proc/ccs/ interface. */
1301 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
1302 static const struct proc_ops ccs_operations = {
1303         .proc_open    = ccs_open,
1304         .proc_release = ccs_release,
1305         .proc_poll    = ccs_poll,
1306         .proc_read    = ccs_read,
1307         .proc_write   = ccs_write,
1308         .proc_lseek   = default_llseek,
1309 };
1310 #else
1311 static
1312 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
1313 const
1314 #endif
1315 struct file_operations ccs_operations = {
1316         .open    = ccs_open,
1317         .release = ccs_release,
1318         .poll    = ccs_poll,
1319         .read    = ccs_read,
1320         .write   = ccs_write,
1321 };
1322 #endif
1323 
1324 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
1325 
1326 /* The inode operations for /proc/ccs/ directory. */
1327 static struct inode_operations ccs_dir_inode_operations;
1328 
1329 /* The inode operations for files under /proc/ccs/ directory. */
1330 static struct inode_operations ccs_file_inode_operations;
1331 
1332 #endif
1333 
1334 /***** SECTION6: Dependent functions section *****/
1335 
1336 /**
1337  * list_for_each_cookie - iterate over a list with cookie.
1338  *
1339  * @pos:  Pointer to "struct list_head".
1340  * @head: Pointer to "struct list_head".
1341  */
1342 #define list_for_each_cookie(pos, head)                                 \
1343         for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \
1344              pos != (head); pos = srcu_dereference(pos->next, &ccs_ss))
1345 
1346 /**
1347  * ccs_read_token - Read a word from a line.
1348  *
1349  * @param: Pointer to "struct ccs_acl_param".
1350  *
1351  * Returns a word on success, "" otherwise.
1352  *
1353  * To allow the caller to skip NULL check, this function returns "" rather than
1354  * NULL if there is no more words to read.
1355  */
1356 static char *ccs_read_token(struct ccs_acl_param *param)
1357 {
1358         char *pos = param->data;
1359         char *del = strchr(pos, ' ');
1360         if (del)
1361                 *del++ = '\0';
1362         else
1363                 del = pos + strlen(pos);
1364         param->data = del;
1365         return pos;
1366 }
1367 
1368 /**
1369  * ccs_make_byte - Make byte value from three octal characters.
1370  *
1371  * @c1: The first character.
1372  * @c2: The second character.
1373  * @c3: The third character.
1374  *
1375  * Returns byte value.
1376  */
1377 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3)
1378 {
1379         return ((c1 - '') << 6) + ((c2 - '') << 3) + (c3 - '');
1380 }
1381 
1382 /**
1383  * ccs_correct_word2 - Check whether the given string follows the naming rules.
1384  *
1385  * @string: The byte sequence to check. Not '\0'-terminated.
1386  * @len:    Length of @string.
1387  *
1388  * Returns true if @string follows the naming rules, false otherwise.
1389  */
1390 static bool ccs_correct_word2(const char *string, size_t len)
1391 {
1392         u8 recursion = 20;
1393         const char *const start = string;
1394         bool in_repetition = false;
1395         if (!len)
1396                 goto out;
1397         while (len--) {
1398                 unsigned char c = *string++;
1399                 if (c == '\\') {
1400                         if (!len--)
1401                                 goto out;
1402                         c = *string++;
1403                         if (c >= '' && c <= '3') {
1404                                 unsigned char d;
1405                                 unsigned char e;
1406                                 if (!len-- || !len--)
1407                                         goto out;
1408                                 d = *string++;
1409                                 e = *string++;
1410                                 if (d < '' || d > '7' || e < '' || e > '7')
1411                                         goto out;
1412                                 c = ccs_make_byte(c, d, e);
1413                                 if (c <= ' ' || c >= 127)
1414                                         continue;
1415                                 goto out;
1416                         }
1417                         switch (c) {
1418                         case '\\':  /* "\\" */
1419                         case '+':   /* "\+" */
1420                         case '?':   /* "\?" */
1421                         case 'x':   /* "\x" */
1422                         case 'a':   /* "\a" */
1423                         case '-':   /* "\-" */
1424                                 continue;
1425                         }
1426                         if (!recursion--)
1427                                 goto out;
1428                         switch (c) {
1429                         case '*':   /* "\*" */
1430                         case '@':   /* "\@" */
1431                         case '$':   /* "\$" */
1432                         case 'X':   /* "\X" */
1433                         case 'A':   /* "\A" */
1434                                 continue;
1435                         case '{':   /* "/\{" */
1436                                 if (string - 3 < start || *(string - 3) != '/')
1437                                         goto out;
1438                                 in_repetition = true;
1439                                 continue;
1440                         case '}':   /* "\}/" */
1441                                 if (*string != '/')
1442                                         goto out;
1443                                 if (!in_repetition)
1444                                         goto out;
1445                                 in_repetition = false;
1446                                 continue;
1447                         }
1448                         goto out;
1449                 } else if (in_repetition && c == '/') {
1450                         goto out;
1451                 } else if (c <= ' ' || c >= 127) {
1452                         goto out;
1453                 }
1454         }
1455         if (in_repetition)
1456                 goto out;
1457         return true;
1458 out:
1459         return false;
1460 }
1461 
1462 /**
1463  * ccs_correct_word - Check whether the given string follows the naming rules.
1464  *
1465  * @string: The string to check.
1466  *
1467  * Returns true if @string follows the naming rules, false otherwise.
1468  */
1469 static bool ccs_correct_word(const char *string)
1470 {
1471         return ccs_correct_word2(string, strlen(string));
1472 }
1473 
1474 /**
1475  * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group".
1476  *
1477  * @param: Pointer to "struct ccs_acl_param".
1478  * @idx:   Index number.
1479  *
1480  * Returns pointer to "struct ccs_group" on success, NULL otherwise.
1481  */
1482 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
1483                                        const u8 idx)
1484 {
1485         struct ccs_group e = { };
1486         struct ccs_group *group = NULL;
1487         struct list_head *list;
1488         const char *group_name = ccs_read_token(param);
1489         bool found = false;
1490         if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
1491                 return NULL;
1492         e.group_name = ccs_get_name(group_name);
1493         if (!e.group_name)
1494                 return NULL;
1495         if (mutex_lock_interruptible(&ccs_policy_lock))
1496                 goto out;
1497         list = &param->ns->group_list[idx];
1498         list_for_each_entry(group, list, head.list) {
1499                 if (e.group_name != group->group_name ||
1500                     atomic_read(&group->head.users) == CCS_GC_IN_PROGRESS)
1501                         continue;
1502                 atomic_inc(&group->head.users);
1503                 found = true;
1504                 break;
1505         }
1506         if (!found) {
1507                 struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e));
1508                 if (entry) {
1509                         INIT_LIST_HEAD(&entry->member_list);
1510                         atomic_set(&entry->head.users, 1);
1511                         list_add_tail_rcu(&entry->head.list, list);
1512                         group = entry;
1513                         found = true;
1514                 }
1515         }
1516         mutex_unlock(&ccs_policy_lock);
1517 out:
1518         ccs_put_name(e.group_name);
1519         return found ? group : NULL;
1520 }
1521 
1522 /**
1523  * ccs_parse_name_union - Parse a ccs_name_union.
1524  *
1525  * @param: Pointer to "struct ccs_acl_param".
1526  * @ptr:   Pointer to "struct ccs_name_union".
1527  *
1528  * Returns true on success, false otherwise.
1529  */
1530 static bool ccs_parse_name_union(struct ccs_acl_param *param,
1531                                  struct ccs_name_union *ptr)
1532 {
1533         char *filename;
1534         if (param->data[0] == '@') {
1535                 param->data++;
1536                 ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
1537                 return ptr->group != NULL;
1538         }
1539         filename = ccs_read_token(param);
1540         if (!ccs_correct_word(filename))
1541                 return false;
1542         ptr->filename = ccs_get_name(filename);
1543         return ptr->filename != NULL;
1544 }
1545 
1546 /**
1547  * ccs_parse_ulong - Parse an "unsigned long" value.
1548  *
1549  * @result: Pointer to "unsigned long".
1550  * @str:    Pointer to string to parse.
1551  *
1552  * Returns one of values in "enum ccs_value_type".
1553  *
1554  * The @src is updated to point the first character after the value
1555  * on success.
1556  */
1557 static u8 ccs_parse_ulong(unsigned long *result, char **str)
1558 {
1559         const char *cp = *str;
1560         char *ep;
1561         int base = 10;
1562         if (*cp == '') {
1563                 char c = *(cp + 1);
1564                 if (c == 'x' || c == 'X') {
1565                         base = 16;
1566                         cp += 2;
1567                 } else if (c >= '' && c <= '7') {
1568                         base = 8;
1569                         cp++;
1570                 }
1571         }
1572         *result = simple_strtoul(cp, &ep, base);
1573         if (cp == ep)
1574                 return CCS_VALUE_TYPE_INVALID;
1575         *str = ep;
1576         switch (base) {
1577         case 16:
1578                 return CCS_VALUE_TYPE_HEXADECIMAL;
1579         case 8:
1580                 return CCS_VALUE_TYPE_OCTAL;
1581         default:
1582                 return CCS_VALUE_TYPE_DECIMAL;
1583         }
1584 }
1585 
1586 /**
1587  * ccs_parse_number_union - Parse a ccs_number_union.
1588  *
1589  * @param: Pointer to "struct ccs_acl_param".
1590  * @ptr:   Pointer to "struct ccs_number_union".
1591  *
1592  * Returns true on success, false otherwise.
1593  */
1594 static bool ccs_parse_number_union(struct ccs_acl_param *param,
1595                                    struct ccs_number_union *ptr)
1596 {
1597         char *data;
1598         u8 type;
1599         unsigned long v;
1600         memset(ptr, 0, sizeof(*ptr));
1601         if (param->data[0] == '@') {
1602                 param->data++;
1603                 ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
1604                 return ptr->group != NULL;
1605         }
1606         data = ccs_read_token(param);
1607         type = ccs_parse_ulong(&v, &data);
1608         if (type == CCS_VALUE_TYPE_INVALID)
1609                 return false;
1610         ptr->values[0] = v;
1611         ptr->value_type[0] = type;
1612         if (!*data) {
1613                 ptr->values[1] = v;
1614                 ptr->value_type[1] = type;
1615                 return true;
1616         }
1617         if (*data++ != '-')
1618                 return false;
1619         type = ccs_parse_ulong(&v, &data);
1620         if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
1621                 return false;
1622         ptr->values[1] = v;
1623         ptr->value_type[1] = type;
1624         return true;
1625 }
1626 
1627 #ifdef CONFIG_CCSECURITY_NETWORK
1628 
1629 /**
1630  * ccs_parse_ipaddr_union - Parse an IP address.
1631  *
1632  * @param: Pointer to "struct ccs_acl_param".
1633  * @ptr:   Pointer to "struct ccs_ipaddr_union".
1634  *
1635  * Returns true on success, false otherwise.
1636  */
1637 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
1638                                    struct ccs_ipaddr_union *ptr)
1639 {
1640         u8 * const min = ptr->ip[0].in6_u.u6_addr8;
1641         u8 * const max = ptr->ip[1].in6_u.u6_addr8;
1642         char *address = ccs_read_token(param);
1643         const char *end;
1644         if (!strchr(address, ':') &&
1645             ccs_in4_pton(address, -1, min, '-', &end) > 0) {
1646                 ptr->is_ipv6 = false;
1647                 if (!*end)
1648                         ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
1649                 else if (*end++ != '-' ||
1650                          ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
1651                         return false;
1652                 return true;
1653         }
1654         if (ccs_in6_pton(address, -1, min, '-', &end) > 0) {
1655                 ptr->is_ipv6 = true;
1656                 if (!*end)
1657                         memmove(max, min, sizeof(u16) * 8);
1658                 else if (*end++ != '-' ||
1659                          ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
1660                         return false;
1661                 return true;
1662         }
1663         return false;
1664 }
1665 
1666 #endif
1667 
1668 /**
1669  * ccs_get_dqword - ccs_get_name() for a quoted string.
1670  *
1671  * @start: String to save.
1672  *
1673  * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
1674  */
1675 static const struct ccs_path_info *ccs_get_dqword(char *start)
1676 {
1677         char *cp = start + strlen(start) - 1;
1678         if (cp == start || *start++ != '"' || *cp != '"')
1679                 return NULL;
1680         *cp = '\0';
1681         if (*start && !ccs_correct_word(start))
1682                 return NULL;
1683         return ccs_get_name(start);
1684 }
1685 
1686 /**
1687  * ccs_parse_name_union_quoted - Parse a quoted word.
1688  *
1689  * @param: Pointer to "struct ccs_acl_param".
1690  * @ptr:   Pointer to "struct ccs_name_union".
1691  *
1692  * Returns true on success, false otherwise.
1693  */
1694 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
1695                                         struct ccs_name_union *ptr)
1696 {
1697         char *filename = param->data;
1698         if (*filename == '@')
1699                 return ccs_parse_name_union(param, ptr);
1700         ptr->filename = ccs_get_dqword(filename);
1701         return ptr->filename != NULL;
1702 }
1703 
1704 /**
1705  * ccs_parse_argv - Parse an argv[] condition part.
1706  *
1707  * @left:  Lefthand value.
1708  * @right: Righthand value.
1709  * @argv:  Pointer to "struct ccs_argv".
1710  *
1711  * Returns true on success, false otherwise.
1712  */
1713 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
1714 {
1715         if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL ||
1716             *left++ != ']' || *left)
1717                 return false;
1718         argv->value = ccs_get_dqword(right);
1719         return argv->value != NULL;
1720 }
1721 
1722 /**
1723  * ccs_parse_envp - Parse an envp[] condition part.
1724  *
1725  * @left:  Lefthand value.
1726  * @right: Righthand value.
1727  * @envp:  Pointer to "struct ccs_envp".
1728  *
1729  * Returns true on success, false otherwise.
1730  */
1731 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
1732 {
1733         const struct ccs_path_info *name;
1734         const struct ccs_path_info *value;
1735         char *cp = left + strlen(left) - 1;
1736         if (*cp-- != ']' || *cp != '"')
1737                 goto out;
1738         *cp = '\0';
1739         if (!ccs_correct_word(left))
1740                 goto out;
1741         name = ccs_get_name(left);
1742         if (!name)
1743                 goto out;
1744         if (!strcmp(right, "NULL")) {
1745                 value = NULL;
1746         } else {
1747                 value = ccs_get_dqword(right);
1748                 if (!value) {
1749                         ccs_put_name(name);
1750                         goto out;
1751                 }
1752         }
1753         envp->name = name;
1754         envp->value = value;
1755         return true;
1756 out:
1757         return false;
1758 }
1759 
1760 /**
1761  * ccs_same_condition - Check for duplicated "struct ccs_condition" entry.
1762  *
1763  * @a: Pointer to "struct ccs_condition".
1764  * @b: Pointer to "struct ccs_condition".
1765  *
1766  * Returns true if @a == @b, false otherwise.
1767  */
1768 static bool ccs_same_condition(const struct ccs_condition *a,
1769                                const struct ccs_condition *b)
1770 {
1771         return a->size == b->size && a->condc == b->condc &&
1772                 a->numbers_count == b->numbers_count &&
1773                 a->names_count == b->names_count &&
1774                 a->argc == b->argc && a->envc == b->envc &&
1775                 a->grant_log == b->grant_log &&
1776                 a->exec_transit == b->exec_transit && a->transit == b->transit
1777                 && !memcmp(a + 1, b + 1, a->size - sizeof(*a));
1778 }
1779 
1780 /**
1781  * ccs_condition_type - Get condition type.
1782  *
1783  * @word: Keyword string.
1784  *
1785  * Returns one of values in "enum ccs_conditions_index" on success,
1786  * CCS_MAX_CONDITION_KEYWORD otherwise.
1787  */
1788 static u8 ccs_condition_type(const char *word)
1789 {
1790         u8 i;
1791         for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) {
1792                 if (!strcmp(word, ccs_condition_keyword[i]))
1793                         break;
1794         }
1795         return i;
1796 }
1797 
1798 /**
1799  * ccs_commit_condition - Commit "struct ccs_condition".
1800  *
1801  * @entry: Pointer to "struct ccs_condition".
1802  *
1803  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
1804  *
1805  * This function merges duplicated entries. This function returns NULL if
1806  * @entry is not duplicated but memory quota for policy has exceeded.
1807  */
1808 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry)
1809 {
1810         struct ccs_condition *ptr;
1811         bool found = false;
1812         if (mutex_lock_interruptible(&ccs_policy_lock)) {
1813                 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
1814                 ptr = NULL;
1815                 found = true;
1816                 goto out;
1817         }
1818         list_for_each_entry(ptr, &ccs_condition_list, head.list) {
1819                 if (!ccs_same_condition(ptr, entry) ||
1820                     atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS)
1821                         continue;
1822                 /* Same entry found. Share this entry. */
1823                 atomic_inc(&ptr->head.users);
1824                 found = true;
1825                 break;
1826         }
1827         if (!found) {
1828                 if (ccs_memory_ok(entry, entry->size)) {
1829                         atomic_set(&entry->head.users, 1);
1830                         list_add(&entry->head.list, &ccs_condition_list);
1831                 } else {
1832                         found = true;
1833                         ptr = NULL;
1834                 }
1835         }
1836         mutex_unlock(&ccs_policy_lock);
1837 out:
1838         if (found) {
1839                 ccs_del_condition(&entry->head.list);
1840                 kfree(entry);
1841                 entry = ptr;
1842         }
1843         return entry;
1844 }
1845 
1846 /**
1847  * ccs_correct_path2 - Check whether the given pathname follows the naming rules.
1848  *
1849  * @filename: The pathname to check.
1850  * @len:      Length of @filename.
1851  *
1852  * Returns true if @filename follows the naming rules, false otherwise.
1853  */
1854 static bool ccs_correct_path2(const char *filename, const size_t len)
1855 {
1856         const char *cp1 = memchr(filename, '/', len);
1857         const char *cp2 = memchr(filename, '.', len);
1858         return cp1 && (!cp2 || (cp1 < cp2)) && ccs_correct_word2(filename, len)
1859                 && (len < 24 ||
1860                     memcmp(filename, "auto_domain_transition=\"", 24));
1861 }
1862 
1863 /**
1864  * ccs_correct_path - Check whether the given pathname follows the naming rules.
1865  *
1866  * @filename: The pathname to check.
1867  *
1868  * Returns true if @filename follows the naming rules, false otherwise.
1869  */
1870 static bool ccs_correct_path(const char *filename)
1871 {
1872         return ccs_correct_path2(filename, strlen(filename));
1873 }
1874 
1875 /**
1876  * ccs_domain_def - Check whether the given token can be a domainname.
1877  *
1878  * @buffer: The token to check.
1879  *
1880  * Returns true if @buffer possibly be a domainname, false otherwise.
1881  */
1882 static bool ccs_domain_def(const unsigned char *buffer)
1883 {
1884         const unsigned char *cp;
1885         int len;
1886         if (*buffer != '<')
1887                 return false;
1888         cp = strchr(buffer, ' ');
1889         if (!cp)
1890                 len = strlen(buffer);
1891         else
1892                 len = cp - buffer;
1893         if (buffer[len - 1] != '>' || !ccs_correct_word2(buffer + 1, len - 2))
1894                 return false;
1895         return true;
1896 }
1897 
1898 /**
1899  * ccs_correct_domain - Check whether the given domainname follows the naming rules.
1900  *
1901  * @domainname: The domainname to check.
1902  *
1903  * Returns true if @domainname follows the naming rules, false otherwise.
1904  */
1905 static bool ccs_correct_domain(const char *domainname)
1906 {
1907         if (!domainname || !ccs_domain_def(domainname))
1908                 return false;
1909         domainname = strchr(domainname, ' ');
1910         if (!domainname++)
1911                 return true;
1912         while (1) {
1913                 const char *cp = strchr(domainname, ' ');
1914                 const int len = cp ? cp - domainname : strlen(domainname);
1915                 if (len == 0)
1916                         return true;
1917                 if (!ccs_correct_path2(domainname, len))
1918                         return false;
1919                 if (!cp)
1920                         return true;
1921                 domainname += len + 1;
1922         }
1923 }
1924 
1925 /**
1926  * ccs_normalize_line - Format string.
1927  *
1928  * @buffer: The line to normalize.
1929  *
1930  * Returns nothing.
1931  *
1932  * Leading and trailing whitespaces are removed.
1933  * Multiple whitespaces are packed into single space.
1934  */
1935 static void ccs_normalize_line(unsigned char *buffer)
1936 {
1937         unsigned char *sp = buffer;
1938         unsigned char *dp = buffer;
1939         bool first = true;
1940         while (*sp && (*sp <= ' ' || *sp >= 127))
1941                 sp++;
1942         while (*sp) {
1943                 if (!first)
1944                         *dp++ = ' ';
1945                 first = false;
1946                 while (*sp > ' ' && *sp < 127)
1947                         *dp++ = *sp++;
1948                 while (*sp && (*sp <= ' ' || *sp >= 127))
1949                         sp++;
1950         }
1951         *dp = '\0';
1952 }
1953 
1954 /**
1955  * ccs_get_domainname - Read a domainname from a line.
1956  *
1957  * @param: Pointer to "struct ccs_acl_param".
1958  *
1959  * Returns a domainname on success, NULL otherwise.
1960  */
1961 static const struct ccs_path_info *ccs_get_domainname
1962 (struct ccs_acl_param *param)
1963 {
1964         char *start = param->data;
1965         char *pos = start;
1966         while (*pos) {
1967                 char *cp;
1968                 size_t len;
1969                 if (*pos++ != ' ')
1970                         continue;
1971                 cp = strchr(pos, ' ');
1972                 len = cp ? cp - pos : strlen(pos);
1973                 if (ccs_correct_path2(pos, len))
1974                         continue;
1975                 *(pos - 1) = '\0';
1976                 break;
1977         }
1978         param->data = pos;
1979         if (ccs_correct_domain(start))
1980                 return ccs_get_name(start);
1981         return NULL;
1982 }
1983 
1984 /**
1985  * ccs_get_transit_preference - Parse domain transition preference for execve().
1986  *
1987  * @param: Pointer to "struct ccs_acl_param".
1988  * @e:     Pointer to "struct ccs_condition".
1989  *
1990  * Returns the condition string part.
1991  */
1992 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
1993                                         struct ccs_condition *e)
1994 {
1995         char * const pos = param->data;
1996         bool flag;
1997         if (*pos == '<') {
1998                 e->transit = ccs_get_domainname(param);
1999                 goto done;
2000         }
2001         {
2002                 char *cp = strchr(pos, ' ');
2003                 if (cp)
2004                         *cp = '\0';
2005                 flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
2006                         !strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
2007                         !strcmp(pos, "child") || !strcmp(pos, "parent");
2008                 if (cp)
2009                         *cp = ' ';
2010         }
2011         if (!flag)
2012                 return pos;
2013         e->transit = ccs_get_name(ccs_read_token(param));
2014 done:
2015         if (e->transit) {
2016                 e->exec_transit = true;
2017                 return param->data;
2018         }
2019         /*
2020          * Return a bad read-only condition string that will let
2021          * ccs_get_condition() return NULL.
2022          */
2023         return "/";
2024 }
2025 
2026 /**
2027  * ccs_get_condition - Parse condition part.
2028  *
2029  * @param: Pointer to "struct ccs_acl_param".
2030  * @pref:  Can include domain transition preference?
2031  *
2032  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
2033  */
2034 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param,
2035                                                const bool pref)
2036 {
2037         struct ccs_condition *entry = NULL;
2038         struct ccs_condition_element *condp = NULL;
2039         struct ccs_number_union *numbers_p = NULL;
2040         struct ccs_name_union *names_p = NULL;
2041         struct ccs_argv *argv = NULL;
2042         struct ccs_envp *envp = NULL;
2043         struct ccs_condition e = { };
2044         char * const start_of_string = pref ?
2045                 ccs_get_transit_preference(param, &e) : param->data;
2046         char * const end_of_string = start_of_string + strlen(start_of_string);
2047         char *pos;
2048 rerun:
2049         pos = start_of_string;
2050         while (1) {
2051                 u8 left = -1;
2052                 u8 right = -1;
2053                 char *left_word = pos;
2054                 char *cp;
2055                 char *right_word;
2056                 bool is_not;
2057                 if (!*left_word)
2058                         break;
2059                 /*
2060                  * Since left-hand condition does not allow use of "path_group"
2061                  * or "number_group" and environment variable's names do not
2062                  * accept '=', it is guaranteed that the original line consists
2063                  * of one or more repetition of $left$operator$right blocks
2064                  * where "$left is free from '=' and ' '" and "$operator is
2065                  * either '=' or '!='" and "$right is free from ' '".
2066                  * Therefore, we can reconstruct the original line at the end
2067                  * of dry run even if we overwrite $operator with '\0'.
2068                  */
2069                 cp = strchr(pos, ' ');
2070                 if (cp) {
2071                         *cp = '\0'; /* Will restore later. */
2072                         pos = cp + 1;
2073                 } else {
2074                         pos = "";
2075                 }
2076                 right_word = strchr(left_word, '=');
2077                 if (!right_word || right_word == left_word)
2078                         goto out;
2079                 is_not = *(right_word - 1) == '!';
2080                 if (is_not)
2081                         *(right_word++ - 1) = '\0'; /* Will restore later. */
2082                 else if (*(right_word + 1) != '=')
2083                         *right_word++ = '\0'; /* Will restore later. */
2084                 else
2085                         goto out;
2086                 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
2087                         is_not ? "!" : "", right_word);
2088                 if (!strcmp(left_word, "grant_log")) {
2089                         if (entry) {
2090                                 if (is_not ||
2091                                     entry->grant_log != CCS_GRANTLOG_AUTO)
2092                                         goto out;
2093                                 else if (!strcmp(right_word, "yes"))
2094                                         entry->grant_log = CCS_GRANTLOG_YES;
2095                                 else if (!strcmp(right_word, "no"))
2096                                         entry->grant_log = CCS_GRANTLOG_NO;
2097                                 else
2098                                         goto out;
2099                         }
2100                         continue;
2101                 }
2102                 if (!strcmp(left_word, "auto_domain_transition")) {
2103                         if (entry) {
2104                                 if (is_not || entry->transit)
2105                                         goto out;
2106                                 entry->transit = ccs_get_dqword(right_word);
2107                                 if (!entry->transit ||
2108                                     (!ccs_correct_path(entry->transit->name) &&
2109                                      !ccs_domain_def(entry->transit->name)))
2110                                         goto out;
2111                         }
2112                         continue;
2113                 }
2114                 if (!strncmp(left_word, "exec.argv[", 10)) {
2115                         if (!argv) {
2116                                 e.argc++;
2117                                 e.condc++;
2118                         } else {
2119                                 e.argc--;
2120                                 e.condc--;
2121                                 left = CCS_ARGV_ENTRY;
2122                                 argv->is_not = is_not;
2123                                 if (!ccs_parse_argv(left_word + 10,
2124                                                     right_word, argv++))
2125                                         goto out;
2126                         }
2127                         goto store_value;
2128                 }
2129                 if (!strncmp(left_word, "exec.envp[\"", 11)) {
2130                         if (!envp) {
2131                                 e.envc++;
2132                                 e.condc++;
2133                         } else {
2134                                 e.envc--;
2135                                 e.condc--;
2136                                 left = CCS_ENVP_ENTRY;
2137                                 envp->is_not = is_not;
2138                                 if (!ccs_parse_envp(left_word + 11,
2139                                                     right_word, envp++))
2140                                         goto out;
2141                         }
2142                         goto store_value;
2143                 }
2144                 left = ccs_condition_type(left_word);
2145                 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
2146                         left);
2147                 if (left == CCS_MAX_CONDITION_KEYWORD) {
2148                         if (!numbers_p) {
2149                                 e.numbers_count++;
2150                         } else {
2151                                 e.numbers_count--;
2152                                 left = CCS_NUMBER_UNION;
2153                                 param->data = left_word;
2154                                 if (*left_word == '@' ||
2155                                     !ccs_parse_number_union(param,
2156                                                             numbers_p++))
2157                                         goto out;
2158                         }
2159                 }
2160                 if (!condp)
2161                         e.condc++;
2162                 else
2163                         e.condc--;
2164                 if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
2165                         if (!names_p) {
2166                                 e.names_count++;
2167                         } else {
2168                                 e.names_count--;
2169                                 right = CCS_NAME_UNION;
2170                                 param->data = right_word;
2171                                 if (!ccs_parse_name_union_quoted(param,
2172                                                                  names_p++))
2173                                         goto out;
2174                         }
2175                         goto store_value;
2176                 }
2177                 right = ccs_condition_type(right_word);
2178                 if (right == CCS_MAX_CONDITION_KEYWORD) {
2179                         if (!numbers_p) {
2180                                 e.numbers_count++;
2181                         } else {
2182                                 e.numbers_count--;
2183                                 right = CCS_NUMBER_UNION;
2184                                 param->data = right_word;
2185                                 if (!ccs_parse_number_union(param,
2186                                                             numbers_p++))
2187                                         goto out;
2188                         }
2189                 }
2190 store_value:
2191                 if (!condp) {
2192                         dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
2193                                 "match=%u\n", __LINE__, left, right, !is_not);
2194                         continue;
2195                 }
2196                 condp->left = left;
2197                 condp->right = right;
2198                 condp->equals = !is_not;
2199                 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
2200                         __LINE__, condp->left, condp->right,
2201                         condp->equals);
2202                 condp++;
2203         }
2204         dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
2205                 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
2206                 e.envc);
2207         if (entry) {
2208                 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc |
2209                        e.condc);
2210                 return ccs_commit_condition(entry);
2211         }
2212         e.size = sizeof(*entry)
2213                 + e.condc * sizeof(struct ccs_condition_element)
2214                 + e.numbers_count * sizeof(struct ccs_number_union)
2215                 + e.names_count * sizeof(struct ccs_name_union)
2216                 + e.argc * sizeof(struct ccs_argv)
2217                 + e.envc * sizeof(struct ccs_envp);
2218         entry = kzalloc(e.size, CCS_GFP_FLAGS);
2219         if (!entry)
2220                 goto out2;
2221         *entry = e;
2222         e.transit = NULL;
2223         condp = (struct ccs_condition_element *) (entry + 1);
2224         numbers_p = (struct ccs_number_union *) (condp + e.condc);
2225         names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
2226         argv = (struct ccs_argv *) (names_p + e.names_count);
2227         envp = (struct ccs_envp *) (argv + e.argc);
2228         {
2229                 bool flag = false;
2230                 for (pos = start_of_string; pos < end_of_string; pos++) {
2231                         if (*pos)
2232                                 continue;
2233                         if (flag) /* Restore " ". */
2234                                 *pos = ' ';
2235                         else if (*(pos + 1) == '=') /* Restore "!=". */
2236                                 *pos = '!';
2237                         else /* Restore "=". */
2238                                 *pos = '=';
2239                         flag = !flag;
2240                 }
2241         }
2242         goto rerun;
2243 out:
2244         dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
2245         if (entry) {
2246                 ccs_del_condition(&entry->head.list);
2247                 kfree(entry);
2248         }
2249 out2:
2250         ccs_put_name(e.transit);
2251         return NULL;
2252 }
2253 
2254 /**
2255  * ccs_yesno - Return "yes" or "no".
2256  *
2257  * @value: Bool value.
2258  *
2259  * Returns "yes" if @value is not 0, "no" otherwise.
2260  */
2261 static const char *ccs_yesno(const unsigned int value)
2262 {
2263         return value ? "yes" : "no";
2264 }
2265 
2266 /**
2267  * ccs_addprintf - strncat()-like-snprintf().
2268  *
2269  * @buffer: Buffer to write to. Must be '\0'-terminated.
2270  * @len:    Size of @buffer.
2271  * @fmt:    The printf()'s format string, followed by parameters.
2272  *
2273  * Returns nothing.
2274  */
2275 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...)
2276 {
2277         va_list args;
2278         const int pos = strlen(buffer);
2279         va_start(args, fmt);
2280         vsnprintf(buffer + pos, len - pos - 1, fmt, args);
2281         va_end(args);
2282 }
2283 
2284 /**
2285  * ccs_flush - Flush queued string to userspace's buffer.
2286  *
2287  * @head: Pointer to "struct ccs_io_buffer".
2288  *
2289  * Returns true if all data was flushed, false otherwise.
2290  */
2291 static bool ccs_flush(struct ccs_io_buffer *head)
2292 {
2293         while (head->r.w_pos) {
2294                 const char *w = head->r.w[0];
2295                 size_t len = strlen(w);
2296                 if (len) {
2297                         if (len > head->read_user_buf_avail)
2298                                 len = head->read_user_buf_avail;
2299                         if (!len)
2300                                 return false;
2301                         if (copy_to_user(head->read_user_buf, w, len))
2302                                 return false;
2303                         head->read_user_buf_avail -= len;
2304                         head->read_user_buf += len;
2305                         w += len;
2306                 }
2307                 head->r.w[0] = w;
2308                 if (*w)
2309                         return false;
2310                 /* Add '\0' for audit logs and query. */
2311                 if (head->type == CCS_AUDIT || head->type == CCS_QUERY) {
2312                         if (!head->read_user_buf_avail ||
2313                             copy_to_user(head->read_user_buf, "", 1))
2314                                 return false;
2315                         head->read_user_buf_avail--;
2316                         head->read_user_buf++;
2317                 }
2318                 head->r.w_pos--;
2319                 for (len = 0; len < head->r.w_pos; len++)
2320                         head->r.w[len] = head->r.w[len + 1];
2321         }
2322         head->r.avail = 0;
2323         return true;
2324 }
2325 
2326 /**
2327  * ccs_set_string - Queue string to "struct ccs_io_buffer" structure.
2328  *
2329  * @head:   Pointer to "struct ccs_io_buffer".
2330  * @string: String to print.
2331  *
2332  * Returns nothing.
2333  *
2334  * Note that @string has to be kept valid until @head is kfree()d.
2335  * This means that char[] allocated on stack memory cannot be passed to
2336  * this function. Use ccs_io_printf() for char[] allocated on stack memory.
2337  */
2338 static void ccs_set_string(struct ccs_io_buffer *head, const char *string)
2339 {
2340         if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) {
2341                 head->r.w[head->r.w_pos++] = string;
2342                 ccs_flush(head);
2343         } else
2344                 printk(KERN_WARNING "Too many words in a line.\n");
2345 }
2346 
2347 /**
2348  * ccs_io_printf - printf() to "struct ccs_io_buffer" structure.
2349  *
2350  * @head: Pointer to "struct ccs_io_buffer".
2351  * @fmt:  The printf()'s format string, followed by parameters.
2352  *
2353  * Returns nothing.
2354  */
2355 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
2356 {
2357         va_list args;
2358         size_t len;
2359         size_t pos = head->r.avail;
2360         int size = head->readbuf_size - pos;
2361         if (size <= 0)
2362                 return;
2363         va_start(args, fmt);
2364         len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
2365         va_end(args);
2366         if (pos + len >= head->readbuf_size) {
2367                 printk(KERN_WARNING "Too many words in a line.\n");
2368                 return;
2369         }
2370         head->r.avail += len;
2371         ccs_set_string(head, head->read_buf + pos);
2372 }
2373 
2374 /**
2375  * ccs_set_space - Put a space to "struct ccs_io_buffer" structure.
2376  *
2377  * @head: Pointer to "struct ccs_io_buffer".
2378  *
2379  * Returns nothing.
2380  */
2381 static void ccs_set_space(struct ccs_io_buffer *head)
2382 {
2383         ccs_set_string(head, " ");
2384 }
2385 
2386 /**
2387  * ccs_set_lf - Put a line feed to "struct ccs_io_buffer" structure.
2388  *
2389  * @head: Pointer to "struct ccs_io_buffer".
2390  *
2391  * Returns true if all data was flushed, false otherwise.
2392  */
2393 static bool ccs_set_lf(struct ccs_io_buffer *head)
2394 {
2395         ccs_set_string(head, "\n");
2396         return !head->r.w_pos;
2397 }
2398 
2399 /**
2400  * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure.
2401  *
2402  * @head: Pointer to "struct ccs_io_buffer".
2403  *
2404  * Returns nothing.
2405  */
2406 static void ccs_set_slash(struct ccs_io_buffer *head)
2407 {
2408         ccs_set_string(head, "/");
2409 }
2410 
2411 /**
2412  * ccs_init_policy_namespace - Initialize namespace.
2413  *
2414  * @ns: Pointer to "struct ccs_policy_namespace".
2415  *
2416  * Returns nothing.
2417  */
2418 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
2419 {
2420         unsigned int idx;
2421         for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++)
2422                 INIT_LIST_HEAD(&ns->acl_group[idx]);
2423         for (idx = 0; idx < CCS_MAX_GROUP; idx++)
2424                 INIT_LIST_HEAD(&ns->group_list[idx]);
2425         for (idx = 0; idx < CCS_MAX_POLICY; idx++)
2426                 INIT_LIST_HEAD(&ns->policy_list[idx]);
2427         ns->profile_version = 20200505;
2428         ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
2429         list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list);
2430 }
2431 
2432 /**
2433  * ccs_print_namespace - Print namespace header.
2434  *
2435  * @head: Pointer to "struct ccs_io_buffer".
2436  *
2437  * Returns nothing.
2438  */
2439 static void ccs_print_namespace(struct ccs_io_buffer *head)
2440 {
2441         if (!ccs_namespace_enabled)
2442                 return;
2443         ccs_set_string(head,
2444                        container_of(head->r.ns, struct ccs_policy_namespace,
2445                                     namespace_list)->name);
2446         ccs_set_space(head);
2447 }
2448 
2449 /**
2450  * ccs_assign_profile - Create a new profile.
2451  *
2452  * @ns:      Pointer to "struct ccs_policy_namespace".
2453  * @profile: Profile number to create.
2454  *
2455  * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
2456  */
2457 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
2458                                               const unsigned int profile)
2459 {
2460         struct ccs_profile *ptr;
2461         struct ccs_profile *entry;
2462         if (profile >= CCS_MAX_PROFILES)
2463                 return NULL;
2464         ptr = ns->profile_ptr[profile];
2465         if (ptr)
2466                 return ptr;
2467         entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
2468         if (mutex_lock_interruptible(&ccs_policy_lock))
2469                 goto out;
2470         ptr = ns->profile_ptr[profile];
2471         if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
2472                 ptr = entry;
2473                 ptr->default_config = CCS_CONFIG_DISABLED |
2474                         CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
2475                 memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
2476                        sizeof(ptr->config));
2477                 ptr->pref[CCS_PREF_MAX_AUDIT_LOG] =
2478                         CONFIG_CCSECURITY_MAX_AUDIT_LOG;
2479                 ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] =
2480                         CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY;
2481                 mb(); /* Avoid out-of-order execution. */
2482                 ns->profile_ptr[profile] = ptr;
2483                 entry = NULL;
2484         }
2485         mutex_unlock(&ccs_policy_lock);
2486 out:
2487         kfree(entry);
2488         return ptr;
2489 }
2490 
2491 /**
2492  * ccs_check_profile - Check all profiles currently assigned to domains are defined.
2493  *
2494  * Returns nothing.
2495  */
2496 static void ccs_check_profile(void)
2497 {
2498         struct ccs_domain_info *domain;
2499         const int idx = ccs_read_lock();
2500         ccs_policy_loaded = true;
2501         printk(KERN_INFO "CCSecurity: 1.8.11   2024/07/15\n");
2502         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
2503                 const u8 profile = domain->profile;
2504                 struct ccs_policy_namespace *ns = domain->ns;
2505                 if (ns->profile_version == 20100903 ||
2506                     ns->profile_version == 20150505) {
2507                         static bool done;
2508                         if (!done)
2509                                 printk(KERN_INFO "Converting profile version "
2510                                        "from %u to %u.\n", ns->profile_version,
2511                                        20200505);
2512                         done = true;
2513                         ns->profile_version = 20200505;
2514                 }
2515                 if (ns->profile_version != 20200505)
2516                         printk(KERN_ERR
2517                                "Profile version %u is not supported.\n",
2518                                ns->profile_version);
2519                 else if (!ns->profile_ptr[profile])
2520                         printk(KERN_ERR
2521                                "Profile %u (used by '%s') is not defined.\n",
2522                                profile, domain->domainname->name);
2523                 else
2524                         continue;
2525                 printk(KERN_ERR
2526                        "Userland tools for TOMOYO 1.8 must be installed and "
2527                        "policy must be initialized.\n");
2528                 printk(KERN_ERR "Please see https://tomoyo.sourceforge.net/1.8/ "
2529                        "for more information.\n");
2530                 panic("STOP!");
2531         }
2532         ccs_read_unlock(idx);
2533         printk(KERN_INFO "Mandatory Access Control activated.\n");
2534 }
2535 
2536 /**
2537  * ccs_profile - Find a profile.
2538  *
2539  * @profile: Profile number to find.
2540  *
2541  * Returns pointer to "struct ccs_profile".
2542  */
2543 static struct ccs_profile *ccs_profile(const u8 profile)
2544 {
2545         static struct ccs_profile ccs_null_profile;
2546         struct ccs_profile *ptr = ccs_current_namespace()->
2547                 profile_ptr[profile];
2548         if (!ptr)
2549                 ptr = &ccs_null_profile;
2550         return ptr;
2551 }
2552 
2553 /**
2554  * ccs_get_config - Get config for specified profile's specified functionality.
2555  *
2556  * @profile: Profile number.
2557  * @index:   Index number of functionality.
2558  *
2559  * Returns config.
2560  *
2561  * First, check for CONFIG::category::functionality.
2562  * If CONFIG::category::functionality is set to use default, then check
2563  * CONFIG::category. If CONFIG::category is set to use default, then use
2564  * CONFIG. CONFIG cannot be set to use default.
2565  */
2566 u8 ccs_get_config(const u8 profile, const u8 index)
2567 {
2568         u8 config;
2569         const struct ccs_profile *p;
2570         if (!ccs_policy_loaded)
2571                 return CCS_CONFIG_DISABLED;
2572         p = ccs_profile(profile);
2573         config = p->config[index];
2574         if (config == CCS_CONFIG_USE_DEFAULT)
2575                 config = p->config[ccs_index2category[index]
2576                                    + CCS_MAX_MAC_INDEX];
2577         if (config == CCS_CONFIG_USE_DEFAULT)
2578                 config = p->default_config;
2579         return config;
2580 }
2581 
2582 /**
2583  * ccs_find_yesno - Find values for specified keyword.
2584  *
2585  * @string: String to check.
2586  * @find:   Name of keyword.
2587  *
2588  * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
2589  */
2590 static s8 ccs_find_yesno(const char *string, const char *find)
2591 {
2592         const char *cp = strstr(string, find);
2593         if (cp) {
2594                 cp += strlen(find);
2595                 if (!strncmp(cp, "=yes", 4))
2596                         return 1;
2597                 else if (!strncmp(cp, "=no", 3))
2598                         return 0;
2599         }
2600         return -1;
2601 }
2602 
2603 /**
2604  * ccs_set_uint - Set value for specified preference.
2605  *
2606  * @i:      Pointer to "unsigned int".
2607  * @string: String to check.
2608  * @find:   Name of keyword.
2609  *
2610  * Returns nothing.
2611  */
2612 static void ccs_set_uint(unsigned int *i, const char *string, const char *find)
2613 {
2614         const char *cp = strstr(string, find);
2615         if (cp)
2616                 sscanf(cp + strlen(find), "=%u", i);
2617 }
2618 
2619 /**
2620  * ccs_str_starts - Check whether the given string starts with the given keyword.
2621  *
2622  * @src:  Pointer to pointer to the string.
2623  * @find: Pointer to the keyword.
2624  *
2625  * Returns true if @src starts with @find, false otherwise.
2626  *
2627  * The @src is updated to point the first character after the @find
2628  * if @src starts with @find.
2629  */
2630 static bool ccs_str_starts(char **src, const char *find)
2631 {
2632         const int len = strlen(find);
2633         char *tmp = *src;
2634         if (strncmp(tmp, find, len))
2635                 return false;
2636         tmp += len;
2637         *src = tmp;
2638         return true;
2639 }
2640 
2641 /**
2642  * ccs_print_group - Print group's name.
2643  *
2644  * @head:  Pointer to "struct ccs_io_buffer".
2645  * @group: Pointer to "struct ccsgroup". Maybe NULL.
2646  *
2647  * Returns true if @group is not NULL. false otherwise.
2648  */
2649 static bool ccs_print_group(struct ccs_io_buffer *head,
2650                             const struct ccs_group *group)
2651 {
2652         if (group) {
2653                 ccs_set_string(head, "@");
2654                 ccs_set_string(head, group->group_name->name);
2655                 return true;
2656         }
2657         return false;
2658 }
2659 
2660 /**
2661  * ccs_set_mode - Set mode for specified profile.
2662  *
2663  * @name:    Name of functionality.
2664  * @value:   Mode for @name.
2665  * @profile: Pointer to "struct ccs_profile".
2666  *
2667  * Returns 0 on success, negative value otherwise.
2668  */
2669 static int ccs_set_mode(char *name, const char *value,
2670                         struct ccs_profile *profile)
2671 {
2672         u8 i;
2673         u8 config;
2674         if (!strcmp(name, "CONFIG")) {
2675                 i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
2676                 config = profile->default_config;
2677         } else if (ccs_str_starts(&name, "CONFIG::")) {
2678                 config = 0;
2679                 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
2680                      i++) {
2681                         int len = 0;
2682                         if (i < CCS_MAX_MAC_INDEX) {
2683                                 const u8 c = ccs_index2category[i];
2684                                 const char *category =
2685                                         ccs_category_keywords[c];
2686                                 len = strlen(category);
2687                                 if (strncmp(name, category, len) ||
2688                                     name[len++] != ':' || name[len++] != ':')
2689                                         continue;
2690                         }
2691                         if (strcmp(name + len, ccs_mac_keywords[i]))
2692                                 continue;
2693                         config = profile->config[i];
2694                         break;
2695                 }
2696                 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
2697                         return -EINVAL;
2698         } else {
2699                 return -EINVAL;
2700         }
2701         if (strstr(value, "use_default")) {
2702                 config = CCS_CONFIG_USE_DEFAULT;
2703         } else {
2704                 u8 mode;
2705                 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
2706                         if (strstr(value, ccs_mode[mode]))
2707                                 /*
2708                                  * Update lower 3 bits in order to distinguish
2709                                  * 'config' from 'CCS_CONFIG_USE_DEFAULT'.
2710                                  */
2711                                 config = (config & ~7) | mode;
2712                 if (config != CCS_CONFIG_USE_DEFAULT) {
2713                         switch (ccs_find_yesno(value, "grant_log")) {
2714                         case 1:
2715                                 config |= CCS_CONFIG_WANT_GRANT_LOG;
2716                                 break;
2717                         case 0:
2718                                 config &= ~CCS_CONFIG_WANT_GRANT_LOG;
2719                                 break;
2720                         }
2721                         switch (ccs_find_yesno(value, "reject_log")) {
2722                         case 1:
2723                                 config |= CCS_CONFIG_WANT_REJECT_LOG;
2724                                 break;
2725                         case 0:
2726                                 config &= ~CCS_CONFIG_WANT_REJECT_LOG;
2727                                 break;
2728                         }
2729                 }
2730         }
2731         if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX)
2732                 profile->config[i] = config;
2733         else if (config != CCS_CONFIG_USE_DEFAULT)
2734                 profile->default_config = config;
2735         return 0;
2736 }
2737 
2738 /**
2739  * ccs_write_profile - Write profile table.
2740  *
2741  * @head: Pointer to "struct ccs_io_buffer".
2742  *
2743  * Returns 0 on success, negative value otherwise.
2744  */
2745 static int ccs_write_profile(struct ccs_io_buffer *head)
2746 {
2747         char *data = head->write_buf;
2748         unsigned int i;
2749         char *cp;
2750         struct ccs_profile *profile;
2751         if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
2752             == 1)
2753                 return 0;
2754         i = simple_strtoul(data, &cp, 10);
2755         if (*cp != '-')
2756                 return -EINVAL;
2757         data = cp + 1;
2758         profile = ccs_assign_profile(head->w.ns, i);
2759         if (!profile)
2760                 return -EINVAL;
2761         cp = strchr(data, '=');
2762         if (!cp)
2763                 return -EINVAL;
2764         *cp++ = '\0';
2765         if (!strcmp(data, "COMMENT")) {
2766                 static DEFINE_SPINLOCK(lock);
2767                 const struct ccs_path_info *new_comment = ccs_get_name(cp);
2768                 const struct ccs_path_info *old_comment;
2769                 if (!new_comment)
2770                         return -ENOMEM;
2771                 spin_lock(&lock);
2772                 old_comment = profile->comment;
2773                 profile->comment = new_comment;
2774                 spin_unlock(&lock);
2775                 ccs_put_name(old_comment);
2776                 return 0;
2777         }
2778         if (!strcmp(data, "PREFERENCE")) {
2779                 for (i = 0; i < CCS_MAX_PREF; i++)
2780                         ccs_set_uint(&profile->pref[i], cp,
2781                                      ccs_pref_keywords[i]);
2782                 return 0;
2783         }
2784         return ccs_set_mode(data, cp, profile);
2785 }
2786 
2787 /**
2788  * ccs_print_config - Print mode for specified functionality.
2789  *
2790  * @head:   Pointer to "struct ccs_io_buffer".
2791  * @config: Mode for that functionality.
2792  *
2793  * Returns nothing.
2794  *
2795  * Caller prints functionality's name.
2796  */
2797 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config)
2798 {
2799         ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
2800                       ccs_mode[config & 3],
2801                       ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG),
2802                       ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG));
2803 }
2804 
2805 /**
2806  * ccs_read_profile - Read profile table.
2807  *
2808  * @head: Pointer to "struct ccs_io_buffer".
2809  *
2810  * Returns nothing.
2811  */
2812 static void ccs_read_profile(struct ccs_io_buffer *head)
2813 {
2814         u8 index;
2815         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
2816                                                        namespace_list);
2817         const struct ccs_profile *profile;
2818         if (head->r.eof)
2819                 return;
2820 next:
2821         index = head->r.index;
2822         profile = ns->profile_ptr[index];
2823         switch (head->r.step) {
2824         case 0:
2825                 ccs_print_namespace(head);
2826                 ccs_io_printf(head, "PROFILE_VERSION=%u\n",
2827                               ns->profile_version);
2828                 head->r.step++;
2829                 break;
2830         case 1:
2831                 for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++)
2832                         if (ns->profile_ptr[head->r.index])
2833                                 break;
2834                 if (head->r.index == CCS_MAX_PROFILES) {
2835                         head->r.eof = true;
2836                         return;
2837                 }
2838                 head->r.step++;
2839                 break;
2840         case 2:
2841                 {
2842                         u8 i;
2843                         const struct ccs_path_info *comment = profile->comment;
2844                         ccs_print_namespace(head);
2845                         ccs_io_printf(head, "%u-COMMENT=", index);
2846                         ccs_set_string(head, comment ? comment->name : "");
2847                         ccs_set_lf(head);
2848                         ccs_print_namespace(head);
2849                         ccs_io_printf(head, "%u-PREFERENCE={ ", index);
2850                         for (i = 0; i < CCS_MAX_PREF; i++)
2851                                 ccs_io_printf(head, "%s=%u ",
2852                                               ccs_pref_keywords[i],
2853                                               profile->pref[i]);
2854                         ccs_set_string(head, "}\n");
2855                         head->r.step++;
2856                 }
2857                 break;
2858         case 3:
2859                 {
2860                         ccs_print_namespace(head);
2861                         ccs_io_printf(head, "%u-%s", index, "CONFIG");
2862                         ccs_print_config(head, profile->default_config);
2863                         head->r.bit = 0;
2864                         head->r.step++;
2865                 }
2866                 break;
2867         case 4:
2868                 for ( ; head->r.bit < CCS_MAX_MAC_INDEX
2869                               + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
2870                         const u8 i = head->r.bit;
2871                         const u8 config = profile->config[i];
2872                         if (config == CCS_CONFIG_USE_DEFAULT)
2873                                 continue;
2874                         ccs_print_namespace(head);
2875                         if (i < CCS_MAX_MAC_INDEX)
2876                                 ccs_io_printf(head, "%u-CONFIG::%s::%s", index,
2877                                               ccs_category_keywords
2878                                               [ccs_index2category[i]],
2879                                               ccs_mac_keywords[i]);
2880                         else
2881                                 ccs_io_printf(head, "%u-CONFIG::%s", index,
2882                                               ccs_mac_keywords[i]);
2883                         ccs_print_config(head, config);
2884                         head->r.bit++;
2885                         break;
2886                 }
2887                 if (head->r.bit == CCS_MAX_MAC_INDEX
2888                     + CCS_MAX_MAC_CATEGORY_INDEX) {
2889                         head->r.index++;
2890                         head->r.step = 1;
2891                 }
2892                 break;
2893         }
2894         if (ccs_flush(head))
2895                 goto next;
2896 }
2897 
2898 /**
2899  * ccs_update_policy - Update an entry for exception policy.
2900  *
2901  * @size:  Size of new entry in bytes.
2902  * @param: Pointer to "struct ccs_acl_param".
2903  *
2904  * Returns 0 on success, negative value otherwise.
2905  *
2906  * Caller holds ccs_read_lock().
2907  */
2908 static int ccs_update_policy(const int size, struct ccs_acl_param *param)
2909 {
2910         struct ccs_acl_head *new_entry = &param->e.acl_head;
2911         int error = param->is_delete ? -ENOENT : -ENOMEM;
2912         struct ccs_acl_head *entry;
2913         struct list_head *list = param->list;
2914         BUG_ON(size < sizeof(*entry));
2915         if (mutex_lock_interruptible(&ccs_policy_lock))
2916                 return -ENOMEM;
2917         list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
2918                 if (entry->is_deleted == CCS_GC_IN_PROGRESS)
2919                         continue;
2920                 if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
2921                         continue;
2922                 entry->is_deleted = param->is_delete;
2923                 error = 0;
2924                 break;
2925         }
2926         if (error && !param->is_delete) {
2927                 entry = ccs_commit_ok(new_entry, size);
2928                 if (entry) {
2929                         list_add_tail_rcu(&entry->list, list);
2930                         error = 0;
2931                 }
2932         }
2933         mutex_unlock(&ccs_policy_lock);
2934         return error;
2935 }
2936 
2937 /**
2938  * ccs_update_manager_entry - Add a manager entry.
2939  *
2940  * @manager:   The path to manager or the domainnamme.
2941  * @is_delete: True if it is a delete request.
2942  *
2943  * Returns 0 on success, negative value otherwise.
2944  */
2945 static int ccs_update_manager_entry(const char *manager,
2946                                     const bool is_delete)
2947 {
2948         struct ccs_acl_param param = {
2949                 /* .ns = &ccs_kernel_namespace, */
2950                 .is_delete = is_delete,
2951                 .list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER],
2952         };
2953         struct ccs_manager *e = &param.e.manager;
2954         int error = is_delete ? -ENOENT : -ENOMEM;
2955         /* Forced zero clear for using memcmp() at ccs_update_policy(). */
2956         memset(&param.e, 0, sizeof(param.e));
2957         if (!ccs_correct_domain(manager) && !ccs_correct_word(manager))
2958                 return -EINVAL;
2959         e->manager = ccs_get_name(manager);
2960         if (e->manager) {
2961                 error = ccs_update_policy(sizeof(*e), &param);
2962                 ccs_put_name(e->manager);
2963         }
2964         return error;
2965 }
2966 
2967 /**
2968  * ccs_write_manager - Write manager policy.
2969  *
2970  * @head: Pointer to "struct ccs_io_buffer".
2971  *
2972  * Returns 0 on success, negative value otherwise.
2973  */
2974 static int ccs_write_manager(struct ccs_io_buffer *head)
2975 {
2976         const char *data = head->write_buf;
2977         if (!strcmp(data, "manage_by_non_root")) {
2978                 ccs_manage_by_non_root = !head->w.is_delete;
2979                 return 0;
2980         }
2981         return ccs_update_manager_entry(data, head->w.is_delete);
2982 }
2983 
2984 /**
2985  * ccs_read_manager - Read manager policy.
2986  *
2987  * @head: Pointer to "struct ccs_io_buffer".
2988  *
2989  * Returns nothing.
2990  *
2991  * Caller holds ccs_read_lock().
2992  */
2993 static void ccs_read_manager(struct ccs_io_buffer *head)
2994 {
2995         if (head->r.eof)
2996                 return;
2997         list_for_each_cookie(head->r.acl, &ccs_kernel_namespace.
2998                              policy_list[CCS_ID_MANAGER]) {
2999                 struct ccs_manager *ptr =
3000                         list_entry(head->r.acl, typeof(*ptr), head.list);
3001                 if (ptr->head.is_deleted)
3002                         continue;
3003                 if (!ccs_flush(head))
3004                         return;
3005                 ccs_set_string(head, ptr->manager->name);
3006                 ccs_set_lf(head);
3007         }
3008         head->r.eof = true;
3009 }
3010 
3011 /**
3012  * ccs_manager - Check whether the current process is a policy manager.
3013  *
3014  * Returns true if the current process is permitted to modify policy
3015  * via /proc/ccs/ interface.
3016  *
3017  * Caller holds ccs_read_lock().
3018  */
3019 static bool ccs_manager(void)
3020 {
3021         struct ccs_manager *ptr;
3022         struct ccs_path_info exe;
3023         struct ccs_security *task = ccs_current_security();
3024         const struct ccs_path_info *domainname
3025                 = ccs_current_domain()->domainname;
3026         bool found = false;
3027         if (!ccs_policy_loaded)
3028                 return true;
3029         if (task->ccs_flags & CCS_TASK_IS_MANAGER)
3030                 return true;
3031         if (!ccs_manage_by_non_root &&
3032             (!uid_eq(current_uid(), GLOBAL_ROOT_UID) ||
3033              !uid_eq(current_euid(), GLOBAL_ROOT_UID)))
3034                 return false;
3035         exe.name = ccs_get_exe();
3036         if (!exe.name)
3037                 return false;
3038         ccs_fill_path_info(&exe);
3039         list_for_each_entry_srcu(ptr, &ccs_kernel_namespace.
3040                                  policy_list[CCS_ID_MANAGER], head.list,
3041                                  &ccs_ss) {
3042                 if (ptr->head.is_deleted)
3043                         continue;
3044                 if (ccs_pathcmp(domainname, ptr->manager) &&
3045                     ccs_pathcmp(&exe, ptr->manager))
3046                         continue;
3047                 /* Set manager flag. */
3048                 task->ccs_flags |= CCS_TASK_IS_MANAGER;
3049                 found = true;
3050                 break;
3051         }
3052         if (!found) { /* Reduce error messages. */
3053                 static pid_t ccs_last_pid;
3054                 const pid_t pid = current->pid;
3055                 if (ccs_last_pid != pid) {
3056                         printk(KERN_WARNING "%s ( %s ) is not permitted to "
3057                                "update policies.\n", domainname->name,
3058                                exe.name);
3059                         ccs_last_pid = pid;
3060                 }
3061         }
3062         kfree(exe.name);
3063         return found;
3064 }
3065 
3066 /**
3067  * ccs_find_domain - Find a domain by the given name.
3068  *
3069  * @domainname: The domainname to find.
3070  *
3071  * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
3072  *
3073  * Caller holds ccs_read_lock().
3074  */
3075 static struct ccs_domain_info *ccs_find_domain(const char *domainname)
3076 {
3077         struct ccs_domain_info *domain;
3078         struct ccs_path_info name;
3079         name.name = domainname;
3080         ccs_fill_path_info(&name);
3081         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
3082                 if (!domain->is_deleted &&
3083                     !ccs_pathcmp(&name, domain->domainname))
3084                         return domain;
3085         }
3086         return NULL;
3087 }
3088 
3089 /**
3090  * ccs_select_domain - Parse select command.
3091  *
3092  * @head: Pointer to "struct ccs_io_buffer".
3093  * @data: String to parse.
3094  *
3095  * Returns true on success, false otherwise.
3096  *
3097  * Caller holds ccs_read_lock().
3098  */
3099 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data)
3100 {
3101         unsigned int pid;
3102         struct ccs_domain_info *domain = NULL;
3103         bool global_pid = false;
3104         if (strncmp(data, "select ", 7))
3105                 return false;
3106         data += 7;
3107         if (sscanf(data, "pid=%u", &pid) == 1 ||
3108             (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
3109                 struct task_struct *p;
3110                 ccs_tasklist_lock();
3111 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
3112                 if (global_pid)
3113                         p = ccsecurity_exports.find_task_by_pid_ns(pid,
3114                                                                &init_pid_ns);
3115                 else
3116                         p = ccsecurity_exports.find_task_by_vpid(pid);
3117 #else
3118                 p = find_task_by_pid(pid);
3119 #endif
3120                 if (p)
3121                         domain = ccs_task_domain(p);
3122                 ccs_tasklist_unlock();
3123         } else if (!strncmp(data, "domain=", 7)) {
3124                 if (*(data + 7) == '<')
3125                         domain = ccs_find_domain(data + 7);
3126         } else if (sscanf(data, "Q=%u", &pid) == 1) {
3127                 domain = ccs_find_domain_by_qid(pid);
3128         } else
3129                 return false;
3130         head->w.domain = domain;
3131         /* Accessing read_buf is safe because head->io_sem is held. */
3132         if (!head->read_buf)
3133                 return true; /* Do nothing if open(O_WRONLY). */
3134         memset(&head->r, 0, sizeof(head->r));
3135         head->r.print_this_domain_only = true;
3136         if (domain)
3137                 head->r.domain = &domain->list;
3138         else
3139                 head->r.eof = true;
3140         ccs_io_printf(head, "# select %s\n", data);
3141         if (domain && domain->is_deleted)
3142                 ccs_set_string(head, "# This is a deleted domain.\n");
3143         return true;
3144 }
3145 
3146 /**
3147  * ccs_update_acl - Update "struct ccs_acl_info" entry.
3148  *
3149  * @size:  Size of new entry in bytes.
3150  * @param: Pointer to "struct ccs_acl_param".
3151  *
3152  * Returns 0 on success, negative value otherwise.
3153  *
3154  * Caller holds ccs_read_lock().
3155  */
3156 static int ccs_update_acl(const int size, struct ccs_acl_param *param)
3157 {
3158         struct ccs_acl_info *new_entry = &param->e.acl_info;
3159         const bool is_delete = param->is_delete;
3160         int error = is_delete ? -ENOENT : -ENOMEM;
3161         struct ccs_acl_info *entry;
3162         struct list_head * const list = param->list;
3163         BUG_ON(size < sizeof(*entry));
3164         if (param->data[0]) {
3165                 /*
3166                  * Domain transition preference is allowed for only
3167                  * "file execute"/"task auto_execute_handler"/
3168                  * "task denied_auto_execute_handler" entries.
3169                  */
3170                 const bool pref = (new_entry->type == CCS_TYPE_PATH_ACL &&
3171                                    new_entry->perm == 1 << CCS_TYPE_EXECUTE)
3172 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3173                         || new_entry->type == CCS_TYPE_AUTO_EXECUTE_HANDLER
3174                         || new_entry->type == CCS_TYPE_DENIED_EXECUTE_HANDLER
3175 #endif
3176                         ;
3177                 new_entry->cond = ccs_get_condition(param, pref);
3178                 if (!new_entry->cond)
3179                         return error;
3180         }
3181         if (mutex_lock_interruptible(&ccs_policy_lock))
3182                 return -ENOMEM;
3183         list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
3184                 if (entry->is_deleted == CCS_GC_IN_PROGRESS)
3185                         continue;
3186                 if (entry->type != new_entry->type ||
3187                     entry->cond != new_entry->cond ||
3188                     memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
3189                         continue;
3190                 if (is_delete)
3191                         entry->perm &= ~new_entry->perm;
3192                 else
3193                         entry->perm |= new_entry->perm;
3194                 entry->is_deleted = !entry->perm;
3195                 error = 0;
3196                 break;
3197         }
3198         if (error && !is_delete) {
3199                 entry = ccs_commit_ok(new_entry, size);
3200                 if (entry) {
3201                         list_add_tail_rcu(&entry->list, list);
3202                         error = 0;
3203                 }
3204         }
3205         mutex_unlock(&ccs_policy_lock);
3206         return error;
3207 }
3208 
3209 /**
3210  * ccs_permstr - Find permission keywords.
3211  *
3212  * @string: String representation for permissions in foo/bar/buz format.
3213  * @keyword: Keyword to find from @string/
3214  *
3215  * Returns true if @keyword was found in @string, false otherwise.
3216  *
3217  * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
3218  */
3219 static bool ccs_permstr(const char *string, const char *keyword)
3220 {
3221         const char *cp = strstr(string, keyword);
3222         if (cp)
3223                 return cp == string || *(cp - 1) == '/';
3224         return false;
3225 }
3226 
3227 /**
3228  * ccs_write_task - Update task related list.
3229  *
3230  * @param: Pointer to "struct ccs_acl_param".
3231  *
3232  * Returns 0 on success, negative value otherwise.
3233  *
3234  * Caller holds ccs_read_lock().
3235  */
3236 static int ccs_write_task(struct ccs_acl_param *param)
3237 {
3238         int error;
3239         const bool is_auto = ccs_str_starts(&param->data,
3240                                             "auto_domain_transition ");
3241         if (!is_auto && !ccs_str_starts(&param->data,
3242                                         "manual_domain_transition ")) {
3243 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3244                 struct ccs_handler_acl *e = &param->e.handler_acl;
3245                 char *handler;
3246                 if (ccs_str_starts(&param->data, "auto_execute_handler "))
3247                         e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
3248                 else if (ccs_str_starts(&param->data,
3249                                         "denied_execute_handler "))
3250                         e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
3251                 else
3252                         return -EINVAL;
3253                 handler = ccs_read_token(param);
3254                 if (*handler != '/' || !ccs_correct_path(handler))
3255                         return -EINVAL;
3256                 e->handler = ccs_get_name(handler);
3257                 if (!e->handler)
3258                         return -ENOMEM;
3259                 if (e->handler->is_patterned)
3260                         return -EINVAL; /* No patterns allowed. */
3261                 return ccs_update_acl(sizeof(*e), param);
3262 #else
3263                 error = -EINVAL;
3264 #endif
3265         } else {
3266 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
3267                 struct ccs_task_acl *e = &param->e.task_acl;
3268                 e->head.type = is_auto ?
3269                         CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL;
3270                 e->domainname = ccs_get_domainname(param);
3271                 if (!e->domainname)
3272                         return -EINVAL;
3273                 return ccs_update_acl(sizeof(*e), param);
3274 #else
3275                 error = -EINVAL;
3276 #endif
3277         }
3278         return error;
3279 }
3280 
3281 #ifdef CONFIG_CCSECURITY_NETWORK
3282 
3283 /**
3284  * ccs_write_inet_network - Write "struct ccs_inet_acl" list.
3285  *
3286  * @param: Pointer to "struct ccs_acl_param".
3287  *
3288  * Returns 0 on success, negative value otherwise.
3289  *
3290  * Caller holds ccs_read_lock().
3291  */
3292 static int ccs_write_inet_network(struct ccs_acl_param *param)
3293 {
3294         struct ccs_inet_acl *e = &param->e.inet_acl;
3295         u8 type;
3296         const char *protocol = ccs_read_token(param);
3297         const char *operation = ccs_read_token(param);
3298         e->head.type = CCS_TYPE_INET_ACL;
3299         for (type = 0; type < CCS_SOCK_MAX; type++)
3300                 if (!strcmp(protocol, ccs_proto_keyword[type]))
3301                         break;
3302         if (type == CCS_SOCK_MAX)
3303                 return -EINVAL;
3304         e->protocol = type;
3305         e->head.perm = 0;
3306         for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
3307                 if (ccs_permstr(operation, ccs_socket_keyword[type]))
3308                         e->head.perm |= 1 << type;
3309         if (!e->head.perm)
3310                 return -EINVAL;
3311         if (param->data[0] == '@') {
3312                 param->data++;
3313                 e->address.group = ccs_get_group(param, CCS_ADDRESS_GROUP);
3314                 if (!e->address.group)
3315                         return -ENOMEM;
3316         } else {
3317                 if (!ccs_parse_ipaddr_union(param, &e->address))
3318                         return -EINVAL;
3319         }
3320         if (!ccs_parse_number_union(param, &e->port) ||
3321             e->port.values[1] > 65535)
3322                 return -EINVAL;
3323         return ccs_update_acl(sizeof(*e), param);
3324 }
3325 
3326 /**
3327  * ccs_write_unix_network - Write "struct ccs_unix_acl" list.
3328  *
3329  * @param: Pointer to "struct ccs_acl_param".
3330  *
3331  * Returns 0 on success, negative value otherwise.
3332  */
3333 static int ccs_write_unix_network(struct ccs_acl_param *param)
3334 {
3335         struct ccs_unix_acl *e = &param->e.unix_acl;
3336         u8 type;
3337         const char *protocol = ccs_read_token(param);
3338         const char *operation = ccs_read_token(param);
3339         e->head.type = CCS_TYPE_UNIX_ACL;
3340         for (type = 0; type < CCS_SOCK_MAX; type++)
3341                 if (!strcmp(protocol, ccs_proto_keyword[type]))
3342                         break;
3343         if (type == CCS_SOCK_MAX)
3344                 return -EINVAL;
3345         e->protocol = type;
3346         e->head.perm = 0;
3347         for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
3348                 if (ccs_permstr(operation, ccs_socket_keyword[type]))
3349                         e->head.perm |= 1 << type;
3350         if (!e->head.perm)
3351                 return -EINVAL;
3352         if (!ccs_parse_name_union(param, &e->name))
3353                 return -EINVAL;
3354         return ccs_update_acl(sizeof(*e), param);
3355 }
3356 
3357 #endif
3358 
3359 /**
3360  * ccs_write_file - Update file related list.
3361  *
3362  * @param: Pointer to "struct ccs_acl_param".
3363  *
3364  * Returns 0 on success, negative value otherwise.
3365  *
3366  * Caller holds ccs_read_lock().
3367  */
3368 static int ccs_write_file(struct ccs_acl_param *param)
3369 {
3370         u16 perm = 0;
3371         u8 type;
3372         const char *operation = ccs_read_token(param);
3373         for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
3374                 if (ccs_permstr(operation, ccs_path_keyword[type]))
3375                         perm |= 1 << type;
3376         if (perm) {
3377                 struct ccs_path_acl *e = &param->e.path_acl;
3378                 e->head.type = CCS_TYPE_PATH_ACL;
3379                 e->head.perm = perm;
3380                 if (!ccs_parse_name_union(param, &e->name))
3381                         return -EINVAL;
3382                 return ccs_update_acl(sizeof(*e), param);
3383         }
3384         for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++)
3385                 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]]))
3386                         perm |= 1 << type;
3387         if (perm) {
3388                 struct ccs_path2_acl *e = &param->e.path2_acl;
3389                 e->head.type = CCS_TYPE_PATH2_ACL;
3390                 e->head.perm = perm;
3391                 if (!ccs_parse_name_union(param, &e->name1) ||
3392                     !ccs_parse_name_union(param, &e->name2))
3393                         return -EINVAL;
3394                 return ccs_update_acl(sizeof(*e), param);
3395         }
3396         for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++)
3397                 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]]))
3398                         perm |= 1 << type;
3399         if (perm) {
3400                 struct ccs_path_number_acl *e = &param->e.path_number_acl;
3401                 e->head.type = CCS_TYPE_PATH_NUMBER_ACL;
3402                 e->head.perm = perm;
3403                 if (!ccs_parse_name_union(param, &e->name) ||
3404                     !ccs_parse_number_union(param, &e->number))
3405                         return -EINVAL;
3406                 return ccs_update_acl(sizeof(*e), param);
3407         }
3408         for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++)
3409                 if (ccs_permstr(operation,
3410                                 ccs_mac_keywords[ccs_pnnn2mac[type]]))
3411                         perm |= 1 << type;
3412         if (perm) {
3413                 struct ccs_mkdev_acl *e = &param->e.mkdev_acl;
3414                 e->head.type = CCS_TYPE_MKDEV_ACL;
3415                 e->head.perm = perm;
3416                 if (!ccs_parse_name_union(param, &e->name) ||
3417                     !ccs_parse_number_union(param, &e->mode) ||
3418                     !ccs_parse_number_union(param, &e->major) ||
3419                     !ccs_parse_number_union(param, &e->minor))
3420                         return -EINVAL;
3421                 return ccs_update_acl(sizeof(*e), param);
3422         }
3423         if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) {
3424                 struct ccs_mount_acl *e = &param->e.mount_acl;
3425                 e->head.type = CCS_TYPE_MOUNT_ACL;
3426                 if (!ccs_parse_name_union(param, &e->dev_name) ||
3427                     !ccs_parse_name_union(param, &e->dir_name) ||
3428                     !ccs_parse_name_union(param, &e->fs_type) ||
3429                     !ccs_parse_number_union(param, &e->flags))
3430                         return -EINVAL;
3431                 return ccs_update_acl(sizeof(*e), param);
3432         }
3433         return -EINVAL;
3434 }
3435 
3436 #ifdef CONFIG_CCSECURITY_MISC
3437 
3438 /**
3439  * ccs_write_misc - Update environment variable list.
3440  *
3441  * @param: Pointer to "struct ccs_acl_param".
3442  *
3443  * Returns 0 on success, negative value otherwise.
3444  */
3445 static int ccs_write_misc(struct ccs_acl_param *param)
3446 {
3447         if (ccs_str_starts(&param->data, "env ")) {
3448                 struct ccs_env_acl *e = &param->e.env_acl;
3449                 const char *data = ccs_read_token(param);
3450                 e->head.type = CCS_TYPE_ENV_ACL;
3451                 if (!ccs_correct_word(data) || strchr(data, '='))
3452                         return -EINVAL;
3453                 e->env = ccs_get_name(data);
3454                 if (!e->env)
3455                         return -ENOMEM;
3456                 return ccs_update_acl(sizeof(*e), param);
3457         }
3458         return -EINVAL;
3459 }
3460 
3461 #endif
3462 
3463 #ifdef CONFIG_CCSECURITY_IPC
3464 
3465 /**
3466  * ccs_write_ipc - Update "struct ccs_signal_acl" list.
3467  *
3468  * @param: Pointer to "struct ccs_acl_param".
3469  *
3470  * Returns 0 on success, negative value otherwise.
3471  */
3472 static int ccs_write_ipc(struct ccs_acl_param *param)
3473 {
3474         struct ccs_signal_acl *e = &param->e.signal_acl;
3475         e->head.type = CCS_TYPE_SIGNAL_ACL;
3476         if (!ccs_parse_number_union(param, &e->sig))
3477                 return -EINVAL;
3478         e->domainname = ccs_get_domainname(param);
3479         if (!e->domainname)
3480                 return -EINVAL;
3481         return ccs_update_acl(sizeof(*e), param);
3482 }
3483 
3484 #endif
3485 
3486 #ifdef CONFIG_CCSECURITY_CAPABILITY
3487 
3488 /**
3489  * ccs_write_capability - Write "struct ccs_capability_acl" list.
3490  *
3491  * @param: Pointer to "struct ccs_acl_param".
3492  *
3493  * Returns 0 on success, negative value otherwise.
3494  *
3495  * Caller holds ccs_read_lock().
3496  */
3497 static int ccs_write_capability(struct ccs_acl_param *param)
3498 {
3499         struct ccs_capability_acl *e = &param->e.capability_acl;
3500         const char *operation = ccs_read_token(param);
3501         u8 type;
3502         e->head.type = CCS_TYPE_CAPABILITY_ACL;
3503         for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) {
3504                 if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]]))
3505                         continue;
3506                 e->operation = type;
3507                 return ccs_update_acl(sizeof(*e), param);
3508         }
3509         return -EINVAL;
3510 }
3511 
3512 #endif
3513 
3514 /**
3515  * ccs_write_acl - Write "struct ccs_acl_info" list.
3516  *
3517  * @ns:        Pointer to "struct ccs_policy_namespace".
3518  * @list:      Pointer to "struct list_head".
3519  * @data:      Policy to be interpreted.
3520  * @is_delete: True if it is a delete request.
3521  *
3522  * Returns 0 on success, negative value otherwise.
3523  *
3524  * Caller holds ccs_read_lock().
3525  */
3526 static int ccs_write_acl(struct ccs_policy_namespace *ns,
3527                          struct list_head *list, char *data,
3528                          const bool is_delete)
3529 {
3530         struct ccs_acl_param param = {
3531                 .ns = ns,
3532                 .list = list,
3533                 .data = data,
3534                 .is_delete = is_delete,
3535         };
3536         static const struct {
3537                 const char *keyword;
3538                 int (*write) (struct ccs_acl_param *);
3539         } ccs_callback[] = {
3540                 { "file ", ccs_write_file },
3541 #ifdef CONFIG_CCSECURITY_NETWORK
3542                 { "network inet ", ccs_write_inet_network },
3543                 { "network unix ", ccs_write_unix_network },
3544 #endif
3545 #ifdef CONFIG_CCSECURITY_MISC
3546                 { "misc ", ccs_write_misc },
3547 #endif
3548 #ifdef CONFIG_CCSECURITY_CAPABILITY
3549                 { "capability ", ccs_write_capability },
3550 #endif
3551 #ifdef CONFIG_CCSECURITY_IPC
3552                 { "ipc signal ", ccs_write_ipc },
3553 #endif
3554                 { "task ", ccs_write_task },
3555         };
3556         u8 i;
3557         /* Forced zero clear for using memcmp() at ccs_update_acl(). */
3558         memset(&param.e, 0, sizeof(param.e));
3559         param.e.acl_info.perm = 1;
3560         for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
3561                 int error;
3562                 if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
3563                         continue;
3564                 error = ccs_callback[i].write(&param);
3565                 ccs_del_acl(&param.e.acl_info.list);
3566                 return error;
3567         }
3568         return -EINVAL;
3569 }
3570 
3571 /**
3572  * ccs_delete_domain - Delete a domain.
3573  *
3574  * @domainname: The name of domain.
3575  *
3576  * Returns 0.
3577  */
3578 static int ccs_delete_domain(char *domainname)
3579 {
3580         struct ccs_domain_info *domain;
3581         struct ccs_path_info name;
3582         name.name = domainname;
3583         ccs_fill_path_info(&name);
3584         if (mutex_lock_interruptible(&ccs_policy_lock))
3585                 return 0;
3586         /* Is there an active domain? */
3587         list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
3588                 /* Never delete ccs_kernel_domain. */
3589                 if (domain == &ccs_kernel_domain)
3590                         continue;
3591                 if (domain->is_deleted ||
3592                     ccs_pathcmp(domain->domainname, &name))
3593                         continue;
3594                 domain->is_deleted = true;
3595                 break;
3596         }
3597         mutex_unlock(&ccs_policy_lock);
3598         return 0;
3599 }
3600 
3601 /**
3602  * ccs_write_domain - Write domain policy.
3603  *
3604  * @head: Pointer to "struct ccs_io_buffer".
3605  *
3606  * Returns 0 on success, negative value otherwise.
3607  *
3608  * Caller holds ccs_read_lock().
3609  */
3610 static int ccs_write_domain(struct ccs_io_buffer *head)
3611 {
3612         char *data = head->write_buf;
3613         struct ccs_policy_namespace *ns;
3614         struct ccs_domain_info *domain = head->w.domain;
3615         const bool is_delete = head->w.is_delete;
3616         const bool is_select = !is_delete && ccs_str_starts(&data, "select ");
3617         unsigned int idx;
3618         if (*data == '<') {
3619                 domain = NULL;
3620                 if (is_delete)
3621                         ccs_delete_domain(data);
3622                 else if (is_select)
3623                         domain = ccs_find_domain(data);
3624                 else
3625                         domain = ccs_assign_domain(data, false);
3626                 head->w.domain = domain;
3627                 return 0;
3628         }
3629         if (!domain)
3630                 return -EINVAL;
3631         ns = domain->ns;
3632         if (sscanf(data, "use_profile %u\n", &idx) == 1 &&
3633             idx < CCS_MAX_PROFILES) {
3634                 if (!ccs_policy_loaded || ns->profile_ptr[(u8) idx])
3635                         if (!is_delete)
3636                                 domain->profile = (u8) idx;
3637                 return 0;
3638         }
3639         if (sscanf(data, "use_group %u\n", &idx) == 1 &&
3640             idx < CCS_MAX_ACL_GROUPS) {
3641                 if (!is_delete)
3642                         set_bit(idx, domain->group);
3643                 else
3644                         clear_bit(idx, domain->group);
3645                 return 0;
3646         }
3647         for (idx = 0; idx < CCS_MAX_DOMAIN_INFO_FLAGS; idx++) {
3648                 const char *cp = ccs_dif[idx];
3649                 if (strncmp(data, cp, strlen(cp) - 1))
3650                         continue;
3651                 domain->flags[idx] = !is_delete;
3652                 return 0;
3653         }
3654         return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete);
3655 }
3656 
3657 /**
3658  * ccs_print_name_union - Print a ccs_name_union.
3659  *
3660  * @head: Pointer to "struct ccs_io_buffer".
3661  * @ptr:  Pointer to "struct ccs_name_union".
3662  *
3663  * Returns nothing.
3664  */
3665 static void ccs_print_name_union(struct ccs_io_buffer *head,
3666                                  const struct ccs_name_union *ptr)
3667 {
3668         ccs_set_space(head);
3669         if (!ccs_print_group(head, ptr->group))
3670                 ccs_set_string(head, ptr->filename->name);
3671 }
3672 
3673 /**
3674  * ccs_print_name_union_quoted - Print a ccs_name_union with a quote.
3675  *
3676  * @head: Pointer to "struct ccs_io_buffer".
3677  * @ptr:  Pointer to "struct ccs_name_union".
3678  *
3679  * Returns nothing.
3680  */
3681 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
3682                                         const struct ccs_name_union *ptr)
3683 {
3684         if (!ccs_print_group(head, ptr->group)) {
3685                 ccs_set_string(head, "\"");
3686                 ccs_set_string(head, ptr->filename->name);
3687                 ccs_set_string(head, "\"");
3688         }
3689 }
3690 
3691 /**
3692  * ccs_print_number_union_nospace - Print a ccs_number_union without a space.
3693  *
3694  * @head: Pointer to "struct ccs_io_buffer".
3695  * @ptr:  Pointer to "struct ccs_number_union".
3696  *
3697  * Returns nothing.
3698  */
3699 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
3700                                            const struct ccs_number_union *ptr)
3701 {
3702         if (!ccs_print_group(head, ptr->group)) {
3703                 int i;
3704                 unsigned long min = ptr->values[0];
3705                 const unsigned long max = ptr->values[1];
3706                 u8 min_type = ptr->value_type[0];
3707                 const u8 max_type = ptr->value_type[1];
3708                 char buffer[128];
3709                 buffer[0] = '\0';
3710                 for (i = 0; i < 2; i++) {
3711                         switch (min_type) {
3712                         case CCS_VALUE_TYPE_HEXADECIMAL:
3713                                 ccs_addprintf(buffer, sizeof(buffer), "0x%lX",
3714                                               min);
3715                                 break;
3716                         case CCS_VALUE_TYPE_OCTAL:
3717                                 ccs_addprintf(buffer, sizeof(buffer), "0%lo",
3718                                               min);
3719                                 break;
3720                         default:
3721                                 ccs_addprintf(buffer, sizeof(buffer), "%lu",
3722                                               min);
3723                                 break;
3724                         }
3725                         if (min == max && min_type == max_type)
3726                                 break;
3727                         ccs_addprintf(buffer, sizeof(buffer), "-");
3728                         min_type = max_type;
3729                         min = max;
3730                 }
3731                 ccs_io_printf(head, "%s", buffer);
3732         }
3733 }
3734 
3735 /**
3736  * ccs_print_number_union - Print a ccs_number_union.
3737  *
3738  * @head: Pointer to "struct ccs_io_buffer".
3739  * @ptr:  Pointer to "struct ccs_number_union".
3740  *
3741  * Returns nothing.
3742  */
3743 static void ccs_print_number_union(struct ccs_io_buffer *head,
3744                                    const struct ccs_number_union *ptr)
3745 {
3746         ccs_set_space(head);
3747         ccs_print_number_union_nospace(head, ptr);
3748 }
3749 
3750 /**
3751  * ccs_print_condition - Print condition part.
3752  *
3753  * @head: Pointer to "struct ccs_io_buffer".
3754  * @cond: Pointer to "struct ccs_condition".
3755  *
3756  * Returns true on success, false otherwise.
3757  */
3758 static bool ccs_print_condition(struct ccs_io_buffer *head,
3759                                 const struct ccs_condition *cond)
3760 {
3761         switch (head->r.cond_step) {
3762         case 0:
3763                 head->r.cond_index = 0;
3764                 head->r.cond_step++;
3765                 if (cond->transit && cond->exec_transit) {
3766                         ccs_set_space(head);
3767                         ccs_set_string(head, cond->transit->name);
3768                 }
3769                 /* fall through */
3770                 fallthrough;
3771         case 1:
3772                 {
3773                         const u16 condc = cond->condc;
3774                         const struct ccs_condition_element *condp =
3775                                 (typeof(condp)) (cond + 1);
3776                         const struct ccs_number_union *numbers_p =
3777                                 (typeof(numbers_p)) (condp + condc);
3778                         const struct ccs_name_union *names_p =
3779                                 (typeof(names_p))
3780                                 (numbers_p + cond->numbers_count);
3781                         const struct ccs_argv *argv =
3782                                 (typeof(argv)) (names_p + cond->names_count);
3783                         const struct ccs_envp *envp =
3784                                 (typeof(envp)) (argv + cond->argc);
3785                         u16 skip;
3786                         for (skip = 0; skip < head->r.cond_index; skip++) {
3787                                 const u8 left = condp->left;
3788                                 const u8 right = condp->right;
3789                                 condp++;
3790                                 switch (left) {
3791                                 case CCS_ARGV_ENTRY:
3792                                         argv++;
3793                                         continue;
3794                                 case CCS_ENVP_ENTRY:
3795                                         envp++;
3796                                         continue;
3797                                 case CCS_NUMBER_UNION:
3798                                         numbers_p++;
3799                                         break;
3800                                 }
3801                                 switch (right) {
3802                                 case CCS_NAME_UNION:
3803                                         names_p++;
3804                                         break;
3805                                 case CCS_NUMBER_UNION:
3806                                         numbers_p++;
3807                                         break;
3808                                 }
3809                         }
3810                         while (head->r.cond_index < condc) {
3811                                 const u8 match = condp->equals;
3812                                 const u8 left = condp->left;
3813                                 const u8 right = condp->right;
3814                                 if (!ccs_flush(head))
3815                                         return false;
3816                                 condp++;
3817                                 head->r.cond_index++;
3818                                 ccs_set_space(head);
3819                                 switch (left) {
3820                                 case CCS_ARGV_ENTRY:
3821                                         ccs_io_printf(head,
3822                                                       "exec.argv[%lu]%s=\"",
3823                                                       argv->index,
3824                                                       argv->is_not ? "!" : "");
3825                                         ccs_set_string(head,
3826                                                        argv->value->name);
3827                                         ccs_set_string(head, "\"");
3828                                         argv++;
3829                                         continue;
3830                                 case CCS_ENVP_ENTRY:
3831                                         ccs_set_string(head, "exec.envp[\"");
3832                                         ccs_set_string(head, envp->name->name);
3833                                         ccs_io_printf(head, "\"]%s=",
3834                                                       envp->is_not ? "!" : "");
3835                                         if (envp->value) {
3836                                                 ccs_set_string(head, "\"");
3837                                                 ccs_set_string(head, envp->
3838                                                                value->name);
3839                                                 ccs_set_string(head, "\"");
3840                                         } else {
3841                                                 ccs_set_string(head, "NULL");
3842                                         }
3843                                         envp++;
3844                                         continue;
3845                                 case CCS_NUMBER_UNION:
3846                                         ccs_print_number_union_nospace
3847                                                 (head, numbers_p++);
3848                                         break;
3849                                 default:
3850                                         ccs_set_string(head,
3851                                                ccs_condition_keyword[left]);
3852                                         break;
3853                                 }
3854                                 ccs_set_string(head, match ? "=" : "!=");
3855                                 switch (right) {
3856                                 case CCS_NAME_UNION:
3857                                         ccs_print_name_union_quoted
3858                                                 (head, names_p++);
3859                                         break;
3860                                 case CCS_NUMBER_UNION:
3861                                         ccs_print_number_union_nospace
3862                                                 (head, numbers_p++);
3863                                         break;
3864                                 default:
3865                                         ccs_set_string(head,
3866                                                ccs_condition_keyword[right]);
3867                                         break;
3868                                 }
3869                         }
3870                 }
3871                 head->r.cond_step++;
3872                 /* fall through */
3873                 fallthrough;
3874         case 2:
3875                 if (!ccs_flush(head))
3876                         break;
3877                 head->r.cond_step++;
3878                 /* fall through */
3879                 fallthrough;
3880         case 3:
3881                 if (cond->grant_log != CCS_GRANTLOG_AUTO)
3882                         ccs_io_printf(head, " grant_log=%s",
3883                                       ccs_yesno(cond->grant_log ==
3884                                                 CCS_GRANTLOG_YES));
3885                 if (cond->transit && !cond->exec_transit) {
3886                         const char *name = cond->transit->name;
3887                         ccs_set_string(head, " auto_domain_transition=\"");
3888                         ccs_set_string(head, name);
3889                         ccs_set_string(head, "\"");
3890                 }
3891                 ccs_set_lf(head);
3892                 return true;
3893         }
3894         return false;
3895 }
3896 
3897 /**
3898  * ccs_set_group - Print "acl_group " header keyword and category name.
3899  *
3900  * @head:     Pointer to "struct ccs_io_buffer".
3901  * @category: Category name.
3902  *
3903  * Returns nothing.
3904  */
3905 static void ccs_set_group(struct ccs_io_buffer *head, const char *category)
3906 {
3907         if (head->type == CCS_EXCEPTION_POLICY) {
3908                 ccs_print_namespace(head);
3909                 ccs_io_printf(head, "acl_group %u ", head->r.acl_group_index);
3910         }
3911         ccs_set_string(head, category);
3912 }
3913 
3914 /**
3915  * ccs_print_entry - Print an ACL entry.
3916  *
3917  * @head: Pointer to "struct ccs_io_buffer".
3918  * @acl:  Pointer to an ACL entry.
3919  *
3920  * Returns true on success, false otherwise.
3921  */
3922 static bool ccs_print_entry(struct ccs_io_buffer *head,
3923                             const struct ccs_acl_info *acl)
3924 {
3925         const u8 acl_type = acl->type;
3926         const bool may_trigger_transition = acl->cond && acl->cond->transit;
3927         bool first = true;
3928         u8 bit;
3929         if (head->r.print_cond_part)
3930                 goto print_cond_part;
3931         if (acl->is_deleted)
3932                 return true;
3933         if (!ccs_flush(head))
3934                 return false;
3935         else if (acl_type == CCS_TYPE_PATH_ACL) {
3936                 struct ccs_path_acl *ptr
3937                         = container_of(acl, typeof(*ptr), head);
3938                 for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
3939                         if (!(acl->perm & (1 << bit)))
3940                                 continue;
3941                         if (head->r.print_transition_related_only &&
3942                             bit != CCS_TYPE_EXECUTE && !may_trigger_transition)
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_path_keyword[bit]);
3951                 }
3952                 if (first)
3953                         return true;
3954                 ccs_print_name_union(head, &ptr->name);
3955 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
3956         } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
3957                    acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
3958                 struct ccs_handler_acl *ptr
3959                         = container_of(acl, typeof(*ptr), head);
3960                 ccs_set_group(head, "task ");
3961                 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
3962                                ? "auto_execute_handler " :
3963                                "denied_execute_handler ");
3964                 ccs_set_string(head, ptr->handler->name);
3965 #endif
3966 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
3967         } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
3968                    acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
3969                 struct ccs_task_acl *ptr =
3970                         container_of(acl, typeof(*ptr), head);
3971                 ccs_set_group(head, "task ");
3972                 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ?
3973                                "auto_domain_transition " :
3974                                "manual_domain_transition ");
3975                 ccs_set_string(head, ptr->domainname->name);
3976 #endif
3977         } else if (head->r.print_transition_related_only &&
3978                    !may_trigger_transition) {
3979                 return true;
3980         } else if (acl_type == CCS_TYPE_MKDEV_ACL) {
3981                 struct ccs_mkdev_acl *ptr =
3982                         container_of(acl, typeof(*ptr), head);
3983                 for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) {
3984                         if (!(acl->perm & (1 << bit)))
3985                                 continue;
3986                         if (first) {
3987                                 ccs_set_group(head, "file ");
3988                                 first = false;
3989                         } else {
3990                                 ccs_set_slash(head);
3991                         }
3992                         ccs_set_string(head, ccs_mac_keywords
3993                                        [ccs_pnnn2mac[bit]]);
3994                 }
3995                 if (first)
3996                         return true;
3997                 ccs_print_name_union(head, &ptr->name);
3998                 ccs_print_number_union(head, &ptr->mode);
3999                 ccs_print_number_union(head, &ptr->major);
4000                 ccs_print_number_union(head, &ptr->minor);
4001         } else if (acl_type == CCS_TYPE_PATH2_ACL) {
4002                 struct ccs_path2_acl *ptr =
4003                         container_of(acl, typeof(*ptr), head);
4004                 for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) {
4005                         if (!(acl->perm & (1 << bit)))
4006                                 continue;
4007                         if (first) {
4008                                 ccs_set_group(head, "file ");
4009                                 first = false;
4010                         } else {
4011                                 ccs_set_slash(head);
4012                         }
4013                         ccs_set_string(head, ccs_mac_keywords
4014                                        [ccs_pp2mac[bit]]);
4015                 }
4016                 if (first)
4017                         return true;
4018                 ccs_print_name_union(head, &ptr->name1);
4019                 ccs_print_name_union(head, &ptr->name2);
4020         } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
4021                 struct ccs_path_number_acl *ptr =
4022                         container_of(acl, typeof(*ptr), head);
4023                 for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) {
4024                         if (!(acl->perm & (1 << bit)))
4025                                 continue;
4026                         if (first) {
4027                                 ccs_set_group(head, "file ");
4028                                 first = false;
4029                         } else {
4030                                 ccs_set_slash(head);
4031                         }
4032                         ccs_set_string(head, ccs_mac_keywords
4033                                        [ccs_pn2mac[bit]]);
4034                 }
4035                 if (first)
4036                         return true;
4037                 ccs_print_name_union(head, &ptr->name);
4038                 ccs_print_number_union(head, &ptr->number);
4039 #ifdef CONFIG_CCSECURITY_MISC
4040         } else if (acl_type == CCS_TYPE_ENV_ACL) {
4041                 struct ccs_env_acl *ptr =
4042                         container_of(acl, typeof(*ptr), head);
4043                 ccs_set_group(head, "misc env ");
4044                 ccs_set_string(head, ptr->env->name);
4045 #endif
4046 #ifdef CONFIG_CCSECURITY_CAPABILITY
4047         } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
4048                 struct ccs_capability_acl *ptr =
4049                         container_of(acl, typeof(*ptr), head);
4050                 ccs_set_group(head, "capability ");
4051                 ccs_set_string(head, ccs_mac_keywords
4052                                [ccs_c2mac[ptr->operation]]);
4053 #endif
4054 #ifdef CONFIG_CCSECURITY_NETWORK
4055         } else if (acl_type == CCS_TYPE_INET_ACL) {
4056                 struct ccs_inet_acl *ptr =
4057                         container_of(acl, typeof(*ptr), head);
4058                 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
4059                         if (!(acl->perm & (1 << bit)))
4060                                 continue;
4061                         if (first) {
4062                                 ccs_set_group(head, "network inet ");
4063                                 ccs_set_string(head, ccs_proto_keyword
4064                                                [ptr->protocol]);
4065                                 ccs_set_space(head);
4066                                 first = false;
4067                         } else {
4068                                 ccs_set_slash(head);
4069                         }
4070                         ccs_set_string(head, ccs_socket_keyword[bit]);
4071                 }
4072                 if (first)
4073                         return true;
4074                 ccs_set_space(head);
4075                 if (!ccs_print_group(head, ptr->address.group)) {
4076                         char buf[128];
4077                         ccs_print_ip(buf, sizeof(buf), &ptr->address);
4078                         ccs_io_printf(head, "%s", buf);
4079                 }
4080                 ccs_print_number_union(head, &ptr->port);
4081         } else if (acl_type == CCS_TYPE_UNIX_ACL) {
4082                 struct ccs_unix_acl *ptr =
4083                         container_of(acl, typeof(*ptr), head);
4084                 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
4085                         if (!(acl->perm & (1 << bit)))
4086                                 continue;
4087                         if (first) {
4088                                 ccs_set_group(head, "network unix ");
4089                                 ccs_set_string(head, ccs_proto_keyword
4090                                                [ptr->protocol]);
4091                                 ccs_set_space(head);
4092                                 first = false;
4093                         } else {
4094                                 ccs_set_slash(head);
4095                         }
4096                         ccs_set_string(head, ccs_socket_keyword[bit]);
4097                 }
4098                 if (first)
4099                         return true;
4100                 ccs_print_name_union(head, &ptr->name);
4101 #endif
4102 #ifdef CONFIG_CCSECURITY_IPC
4103         } else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
4104                 struct ccs_signal_acl *ptr =
4105                         container_of(acl, typeof(*ptr), head);
4106                 ccs_set_group(head, "ipc signal ");
4107                 ccs_print_number_union_nospace(head, &ptr->sig);
4108                 ccs_set_space(head);
4109                 ccs_set_string(head, ptr->domainname->name);
4110 #endif
4111         } else if (acl_type == CCS_TYPE_MOUNT_ACL) {
4112                 struct ccs_mount_acl *ptr =
4113                         container_of(acl, typeof(*ptr), head);
4114                 ccs_set_group(head, "file mount");
4115                 ccs_print_name_union(head, &ptr->dev_name);
4116                 ccs_print_name_union(head, &ptr->dir_name);
4117                 ccs_print_name_union(head, &ptr->fs_type);
4118                 ccs_print_number_union(head, &ptr->flags);
4119         }
4120         if (acl->cond) {
4121                 head->r.print_cond_part = true;
4122                 head->r.cond_step = 0;
4123                 if (!ccs_flush(head))
4124                         return false;
4125 print_cond_part:
4126                 if (!ccs_print_condition(head, acl->cond))
4127                         return false;
4128                 head->r.print_cond_part = false;
4129         } else {
4130                 ccs_set_lf(head);
4131         }
4132         return true;
4133 }
4134 
4135 /**
4136  * ccs_read_acl - Read "struct ccs_acl_info" list.
4137  *
4138  * @head: Pointer to "struct ccs_io_buffer".
4139  * @list: Pointer to "struct list_head".
4140  *
4141  * Returns true on success, false otherwise.
4142  *
4143  * Caller holds ccs_read_lock().
4144  */
4145 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list)
4146 {
4147         list_for_each_cookie(head->r.acl, list) {
4148                 struct ccs_acl_info *ptr =
4149                         list_entry(head->r.acl, typeof(*ptr), list);
4150                 if (!ccs_print_entry(head, ptr))
4151                         return false;
4152         }
4153         head->r.acl = NULL;
4154         return true;
4155 }
4156 
4157 /**
4158  * ccs_read_domain - Read domain policy.
4159  *
4160  * @head: Pointer to "struct ccs_io_buffer".
4161  *
4162  * Returns nothing.
4163  *
4164  * Caller holds ccs_read_lock().
4165  */
4166 static void ccs_read_domain(struct ccs_io_buffer *head)
4167 {
4168         if (head->r.eof)
4169                 return;
4170         list_for_each_cookie(head->r.domain, &ccs_domain_list) {
4171                 struct ccs_domain_info *domain =
4172                         list_entry(head->r.domain, typeof(*domain), list);
4173                 switch (head->r.step) {
4174                         u8 i;
4175                 case 0:
4176                         if (domain->is_deleted &&
4177                             !head->r.print_this_domain_only)
4178                                 continue;
4179                         /* Print domainname and flags. */
4180                         ccs_set_string(head, domain->domainname->name);
4181                         ccs_set_lf(head);
4182                         ccs_io_printf(head, "use_profile %u\n",
4183                                       domain->profile);
4184                         for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
4185                                 if (domain->flags[i])
4186                                         ccs_set_string(head, ccs_dif[i]);
4187                         head->r.index = 0;
4188                         head->r.step++;
4189                         /* fall through */
4190                         fallthrough;
4191                 case 1:
4192                         while (head->r.index < CCS_MAX_ACL_GROUPS) {
4193                                 i = head->r.index++;
4194                                 if (!test_bit(i, domain->group))
4195                                         continue;
4196                                 ccs_io_printf(head, "use_group %u\n", i);
4197                                 if (!ccs_flush(head))
4198                                         return;
4199                         }
4200                         head->r.index = 0;
4201                         head->r.step++;
4202                         ccs_set_lf(head);
4203                         /* fall through */
4204                         fallthrough;
4205                 case 2:
4206                         if (!ccs_read_acl(head, &domain->acl_info_list))
4207                                 return;
4208                         head->r.step++;
4209                         if (!ccs_set_lf(head))
4210                                 return;
4211                         /* fall through */
4212                         fallthrough;
4213                 case 3:
4214                         head->r.step = 0;
4215                         if (head->r.print_this_domain_only)
4216                                 goto done;
4217                 }
4218         }
4219 done:
4220         head->r.eof = true;
4221 }
4222 
4223 /**
4224  * ccs_write_pid - Specify PID to obtain domainname.
4225  *
4226  * @head: Pointer to "struct ccs_io_buffer".
4227  *
4228  * Returns 0.
4229  */
4230 static int ccs_write_pid(struct ccs_io_buffer *head)
4231 {
4232         head->r.eof = false;
4233         return 0;
4234 }
4235 
4236 /**
4237  * ccs_read_pid - Read information of a process.
4238  *
4239  * @head: Pointer to "struct ccs_io_buffer".
4240  *
4241  * Returns the domainname which the specified PID is in or
4242  * process information of the specified PID on success,
4243  * empty string otherwise.
4244  *
4245  * Caller holds ccs_read_lock().
4246  */
4247 static void ccs_read_pid(struct ccs_io_buffer *head)
4248 {
4249         char *buf = head->write_buf;
4250         bool task_info = false;
4251         bool global_pid = false;
4252         unsigned int pid;
4253         struct task_struct *p;
4254         struct ccs_domain_info *domain = NULL;
4255         u32 ccs_flags = 0;
4256         /* Accessing write_buf is safe because head->io_sem is held. */
4257         if (!buf) {
4258                 head->r.eof = true;
4259                 return; /* Do nothing if open(O_RDONLY). */
4260         }
4261         if (head->r.w_pos || head->r.eof)
4262                 return;
4263         head->r.eof = true;
4264         if (ccs_str_starts(&buf, "info "))
4265                 task_info = true;
4266         if (ccs_str_starts(&buf, "global-pid "))
4267                 global_pid = true;
4268         pid = (unsigned int) simple_strtoul(buf, NULL, 10);
4269         ccs_tasklist_lock();
4270 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
4271         if (global_pid)
4272                 p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns);
4273         else
4274                 p = ccsecurity_exports.find_task_by_vpid(pid);
4275 #else
4276         p = find_task_by_pid(pid);
4277 #endif
4278         if (p) {
4279                 domain = ccs_task_domain(p);
4280                 ccs_flags = ccs_task_flags(p);
4281         }
4282         ccs_tasklist_unlock();
4283         if (!domain)
4284                 return;
4285         if (!task_info) {
4286                 ccs_io_printf(head, "%u %u ", pid, domain->profile);
4287                 ccs_set_string(head, domain->domainname->name);
4288         } else {
4289                 ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid,
4290                               ccs_yesno(ccs_flags &
4291                                         CCS_TASK_IS_MANAGER),
4292                               ccs_yesno(ccs_flags &
4293                                         CCS_TASK_IS_EXECUTE_HANDLER));
4294         }
4295 }
4296 
4297 /**
4298  * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
4299  *
4300  * @param: Pointer to "struct ccs_acl_param".
4301  * @type:  Type of this group.
4302  *
4303  * Returns 0 on success, negative value otherwise.
4304  */
4305 static int ccs_write_group(struct ccs_acl_param *param, const u8 type)
4306 {
4307         struct ccs_group *group = ccs_get_group(param, type);
4308         int error = -EINVAL;
4309         if (!group)
4310                 return -ENOMEM;
4311         param->list = &group->member_list;
4312         if (type == CCS_PATH_GROUP) {
4313                 struct ccs_path_group *e = &param->e.path_group;
4314                 e->member_name = ccs_get_name(ccs_read_token(param));
4315                 if (!e->member_name) {
4316                         error = -ENOMEM;
4317                         goto out;
4318                 }
4319                 error = ccs_update_policy(sizeof(*e), param);
4320                 ccs_put_name(e->member_name);
4321         } else if (type == CCS_NUMBER_GROUP) {
4322                 struct ccs_number_group *e = &param->e.number_group;
4323                 if (param->data[0] == '@' ||
4324                     !ccs_parse_number_union(param, &e->number))
4325                         goto out;
4326                 error = ccs_update_policy(sizeof(*e), param);
4327 #ifdef CONFIG_CCSECURITY_NETWORK
4328         } else {
4329                 struct ccs_address_group *e = &param->e.address_group;
4330                 if (param->data[0] == '@' ||
4331                     !ccs_parse_ipaddr_union(param, &e->address))
4332                         goto out;
4333                 error = ccs_update_policy(sizeof(*e), param);
4334 #endif
4335         }
4336 out:
4337         ccs_put_group(group);
4338         return error;
4339 }
4340 
4341 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4342 /**
4343  * ccs_lport_reserved - Check whether local port is reserved or not.
4344  *
4345  * @port: Port number.
4346  *
4347  * Returns true if local port is reserved, false otherwise.
4348  */
4349 static bool __ccs_lport_reserved(const u16 port)
4350 {
4351         return ccs_reserved_port_map[port >> 3] & (1 << (port & 7))
4352                 ? true : false;
4353 }
4354 
4355 /**
4356  * ccs_write_reserved_port - Update "struct ccs_reserved" list.
4357  *
4358  * @param: Pointer to "struct ccs_acl_param".
4359  *
4360  * Returns 0 on success, negative value otherwise.
4361  *
4362  * Caller holds ccs_read_lock().
4363  */
4364 static int ccs_write_reserved_port(struct ccs_acl_param *param)
4365 {
4366         struct ccs_reserved *e = &param->e.reserved;
4367         struct ccs_policy_namespace *ns = param->ns;
4368         int error;
4369         u8 *tmp;
4370         if (param->data[0] == '@' ||
4371             !ccs_parse_number_union(param, &e->port) ||
4372             e->port.values[1] > 65535 || param->data[0])
4373                 return -EINVAL;
4374         param->list = &ns->policy_list[CCS_ID_RESERVEDPORT];
4375         error = ccs_update_policy(sizeof(*e), param);
4376         if (error)
4377                 return error;
4378         tmp = kzalloc(sizeof(ccs_reserved_port_map), CCS_GFP_FLAGS);
4379         if (!tmp)
4380                 return -ENOMEM;
4381         list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list,
4382                                  &ccs_ss) {
4383                 struct ccs_reserved *ptr;
4384                 struct list_head *list = &ns->policy_list[CCS_ID_RESERVEDPORT];
4385                 list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
4386                         unsigned int port;
4387                         if (ptr->head.is_deleted)
4388                                 continue;
4389                         for (port = ptr->port.values[0];
4390                              port <= ptr->port.values[1]; port++)
4391                                 tmp[port >> 3] |= 1 << (port & 7);
4392                 }
4393         }
4394         memmove(ccs_reserved_port_map, tmp, sizeof(ccs_reserved_port_map));
4395         kfree(tmp);
4396         /*
4397          * Since this feature is no-op by default, we don't need to register
4398          * this callback hook unless the first entry is added.
4399          */
4400         ccsecurity_ops.lport_reserved = __ccs_lport_reserved;
4401         return 0;
4402 }
4403 #endif
4404 
4405 /**
4406  * ccs_write_aggregator - Write "struct ccs_aggregator" list.
4407  *
4408  * @param: Pointer to "struct ccs_acl_param".
4409  *
4410  * Returns 0 on success, negative value otherwise.
4411  */
4412 static int ccs_write_aggregator(struct ccs_acl_param *param)
4413 {
4414         struct ccs_aggregator *e = &param->e.aggregator;
4415         int error = param->is_delete ? -ENOENT : -ENOMEM;
4416         const char *original_name = ccs_read_token(param);
4417         const char *aggregated_name = ccs_read_token(param);
4418         if (!ccs_correct_word(original_name) ||
4419             !ccs_correct_path(aggregated_name))
4420                 return -EINVAL;
4421         e->original_name = ccs_get_name(original_name);
4422         e->aggregated_name = ccs_get_name(aggregated_name);
4423         if (!e->original_name || !e->aggregated_name ||
4424             e->aggregated_name->is_patterned) /* No patterns allowed. */
4425                 goto out;
4426         param->list = &param->ns->policy_list[CCS_ID_AGGREGATOR];
4427         error = ccs_update_policy(sizeof(*e), param);
4428 out:
4429         ccs_put_name(e->original_name);
4430         ccs_put_name(e->aggregated_name);
4431         return error;
4432 }
4433 
4434 /**
4435  * ccs_write_transition_control - Write "struct ccs_transition_control" list.
4436  *
4437  * @param: Pointer to "struct ccs_acl_param".
4438  * @type:  Type of this entry.
4439  *
4440  * Returns 0 on success, negative value otherwise.
4441  */
4442 static int ccs_write_transition_control(struct ccs_acl_param *param,
4443                                         const u8 type)
4444 {
4445         struct ccs_transition_control *e = &param->e.transition_control;
4446         int error = param->is_delete ? -ENOENT : -ENOMEM;
4447         char *program = param->data;
4448         char *domainname = strstr(program, " from ");
4449         e->type = type;
4450         if (domainname) {
4451                 *domainname = '\0';
4452                 domainname += 6;
4453         } else if (type == CCS_TRANSITION_CONTROL_NO_KEEP ||
4454                    type == CCS_TRANSITION_CONTROL_KEEP) {
4455                 domainname = program;
4456                 program = NULL;
4457         }
4458         if (program && strcmp(program, "any")) {
4459                 if (!ccs_correct_path(program))
4460                         return -EINVAL;
4461                 e->program = ccs_get_name(program);
4462                 if (!e->program)
4463                         goto out;
4464         }
4465         if (domainname && strcmp(domainname, "any")) {
4466                 if (!ccs_correct_domain(domainname)) {
4467                         if (!ccs_correct_path(domainname))
4468                                 goto out;
4469                         e->is_last_name = true;
4470                 }
4471                 e->domainname = ccs_get_name(domainname);
4472                 if (!e->domainname)
4473                         goto out;
4474         }
4475         param->list = &param->ns->policy_list[CCS_ID_TRANSITION_CONTROL];
4476         error = ccs_update_policy(sizeof(*e), param);
4477 out:
4478         ccs_put_name(e->domainname);
4479         ccs_put_name(e->program);
4480         return error;
4481 }
4482 
4483 /**
4484  * ccs_write_exception - Write exception policy.
4485  *
4486  * @head: Pointer to "struct ccs_io_buffer".
4487  *
4488  * Returns 0 on success, negative value otherwise.
4489  */
4490 static int ccs_write_exception(struct ccs_io_buffer *head)
4491 {
4492         const bool is_delete = head->w.is_delete;
4493         struct ccs_acl_param param = {
4494                 .ns = head->w.ns,
4495                 .is_delete = is_delete,
4496                 .data = head->write_buf,
4497         };
4498         u8 i;
4499         /* Forced zero clear for using memcmp() at ccs_update_policy(). */
4500         memset(&param.e, 0, sizeof(param.e));
4501         if (ccs_str_starts(&param.data, "aggregator "))
4502                 return ccs_write_aggregator(&param);
4503 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4504         if (ccs_str_starts(&param.data, "deny_autobind "))
4505                 return ccs_write_reserved_port(&param);
4506 #endif
4507         for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
4508                 if (ccs_str_starts(&param.data, ccs_transition_type[i]))
4509                         return ccs_write_transition_control(&param, i);
4510         for (i = 0; i < CCS_MAX_GROUP; i++)
4511                 if (ccs_str_starts(&param.data, ccs_group_name[i]))
4512                         return ccs_write_group(&param, i);
4513         if (ccs_str_starts(&param.data, "acl_group ")) {
4514                 unsigned int group;
4515                 char *data;
4516                 group = simple_strtoul(param.data, &data, 10);
4517                 if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ')
4518                         return ccs_write_acl(head->w.ns,
4519                                              &head->w.ns->acl_group[group],
4520                                              data, is_delete);
4521         }
4522         return -EINVAL;
4523 }
4524 
4525 /**
4526  * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
4527  *
4528  * @head: Pointer to "struct ccs_io_buffer".
4529  * @idx:  Index number.
4530  *
4531  * Returns true on success, false otherwise.
4532  *
4533  * Caller holds ccs_read_lock().
4534  */
4535 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
4536 {
4537         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4538                                                        namespace_list);
4539         struct list_head *list = &ns->group_list[idx];
4540         list_for_each_cookie(head->r.group, list) {
4541                 struct ccs_group *group =
4542                         list_entry(head->r.group, typeof(*group), head.list);
4543                 list_for_each_cookie(head->r.acl, &group->member_list) {
4544                         struct ccs_acl_head *ptr =
4545                                 list_entry(head->r.acl, typeof(*ptr), list);
4546                         if (ptr->is_deleted)
4547                                 continue;
4548                         if (!ccs_flush(head))
4549                                 return false;
4550                         ccs_print_namespace(head);
4551                         ccs_set_string(head, ccs_group_name[idx]);
4552                         ccs_set_string(head, group->group_name->name);
4553                         if (idx == CCS_PATH_GROUP) {
4554                                 ccs_set_space(head);
4555                                 ccs_set_string(head, container_of
4556                                                (ptr, struct ccs_path_group,
4557                                                 head)->member_name->name);
4558                         } else if (idx == CCS_NUMBER_GROUP) {
4559                                 ccs_print_number_union(head, &container_of
4560                                                (ptr, struct ccs_number_group,
4561                                                 head)->number);
4562 #ifdef CONFIG_CCSECURITY_NETWORK
4563                         } else if (idx == CCS_ADDRESS_GROUP) {
4564                                 char buffer[128];
4565                                 struct ccs_address_group *member =
4566                                         container_of(ptr, typeof(*member),
4567                                                      head);
4568                                 ccs_print_ip(buffer, sizeof(buffer),
4569                                              &member->address);
4570                                 ccs_io_printf(head, " %s", buffer);
4571 #endif
4572                         }
4573                         ccs_set_lf(head);
4574                 }
4575                 head->r.acl = NULL;
4576         }
4577         head->r.group = NULL;
4578         return true;
4579 }
4580 
4581 /**
4582  * ccs_read_policy - Read "struct ccs_..._entry" list.
4583  *
4584  * @head: Pointer to "struct ccs_io_buffer".
4585  * @idx:  Index number.
4586  *
4587  * Returns true on success, false otherwise.
4588  *
4589  * Caller holds ccs_read_lock().
4590  */
4591 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
4592 {
4593         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4594                                                        namespace_list);
4595         struct list_head *list = &ns->policy_list[idx];
4596         list_for_each_cookie(head->r.acl, list) {
4597                 struct ccs_acl_head *acl =
4598                         container_of(head->r.acl, typeof(*acl), list);
4599                 if (acl->is_deleted)
4600                         continue;
4601                 if (head->r.print_transition_related_only &&
4602                     idx != CCS_ID_TRANSITION_CONTROL)
4603                         continue;
4604                 if (!ccs_flush(head))
4605                         return false;
4606                 switch (idx) {
4607                 case CCS_ID_TRANSITION_CONTROL:
4608                         {
4609                                 struct ccs_transition_control *ptr =
4610                                         container_of(acl, typeof(*ptr), head);
4611                                 ccs_print_namespace(head);
4612                                 ccs_set_string(head,
4613                                                ccs_transition_type[ptr->type]);
4614                                 ccs_set_string(head, ptr->program ?
4615                                                ptr->program->name : "any");
4616                                 ccs_set_string(head, " from ");
4617                                 ccs_set_string(head, ptr->domainname ?
4618                                                ptr->domainname->name : "any");
4619                         }
4620                         break;
4621                 case CCS_ID_AGGREGATOR:
4622                         {
4623                                 struct ccs_aggregator *ptr =
4624                                         container_of(acl, typeof(*ptr), head);
4625                                 ccs_print_namespace(head);
4626                                 ccs_set_string(head, "aggregator ");
4627                                 ccs_set_string(head, ptr->original_name->name);
4628                                 ccs_set_space(head);
4629                                 ccs_set_string(head,
4630                                                ptr->aggregated_name->name);
4631                         }
4632                         break;
4633 #ifdef CONFIG_CCSECURITY_PORTRESERVE
4634                 case CCS_ID_RESERVEDPORT:
4635                         {
4636                                 struct ccs_reserved *ptr =
4637                                         container_of(acl, typeof(*ptr), head);
4638                                 ccs_print_namespace(head);
4639                                 ccs_set_string(head, "deny_autobind ");
4640                                 ccs_print_number_union_nospace(head,
4641                                                                &ptr->port);
4642                         }
4643                         break;
4644 #endif
4645                 default:
4646                         continue;
4647                 }
4648                 ccs_set_lf(head);
4649         }
4650         head->r.acl = NULL;
4651         return true;
4652 }
4653 
4654 /**
4655  * ccs_read_exception - Read exception policy.
4656  *
4657  * @head: Pointer to "struct ccs_io_buffer".
4658  *
4659  * Returns nothing.
4660  *
4661  * Caller holds ccs_read_lock().
4662  */
4663 static void ccs_read_exception(struct ccs_io_buffer *head)
4664 {
4665         struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
4666                                                        namespace_list);
4667         if (head->r.eof)
4668                 return;
4669         while (head->r.step < CCS_MAX_POLICY &&
4670                ccs_read_policy(head, head->r.step))
4671                 head->r.step++;
4672         if (head->r.step < CCS_MAX_POLICY)
4673                 return;
4674         while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
4675                ccs_read_group(head, head->r.step - CCS_MAX_POLICY))
4676                 head->r.step++;
4677         if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
4678                 return;
4679         while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
4680                + CCS_MAX_ACL_GROUPS) {
4681                 head->r.acl_group_index =
4682                         head->r.step - CCS_MAX_POLICY - CCS_MAX_GROUP;
4683                 if (!ccs_read_acl(head, &ns->acl_group
4684                                   [head->r.acl_group_index]))
4685                         return;
4686                 head->r.step++;
4687         }
4688         head->r.eof = true;
4689 }
4690 
4691 /**
4692  * ccs_truncate - Truncate a line.
4693  *
4694  * @str: String to truncate.
4695  *
4696  * Returns length of truncated @str.
4697  */
4698 static int ccs_truncate(char *str)
4699 {
4700         char *start = str;
4701         while (*(unsigned char *) str > (unsigned char) ' ')
4702                 str++;
4703         *str = '\0';
4704         return strlen(start) + 1;
4705 }
4706 
4707 /**
4708  * ccs_add_entry - Add an ACL to current thread's domain. Used by learning mode.
4709  *
4710  * @header: Lines containing ACL.
4711  *
4712  * Returns nothing.
4713  */
4714 static void ccs_add_entry(char *header)
4715 {
4716         char *buffer;
4717         char *realpath = NULL;
4718         char *argv0 = NULL;
4719         char *symlink = NULL;
4720 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4721         char *handler;
4722 #endif
4723         char *cp = strchr(header, '\n');
4724         int len;
4725         if (!cp)
4726                 return;
4727         cp = strchr(cp + 1, '\n');
4728         if (!cp)
4729                 return;
4730         *cp++ = '\0';
4731         len = strlen(cp) + 1;
4732         /* strstr() will return NULL if ordering is wrong. */
4733         if (*cp == 'f') {
4734                 argv0 = strstr(header, " argv[]={ \"");
4735                 if (argv0) {
4736                         argv0 += 10;
4737                         len += ccs_truncate(argv0) + 14;
4738                 }
4739                 realpath = strstr(header, " exec={ realpath=\"");
4740                 if (realpath) {
4741                         realpath += 8;
4742                         len += ccs_truncate(realpath) + 6;
4743                 }
4744                 symlink = strstr(header, " symlink.target=\"");
4745                 if (symlink)
4746                         len += ccs_truncate(symlink + 1) + 1;
4747         }
4748 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4749         handler = strstr(header, "type=execute_handler");
4750         if (handler)
4751                 len += ccs_truncate(handler) + 6;
4752 #endif
4753         buffer = kmalloc(len, CCS_GFP_FLAGS);
4754         if (!buffer)
4755                 return;
4756         snprintf(buffer, len - 1, "%s", cp);
4757 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4758         if (handler)
4759                 ccs_addprintf(buffer, len, " task.%s", handler);
4760 #endif
4761         if (realpath)
4762                 ccs_addprintf(buffer, len, " exec.%s", realpath);
4763         if (argv0)
4764                 ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
4765         if (symlink)
4766                 ccs_addprintf(buffer, len, "%s", symlink);
4767         ccs_normalize_line(buffer);
4768         {
4769                 struct ccs_domain_info *domain = ccs_current_domain();
4770                 if (!ccs_write_acl(domain->ns, &domain->acl_info_list,
4771                                    buffer, false))
4772                         ccs_update_stat(CCS_STAT_POLICY_UPDATES);
4773         }
4774         kfree(buffer);
4775 }
4776 
4777 /**
4778  * ccs_domain_quota_ok - Check for domain's quota.
4779  *
4780  * @r: Pointer to "struct ccs_request_info".
4781  *
4782  * Returns true if the domain is not exceeded quota, false otherwise.
4783  *
4784  * Caller holds ccs_read_lock().
4785  */
4786 static bool ccs_domain_quota_ok(struct ccs_request_info *r)
4787 {
4788         unsigned int count = 0;
4789         struct ccs_domain_info * const domain = ccs_current_domain();
4790         struct ccs_acl_info *ptr;
4791         if (r->mode != CCS_CONFIG_LEARNING)
4792                 return false;
4793         if (!domain)
4794                 return true;
4795         if (domain->flags[CCS_DIF_QUOTA_WARNED])
4796                 return false;
4797         list_for_each_entry_srcu(ptr, &domain->acl_info_list, list, &ccs_ss) {
4798                 u16 perm;
4799                 if (ptr->is_deleted)
4800                         continue;
4801                 switch (ptr->type) {
4802                 case CCS_TYPE_PATH_ACL:
4803                 case CCS_TYPE_PATH2_ACL:
4804                 case CCS_TYPE_PATH_NUMBER_ACL:
4805                 case CCS_TYPE_MKDEV_ACL:
4806 #ifdef CONFIG_CCSECURITY_NETWORK
4807                 case CCS_TYPE_INET_ACL:
4808                 case CCS_TYPE_UNIX_ACL:
4809 #endif
4810                         perm = ptr->perm;
4811                         break;
4812 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
4813                 case CCS_TYPE_AUTO_EXECUTE_HANDLER:
4814                 case CCS_TYPE_DENIED_EXECUTE_HANDLER:
4815 #endif
4816 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
4817                 case CCS_TYPE_AUTO_TASK_ACL:
4818                 case CCS_TYPE_MANUAL_TASK_ACL:
4819 #endif
4820                         perm = 0;
4821                         break;
4822                 default:
4823                         perm = 1;
4824                 }
4825                 count += hweight16(perm);
4826         }
4827         if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY])
4828                 return true;
4829         domain->flags[CCS_DIF_QUOTA_WARNED] = true;
4830         /* r->granted = false; */
4831         ccs_write_log(r, "%s", ccs_dif[CCS_DIF_QUOTA_WARNED]);
4832         printk(KERN_WARNING "WARNING: Domain '%s' has too many ACLs to hold. "
4833                "Stopped learning mode.\n", domain->domainname->name);
4834         return false;
4835 }
4836 
4837 /**
4838  * ccs_supervisor - Ask for the supervisor's decision.
4839  *
4840  * @r:   Pointer to "struct ccs_request_info".
4841  * @fmt: The printf()'s format string, followed by parameters.
4842  *
4843  * Returns 0 if the supervisor decided to permit the access request which
4844  * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor
4845  * decided to retry the access request which violated the policy in enforcing
4846  * mode, 0 if it is not in enforcing mode, -EPERM otherwise.
4847  */
4848 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
4849 {
4850         va_list args;
4851         int error;
4852         int len;
4853         static unsigned int ccs_serial;
4854         struct ccs_query entry = { };
4855         bool quota_exceeded = false;
4856         va_start(args, fmt);
4857         len = vsnprintf((char *) &len, 1, fmt, args) + 1;
4858         va_end(args);
4859         /* Write /proc/ccs/audit. */
4860         va_start(args, fmt);
4861         ccs_write_log2(r, len, fmt, args);
4862         va_end(args);
4863         /* Nothing more to do if granted. */
4864         if (r->granted)
4865                 return 0;
4866         if (r->mode)
4867                 ccs_update_stat(r->mode);
4868         switch (r->mode) {
4869                 int i;
4870                 struct ccs_profile *p;
4871         case CCS_CONFIG_ENFORCING:
4872                 error = -EPERM;
4873                 if (atomic_read(&ccs_query_observers))
4874                         break;
4875                 if (r->dont_sleep_on_enforce_error)
4876                         goto out;
4877                 p = ccs_profile(r->profile);
4878                 /* Check enforcing_penalty parameter. */
4879                 for (i = 0; i < p->pref[CCS_PREF_ENFORCING_PENALTY]; i++) {
4880                         set_current_state(TASK_INTERRUPTIBLE);
4881                         schedule_timeout(HZ / 10);
4882                 }
4883                 goto out;
4884         case CCS_CONFIG_LEARNING:
4885                 error = 0;
4886                 /* Check max_learning_entry parameter. */
4887                 if (ccs_domain_quota_ok(r))
4888                         break;
4889                 /* fall through */
4890                 fallthrough;
4891         default:
4892                 return 0;
4893         }
4894         /* Get message. */
4895         va_start(args, fmt);
4896         entry.query = ccs_init_log(r, len, fmt, args);
4897         va_end(args);
4898         if (!entry.query)
4899                 goto out;
4900         entry.query_len = strlen(entry.query) + 1;
4901         if (!error) {
4902                 ccs_add_entry(entry.query);
4903                 goto out;
4904         }
4905         len = ccs_round2(entry.query_len);
4906         entry.domain = ccs_current_domain();
4907         spin_lock(&ccs_query_list_lock);
4908         if (ccs_memory_quota[CCS_MEMORY_QUERY] &&
4909             ccs_memory_used[CCS_MEMORY_QUERY] + len
4910             >= ccs_memory_quota[CCS_MEMORY_QUERY]) {
4911                 quota_exceeded = true;
4912         } else {
4913                 entry.serial = ccs_serial++;
4914                 entry.retry = r->retry;
4915                 ccs_memory_used[CCS_MEMORY_QUERY] += len;
4916                 list_add_tail(&entry.list, &ccs_query_list);
4917         }
4918         spin_unlock(&ccs_query_list_lock);
4919         if (quota_exceeded)
4920                 goto out;
4921         /* Give 10 seconds for supervisor's opinion. */
4922         while (entry.timer < 10) {
4923                 wake_up_all(&ccs_query_wait);
4924                 if (wait_event_interruptible_timeout
4925                     (ccs_answer_wait, entry.answer ||
4926                      !atomic_read(&ccs_query_observers), HZ))
4927                         break;
4928                 else
4929                         entry.timer++;
4930         }
4931         spin_lock(&ccs_query_list_lock);
4932         list_del(&entry.list);
4933         ccs_memory_used[CCS_MEMORY_QUERY] -= len;
4934         spin_unlock(&ccs_query_list_lock);
4935         switch (entry.answer) {
4936         case 3: /* Asked to retry by administrator. */
4937                 error = CCS_RETRY_REQUEST;
4938                 r->retry++;
4939                 break;
4940         case 1:
4941                 /* Granted by administrator. */
4942                 error = 0;
4943                 break;
4944         default:
4945                 /* Timed out or rejected by administrator. */
4946                 break;
4947         }
4948 out:
4949         kfree(entry.query);
4950         return error;
4951 }
4952 
4953 /**
4954  * ccs_audit_log - Audit permission check log.
4955  *
4956  * @r: Pointer to "struct ccs_request_info".
4957  *
4958  * Returns return value of ccs_supervisor().
4959  */
4960 int ccs_audit_log(struct ccs_request_info *r)
4961 {
4962         switch (r->param_type) {
4963                 u8 type;
4964                 char buf[48];
4965 #ifdef CONFIG_CCSECURITY_NETWORK
4966                 const u32 *address;
4967 #endif
4968         case CCS_TYPE_PATH_ACL:
4969                 return ccs_supervisor(r, "file %s %s\n", ccs_path_keyword
4970                                       [r->param.path.operation],
4971                                       r->param.path.filename->name);
4972         case CCS_TYPE_PATH2_ACL:
4973                 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
4974                                       [ccs_pp2mac[r->param.path2.operation]],
4975                                       r->param.path2.filename1->name,
4976                                       r->param.path2.filename2->name);
4977         case CCS_TYPE_PATH_NUMBER_ACL:
4978                 type = r->param.path_number.operation;
4979                 switch (type) {
4980                 case CCS_TYPE_CREATE:
4981                 case CCS_TYPE_MKDIR:
4982                 case CCS_TYPE_MKFIFO:
4983                 case CCS_TYPE_MKSOCK:
4984                 case CCS_TYPE_CHMOD:
4985                         snprintf(buf, sizeof(buf), "0%lo",
4986                                  r->param.path_number.number);
4987                         break;
4988                 case CCS_TYPE_IOCTL:
4989                         snprintf(buf, sizeof(buf), "0x%lX",
4990                                  r->param.path_number.number);
4991                         break;
4992                 default:
4993                         snprintf(buf, sizeof(buf), "%lu",
4994                                  r->param.path_number.number);
4995                         break;
4996                 }
4997                 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
4998                                       [ccs_pn2mac[type]],
4999                                       r->param.path_number.filename->name,
5000                                       buf);
5001         case CCS_TYPE_MKDEV_ACL:
5002                 return ccs_supervisor(r, "file %s %s 0%o %u %u\n",
5003                                       ccs_mac_keywords
5004                                       [ccs_pnnn2mac[r->param.mkdev.operation]],
5005                                       r->param.mkdev.filename->name,
5006                                       r->param.mkdev.mode,
5007                                       r->param.mkdev.major,
5008                                       r->param.mkdev.minor);
5009         case CCS_TYPE_MOUNT_ACL:
5010                 return ccs_supervisor(r, "file mount %s %s %s 0x%lX\n",
5011                                       r->param.mount.dev->name,
5012                                       r->param.mount.dir->name,
5013                                       r->param.mount.type->name,
5014                                       r->param.mount.flags);
5015 #ifdef CONFIG_CCSECURITY_MISC
5016         case CCS_TYPE_ENV_ACL:
5017                 return ccs_supervisor(r, "misc env %s\n",
5018                                       r->param.environ.name->name);
5019 #endif
5020 #ifdef CONFIG_CCSECURITY_CAPABILITY
5021         case CCS_TYPE_CAPABILITY_ACL:
5022                 return ccs_supervisor(r, "capability %s\n", ccs_mac_keywords
5023                                       [ccs_c2mac[r->param.capability.
5024                                                  operation]]);
5025 #endif
5026 #ifdef CONFIG_CCSECURITY_NETWORK
5027         case CCS_TYPE_INET_ACL:
5028                 address = r->param.inet_network.address;
5029                 if (r->param.inet_network.is_ipv6)
5030                         ccs_print_ipv6(buf, sizeof(buf),
5031                                        (const struct in6_addr *) address);
5032                 else
5033                         ccs_print_ipv4(buf, sizeof(buf), address);
5034                 return ccs_supervisor(r, "network inet %s %s %s %u\n",
5035                                       ccs_proto_keyword[r->param.inet_network.
5036                                                         protocol],
5037                                       ccs_socket_keyword[r->param.inet_network.
5038                                                          operation],
5039                                       buf, r->param.inet_network.port);
5040         case CCS_TYPE_UNIX_ACL:
5041                 return ccs_supervisor(r, "network unix %s %s %s\n",
5042                                       ccs_proto_keyword[r->param.
5043                                                         unix_network.protocol],
5044                                       ccs_socket_keyword[r->param.unix_network.
5045                                                          operation],
5046                                       r->param.unix_network.address->name);
5047 #endif
5048 #ifdef CONFIG_CCSECURITY_IPC
5049         case CCS_TYPE_SIGNAL_ACL:
5050                 return ccs_supervisor(r, "ipc signal %d %s\n",
5051                                       r->param.signal.sig,
5052                                       r->param.signal.dest_pattern);
5053 #endif
5054         }
5055         return 0;
5056 }
5057 
5058 /**
5059  * ccs_find_domain_by_qid - Get domain by query id.
5060  *
5061  * @serial: Query ID assigned by ccs_supervisor().
5062  *
5063  * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise.
5064  */
5065 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial)
5066 {
5067         struct ccs_query *ptr;
5068         struct ccs_domain_info *domain = NULL;
5069         spin_lock(&ccs_query_list_lock);
5070         list_for_each_entry(ptr, &ccs_query_list, list) {
5071                 if (ptr->serial != serial)
5072                         continue;
5073                 domain = ptr->domain;
5074                 break;
5075         }
5076         spin_unlock(&ccs_query_list_lock);
5077         return domain;
5078 }
5079 
5080 /**
5081  * ccs_read_query - Read access requests which violated policy in enforcing mode.
5082  *
5083  * @head: Pointer to "struct ccs_io_buffer".
5084  *
5085  * Returns nothing.
5086  */
5087 static void ccs_read_query(struct ccs_io_buffer *head)
5088 {
5089         struct list_head *tmp;
5090         unsigned int pos = 0;
5091         size_t len = 0;
5092         char *buf;
5093         if (head->r.w_pos)
5094                 return;
5095         kfree(head->read_buf);
5096         head->read_buf = NULL;
5097         spin_lock(&ccs_query_list_lock);
5098         list_for_each(tmp, &ccs_query_list) {
5099                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5100                 if (pos++ != head->r.query_index)
5101                         continue;
5102                 len = ptr->query_len;
5103                 break;
5104         }
5105         spin_unlock(&ccs_query_list_lock);
5106         if (!len) {
5107                 head->r.query_index = 0;
5108                 return;
5109         }
5110         buf = kzalloc(len + 32, CCS_GFP_FLAGS);
5111         if (!buf)
5112                 return;
5113         pos = 0;
5114         spin_lock(&ccs_query_list_lock);
5115         list_for_each(tmp, &ccs_query_list) {
5116                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5117                 if (pos++ != head->r.query_index)
5118                         continue;
5119                 /*
5120                  * Some query can be skipped because ccs_query_list
5121                  * can change, but I don't care.
5122                  */
5123                 if (len == ptr->query_len)
5124                         snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
5125                                  ptr->retry, ptr->query);
5126                 break;
5127         }
5128         spin_unlock(&ccs_query_list_lock);
5129         if (buf[0]) {
5130                 head->read_buf = buf;
5131                 head->r.w[head->r.w_pos++] = buf;
5132                 head->r.query_index++;
5133         } else {
5134                 kfree(buf);
5135         }
5136 }
5137 
5138 /**
5139  * ccs_write_answer - Write the supervisor's decision.
5140  *
5141  * @head: Pointer to "struct ccs_io_buffer".
5142  *
5143  * Returns 0 on success, -EINVAL otherwise.
5144  */
5145 static int ccs_write_answer(struct ccs_io_buffer *head)
5146 {
5147         char *data = head->write_buf;
5148         struct list_head *tmp;
5149         unsigned int serial;
5150         unsigned int answer;
5151         spin_lock(&ccs_query_list_lock);
5152         list_for_each(tmp, &ccs_query_list) {
5153                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5154                 ptr->timer = 0;
5155         }
5156         spin_unlock(&ccs_query_list_lock);
5157         if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
5158                 return -EINVAL;
5159         spin_lock(&ccs_query_list_lock);
5160         list_for_each(tmp, &ccs_query_list) {
5161                 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list);
5162                 if (ptr->serial != serial)
5163                         continue;
5164                 ptr->answer = (u8) answer;
5165                 /* Remove from ccs_query_list. */
5166                 if (ptr->answer) {
5167                         list_del(&ptr->list);
5168                         INIT_LIST_HEAD(&ptr->list);
5169                 }
5170                 break;
5171         }
5172         spin_unlock(&ccs_query_list_lock);
5173         wake_up_all(&ccs_answer_wait);
5174         return 0;
5175 }
5176 
5177 /**
5178  * ccs_read_version - Get version.
5179  *
5180  * @head: Pointer to "struct ccs_io_buffer".
5181  *
5182  * Returns nothing.
5183  */
5184 static void ccs_read_version(struct ccs_io_buffer *head)
5185 {
5186         if (head->r.eof)
5187                 return;
5188         ccs_set_string(head, "1.8.11");
5189         head->r.eof = true;
5190 }
5191 
5192 /**
5193  * ccs_update_stat - Update statistic counters.
5194  *
5195  * @index: Index for policy type.
5196  *
5197  * Returns nothing.
5198  */
5199 static void ccs_update_stat(const u8 index)
5200 {
5201 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
5202         struct timeval tv;
5203 #endif
5204 
5205         atomic_inc(&ccs_stat_updated[index]);
5206 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
5207         do_gettimeofday(&tv);
5208         ccs_stat_modified[index] = tv.tv_sec;
5209 #elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
5210         ccs_stat_modified[index] = get_seconds();
5211 #else
5212         ccs_stat_modified[index] = ktime_get_real_seconds();
5213 #endif
5214 }
5215 
5216 /**
5217  * ccs_read_stat - Read statistic data.
5218  *
5219  * @head: Pointer to "struct ccs_io_buffer".
5220  *
5221  * Returns nothing.
5222  */
5223 static void ccs_read_stat(struct ccs_io_buffer *head)
5224 {
5225         u8 i;
5226         unsigned int total = 0;
5227         if (head->r.eof)
5228                 return;
5229         for (i = 0; i < CCS_MAX_POLICY_STAT; i++) {
5230                 ccs_io_printf(head, "Policy %-30s %10u", ccs_policy_headers[i],
5231                               atomic_read(&ccs_stat_updated[i]));
5232                 if (ccs_stat_modified[i]) {
5233                         struct ccs_time stamp;
5234                         ccs_convert_time(ccs_stat_modified[i], &stamp);
5235                         ccs_io_printf(head, " (Last: %04u/%02u/%02u "
5236                                       "%02u:%02u:%02u)",
5237                                       stamp.year, stamp.month, stamp.day,
5238                                       stamp.hour, stamp.min, stamp.sec);
5239                 }
5240                 ccs_set_lf(head);
5241         }
5242         for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) {
5243                 unsigned int used = ccs_memory_used[i];
5244                 total += used;
5245                 ccs_io_printf(head, "Memory used by %-22s %10u",
5246                               ccs_memory_headers[i], used);
5247                 used = ccs_memory_quota[i];
5248                 if (used)
5249                         ccs_io_printf(head, " (Quota: %10u)", used);
5250                 ccs_set_lf(head);
5251         }
5252         ccs_io_printf(head, "Total memory used:                    %10u\n",
5253                       total);
5254         head->r.eof = true;
5255 }
5256 
5257 /**
5258  * ccs_write_stat - Set memory quota.
5259  *
5260  * @head: Pointer to "struct ccs_io_buffer".
5261  *
5262  * Returns 0.
5263  */
5264 static int ccs_write_stat(struct ccs_io_buffer *head)
5265 {
5266         char *data = head->write_buf;
5267         u8 i;
5268         if (ccs_str_starts(&data, "Memory used by "))
5269                 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++)
5270                         if (ccs_str_starts(&data, ccs_memory_headers[i])) {
5271                                 if (*data == ' ')
5272                                         data++;
5273                                 ccs_memory_quota[i] =
5274                                         simple_strtoul(data, NULL, 10);
5275                         }
5276         return 0;
5277 }
5278 
5279 /**
5280  * ccs_print_bprm - Print "struct linux_binprm" for auditing.
5281  *
5282  * @bprm: Pointer to "struct linux_binprm".
5283  * @dump: Pointer to "struct ccs_page_dump".
5284  *
5285  * Returns the contents of @bprm on success, NULL otherwise.
5286  *
5287  * This function uses kzalloc(), so caller must kfree() if this function
5288  * didn't return NULL.
5289  */
5290 static char *ccs_print_bprm(struct linux_binprm *bprm,
5291                             struct ccs_page_dump *dump)
5292 {
5293         static const int ccs_buffer_len = 4096 * 2;
5294         char *buffer = kzalloc(ccs_buffer_len, CCS_GFP_FLAGS);
5295         char *cp;
5296         char *last_start;
5297         int len;
5298         unsigned long pos = bprm->p;
5299         int offset = pos % PAGE_SIZE;
5300         int argv_count = bprm->argc;
5301         int envp_count = bprm->envc;
5302         bool truncated = false;
5303         if (!buffer)
5304                 return NULL;
5305         len = snprintf(buffer, ccs_buffer_len - 1, "argv[]={ ");
5306         cp = buffer + len;
5307         if (!argv_count) {
5308                 memmove(cp, "} envp[]={ ", 11);
5309                 cp += 11;
5310         }
5311         last_start = cp;
5312         while (argv_count || envp_count) {
5313                 if (!ccs_dump_page(bprm, pos, dump))
5314                         goto out;
5315                 pos += PAGE_SIZE - offset;
5316                 /* Read. */
5317                 while (offset < PAGE_SIZE) {
5318                         const char *kaddr = dump->data;
5319                         const unsigned char c = kaddr[offset++];
5320                         if (cp == last_start)
5321                                 *cp++ = '"';
5322                         if (cp >= buffer + ccs_buffer_len - 32) {
5323                                 /* Reserve some room for "..." string. */
5324                                 truncated = true;
5325                         } else if (c == '\\') {
5326                                 *cp++ = '\\';
5327                                 *cp++ = '\\';
5328                         } else if (c > ' ' && c < 127) {
5329                                 *cp++ = c;
5330                         } else if (!c) {
5331                                 *cp++ = '"';
5332                                 *cp++ = ' ';
5333                                 last_start = cp;
5334                         } else {
5335                                 *cp++ = '\\';
5336                                 *cp++ = (c >> 6) + '';
5337                                 *cp++ = ((c >> 3) & 7) + '';
5338                                 *cp++ = (c & 7) + '';
5339                         }
5340                         if (c)
5341                                 continue;
5342                         if (argv_count) {
5343                                 if (--argv_count == 0) {
5344                                         if (truncated) {
5345                                                 cp = last_start;
5346                                                 memmove(cp, "... ", 4);
5347                                                 cp += 4;
5348                                         }
5349                                         memmove(cp, "} envp[]={ ", 11);
5350                                         cp += 11;
5351                                         last_start = cp;
5352                                         truncated = false;
5353                                 }
5354                         } else if (envp_count) {
5355                                 if (--envp_count == 0) {
5356                                         if (truncated) {
5357                                                 cp = last_start;
5358                                                 memmove(cp, "... ", 4);
5359                                                 cp += 4;
5360                                         }
5361                                 }
5362                         }
5363                         if (!argv_count && !envp_count)
5364                                 break;
5365                 }
5366                 offset = 0;
5367         }
5368         *cp++ = '}';
5369         *cp = '\0';
5370         return buffer;
5371 out:
5372         snprintf(buffer, ccs_buffer_len - 1, "argv[]={ ... } envp[]= { ... }");
5373         return buffer;
5374 }
5375 
5376 /**
5377  * ccs_filetype - Get string representation of file type.
5378  *
5379  * @mode: Mode value for stat().
5380  *
5381  * Returns file type string.
5382  */
5383 static inline const char *ccs_filetype(const umode_t mode)
5384 {
5385         switch (mode & S_IFMT) {
5386         case S_IFREG:
5387         case 0:
5388                 return ccs_condition_keyword[CCS_TYPE_IS_FILE];
5389         case S_IFDIR:
5390                 return ccs_condition_keyword[CCS_TYPE_IS_DIRECTORY];
5391         case S_IFLNK:
5392                 return ccs_condition_keyword[CCS_TYPE_IS_SYMLINK];
5393         case S_IFIFO:
5394                 return ccs_condition_keyword[CCS_TYPE_IS_FIFO];
5395         case S_IFSOCK:
5396                 return ccs_condition_keyword[CCS_TYPE_IS_SOCKET];
5397         case S_IFBLK:
5398                 return ccs_condition_keyword[CCS_TYPE_IS_BLOCK_DEV];
5399         case S_IFCHR:
5400                 return ccs_condition_keyword[CCS_TYPE_IS_CHAR_DEV];
5401         }
5402         return "unknown"; /* This should not happen. */
5403 }
5404 
5405 /**
5406  * ccs_print_header - Get header line of audit log.
5407  *
5408  * @r: Pointer to "struct ccs_request_info".
5409  *
5410  * Returns string representation.
5411  *
5412  * This function uses kmalloc(), so caller must kfree() if this function
5413  * didn't return NULL.
5414  */
5415 static char *ccs_print_header(struct ccs_request_info *r)
5416 {
5417         struct ccs_time stamp;
5418         struct ccs_obj_info *obj = r->obj;
5419         const u32 ccs_flags = ccs_current_flags();
5420 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
5421         const pid_t gpid = ccs_sys_getpid();
5422 #else
5423         const pid_t gpid = task_pid_nr(current);
5424 #endif
5425         static const int ccs_buffer_len = 4096;
5426         char *buffer = kmalloc(ccs_buffer_len, CCS_GFP_FLAGS);
5427         int pos;
5428         u8 i;
5429         if (!buffer)
5430                 return NULL;
5431 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
5432         {
5433                 struct timeval tv;
5434                 do_gettimeofday(&tv);
5435                 ccs_convert_time(tv.tv_sec, &stamp);
5436         }
5437 #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
5438         ccs_convert_time(get_seconds(), &stamp);
5439 #else
5440         ccs_convert_time(ktime_get_real_seconds(), &stamp);
5441 #endif
5442         pos = snprintf(buffer, ccs_buffer_len - 1,
5443                        "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
5444                        "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
5445                        "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
5446                        "fsuid=%u fsgid=%u type%s=execute_handler }",
5447                        stamp.year, stamp.month, stamp.day, stamp.hour,
5448                        stamp.min, stamp.sec, r->profile, ccs_mode[r->mode],
5449                        ccs_yesno(r->granted), gpid, ccs_sys_getpid(),
5450                        ccs_sys_getppid(),
5451                        from_kuid(&init_user_ns, current_uid()),
5452                        from_kgid(&init_user_ns, current_gid()),
5453                        from_kuid(&init_user_ns, current_euid()),
5454                        from_kgid(&init_user_ns, current_egid()),
5455                        from_kuid(&init_user_ns, current_suid()),
5456                        from_kgid(&init_user_ns, current_sgid()),
5457                        from_kuid(&init_user_ns, current_fsuid()),
5458                        from_kgid(&init_user_ns, current_fsgid()),
5459                        ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ? "" : "!");
5460         if (!obj)
5461                 goto no_obj_info;
5462         if (!obj->validate_done) {
5463                 ccs_get_attributes(obj);
5464                 obj->validate_done = true;
5465         }
5466         for (i = 0; i < CCS_MAX_PATH_STAT; i++) {
5467                 struct ccs_mini_stat *stat;
5468                 unsigned int dev;
5469                 umode_t mode;
5470                 if (!obj->stat_valid[i])
5471                         continue;
5472                 stat = &obj->stat[i];
5473                 dev = stat->dev;
5474                 mode = stat->mode;
5475                 if (i & 1) {
5476                         pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos,
5477                                         " path%u.parent={ uid=%u gid=%u "
5478                                         "ino=%lu perm=0%o }", (i >> 1) + 1,
5479                                         from_kuid(&init_user_ns, stat->uid),
5480                                         from_kgid(&init_user_ns, stat->gid),
5481                                         (unsigned long) stat->ino,
5482                                         stat->mode & S_IALLUGO);
5483                         continue;
5484                 }
5485                 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos,
5486                                 " path%u={ uid=%u gid=%u ino=%lu major=%u"
5487                                 " minor=%u perm=0%o type=%s", (i >> 1) + 1,
5488                                 from_kuid(&init_user_ns, stat->uid),
5489                                 from_kgid(&init_user_ns, stat->gid),
5490                                 (unsigned long) stat->ino, MAJOR(dev),
5491                                 MINOR(dev), mode & S_IALLUGO,
5492                                 ccs_filetype(mode));
5493                 if (S_ISCHR(mode) || S_ISBLK(mode)) {
5494                         dev = stat->rdev;
5495                         pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos,
5496                                         " dev_major=%u dev_minor=%u",
5497                                         MAJOR(dev), MINOR(dev));
5498                 }
5499                 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, " }");
5500         }
5501 no_obj_info:
5502         if (pos < ccs_buffer_len - 1)
5503                 return buffer;
5504         kfree(buffer);
5505         return NULL;
5506 }
5507 
5508 /**
5509  * ccs_init_log - Allocate buffer for audit logs.
5510  *
5511  * @r:    Pointer to "struct ccs_request_info".
5512  * @len:  Buffer size needed for @fmt and @args.
5513  * @fmt:  The printf()'s format string.
5514  * @args: va_list structure for @fmt.
5515  *
5516  * Returns pointer to allocated memory.
5517  *
5518  * This function uses kzalloc(), so caller must kfree() if this function
5519  * didn't return NULL.
5520  */
5521 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt,
5522                           va_list args)
5523 {
5524         char *buf = NULL;
5525         char *bprm_info = NULL;
5526         char *realpath = NULL;
5527         const char *symlink = NULL;
5528         const char *header = NULL;
5529         int pos;
5530         const char *domainname = ccs_current_domain()->domainname->name;
5531         header = ccs_print_header(r);
5532         if (!header)
5533                 return NULL;
5534         /* +10 is for '\n' etc. and '\0'. */
5535         len += strlen(domainname) + strlen(header) + 10;
5536         if (r->ee) {
5537                 struct file *file = r->ee->bprm->file;
5538 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
5539                 struct path path = { file->f_vfsmnt, file->f_dentry };
5540                 realpath = ccs_realpath(&path);
5541 #else
5542                 realpath = ccs_realpath(&file->f_path);
5543 #endif
5544                 bprm_info = ccs_print_bprm(r->ee->bprm, &r->ee->dump);
5545                 if (!realpath || !bprm_info)
5546                         goto out;
5547                 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
5548                 len += strlen(realpath) + 80 + strlen(bprm_info);
5549         } else if (r->obj && r->obj->symlink_target) {
5550                 symlink = r->obj->symlink_target->name;
5551                 /* +18 is for " symlink.target=\"%s\"" */
5552                 len += 18 + strlen(symlink);
5553         }
5554         len = ccs_round2(len);
5555         buf = kzalloc(len, CCS_GFP_FLAGS);
5556         if (!buf)
5557                 goto out;
5558         len--;
5559         pos = snprintf(buf, len, "%s", header);
5560         if (realpath) {
5561                 struct linux_binprm *bprm = r->ee->bprm;
5562                 pos += snprintf(buf + pos, len - pos,
5563                                 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
5564                                 realpath, bprm->argc, bprm->envc, bprm_info);
5565         } else if (symlink)
5566                 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
5567                                 symlink);
5568         pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
5569         vsnprintf(buf + pos, len - pos, fmt, args);
5570 out:
5571         kfree(realpath);
5572         kfree(bprm_info);
5573         kfree(header);
5574         return buf;
5575 }
5576 
5577 /**
5578  * ccs_transition_failed - Print waning message and send signal when domain transition failed.
5579  *
5580  * @domainname: Name of domain to transit.
5581  *
5582  * Returns nothing.
5583  *
5584  * Note that if current->pid == 1, sending SIGKILL won't work.
5585  */
5586 void ccs_transition_failed(const char *domainname)
5587 {
5588         printk(KERN_WARNING
5589                "ERROR: Unable to transit to '%s' domain.\n", domainname);
5590 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0)
5591         force_sig(SIGKILL, current);
5592 #else
5593         force_sig(SIGKILL);
5594 #endif
5595 }
5596 
5597 /**
5598  * ccs_update_task_domain - Update task's domain.
5599  *
5600  * @r: Pointer to "struct ccs_request_info".
5601  *
5602  * Returns nothing.
5603  *
5604  * The task will retry as hard as possible. But if domain transition failed,
5605  * the task will be killed by SIGKILL.
5606  */
5607 static void ccs_update_task_domain(struct ccs_request_info *r)
5608 {
5609         char *buf;
5610         const char *cp;
5611         const struct ccs_acl_info *acl = r->matched_acl;
5612         if (!acl || !acl->cond || !acl->cond->transit ||
5613             acl->cond->exec_transit)
5614                 return;
5615         while (1) {
5616                 buf = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
5617                 if (buf)
5618                         break;
5619                 ssleep(1);
5620                 if (fatal_signal_pending(current))
5621                         return;
5622         }
5623         cp = acl->cond->transit->name;
5624         if (!ccs_domain_def(cp))
5625                 snprintf(buf, CCS_EXEC_TMPSIZE - 1, "%s %s",
5626                          ccs_current_domain()->domainname->name, cp);
5627         else
5628                 strncpy(buf, cp, CCS_EXEC_TMPSIZE - 1);
5629         if (!ccs_assign_domain(buf, true))
5630                 ccs_transition_failed(buf);
5631         kfree(buf);
5632 }
5633 
5634 /**
5635  * ccs_get_audit - Get audit mode.
5636  *
5637  * @r: Pointer to "struct ccs_request_info".
5638  *
5639  * Returns true if this request should be audited, false otherwise.
5640  */
5641 static bool ccs_get_audit(const struct ccs_request_info *r)
5642 {
5643         const struct ccs_acl_info *matched_acl = r->matched_acl;
5644         const u8 profile = r->profile;
5645         const u8 index = r->type;
5646         const bool is_granted = r->granted;
5647         u8 mode;
5648         struct ccs_profile *p;
5649         if (!ccs_policy_loaded)
5650                 return false;
5651         p = ccs_profile(profile);
5652         if (ccs_log_count >= p->pref[CCS_PREF_MAX_AUDIT_LOG])
5653                 return false;
5654         if (is_granted && matched_acl && matched_acl->cond &&
5655             matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO)
5656                 return matched_acl->cond->grant_log == CCS_GRANTLOG_YES;
5657         mode = p->config[index];
5658         if (mode == CCS_CONFIG_USE_DEFAULT)
5659                 mode = p->config
5660                         [ccs_index2category[index] + CCS_MAX_MAC_INDEX];
5661         if (mode == CCS_CONFIG_USE_DEFAULT)
5662                 mode = p->default_config;
5663         if (is_granted)
5664                 return mode & CCS_CONFIG_WANT_GRANT_LOG;
5665         return mode & CCS_CONFIG_WANT_REJECT_LOG;
5666 }
5667 
5668 /**
5669  * ccs_write_log2 - Write an audit log.
5670  *
5671  * @r:    Pointer to "struct ccs_request_info".
5672  * @len:  Buffer size needed for @fmt and @args.
5673  * @fmt:  The printf()'s format string.
5674  * @args: va_list structure for @fmt.
5675  *
5676  * Returns nothing.
5677  */
5678 static void ccs_write_log2(struct ccs_request_info *r, int len,
5679                            const char *fmt, va_list args)
5680 {
5681         char *buf;
5682         struct ccs_log *entry;
5683         bool quota_exceeded = false;
5684         if (!ccs_get_audit(r))
5685                 goto out;
5686         buf = ccs_init_log(r, len, fmt, args);
5687         if (!buf)
5688                 goto out;
5689         entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
5690         if (!entry) {
5691                 kfree(buf);
5692                 goto out;
5693         }
5694         entry->log = buf;
5695         len = ccs_round2(strlen(buf) + 1);
5696         /*
5697          * The entry->size is used for memory quota checks.
5698          * Don't go beyond strlen(entry->log).
5699          */
5700         entry->size = len + ccs_round2(sizeof(*entry));
5701         spin_lock(&ccs_log_lock);
5702         if (ccs_memory_quota[CCS_MEMORY_AUDIT] &&
5703             ccs_memory_used[CCS_MEMORY_AUDIT] + entry->size >=
5704             ccs_memory_quota[CCS_MEMORY_AUDIT]) {
5705                 quota_exceeded = true;
5706         } else {
5707                 ccs_memory_used[CCS_MEMORY_AUDIT] += entry->size;
5708                 list_add_tail(&entry->list, &ccs_log);
5709                 ccs_log_count++;
5710         }
5711         spin_unlock(&ccs_log_lock);
5712         if (quota_exceeded) {
5713                 kfree(buf);
5714                 kfree(entry);
5715                 goto out;
5716         }
5717         wake_up(&ccs_log_wait);
5718 out:
5719         ccs_update_task_domain(r);
5720 }
5721 
5722 /**
5723  * ccs_write_log - Write an audit log.
5724  *
5725  * @r:   Pointer to "struct ccs_request_info".
5726  * @fmt: The printf()'s format string, followed by parameters.
5727  *
5728  * Returns nothing.
5729  */
5730 void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
5731 {
5732         va_list args;
5733         int len;
5734         va_start(args, fmt);
5735         len = vsnprintf((char *) &len, 1, fmt, args) + 1;
5736         va_end(args);
5737         va_start(args, fmt);
5738         ccs_write_log2(r, len, fmt, args);
5739         va_end(args);
5740 }
5741 
5742 /**
5743  * ccs_read_log - Read an audit log.
5744  *
5745  * @head: Pointer to "struct ccs_io_buffer".
5746  *
5747  * Returns nothing.
5748  */
5749 static void ccs_read_log(struct ccs_io_buffer *head)
5750 {
5751         struct ccs_log *ptr = NULL;
5752         if (head->r.w_pos)
5753                 return;
5754         kfree(head->read_buf);
5755         head->read_buf = NULL;
5756         spin_lock(&ccs_log_lock);
5757         if (!list_empty(&ccs_log)) {
5758                 ptr = list_entry(ccs_log.next, typeof(*ptr), list);
5759                 list_del(&ptr->list);
5760                 ccs_log_count--;
5761                 ccs_memory_used[CCS_MEMORY_AUDIT] -= ptr->size;
5762         }
5763         spin_unlock(&ccs_log_lock);
5764         if (ptr) {
5765                 head->read_buf = ptr->log;
5766                 head->r.w[head->r.w_pos++] = head->read_buf;
5767                 kfree(ptr);
5768         }
5769 }
5770 
5771 /**
5772  * ccs_set_namespace_cursor - Set namespace to read.
5773  *
5774  * @head: Pointer to "struct ccs_io_buffer".
5775  *
5776  * Returns nothing.
5777  */
5778 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head)
5779 {
5780         struct list_head *ns;
5781         if (head->type != CCS_EXCEPTION_POLICY && head->type != CCS_PROFILE)
5782                 return;
5783         /*
5784          * If this is the first read, or reading previous namespace finished
5785          * and has more namespaces to read, update the namespace cursor.
5786          */
5787         ns = head->r.ns;
5788         if (!ns || (head->r.eof && ns->next != &ccs_namespace_list)) {
5789                 /* Clearing is OK because ccs_flush() returned true. */
5790                 memset(&head->r, 0, sizeof(head->r));
5791                 head->r.ns = ns ? ns->next : ccs_namespace_list.next;
5792         }
5793 }
5794 
5795 /**
5796  * ccs_has_more_namespace - Check for unread namespaces.
5797  *
5798  * @head: Pointer to "struct ccs_io_buffer".
5799  *
5800  * Returns true if we have more entries to print, false otherwise.
5801  */
5802 static bool ccs_has_more_namespace(struct ccs_io_buffer *head)
5803 {
5804         return (head->type == CCS_EXCEPTION_POLICY ||
5805                 head->type == CCS_PROFILE) && head->r.eof &&
5806                 head->r.ns->next != &ccs_namespace_list;
5807 }
5808 
5809 /**
5810  * ccs_find_namespace - Find specified namespace.
5811  *
5812  * @name: Name of namespace to find.
5813  * @len:  Length of @name.
5814  *
5815  * Returns pointer to "struct ccs_policy_namespace" if found, NULL otherwise.
5816  *
5817  * Caller holds ccs_read_lock().
5818  */
5819 static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
5820                                                        const unsigned int len)
5821 {
5822         struct ccs_policy_namespace *ns;
5823         list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list,
5824                                  &ccs_ss) {
5825                 if (strncmp(name, ns->name, len) ||
5826                     (name[len] && name[len] != ' '))
5827                         continue;
5828                 return ns;
5829         }
5830         return NULL;
5831 }
5832 
5833 /**
5834  * ccs_assign_namespace - Create a new namespace.
5835  *
5836  * @domainname: Name of namespace to create.
5837  *
5838  * Returns pointer to "struct ccs_policy_namespace" on success, NULL otherwise.
5839  *
5840  * Caller holds ccs_read_lock().
5841  */
5842 static struct ccs_policy_namespace *ccs_assign_namespace
5843 (const char *domainname)
5844 {
5845         struct ccs_policy_namespace *ptr;
5846         struct ccs_policy_namespace *entry;
5847         const char *cp = domainname;
5848         unsigned int len = 0;
5849         while (*cp && *cp++ != ' ')
5850                 len++;
5851         ptr = ccs_find_namespace(domainname, len);
5852         if (ptr)
5853                 return ptr;
5854         if (len >= CCS_EXEC_TMPSIZE - 10 || !ccs_domain_def(domainname))
5855                 return NULL;
5856         entry = kzalloc(sizeof(*entry) + len + 1, CCS_GFP_FLAGS);
5857         if (!entry)
5858                 return NULL;
5859         if (mutex_lock_interruptible(&ccs_policy_lock))
5860                 goto out;
5861         ptr = ccs_find_namespace(domainname, len);
5862         if (!ptr && ccs_memory_ok(entry, sizeof(*entry) + len + 1)) {
5863                 char *name = (char *) (entry + 1);
5864                 ptr = entry;
5865                 memmove(name, domainname, len);
5866                 name[len] = '\0';
5867                 entry->name = name;
5868                 ccs_init_policy_namespace(entry);
5869                 entry = NULL;
5870         }
5871         mutex_unlock(&ccs_policy_lock);
5872 out:
5873         kfree(entry);
5874         return ptr;
5875 }
5876 
5877 /**
5878  * ccs_namespace_jump - Check for namespace jump.
5879  *
5880  * @domainname: Name of domain.
5881  *
5882  * Returns true if namespace differs, false otherwise.
5883  */
5884 static bool ccs_namespace_jump(const char *domainname)
5885 {
5886         const char *namespace = ccs_current_namespace()->name;
5887         const int len = strlen(namespace);
5888         return strncmp(domainname, namespace, len) ||
5889                 (domainname[len] && domainname[len] != ' ');
5890 }
5891 
5892 /**
5893  * ccs_assign_domain - Create a domain or a namespace.
5894  *
5895  * @domainname: The name of domain.
5896  * @transit:    True if transit to domain found or created.
5897  *
5898  * Returns pointer to "struct ccs_domain_info" on success, NULL otherwise.
5899  *
5900  * Caller holds ccs_read_lock().
5901  */
5902 struct ccs_domain_info *ccs_assign_domain(const char *domainname,
5903                                           const bool transit)
5904 {
5905         struct ccs_security *security = ccs_current_security();
5906         struct ccs_domain_info e = { };
5907         struct ccs_domain_info *entry = ccs_find_domain(domainname);
5908         bool created = false;
5909         if (entry) {
5910                 if (transit) {
5911                         /*
5912                          * Since namespace is created at runtime, profiles may
5913                          * not be created by the moment the process transits to
5914                          * that domain. Do not perform domain transition if
5915                          * profile for that domain is not yet created.
5916                          */
5917                         if (ccs_policy_loaded &&
5918                             !entry->ns->profile_ptr[entry->profile])
5919                                 return NULL;
5920                         security->ccs_domain_info = entry;
5921                 }
5922                 return entry;
5923         }
5924         /* Requested domain does not exist. */
5925         /* Don't create requested domain if domainname is invalid. */
5926         if (strlen(domainname) >= CCS_EXEC_TMPSIZE - 10 ||
5927             !ccs_correct_domain(domainname))
5928                 return NULL;
5929         /*
5930          * Since definition of profiles and acl_groups may differ across
5931          * namespaces, do not inherit "use_profile" and "use_group" settings
5932          * by automatically creating requested domain upon domain transition.
5933          */
5934         if (transit && ccs_namespace_jump(domainname))
5935                 return NULL;
5936         e.ns = ccs_assign_namespace(domainname);
5937         if (!e.ns)
5938                 return NULL;
5939         /*
5940          * "use_profile" and "use_group" settings for automatically created
5941          * domains are inherited from current domain. These are 0 for manually
5942          * created domains.
5943          */
5944         if (transit) {
5945                 const struct ccs_domain_info *domain =
5946                         security->ccs_domain_info;
5947                 e.profile = domain->profile;
5948                 memcpy(e.group, domain->group, sizeof(e.group));
5949         }
5950         e.domainname = ccs_get_name(domainname);
5951         if (!e.domainname)
5952                 return NULL;
5953         if (mutex_lock_interruptible(&ccs_policy_lock))
5954                 goto out;
5955         entry = ccs_find_domain(domainname);
5956         if (!entry) {
5957                 entry = ccs_commit_ok(&e, sizeof(e));
5958                 if (entry) {
5959                         INIT_LIST_HEAD(&entry->acl_info_list);
5960                         list_add_tail_rcu(&entry->list, &ccs_domain_list);
5961                         created = true;
5962                 }
5963         }
5964         mutex_unlock(&ccs_policy_lock);
5965 out:
5966         ccs_put_name(e.domainname);
5967         if (entry && transit) {
5968                 security->ccs_domain_info = entry;
5969                 if (created) {
5970                         struct ccs_request_info r;
5971                         int i;
5972                         ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);
5973                         r.granted = false;
5974                         ccs_write_log(&r, "use_profile %u\n", entry->profile);
5975                         for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
5976                                 if (test_bit(i, entry->group))
5977                                         ccs_write_log(&r, "use_group %u\n", i);
5978                         ccs_update_stat(CCS_STAT_POLICY_UPDATES);
5979                 }
5980         }
5981         return entry;
5982 }
5983 
5984 /**
5985  * ccs_parse_policy - Parse a policy line.
5986  *
5987  * @head: Pointer to "struct ccs_io_buffer".
5988  * @line: Line to parse.
5989  *
5990  * Returns 0 on success, negative value otherwise.
5991  *
5992  * Caller holds ccs_read_lock().
5993  */
5994 static int ccs_parse_policy(struct ccs_io_buffer *head, char *line)
5995 {
5996         /* Delete request? */
5997         head->w.is_delete = !strncmp(line, "delete ", 7);
5998         if (head->w.is_delete)
5999                 memmove(line, line + 7, strlen(line + 7) + 1);
6000         /* Selecting namespace to update. */
6001         if (head->type == CCS_EXCEPTION_POLICY || head->type == CCS_PROFILE) {
6002                 if (*line == '<') {
6003                         char *cp = strchr(line, ' ');
6004                         if (cp) {
6005                                 *cp++ = '\0';
6006                                 head->w.ns = ccs_assign_namespace(line);
6007                                 memmove(line, cp, strlen(cp) + 1);
6008                         } else
6009                                 head->w.ns = NULL;
6010                 } else
6011                         head->w.ns = &ccs_kernel_namespace;
6012                 /* Don't allow updating if namespace is invalid. */
6013                 if (!head->w.ns)
6014                         return -ENOENT;
6015         }
6016         /* Do the update. */
6017         switch (head->type) {
6018         case CCS_DOMAIN_POLICY:
6019                 return ccs_write_domain(head);
6020         case CCS_EXCEPTION_POLICY:
6021                 return ccs_write_exception(head);
6022 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
6023         case CCS_EXECUTE_HANDLER:
6024 #endif
6025         case CCS_PROCESS_STATUS:
6026                 return ccs_write_pid(head);
6027         case CCS_STAT:
6028                 return ccs_write_stat(head);
6029         case CCS_PROFILE:
6030                 return ccs_write_profile(head);
6031         case CCS_QUERY:
6032                 return ccs_write_answer(head);
6033         case CCS_MANAGER:
6034                 return ccs_write_manager(head);
6035         default:
6036                 return -EINVAL;
6037         }
6038 }
6039 
6040 /**
6041  * ccs_policy_io_init - Register hooks for policy I/O.
6042  *
6043  * Returns nothing.
6044  */
6045 static void __init ccs_policy_io_init(void)
6046 {
6047         ccsecurity_ops.check_profile = ccs_check_profile;
6048 }
6049 
6050 /**
6051  * ccs_load_builtin_policy - Load built-in policy.
6052  *
6053  * Returns nothing.
6054  */
6055 static void __init ccs_load_builtin_policy(void)
6056 {
6057         /*
6058          * This include file is manually created and contains built-in policy
6059          * named "ccs_builtin_profile", "ccs_builtin_exception_policy",
6060          * "ccs_builtin_domain_policy", "ccs_builtin_manager",
6061          * "ccs_builtin_stat" in the form of "static char [] __initdata".
6062          */
6063 #include "builtin-policy.h"
6064         u8 i;
6065         const int idx = ccs_read_lock();
6066         for (i = 0; i < 5; i++) {
6067                 struct ccs_io_buffer head = { };
6068                 char *start = "";
6069                 switch (i) {
6070                 case 0:
6071                         start = ccs_builtin_profile;
6072                         head.type = CCS_PROFILE;
6073                         break;
6074                 case 1:
6075                         start = ccs_builtin_exception_policy;
6076                         head.type = CCS_EXCEPTION_POLICY;
6077                         break;
6078                 case 2:
6079                         start = ccs_builtin_domain_policy;
6080                         head.type = CCS_DOMAIN_POLICY;
6081                         break;
6082                 case 3:
6083                         start = ccs_builtin_manager;
6084                         head.type = CCS_MANAGER;
6085                         break;
6086                 case 4:
6087                         start = ccs_builtin_stat;
6088                         head.type = CCS_STAT;
6089                         break;
6090                 }
6091                 while (1) {
6092                         char *end = strchr(start, '\n');
6093                         if (!end)
6094                                 break;
6095                         *end = '\0';
6096                         ccs_normalize_line(start);
6097                         head.write_buf = start;
6098                         ccs_parse_policy(&head, start);
6099                         start = end + 1;
6100                 }
6101         }
6102         ccs_read_unlock(idx);
6103 #ifdef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
6104         ccs_check_profile();
6105 #endif
6106 }
6107 
6108 /**
6109  * ccs_read_self - read() for /proc/ccs/self_domain interface.
6110  *
6111  * @file:  Pointer to "struct file".
6112  * @buf:   Domainname which current thread belongs to.
6113  * @count: Size of @buf.
6114  * @ppos:  Bytes read by now.
6115  *
6116  * Returns read size on success, negative value otherwise.
6117  */
6118 static ssize_t ccs_read_self(struct file *file, char __user *buf, size_t count,
6119                              loff_t *ppos)
6120 {
6121         const char *domain = ccs_current_domain()->domainname->name;
6122         loff_t len = strlen(domain);
6123         loff_t pos = *ppos;
6124         if (pos >= len || !count)
6125                 return 0;
6126         len -= pos;
6127         if (count < len)
6128                 len = count;
6129         if (copy_to_user(buf, domain + pos, len))
6130                 return -EFAULT;
6131         *ppos += len;
6132         return len;
6133 }
6134 
6135 /**
6136  * ccs_open - open() for /proc/ccs/ interface.
6137  *
6138  * @inode: Pointer to "struct inode".
6139  * @file:  Pointer to "struct file".
6140  *
6141  * Returns 0 on success, negative value otherwise.
6142  */
6143 static int ccs_open(struct inode *inode, struct file *file)
6144 {
6145 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) || (defined(RHEL_MAJOR) && RHEL_MAJOR == 9 && defined(RHEL_MINOR) && RHEL_MINOR >= 1)
6146         const u8 type = (unsigned long) pde_data(inode);
6147 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
6148         const u8 type = (unsigned long) PDE_DATA(inode);
6149 #else
6150         const u8 type = (unsigned long) PDE(inode)->data;
6151 #endif
6152         struct ccs_io_buffer *head = kzalloc(sizeof(*head), CCS_GFP_FLAGS);
6153         if (!head)
6154                 return -ENOMEM;
6155         mutex_init(&head->io_sem);
6156         head->type = type;
6157 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
6158         if (type == CCS_EXECUTE_HANDLER) {
6159                 /* Allow execute_handler to read process's status. */
6160                 if (!(ccs_current_flags() & CCS_TASK_IS_EXECUTE_HANDLER)) {
6161                         kfree(head);
6162                         return -EPERM;
6163                 }
6164         }
6165 #endif
6166         if ((file->f_mode & FMODE_READ) && type != CCS_AUDIT &&
6167             type != CCS_QUERY) {
6168                 /* Don't allocate read_buf for poll() access. */
6169                 head->readbuf_size = 4096;
6170                 head->read_buf = kzalloc(head->readbuf_size, CCS_GFP_FLAGS);
6171                 if (!head->read_buf) {
6172                         kfree(head);
6173                         return -ENOMEM;
6174                 }
6175         }
6176         if (file->f_mode & FMODE_WRITE) {
6177                 head->writebuf_size = 4096;
6178                 head->write_buf = kzalloc(head->writebuf_size, CCS_GFP_FLAGS);
6179                 if (!head->write_buf) {
6180                         kfree(head->read_buf);
6181                         kfree(head);
6182                         return -ENOMEM;
6183                 }
6184         }
6185         /*
6186          * If the file is /proc/ccs/query, increment the observer counter.
6187          * The obserber counter is used by ccs_supervisor() to see if
6188          * there is some process monitoring /proc/ccs/query.
6189          */
6190         if (type == CCS_QUERY)
6191                 atomic_inc(&ccs_query_observers);
6192         file->private_data = head;
6193         ccs_notify_gc(head, true);
6194         return 0;
6195 }
6196 
6197 /**
6198  * ccs_release - close() for /proc/ccs/ interface.
6199  *
6200  * @inode: Pointer to "struct inode".
6201  * @file:  Pointer to "struct file".
6202  *
6203  * Returns 0.
6204  */
6205 static int ccs_release(struct inode *inode, struct file *file)
6206 {
6207         struct ccs_io_buffer *head = file->private_data;
6208         /*
6209          * If the file is /proc/ccs/query, decrement the observer counter.
6210          */
6211         if (head->type == CCS_QUERY &&
6212             atomic_dec_and_test(&ccs_query_observers))
6213                 wake_up_all(&ccs_answer_wait);
6214         ccs_notify_gc(head, false);
6215         return 0;
6216 }
6217 
6218 /**
6219  * ccs_poll - poll() for /proc/ccs/ interface.
6220  *
6221  * @file: Pointer to "struct file".
6222  * @wait: Pointer to "poll_table". Maybe NULL.
6223  *
6224  * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write,
6225  * POLLOUT | POLLWRNORM otherwise.
6226  */
6227 static unsigned int ccs_poll(struct file *file, poll_table *wait)
6228 {
6229         struct ccs_io_buffer *head = file->private_data;
6230         if (head->type == CCS_AUDIT) {
6231                 if (!ccs_memory_used[CCS_MEMORY_AUDIT]) {
6232                         poll_wait(file, &ccs_log_wait, wait);
6233                         if (!ccs_memory_used[CCS_MEMORY_AUDIT])
6234                                 return POLLOUT | POLLWRNORM;
6235                 }
6236         } else if (head->type == CCS_QUERY) {
6237                 if (list_empty(&ccs_query_list)) {
6238                         poll_wait(file, &ccs_query_wait, wait);
6239                         if (list_empty(&ccs_query_list))
6240                                 return POLLOUT | POLLWRNORM;
6241                 }
6242         }
6243         return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM;
6244 }
6245 
6246 /**
6247  * ccs_read - read() for /proc/ccs/ interface.
6248  *
6249  * @file:  Pointer to "struct file".
6250  * @buf:   Pointer to buffer.
6251  * @count: Size of @buf.
6252  * @ppos:  Unused.
6253  *
6254  * Returns bytes read on success, negative value otherwise.
6255  */
6256 static ssize_t ccs_read(struct file *file, char __user *buf, size_t count,
6257                         loff_t *ppos)
6258 {
6259         struct ccs_io_buffer *head = file->private_data;
6260         int len;
6261         int idx;
6262         if (mutex_lock_interruptible(&head->io_sem))
6263                 return -EINTR;
6264         head->read_user_buf = buf;
6265         head->read_user_buf_avail = count;
6266         idx = ccs_read_lock();
6267         if (ccs_flush(head))
6268                 /* Call the policy handler. */
6269                 do {
6270                         ccs_set_namespace_cursor(head);
6271                         switch (head->type) {
6272                         case CCS_DOMAIN_POLICY:
6273                                 ccs_read_domain(head);
6274                                 break;
6275                         case CCS_EXCEPTION_POLICY:
6276                                 ccs_read_exception(head);
6277                                 break;
6278                         case CCS_AUDIT:
6279                                 ccs_read_log(head);
6280                                 break;
6281 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
6282                         case CCS_EXECUTE_HANDLER:
6283 #endif
6284                         case CCS_PROCESS_STATUS:
6285                                 ccs_read_pid(head);
6286                                 break;
6287                         case CCS_VERSION:
6288                                 ccs_read_version(head);
6289                                 break;
6290                         case CCS_STAT:
6291                                 ccs_read_stat(head);
6292                                 break;
6293                         case CCS_PROFILE:
6294                                 ccs_read_profile(head);
6295                                 break;
6296                         case CCS_QUERY:
6297                                 ccs_read_query(head);
6298                                 break;
6299                         case CCS_MANAGER:
6300                                 ccs_read_manager(head);
6301                                 break;
6302                         }
6303                 } while (ccs_flush(head) && ccs_has_more_namespace(head));
6304         ccs_read_unlock(idx);
6305         len = head->read_user_buf - buf;
6306         mutex_unlock(&head->io_sem);
6307         return len;
6308 }
6309 
6310 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
6311 
6312 /**
6313  * ccs_write_self - write() for /proc/ccs/self_domain interface.
6314  *
6315  * @file:  Pointer to "struct file".
6316  * @buf:   Domainname to transit to.
6317  * @count: Size of @buf.
6318  * @ppos:  Unused.
6319  *
6320  * Returns @count on success, negative value otherwise.
6321  *
6322  * If domain transition was permitted but the domain transition failed, this
6323  * function returns error rather than terminating current thread with SIGKILL.
6324  */
6325 static ssize_t ccs_write_self(struct file *file, const char __user *buf,
6326                               size_t count, loff_t *ppos)
6327 {
6328         char *data;
6329         int error;
6330         if (!count || count >= CCS_EXEC_TMPSIZE - 10)
6331                 return -ENOMEM;
6332 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
6333         data = kzalloc(count + 1, CCS_GFP_FLAGS);
6334         if (!data)
6335                 return -ENOMEM;
6336         if (copy_from_user(data, buf, count)) {
6337                 error = -EFAULT;
6338                 goto out;
6339         }
6340 #else
6341         data = memdup_user_nul(buf, count);
6342         if (IS_ERR(data))
6343                 return PTR_ERR(data);
6344 #endif
6345         ccs_normalize_line(data);
6346         if (ccs_correct_domain(data)) {
6347                 const int idx = ccs_read_lock();
6348                 struct ccs_path_info name;
6349                 struct ccs_request_info r;
6350                 name.name = data;
6351                 ccs_fill_path_info(&name);
6352                 /* Check "task manual_domain_transition" permission. */
6353                 ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);
6354                 r.param_type = CCS_TYPE_MANUAL_TASK_ACL;
6355                 r.param.task.domainname = &name;
6356                 ccs_check_acl(&r);
6357                 if (!r.granted)
6358                         error = -EPERM;
6359                 else
6360                         error = ccs_assign_domain(data, true) ? 0 : -ENOENT;
6361                 ccs_read_unlock(idx);
6362         } else
6363                 error = -EINVAL;
6364 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
6365 out:
6366 #endif
6367         kfree(data);
6368         return error ? error : count;
6369 }
6370 
6371 #endif
6372 
6373 /**
6374  * ccs_write - write() for /proc/ccs/ interface.
6375  *
6376  * @file:  Pointer to "struct file".
6377  * @buf:   Pointer to buffer.
6378  * @count: Size of @buf.
6379  * @ppos:  Unused.
6380  *
6381  * Returns @count on success, negative value otherwise.
6382  */
6383 static ssize_t ccs_write(struct file *file, const char __user *buf,
6384                          size_t count, loff_t *ppos)
6385 {
6386         struct ccs_io_buffer *head = file->private_data;
6387         int error = count;
6388         char *cp0;
6389         int idx;
6390         if (mutex_lock_interruptible(&head->io_sem))
6391                 return -EINTR;
6392         cp0 = head->write_buf;
6393         head->read_user_buf_avail = 0;
6394         idx = ccs_read_lock();
6395         /* Read a line and dispatch it to the policy handler. */
6396         while (count) {
6397                 char c;
6398                 if (head->w.avail >= head->writebuf_size - 1) {
6399                         const int len = head->writebuf_size * 2;
6400                         char *cp = kzalloc(len, CCS_GFP_FLAGS);
6401                         if (!cp) {
6402                                 error = -ENOMEM;
6403                                 break;
6404                         }
6405                         memmove(cp, cp0, head->w.avail);
6406                         kfree(cp0);
6407                         head->write_buf = cp;
6408                         cp0 = cp;
6409                         head->writebuf_size = len;
6410                 }
6411                 if (get_user(c, buf)) {
6412                         error = -EFAULT;
6413                         break;
6414                 }
6415                 buf++;
6416                 count--;
6417                 cp0[head->w.avail++] = c;
6418                 if (c != '\n')
6419                         continue;
6420                 cp0[head->w.avail - 1] = '\0';
6421                 head->w.avail = 0;
6422                 ccs_normalize_line(cp0);
6423                 if (!strcmp(cp0, "reset")) {
6424                         head->w.ns = &ccs_kernel_namespace;
6425                         head->w.domain = NULL;
6426                         memset(&head->r, 0, sizeof(head->r));
6427                         continue;
6428                 }
6429                 /* Don't allow updating policies by non manager programs. */
6430                 switch (head->type) {
6431                 case CCS_PROCESS_STATUS:
6432                         /* This does not write anything. */
6433                         break;
6434                 case CCS_DOMAIN_POLICY:
6435                         if (ccs_select_domain(head, cp0))
6436                                 continue;
6437                         /* fall through */
6438                         fallthrough;
6439                 case CCS_EXCEPTION_POLICY:
6440                         if (!strcmp(cp0, "select transition_only")) {
6441                                 head->r.print_transition_related_only = true;
6442                                 continue;
6443                         }
6444                         /* fall through */
6445                         fallthrough;
6446                 default:
6447                         if (!ccs_manager()) {
6448                                 error = -EPERM;
6449                                 goto out;
6450                         }
6451                 }
6452                 switch (ccs_parse_policy(head, cp0)) {
6453                 case -EPERM:
6454                         error = -EPERM;
6455                         goto out;
6456                 case 0:
6457                         /* Update statistics. */
6458                         switch (head->type) {
6459                         case CCS_DOMAIN_POLICY:
6460                         case CCS_EXCEPTION_POLICY:
6461                         case CCS_STAT:
6462                         case CCS_PROFILE:
6463                         case CCS_MANAGER:
6464                                 ccs_update_stat(CCS_STAT_POLICY_UPDATES);
6465                                 break;
6466                         default:
6467                                 break;
6468                         }
6469                         break;
6470                 }
6471         }
6472 out:
6473         ccs_read_unlock(idx);
6474         mutex_unlock(&head->io_sem);
6475         return error;
6476 }
6477 
6478 /**
6479  * ccs_create_entry - Create interface files under /proc/ccs/ directory.
6480  *
6481  * @name:   The name of the interface file.
6482  * @mode:   The permission of the interface file.
6483  * @parent: The parent directory.
6484  * @key:    Type of interface.
6485  *
6486  * Returns nothing.
6487  */
6488 static void __init ccs_create_entry(const char *name, const umode_t mode,
6489                                     struct proc_dir_entry *parent,
6490                                     const u8 key)
6491 {
6492 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
6493         proc_create_data(name, mode, parent, &ccs_operations,
6494                          ((u8 *) NULL) + key);
6495 #else
6496         struct proc_dir_entry *entry = create_proc_entry(name, mode, parent);
6497         if (entry) {
6498                 entry->proc_fops = &ccs_operations;
6499                 entry->data = ((u8 *) NULL) + key;
6500 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
6501                 if (entry->proc_iops)
6502                         ccs_file_inode_operations = *entry->proc_iops;
6503                 if (!ccs_file_inode_operations.setattr)
6504                         ccs_file_inode_operations.setattr = proc_notify_change;
6505                 entry->proc_iops = &ccs_file_inode_operations;
6506 #endif
6507         }
6508 #endif
6509 }
6510 
6511 /**
6512  * ccs_proc_init - Initialize /proc/ccs/ interface.
6513  *
6514  * Returns nothing.
6515  */
6516 static void __init ccs_proc_init(void)
6517 {
6518         struct proc_dir_entry *ccs_dir = proc_mkdir("ccs", NULL);
6519 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
6520         if (ccs_dir->proc_iops)
6521                 ccs_dir_inode_operations = *ccs_dir->proc_iops;
6522         if (!ccs_dir_inode_operations.setattr)
6523                 ccs_dir_inode_operations.setattr = proc_notify_change;
6524         ccs_dir->proc_iops = &ccs_dir_inode_operations;
6525 #endif
6526         ccs_create_entry("query",            0600, ccs_dir, CCS_QUERY);
6527         ccs_create_entry("domain_policy",    0600, ccs_dir, CCS_DOMAIN_POLICY);
6528         ccs_create_entry("exception_policy", 0600, ccs_dir,
6529                          CCS_EXCEPTION_POLICY);
6530         ccs_create_entry("audit",            0400, ccs_dir, CCS_AUDIT);
6531         ccs_create_entry(".process_status",  0600, ccs_dir,
6532                          CCS_PROCESS_STATUS);
6533         ccs_create_entry("stat",             0644, ccs_dir, CCS_STAT);
6534         ccs_create_entry("profile",          0600, ccs_dir, CCS_PROFILE);
6535         ccs_create_entry("manager",          0600, ccs_dir, CCS_MANAGER);
6536         ccs_create_entry("version",          0400, ccs_dir, CCS_VERSION);
6537 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
6538         ccs_create_entry(".execute_handler", 0666, ccs_dir,
6539                          CCS_EXECUTE_HANDLER);
6540 #endif
6541 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
6542         proc_create("self_domain", 0666, ccs_dir, &ccs_self_operations);
6543 #else
6544         {
6545                 struct proc_dir_entry *e = create_proc_entry("self_domain",
6546                                                              0666, ccs_dir);
6547                 if (e)
6548                         e->proc_fops = &ccs_self_operations;
6549         }
6550 #endif
6551 }
6552 
6553 /**
6554  * ccs_init_module - Initialize this module.
6555  *
6556  * Returns 0 on success, negative value otherwise.
6557  */
6558 static int __init ccs_init_module(void)
6559 {
6560         if (ccsecurity_ops.disabled)
6561                 return -EINVAL;
6562 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
6563         MOD_INC_USE_COUNT;
6564 #endif
6565 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
6566         if (init_srcu_struct(&ccs_ss))
6567                 panic("Out of memory.");
6568 #endif
6569         ccs_kernel_namespace.name = "<kernel>";
6570         ccs_init_policy_namespace(&ccs_kernel_namespace);
6571         ccs_kernel_domain.ns = &ccs_kernel_namespace;
6572         INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
6573         ccs_mm_init();
6574         ccs_policy_io_init();
6575         ccs_permission_init();
6576         ccs_proc_init();
6577         ccs_load_builtin_policy();
6578         return 0;
6579 }
6580 
6581 MODULE_LICENSE("GPL");
6582 module_init(ccs_init_module);
6583 

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

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php