• R/O
  • SSH
  • HTTPS

caitsith: コミット


コミットメタ情報

リビジョン76 (tree)
日時2013-01-06 20:18:53
作者kumaneko

ログメッセージ

(メッセージはありません)

変更サマリ

差分

--- trunk/caitsith-tools/kernel_test/caitsith-parser-test.c (revision 75)
+++ trunk/caitsith-tools/kernel_test/caitsith-parser-test.c (nonexistent)
@@ -1,916 +0,0 @@
1-/*
2- * caitsith-parser-test.c
3- *
4- * Copyright (C) 2012 Tetsuo Handa
5- *
6- * Version: 0.1 2012/09/17
7- *
8- * This program is free software; you can redistribute it and/or modify it
9- * under the terms of the GNU General Public License v2 as published by the
10- * Free Software Foundation.
11- *
12- * This program is distributed in the hope that it will be useful, but WITHOUT
13- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15- * more details.
16- *
17- * You should have received a copy of the GNU General Public License along with
18- * this program; if not, write to the Free Software Foundation, Inc.,
19- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20- */
21-
22-#include <stdio.h>
23-#include <string.h>
24-#include <stdlib.h>
25-#include <sys/types.h>
26-#include <sys/stat.h>
27-#include <fcntl.h>
28-#include <unistd.h>
29-#include <time.h>
30-
31-enum ccs_mac_index {
32- CCS_MAC_EXECUTE,
33- CCS_MAC_READ,
34- CCS_MAC_WRITE,
35- CCS_MAC_APPEND,
36- CCS_MAC_CREATE,
37- CCS_MAC_UNLINK,
38- CCS_MAC_GETATTR,
39- CCS_MAC_MKDIR,
40- CCS_MAC_RMDIR,
41- CCS_MAC_MKFIFO,
42- CCS_MAC_MKSOCK,
43- CCS_MAC_TRUNCATE,
44- CCS_MAC_SYMLINK,
45- CCS_MAC_MKBLOCK,
46- CCS_MAC_MKCHAR,
47- CCS_MAC_LINK,
48- CCS_MAC_RENAME,
49- CCS_MAC_CHMOD,
50- CCS_MAC_CHOWN,
51- CCS_MAC_CHGRP,
52- CCS_MAC_IOCTL,
53- CCS_MAC_CHROOT,
54- CCS_MAC_MOUNT,
55- CCS_MAC_UMOUNT,
56- CCS_MAC_PIVOT_ROOT,
57- CCS_MAC_INET_STREAM_BIND,
58- CCS_MAC_INET_STREAM_LISTEN,
59- CCS_MAC_INET_STREAM_CONNECT,
60- CCS_MAC_INET_STREAM_ACCEPT,
61- CCS_MAC_INET_DGRAM_BIND,
62- CCS_MAC_INET_DGRAM_SEND,
63- CCS_MAC_INET_DGRAM_RECV,
64- CCS_MAC_INET_RAW_BIND,
65- CCS_MAC_INET_RAW_SEND,
66- CCS_MAC_INET_RAW_RECV,
67- CCS_MAC_UNIX_STREAM_BIND,
68- CCS_MAC_UNIX_STREAM_LISTEN,
69- CCS_MAC_UNIX_STREAM_CONNECT,
70- CCS_MAC_UNIX_STREAM_ACCEPT,
71- CCS_MAC_UNIX_DGRAM_BIND,
72- CCS_MAC_UNIX_DGRAM_SEND,
73- CCS_MAC_UNIX_DGRAM_RECV,
74- CCS_MAC_UNIX_SEQPACKET_BIND,
75- CCS_MAC_UNIX_SEQPACKET_LISTEN,
76- CCS_MAC_UNIX_SEQPACKET_CONNECT,
77- CCS_MAC_UNIX_SEQPACKET_ACCEPT,
78- CCS_MAC_ENVIRON,
79- CCS_MAC_PTRACE,
80- CCS_MAC_SIGNAL,
81- CCS_MAC_MODIFY_POLICY,
82- CCS_MAC_USE_NETLINK_SOCKET,
83- CCS_MAC_USE_PACKET_SOCKET,
84- CCS_MAC_USE_REBOOT,
85- CCS_MAC_USE_VHANGUP,
86- CCS_MAC_SET_TIME,
87- CCS_MAC_SET_PRIORITY,
88- CCS_MAC_SET_HOSTNAME,
89- CCS_MAC_USE_KERNEL_MODULE,
90- CCS_MAC_USE_NEW_KERNEL,
91- CCS_MAC_AUTO_DOMAIN_TRANSITION,
92- CCS_MAC_MANUAL_DOMAIN_TRANSITION,
93- CCS_MAX_MAC_INDEX
94-};
95-
96-static const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX] = {
97- [CCS_MAC_EXECUTE] = "execute",
98- [CCS_MAC_READ] = "read",
99- [CCS_MAC_WRITE] = "write",
100- [CCS_MAC_APPEND] = "append",
101- [CCS_MAC_CREATE] = "create",
102- [CCS_MAC_UNLINK] = "unlink",
103- [CCS_MAC_GETATTR] = "getattr",
104- [CCS_MAC_MKDIR] = "mkdir",
105- [CCS_MAC_RMDIR] = "rmdir",
106- [CCS_MAC_MKFIFO] = "mkfifo",
107- [CCS_MAC_MKSOCK] = "mksock",
108- [CCS_MAC_TRUNCATE] = "truncate",
109- [CCS_MAC_SYMLINK] = "symlink",
110- [CCS_MAC_MKBLOCK] = "mkblock",
111- [CCS_MAC_MKCHAR] = "mkchar",
112- [CCS_MAC_LINK] = "link",
113- [CCS_MAC_RENAME] = "rename",
114- [CCS_MAC_CHMOD] = "chmod",
115- [CCS_MAC_CHOWN] = "chown",
116- [CCS_MAC_CHGRP] = "chgrp",
117- [CCS_MAC_IOCTL] = "ioctl",
118- [CCS_MAC_CHROOT] = "chroot",
119- [CCS_MAC_MOUNT] = "mount",
120- [CCS_MAC_UMOUNT] = "unmount",
121- [CCS_MAC_PIVOT_ROOT] = "pivot_root",
122- [CCS_MAC_INET_STREAM_BIND] = "inet_stream_bind",
123- [CCS_MAC_INET_STREAM_LISTEN] = "inet_stream_listen",
124- [CCS_MAC_INET_STREAM_CONNECT] = "inet_stream_connect",
125- [CCS_MAC_INET_STREAM_ACCEPT] = "inet_stream_accept",
126- [CCS_MAC_INET_DGRAM_BIND] = "inet_dgram_bind",
127- [CCS_MAC_INET_DGRAM_SEND] = "inet_dgram_send",
128- [CCS_MAC_INET_DGRAM_RECV] = "inet_dgram_recv",
129- [CCS_MAC_INET_RAW_BIND] = "inet_raw_bind",
130- [CCS_MAC_INET_RAW_SEND] = "inet_raw_send",
131- [CCS_MAC_INET_RAW_RECV] = "inet_raw_recv",
132- [CCS_MAC_UNIX_STREAM_BIND] = "unix_stream_bind",
133- [CCS_MAC_UNIX_STREAM_LISTEN] = "unix_stream_listen",
134- [CCS_MAC_UNIX_STREAM_CONNECT] = "unix_stream_connect",
135- [CCS_MAC_UNIX_STREAM_ACCEPT] = "unix_stream_accept",
136- [CCS_MAC_UNIX_DGRAM_BIND] = "unix_dgram_bind",
137- [CCS_MAC_UNIX_DGRAM_SEND] = "unix_dgram_send",
138- [CCS_MAC_UNIX_DGRAM_RECV] = "unix_dgram_recv",
139- [CCS_MAC_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
140- [CCS_MAC_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
141- [CCS_MAC_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
142- [CCS_MAC_UNIX_SEQPACKET_ACCEPT] = "unix_seqpacket_accept",
143- [CCS_MAC_ENVIRON] = "environ",
144- [CCS_MAC_PTRACE] = "ptrace",
145- [CCS_MAC_SIGNAL] = "signal",
146- [CCS_MAC_MODIFY_POLICY] = "modify_policy",
147- [CCS_MAC_USE_NETLINK_SOCKET] = "use_netlink_socket",
148- [CCS_MAC_USE_PACKET_SOCKET] = "use_packet_socket",
149- [CCS_MAC_USE_REBOOT] = "use_reboot",
150- [CCS_MAC_USE_VHANGUP] = "use_vhangup",
151- [CCS_MAC_SET_TIME] = "set_time",
152- [CCS_MAC_SET_PRIORITY] = "set_priority",
153- [CCS_MAC_SET_HOSTNAME] = "set_hostname",
154- [CCS_MAC_USE_KERNEL_MODULE] = "use_kernel_module",
155- [CCS_MAC_USE_NEW_KERNEL] = "use_new_kernel",
156- [CCS_MAC_AUTO_DOMAIN_TRANSITION] = "auto_domain_transition",
157- [CCS_MAC_MANUAL_DOMAIN_TRANSITION] = "manual_domain_transition",
158-};
159-
160-#define F(bit) (1ULL << bit)
161-
162-#define CCS_ALL_OK \
163- (F(CCS_MAC_EXECUTE) | \
164- F(CCS_MAC_READ) | \
165- F(CCS_MAC_WRITE) | \
166- F(CCS_MAC_APPEND) | \
167- F(CCS_MAC_CREATE) | \
168- F(CCS_MAC_UNLINK) | \
169- F(CCS_MAC_GETATTR) | \
170- F(CCS_MAC_MKDIR) | \
171- F(CCS_MAC_RMDIR) | \
172- F(CCS_MAC_MKFIFO) | \
173- F(CCS_MAC_MKSOCK) | \
174- F(CCS_MAC_TRUNCATE) | \
175- F(CCS_MAC_SYMLINK) | \
176- F(CCS_MAC_MKBLOCK) | \
177- F(CCS_MAC_MKCHAR) | \
178- F(CCS_MAC_LINK) | \
179- F(CCS_MAC_RENAME) | \
180- F(CCS_MAC_CHMOD) | \
181- F(CCS_MAC_CHOWN) | \
182- F(CCS_MAC_CHGRP) | \
183- F(CCS_MAC_IOCTL) | \
184- F(CCS_MAC_CHROOT) | \
185- F(CCS_MAC_MOUNT) | \
186- F(CCS_MAC_UMOUNT) | \
187- F(CCS_MAC_PIVOT_ROOT) | \
188- F(CCS_MAC_INET_STREAM_BIND) | \
189- F(CCS_MAC_INET_STREAM_LISTEN) | \
190- F(CCS_MAC_INET_STREAM_CONNECT) | \
191- F(CCS_MAC_INET_STREAM_ACCEPT) | \
192- F(CCS_MAC_INET_DGRAM_BIND) | \
193- F(CCS_MAC_INET_DGRAM_SEND) | \
194- F(CCS_MAC_INET_DGRAM_RECV) | \
195- F(CCS_MAC_INET_RAW_BIND) | \
196- F(CCS_MAC_INET_RAW_SEND) | \
197- F(CCS_MAC_INET_RAW_RECV) | \
198- F(CCS_MAC_UNIX_STREAM_BIND) | \
199- F(CCS_MAC_UNIX_STREAM_LISTEN) | \
200- F(CCS_MAC_UNIX_STREAM_CONNECT) | \
201- F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
202- F(CCS_MAC_UNIX_DGRAM_BIND) | \
203- F(CCS_MAC_UNIX_DGRAM_SEND) | \
204- F(CCS_MAC_UNIX_DGRAM_RECV) | \
205- F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
206- F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
207- F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
208- F(CCS_MAC_UNIX_SEQPACKET_ACCEPT) | \
209- F(CCS_MAC_ENVIRON) | \
210- F(CCS_MAC_PTRACE) | \
211- F(CCS_MAC_SIGNAL) | \
212- F(CCS_MAC_MODIFY_POLICY) | \
213- F(CCS_MAC_USE_NETLINK_SOCKET) | \
214- F(CCS_MAC_USE_PACKET_SOCKET) | \
215- F(CCS_MAC_USE_REBOOT) | \
216- F(CCS_MAC_USE_VHANGUP) | \
217- F(CCS_MAC_SET_TIME) | \
218- F(CCS_MAC_SET_PRIORITY) | \
219- F(CCS_MAC_SET_HOSTNAME) | \
220- F(CCS_MAC_USE_KERNEL_MODULE) | \
221- F(CCS_MAC_USE_NEW_KERNEL) | \
222- F(CCS_MAC_AUTO_DOMAIN_TRANSITION) | \
223- F(CCS_MAC_MANUAL_DOMAIN_TRANSITION))
224-
225-#define CCS_PATH_SELF_OK \
226- (F(CCS_MAC_EXECUTE) | \
227- F(CCS_MAC_READ) | \
228- F(CCS_MAC_WRITE) | \
229- F(CCS_MAC_APPEND) | \
230- F(CCS_MAC_UNLINK) | \
231- F(CCS_MAC_GETATTR) | \
232- F(CCS_MAC_RMDIR) | \
233- F(CCS_MAC_TRUNCATE) | \
234- F(CCS_MAC_CHMOD) | \
235- F(CCS_MAC_CHOWN) | \
236- F(CCS_MAC_CHGRP) | \
237- F(CCS_MAC_IOCTL) | \
238- F(CCS_MAC_CHROOT) | \
239- F(CCS_MAC_UMOUNT))
240-
241-#define CCS_PATH_PARENT_OK \
242- (F(CCS_MAC_CREATE) | \
243- F(CCS_MAC_MKDIR) | \
244- F(CCS_MAC_MKFIFO) | \
245- F(CCS_MAC_MKSOCK) | \
246- F(CCS_MAC_SYMLINK) | \
247- F(CCS_MAC_MKBLOCK) | \
248- F(CCS_MAC_MKCHAR))
249-
250-#define CCS_PATH_OK (CCS_PATH_SELF_OK | CCS_PATH_PARENT_OK)
251-
252-#define CCS_RENAME_OR_LINK_OK (F(CCS_MAC_LINK) | F(CCS_MAC_RENAME))
253-
254-#define CCS_EXECUTE_OR_ENVIRON_OK (F(CCS_MAC_EXECUTE) | F(CCS_MAC_ENVIRON))
255-
256-#define CCS_MKDEV_OK (F(CCS_MAC_MKBLOCK) | F(CCS_MAC_MKCHAR))
257-
258-#define CCS_PATH_PERM_OK \
259- (F(CCS_MAC_MKDIR) | \
260- F(CCS_MAC_MKBLOCK) | \
261- F(CCS_MAC_MKCHAR) | \
262- F(CCS_MAC_MKFIFO) | \
263- F(CCS_MAC_MKSOCK) | \
264- F(CCS_MAC_CREATE) | \
265- F(CCS_MAC_CHMOD))
266-
267-#define CCS_IP_SOCKET_OK \
268- (F(CCS_MAC_INET_STREAM_BIND) | \
269- F(CCS_MAC_INET_STREAM_LISTEN) | \
270- F(CCS_MAC_INET_STREAM_CONNECT) | \
271- F(CCS_MAC_INET_STREAM_ACCEPT) | \
272- F(CCS_MAC_INET_DGRAM_BIND) | \
273- F(CCS_MAC_INET_DGRAM_SEND) | \
274- F(CCS_MAC_INET_DGRAM_RECV))
275-
276-#define CCS_RAW_SOCKET_OK \
277- (F(CCS_MAC_INET_RAW_BIND) | \
278- F(CCS_MAC_INET_RAW_SEND) | \
279- F(CCS_MAC_INET_RAW_RECV))
280-
281-#define CCS_INET_SOCKET_OK (CCS_IP_SOCKET_OK | CCS_RAW_SOCKET_OK)
282-
283-#define CCS_UNIX_SOCKET_OK \
284- (F(CCS_MAC_UNIX_STREAM_BIND) | \
285- F(CCS_MAC_UNIX_STREAM_LISTEN) | \
286- F(CCS_MAC_UNIX_STREAM_CONNECT) | \
287- F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
288- F(CCS_MAC_UNIX_DGRAM_BIND) | \
289- F(CCS_MAC_UNIX_DGRAM_SEND) | \
290- F(CCS_MAC_UNIX_DGRAM_RECV) | \
291- F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
292- F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
293- F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
294- F(CCS_MAC_UNIX_SEQPACKET_ACCEPT))
295-
296-enum ccs_var_type {
297- CCS_TYPE_INVALID,
298- CCS_TYPE_NUMBER,
299- CCS_TYPE_STRING,
300- CCS_TYPE_IPADDR,
301- CCS_TYPE_FILEPERM,
302- CCS_TYPE_FILETYPE,
303- CCS_TYPE_TASKTYPE,
304- CCS_TYPE_ASSIGN,
305-};
306-
307-static const struct {
308- const char * const keyword;
309- const enum ccs_var_type left_type;
310- const enum ccs_var_type right_type;
311- const unsigned long long available;
312-} ccs_conditions[] = {
313- { "addr", CCS_TYPE_STRING, CCS_TYPE_STRING,
314- CCS_UNIX_SOCKET_OK },
315- { "argc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
316- CCS_EXECUTE_OR_ENVIRON_OK },
317- { "block", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
318- CCS_ALL_OK },
319- { "char", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
320- CCS_ALL_OK },
321- { "cmd", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
322- F(CCS_MAC_IOCTL) | F(CCS_MAC_PTRACE) },
323- { "data", CCS_TYPE_STRING, CCS_TYPE_STRING,
324- F(CCS_MAC_MOUNT) },
325- { "dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
326- CCS_MKDEV_OK },
327- { "dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
328- CCS_MKDEV_OK },
329- { "directory", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
330- CCS_ALL_OK },
331- { "domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
332- F(CCS_MAC_PTRACE) | F(CCS_MAC_MANUAL_DOMAIN_TRANSITION) },
333- { "envc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
334- CCS_EXECUTE_OR_ENVIRON_OK },
335- { "exec", CCS_TYPE_STRING, CCS_TYPE_STRING,
336- CCS_EXECUTE_OR_ENVIRON_OK },
337- { "exec.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
338- CCS_EXECUTE_OR_ENVIRON_OK },
339- { "exec.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
340- CCS_EXECUTE_OR_ENVIRON_OK },
341- { "exec.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
342- CCS_EXECUTE_OR_ENVIRON_OK },
343- { "exec.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
344- CCS_EXECUTE_OR_ENVIRON_OK },
345- { "exec.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
346- CCS_EXECUTE_OR_ENVIRON_OK },
347- { "exec.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
348- CCS_EXECUTE_OR_ENVIRON_OK },
349- { "exec.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
350- CCS_EXECUTE_OR_ENVIRON_OK },
351- { "exec.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
352- CCS_EXECUTE_OR_ENVIRON_OK },
353- { "exec.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
354- CCS_EXECUTE_OR_ENVIRON_OK },
355- { "exec.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
356- CCS_EXECUTE_OR_ENVIRON_OK },
357- { "exec.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
358- CCS_EXECUTE_OR_ENVIRON_OK },
359- { "exec.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
360- CCS_EXECUTE_OR_ENVIRON_OK },
361- { "exec.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
362- CCS_EXECUTE_OR_ENVIRON_OK },
363- { "exec.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
364- CCS_EXECUTE_OR_ENVIRON_OK },
365- { "exec.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
366- CCS_EXECUTE_OR_ENVIRON_OK },
367- { "execute_handler", CCS_TYPE_INVALID, CCS_TYPE_TASKTYPE,
368- CCS_ALL_OK },
369- { "fifo", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
370- CCS_ALL_OK },
371- { "file", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
372- CCS_ALL_OK },
373- { "flags", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
374- F(CCS_MAC_MOUNT) | F(CCS_MAC_UMOUNT) },
375- { "fstype", CCS_TYPE_STRING, CCS_TYPE_STRING,
376- F(CCS_MAC_MOUNT) },
377- { "gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
378- F(CCS_MAC_CHGRP) },
379- { "group_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
380- CCS_ALL_OK },
381- { "group_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
382- CCS_ALL_OK },
383- { "group_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
384- CCS_ALL_OK },
385- { "handler", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
386- F(CCS_MAC_EXECUTE) },
387- { "ip", CCS_TYPE_IPADDR, CCS_TYPE_INVALID,
388- CCS_INET_SOCKET_OK },
389- { "name", CCS_TYPE_STRING, CCS_TYPE_STRING,
390- F(CCS_MAC_ENVIRON) },
391- { "new_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
392- CCS_RENAME_OR_LINK_OK },
393- { "new_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
394- F(CCS_MAC_RENAME) },
395- { "new_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
396- F(CCS_MAC_RENAME) },
397- { "new_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
398- F(CCS_MAC_RENAME) },
399- { "new_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
400- F(CCS_MAC_RENAME) },
401- { "new_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
402- F(CCS_MAC_RENAME) },
403- { "new_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
404- F(CCS_MAC_RENAME) },
405- { "new_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
406- F(CCS_MAC_RENAME) },
407- { "new_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
408- CCS_RENAME_OR_LINK_OK },
409- { "new_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
410- CCS_RENAME_OR_LINK_OK },
411- { "new_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
412- CCS_RENAME_OR_LINK_OK },
413- { "new_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
414- CCS_RENAME_OR_LINK_OK },
415- { "new_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
416- CCS_RENAME_OR_LINK_OK },
417- { "new_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
418- CCS_RENAME_OR_LINK_OK },
419- { "new_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
420- CCS_RENAME_OR_LINK_OK },
421- { "new_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
422- F(CCS_MAC_RENAME) },
423- { "new_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
424- F(CCS_MAC_RENAME) },
425- { "new_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
426- F(CCS_MAC_RENAME) },
427- { "new_root", CCS_TYPE_STRING, CCS_TYPE_STRING,
428- F(CCS_MAC_PIVOT_ROOT) },
429- { "new_root.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
430- F(CCS_MAC_PIVOT_ROOT) },
431- { "new_root.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
432- F(CCS_MAC_PIVOT_ROOT) },
433- { "new_root.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
434- F(CCS_MAC_PIVOT_ROOT) },
435- { "new_root.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
436- F(CCS_MAC_PIVOT_ROOT) },
437- { "new_root.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
438- F(CCS_MAC_PIVOT_ROOT) },
439- { "new_root.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
440- F(CCS_MAC_PIVOT_ROOT) },
441- { "new_root.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
442- F(CCS_MAC_PIVOT_ROOT) },
443- { "new_root.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
444- F(CCS_MAC_PIVOT_ROOT) },
445- { "new_root.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
446- F(CCS_MAC_PIVOT_ROOT) },
447- { "new_root.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
448- F(CCS_MAC_PIVOT_ROOT) },
449- { "new_root.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
450- F(CCS_MAC_PIVOT_ROOT) },
451- { "new_root.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
452- F(CCS_MAC_PIVOT_ROOT) },
453- { "new_root.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
454- F(CCS_MAC_PIVOT_ROOT) },
455- { "new_root.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
456- F(CCS_MAC_PIVOT_ROOT) },
457- { "new_root.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
458- F(CCS_MAC_PIVOT_ROOT) },
459- { "new_root.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
460- F(CCS_MAC_PIVOT_ROOT) },
461- { "new_root.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
462- F(CCS_MAC_PIVOT_ROOT) },
463- { "old_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
464- CCS_RENAME_OR_LINK_OK },
465- { "old_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
466- CCS_RENAME_OR_LINK_OK },
467- { "old_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
468- CCS_RENAME_OR_LINK_OK },
469- { "old_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
470- CCS_RENAME_OR_LINK_OK },
471- { "old_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
472- CCS_RENAME_OR_LINK_OK },
473- { "old_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
474- CCS_RENAME_OR_LINK_OK },
475- { "old_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
476- CCS_RENAME_OR_LINK_OK },
477- { "old_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
478- CCS_RENAME_OR_LINK_OK },
479- { "old_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
480- CCS_RENAME_OR_LINK_OK },
481- { "old_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
482- CCS_RENAME_OR_LINK_OK },
483- { "old_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
484- CCS_RENAME_OR_LINK_OK },
485- { "old_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
486- CCS_RENAME_OR_LINK_OK },
487- { "old_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
488- CCS_RENAME_OR_LINK_OK },
489- { "old_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
490- CCS_RENAME_OR_LINK_OK },
491- { "old_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
492- CCS_RENAME_OR_LINK_OK },
493- { "old_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
494- CCS_RENAME_OR_LINK_OK },
495- { "old_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
496- CCS_RENAME_OR_LINK_OK },
497- { "old_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
498- CCS_RENAME_OR_LINK_OK },
499- { "others_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
500- CCS_ALL_OK },
501- { "others_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
502- CCS_ALL_OK },
503- { "others_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
504- CCS_ALL_OK },
505- { "owner_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
506- CCS_ALL_OK },
507- { "owner_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
508- CCS_ALL_OK },
509- { "owner_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
510- CCS_ALL_OK },
511- { "path", CCS_TYPE_STRING, CCS_TYPE_STRING,
512- CCS_PATH_OK },
513- { "path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
514- CCS_PATH_SELF_OK },
515- { "path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
516- CCS_PATH_SELF_OK },
517- { "path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
518- CCS_PATH_SELF_OK },
519- { "path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
520- CCS_PATH_SELF_OK },
521- { "path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
522- CCS_PATH_SELF_OK },
523- { "path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
524- CCS_PATH_SELF_OK },
525- { "path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
526- CCS_PATH_SELF_OK },
527- { "path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
528- CCS_PATH_OK },
529- { "path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
530- CCS_PATH_OK },
531- { "path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
532- CCS_PATH_OK },
533- { "path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
534- CCS_PATH_OK },
535- { "path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
536- CCS_PATH_OK },
537- { "path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
538- CCS_PATH_OK },
539- { "path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
540- CCS_PATH_OK },
541- { "path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
542- CCS_PATH_SELF_OK },
543- { "path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
544- CCS_PATH_SELF_OK },
545- { "path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
546- CCS_PATH_SELF_OK },
547- { "perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
548- CCS_PATH_PERM_OK },
549- { "port", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
550- CCS_IP_SOCKET_OK },
551- { "proto", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
552- CCS_RAW_SOCKET_OK },
553- { "put_old", CCS_TYPE_STRING, CCS_TYPE_STRING,
554- F(CCS_MAC_PIVOT_ROOT) },
555- { "put_old.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
556- F(CCS_MAC_PIVOT_ROOT) },
557- { "put_old.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
558- F(CCS_MAC_PIVOT_ROOT) },
559- { "put_old.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
560- F(CCS_MAC_PIVOT_ROOT) },
561- { "put_old.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
562- F(CCS_MAC_PIVOT_ROOT) },
563- { "put_old.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
564- F(CCS_MAC_PIVOT_ROOT) },
565- { "put_old.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
566- F(CCS_MAC_PIVOT_ROOT) },
567- { "put_old.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
568- F(CCS_MAC_PIVOT_ROOT) },
569- { "put_old.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
570- F(CCS_MAC_PIVOT_ROOT) },
571- { "put_old.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
572- F(CCS_MAC_PIVOT_ROOT) },
573- { "put_old.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
574- F(CCS_MAC_PIVOT_ROOT) },
575- { "put_old.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
576- F(CCS_MAC_PIVOT_ROOT) },
577- { "put_old.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
578- F(CCS_MAC_PIVOT_ROOT) },
579- { "put_old.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
580- F(CCS_MAC_PIVOT_ROOT) },
581- { "put_old.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
582- F(CCS_MAC_PIVOT_ROOT) },
583- { "put_old.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
584- F(CCS_MAC_PIVOT_ROOT) },
585- { "put_old.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
586- F(CCS_MAC_PIVOT_ROOT) },
587- { "put_old.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
588- F(CCS_MAC_PIVOT_ROOT) },
589- { "setgid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
590- CCS_ALL_OK },
591- { "setuid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
592- CCS_ALL_OK },
593- { "sig", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
594- F(CCS_MAC_SIGNAL) },
595- { "socket", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
596- CCS_ALL_OK },
597- { "source", CCS_TYPE_STRING, CCS_TYPE_STRING,
598- F(CCS_MAC_MOUNT) },
599- { "source.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
600- F(CCS_MAC_MOUNT) },
601- { "source.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
602- F(CCS_MAC_MOUNT) },
603- { "source.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
604- F(CCS_MAC_MOUNT) },
605- { "source.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
606- F(CCS_MAC_MOUNT) },
607- { "source.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
608- F(CCS_MAC_MOUNT) },
609- { "source.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
610- F(CCS_MAC_MOUNT) },
611- { "source.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
612- F(CCS_MAC_MOUNT) },
613- { "source.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
614- F(CCS_MAC_MOUNT) },
615- { "source.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
616- F(CCS_MAC_MOUNT) },
617- { "source.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
618- F(CCS_MAC_MOUNT) },
619- { "source.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
620- F(CCS_MAC_MOUNT) },
621- { "source.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
622- F(CCS_MAC_MOUNT) },
623- { "source.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
624- F(CCS_MAC_MOUNT) },
625- { "source.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
626- F(CCS_MAC_MOUNT) },
627- { "source.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
628- F(CCS_MAC_MOUNT) },
629- { "source.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
630- F(CCS_MAC_MOUNT) },
631- { "source.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
632- F(CCS_MAC_MOUNT) },
633- { "sticky", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
634- CCS_ALL_OK },
635- { "symlink", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
636- CCS_ALL_OK },
637- { "target", CCS_TYPE_STRING, CCS_TYPE_STRING,
638- F(CCS_MAC_MOUNT) | F(CCS_MAC_SYMLINK) },
639- { "target.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
640- F(CCS_MAC_MOUNT) },
641- { "target.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
642- F(CCS_MAC_MOUNT) },
643- { "target.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
644- F(CCS_MAC_MOUNT) },
645- { "target.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
646- F(CCS_MAC_MOUNT) },
647- { "target.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
648- F(CCS_MAC_MOUNT) },
649- { "target.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
650- F(CCS_MAC_MOUNT) },
651- { "target.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
652- F(CCS_MAC_MOUNT) },
653- { "target.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
654- F(CCS_MAC_MOUNT) },
655- { "target.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
656- F(CCS_MAC_MOUNT) },
657- { "target.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
658- F(CCS_MAC_MOUNT) },
659- { "target.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
660- F(CCS_MAC_MOUNT) },
661- { "target.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
662- F(CCS_MAC_MOUNT) },
663- { "target.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
664- F(CCS_MAC_MOUNT) },
665- { "target.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
666- F(CCS_MAC_MOUNT) },
667- { "target.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
668- F(CCS_MAC_MOUNT) },
669- { "target.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
670- F(CCS_MAC_MOUNT) },
671- { "target.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
672- F(CCS_MAC_MOUNT) },
673- { "task.domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
674- CCS_ALL_OK },
675- { "task.egid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
676- CCS_ALL_OK },
677- { "task.euid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
678- CCS_ALL_OK },
679- { "task.exe", CCS_TYPE_STRING, CCS_TYPE_STRING,
680- CCS_ALL_OK },
681- { "task.fsgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
682- CCS_ALL_OK },
683- { "task.fsuid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
684- CCS_ALL_OK },
685- { "task.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
686- CCS_ALL_OK },
687- { "task.pid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
688- CCS_ALL_OK },
689- { "task.ppid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
690- CCS_ALL_OK },
691- { "task.sgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
692- CCS_ALL_OK },
693- { "task.suid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
694- CCS_ALL_OK },
695- { "task.type", CCS_TYPE_TASKTYPE, CCS_TYPE_INVALID,
696- CCS_ALL_OK },
697- { "task.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
698- CCS_ALL_OK },
699- { "transition", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
700- F(CCS_MAC_EXECUTE) | F(CCS_MAC_AUTO_DOMAIN_TRANSITION) },
701- { "uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
702- F(CCS_MAC_CHOWN) },
703- { "value", CCS_TYPE_STRING, CCS_TYPE_STRING,
704- F(CCS_MAC_ENVIRON) },
705- { "argv[0]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
706- CCS_EXECUTE_OR_ENVIRON_OK },
707- { "argv[4294967295]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
708- CCS_EXECUTE_OR_ENVIRON_OK },
709- { "envp[\"PATH\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
710- CCS_EXECUTE_OR_ENVIRON_OK },
711- { "envp[\"\\*\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
712- CCS_EXECUTE_OR_ENVIRON_OK },
713- { "NULL", CCS_TYPE_INVALID, CCS_TYPE_STRING,
714- CCS_ALL_OK },
715- { "\"word\"", CCS_TYPE_INVALID, CCS_TYPE_ASSIGN,
716- CCS_ALL_OK },
717- { "\"/\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
718- CCS_ALL_OK },
719- { "\"/\\*\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
720- CCS_ALL_OK },
721- { "@STRING_GROUP", CCS_TYPE_INVALID, CCS_TYPE_STRING,
722- CCS_ALL_OK },
723- { "0", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
724- CCS_ALL_OK },
725- { "0-4294967295", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
726- CCS_ALL_OK },
727- { "@NUMBER_GROUP", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
728- CCS_ALL_OK },
729- { "127.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
730- CCS_ALL_OK },
731- { "0.0.0.0-0.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
732- CCS_ALL_OK },
733- { "::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
734- CCS_ALL_OK },
735- { "::-::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
736- CCS_ALL_OK },
737- { "@IP_GROUP", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
738- CCS_ALL_OK },
739-};
740-
741-static char *policy = NULL;
742-static int policy_len = 0;
743-
744-static inline void truncate_policy(void)
745-{
746- policy_len = 0;
747-}
748-
749-static void add_policy(const char *data)
750-{
751- const int len = strlen(data);
752- char *tmp = realloc(policy, policy_len + len + 1);
753- if (!tmp) {
754- fprintf(stderr, "Out of memory\n");
755- exit(1);
756- }
757- policy = tmp;
758- memmove(policy + policy_len, data, len + 1);
759- policy_len += len;
760-}
761-
762-static unsigned int tests_now = 0;
763-
764-static void check_policy_written(const _Bool valid)
765-{
766- int fd1 = open("/proc/caitsith/policy", O_RDWR);
767- int fd2 = open("/proc/caitsith/policy", O_RDWR);
768- int len = strlen(policy);
769- int ret;
770- char *buffer;
771- if (fd1 == EOF || fd2 == EOF) {
772- printf("%s", policy);
773- return;
774- }
775- ret = write(fd1, policy, len);
776- if (ret != len) {
777- fprintf(stderr, "Write error (%d, %d)\n", ret, len);
778- exit(1);
779- }
780- buffer = calloc(len + 4096, 1);
781- if (!buffer) {
782- fprintf(stderr, "Out of memory\n");
783- exit(1);
784- }
785- ret = read(fd1, buffer, len + 4095);
786- if (!strstr(buffer, policy) != !valid) {
787- fprintf(stderr, "Test %u: FAILED(add) '%s' : '%s' valid=%u\n",
788- tests_now - 1, buffer, policy, valid);
789- exit(1);
790- }
791- printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
792- if (write(fd2, "delete ", 7) != 7 || write(fd2, policy, len) != len) {
793- fprintf(stderr, "Write error\n");
794- exit(1);
795- }
796- memset(buffer, 0, len + 1024);
797- ret = read(fd2, buffer, len + 1023);
798- if (strstr(buffer, policy)) {
799- fprintf(stderr, "Test %u: FAILED(remove) '%s' : '%s'\n",
800- tests_now - 1, buffer, policy);
801- exit(1);
802- }
803- printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
804- free(buffer);
805- close(fd1);
806- close(fd2);
807-}
808-
809-static inline void add_policy2(const char *data1, const char *data2)
810-{
811- add_policy(data1);
812- add_policy(data2);
813-}
814-
815-static inline void add_policy3(const char *data1, const char *data2,
816- const char *data3)
817-{
818- add_policy(data1);
819- add_policy(data2);
820- add_policy(data3);
821-}
822-
823-static _Bool adjust_exception(const int mac, const int p1, const int p2)
824-{
825- if (ccs_conditions[p1].left_type == CCS_TYPE_ASSIGN)
826- return !strcmp(ccs_conditions[p2].keyword, "NULL") ||
827- !strcmp(ccs_conditions[p2].keyword,"\"/\"");
828- if (ccs_conditions[p2].keyword[0] == '@')
829- return ccs_conditions[p1].left_type == CCS_TYPE_STRING ||
830- ccs_conditions[p1].left_type == CCS_TYPE_NUMBER ||
831- ccs_conditions[p1].left_type == CCS_TYPE_IPADDR ||
832- ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM;
833- if (ccs_conditions[p1].left_type == CCS_TYPE_STRING)
834- return !strcmp(ccs_conditions[p2].keyword, "\"word\"");
835- if (ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM &&
836- ccs_conditions[p2].right_type == CCS_TYPE_NUMBER)
837- return 1;
838- return 0;
839-}
840-
841-static unsigned int tests_start = 0;
842-
843-static void check_righthand(const int mac, const int p1, const _Bool org_valid)
844-{
845- int p2;
846- const enum ccs_var_type type = ccs_conditions[p1].left_type;
847- for (p2 = 0; p2 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
848- p2++) {
849- _Bool valid = org_valid;
850- if (tests_now++ < tests_start)
851- continue;
852- if (valid) {
853- if (!(ccs_conditions[p2].available & F(mac)))
854- valid = 0;
855- else if (ccs_conditions[p2].right_type != type)
856- valid = adjust_exception(mac, p1, p2);
857- }
858- truncate_policy();
859- add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
860- " audit 0\n 0 allow");
861- add_policy2(" ", ccs_conditions[p1].keyword);
862- add_policy2("=", ccs_conditions[p2].keyword);
863- if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
864- strcmp(ccs_conditions[p1].keyword, "transition"))
865- add_policy(" transition=\"word\"");
866- add_policy("\n");
867- check_policy_written(valid);
868- if (type == CCS_TYPE_ASSIGN)
869- valid = 0;
870- truncate_policy();
871- add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
872- " audit 0\n 0 allow");
873- add_policy2(" ", ccs_conditions[p1].keyword);
874- add_policy2("!=", ccs_conditions[p2].keyword);
875- if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
876- strcmp(ccs_conditions[p1].keyword, "transition"))
877- add_policy(" transition=\"word\"");
878- add_policy("\n");
879- check_policy_written(valid);
880- {
881- static time_t last = 0;
882- time_t now = time(NULL);
883- if (now - last >= (time_t) 10) {
884- last = now;
885- fprintf(stderr, "Test %u passed\n",
886- tests_now - 1);
887- }
888- }
889- }
890-}
891-
892-int main(int argc, char *argv[]) {
893- int mac;
894- if (argc > 1)
895- tests_start = atoi(argv[1]);
896- for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
897- truncate_policy();
898- add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
899- " audit 0\n");
900- check_policy_written(1);
901- }
902- for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
903- int p1;
904- for (p1 = 0;
905- p1 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
906- p1++) {
907- _Bool valid = 1;
908- if (ccs_conditions[p1].left_type == CCS_TYPE_INVALID ||
909- !(ccs_conditions[p1].available & F(mac)))
910- valid = 0;
911- check_righthand(mac, p1, valid);
912- }
913- }
914- fprintf(stderr, "Test %u passed\n", tests_now - 1);
915- return 0;
916-}
--- trunk/caitsith-tools/kernel_test/caitsith_bool_test.c (nonexistent)
+++ trunk/caitsith-tools/kernel_test/caitsith_bool_test.c (revision 76)
@@ -0,0 +1,918 @@
1+/*
2+ * caitsith_bool_test.c
3+ *
4+ * Copyright (C) 2012-2013 Tetsuo Handa
5+ *
6+ * Version: 0.1 2013/01/06
7+ *
8+ * This program is free software; you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License v2 as published by the
10+ * Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful, but WITHOUT
13+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15+ * more details.
16+ *
17+ * You should have received a copy of the GNU General Public License along with
18+ * this program; if not, write to the Free Software Foundation, Inc.,
19+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+ */
21+
22+#include <stdio.h>
23+#include <string.h>
24+#include <stdlib.h>
25+#include <sys/types.h>
26+#include <sys/stat.h>
27+#include <fcntl.h>
28+#include <unistd.h>
29+#include <time.h>
30+
31+enum ccs_mac_index {
32+ CCS_MAC_EXECUTE,
33+ CCS_MAC_READ,
34+ CCS_MAC_WRITE,
35+ CCS_MAC_APPEND,
36+ CCS_MAC_CREATE,
37+ CCS_MAC_UNLINK,
38+ CCS_MAC_GETATTR,
39+ CCS_MAC_MKDIR,
40+ CCS_MAC_RMDIR,
41+ CCS_MAC_MKFIFO,
42+ CCS_MAC_MKSOCK,
43+ CCS_MAC_TRUNCATE,
44+ CCS_MAC_SYMLINK,
45+ CCS_MAC_MKBLOCK,
46+ CCS_MAC_MKCHAR,
47+ CCS_MAC_LINK,
48+ CCS_MAC_RENAME,
49+ CCS_MAC_CHMOD,
50+ CCS_MAC_CHOWN,
51+ CCS_MAC_CHGRP,
52+ CCS_MAC_IOCTL,
53+ CCS_MAC_CHROOT,
54+ CCS_MAC_MOUNT,
55+ CCS_MAC_UMOUNT,
56+ CCS_MAC_PIVOT_ROOT,
57+ CCS_MAC_INET_STREAM_BIND,
58+ CCS_MAC_INET_STREAM_LISTEN,
59+ CCS_MAC_INET_STREAM_CONNECT,
60+ CCS_MAC_INET_STREAM_ACCEPT,
61+ CCS_MAC_INET_DGRAM_BIND,
62+ CCS_MAC_INET_DGRAM_SEND,
63+ CCS_MAC_INET_DGRAM_RECV,
64+ CCS_MAC_INET_RAW_BIND,
65+ CCS_MAC_INET_RAW_SEND,
66+ CCS_MAC_INET_RAW_RECV,
67+ CCS_MAC_UNIX_STREAM_BIND,
68+ CCS_MAC_UNIX_STREAM_LISTEN,
69+ CCS_MAC_UNIX_STREAM_CONNECT,
70+ CCS_MAC_UNIX_STREAM_ACCEPT,
71+ CCS_MAC_UNIX_DGRAM_BIND,
72+ CCS_MAC_UNIX_DGRAM_SEND,
73+ CCS_MAC_UNIX_DGRAM_RECV,
74+ CCS_MAC_UNIX_SEQPACKET_BIND,
75+ CCS_MAC_UNIX_SEQPACKET_LISTEN,
76+ CCS_MAC_UNIX_SEQPACKET_CONNECT,
77+ CCS_MAC_UNIX_SEQPACKET_ACCEPT,
78+ CCS_MAC_ENVIRON,
79+ CCS_MAC_PTRACE,
80+ CCS_MAC_SIGNAL,
81+ CCS_MAC_MODIFY_POLICY,
82+ CCS_MAC_USE_NETLINK_SOCKET,
83+ CCS_MAC_USE_PACKET_SOCKET,
84+ CCS_MAC_USE_REBOOT,
85+ CCS_MAC_USE_VHANGUP,
86+ CCS_MAC_SET_TIME,
87+ CCS_MAC_SET_PRIORITY,
88+ CCS_MAC_SET_HOSTNAME,
89+ CCS_MAC_USE_KERNEL_MODULE,
90+ CCS_MAC_USE_NEW_KERNEL,
91+ CCS_MAC_AUTO_DOMAIN_TRANSITION,
92+ CCS_MAC_MANUAL_DOMAIN_TRANSITION,
93+ CCS_MAX_MAC_INDEX
94+};
95+
96+static const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX] = {
97+ [CCS_MAC_EXECUTE] = "execute",
98+ [CCS_MAC_READ] = "read",
99+ [CCS_MAC_WRITE] = "write",
100+ [CCS_MAC_APPEND] = "append",
101+ [CCS_MAC_CREATE] = "create",
102+ [CCS_MAC_UNLINK] = "unlink",
103+ [CCS_MAC_GETATTR] = "getattr",
104+ [CCS_MAC_MKDIR] = "mkdir",
105+ [CCS_MAC_RMDIR] = "rmdir",
106+ [CCS_MAC_MKFIFO] = "mkfifo",
107+ [CCS_MAC_MKSOCK] = "mksock",
108+ [CCS_MAC_TRUNCATE] = "truncate",
109+ [CCS_MAC_SYMLINK] = "symlink",
110+ [CCS_MAC_MKBLOCK] = "mkblock",
111+ [CCS_MAC_MKCHAR] = "mkchar",
112+ [CCS_MAC_LINK] = "link",
113+ [CCS_MAC_RENAME] = "rename",
114+ [CCS_MAC_CHMOD] = "chmod",
115+ [CCS_MAC_CHOWN] = "chown",
116+ [CCS_MAC_CHGRP] = "chgrp",
117+ [CCS_MAC_IOCTL] = "ioctl",
118+ [CCS_MAC_CHROOT] = "chroot",
119+ [CCS_MAC_MOUNT] = "mount",
120+ [CCS_MAC_UMOUNT] = "unmount",
121+ [CCS_MAC_PIVOT_ROOT] = "pivot_root",
122+ [CCS_MAC_INET_STREAM_BIND] = "inet_stream_bind",
123+ [CCS_MAC_INET_STREAM_LISTEN] = "inet_stream_listen",
124+ [CCS_MAC_INET_STREAM_CONNECT] = "inet_stream_connect",
125+ [CCS_MAC_INET_STREAM_ACCEPT] = "inet_stream_accept",
126+ [CCS_MAC_INET_DGRAM_BIND] = "inet_dgram_bind",
127+ [CCS_MAC_INET_DGRAM_SEND] = "inet_dgram_send",
128+ [CCS_MAC_INET_DGRAM_RECV] = "inet_dgram_recv",
129+ [CCS_MAC_INET_RAW_BIND] = "inet_raw_bind",
130+ [CCS_MAC_INET_RAW_SEND] = "inet_raw_send",
131+ [CCS_MAC_INET_RAW_RECV] = "inet_raw_recv",
132+ [CCS_MAC_UNIX_STREAM_BIND] = "unix_stream_bind",
133+ [CCS_MAC_UNIX_STREAM_LISTEN] = "unix_stream_listen",
134+ [CCS_MAC_UNIX_STREAM_CONNECT] = "unix_stream_connect",
135+ [CCS_MAC_UNIX_STREAM_ACCEPT] = "unix_stream_accept",
136+ [CCS_MAC_UNIX_DGRAM_BIND] = "unix_dgram_bind",
137+ [CCS_MAC_UNIX_DGRAM_SEND] = "unix_dgram_send",
138+ [CCS_MAC_UNIX_DGRAM_RECV] = "unix_dgram_recv",
139+ [CCS_MAC_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
140+ [CCS_MAC_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
141+ [CCS_MAC_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
142+ [CCS_MAC_UNIX_SEQPACKET_ACCEPT] = "unix_seqpacket_accept",
143+ [CCS_MAC_ENVIRON] = "environ",
144+ [CCS_MAC_PTRACE] = "ptrace",
145+ [CCS_MAC_SIGNAL] = "signal",
146+ [CCS_MAC_MODIFY_POLICY] = "modify_policy",
147+ [CCS_MAC_USE_NETLINK_SOCKET] = "use_netlink_socket",
148+ [CCS_MAC_USE_PACKET_SOCKET] = "use_packet_socket",
149+ [CCS_MAC_USE_REBOOT] = "use_reboot",
150+ [CCS_MAC_USE_VHANGUP] = "use_vhangup",
151+ [CCS_MAC_SET_TIME] = "set_time",
152+ [CCS_MAC_SET_PRIORITY] = "set_priority",
153+ [CCS_MAC_SET_HOSTNAME] = "set_hostname",
154+ [CCS_MAC_USE_KERNEL_MODULE] = "use_kernel_module",
155+ [CCS_MAC_USE_NEW_KERNEL] = "use_new_kernel",
156+ [CCS_MAC_AUTO_DOMAIN_TRANSITION] = "auto_domain_transition",
157+ [CCS_MAC_MANUAL_DOMAIN_TRANSITION] = "manual_domain_transition",
158+};
159+
160+#define F(bit) (1ULL << bit)
161+
162+#define CCS_ALL_OK \
163+ (F(CCS_MAC_EXECUTE) | \
164+ F(CCS_MAC_READ) | \
165+ F(CCS_MAC_WRITE) | \
166+ F(CCS_MAC_APPEND) | \
167+ F(CCS_MAC_CREATE) | \
168+ F(CCS_MAC_UNLINK) | \
169+ F(CCS_MAC_GETATTR) | \
170+ F(CCS_MAC_MKDIR) | \
171+ F(CCS_MAC_RMDIR) | \
172+ F(CCS_MAC_MKFIFO) | \
173+ F(CCS_MAC_MKSOCK) | \
174+ F(CCS_MAC_TRUNCATE) | \
175+ F(CCS_MAC_SYMLINK) | \
176+ F(CCS_MAC_MKBLOCK) | \
177+ F(CCS_MAC_MKCHAR) | \
178+ F(CCS_MAC_LINK) | \
179+ F(CCS_MAC_RENAME) | \
180+ F(CCS_MAC_CHMOD) | \
181+ F(CCS_MAC_CHOWN) | \
182+ F(CCS_MAC_CHGRP) | \
183+ F(CCS_MAC_IOCTL) | \
184+ F(CCS_MAC_CHROOT) | \
185+ F(CCS_MAC_MOUNT) | \
186+ F(CCS_MAC_UMOUNT) | \
187+ F(CCS_MAC_PIVOT_ROOT) | \
188+ F(CCS_MAC_INET_STREAM_BIND) | \
189+ F(CCS_MAC_INET_STREAM_LISTEN) | \
190+ F(CCS_MAC_INET_STREAM_CONNECT) | \
191+ F(CCS_MAC_INET_STREAM_ACCEPT) | \
192+ F(CCS_MAC_INET_DGRAM_BIND) | \
193+ F(CCS_MAC_INET_DGRAM_SEND) | \
194+ F(CCS_MAC_INET_DGRAM_RECV) | \
195+ F(CCS_MAC_INET_RAW_BIND) | \
196+ F(CCS_MAC_INET_RAW_SEND) | \
197+ F(CCS_MAC_INET_RAW_RECV) | \
198+ F(CCS_MAC_UNIX_STREAM_BIND) | \
199+ F(CCS_MAC_UNIX_STREAM_LISTEN) | \
200+ F(CCS_MAC_UNIX_STREAM_CONNECT) | \
201+ F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
202+ F(CCS_MAC_UNIX_DGRAM_BIND) | \
203+ F(CCS_MAC_UNIX_DGRAM_SEND) | \
204+ F(CCS_MAC_UNIX_DGRAM_RECV) | \
205+ F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
206+ F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
207+ F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
208+ F(CCS_MAC_UNIX_SEQPACKET_ACCEPT) | \
209+ F(CCS_MAC_ENVIRON) | \
210+ F(CCS_MAC_PTRACE) | \
211+ F(CCS_MAC_SIGNAL) | \
212+ F(CCS_MAC_MODIFY_POLICY) | \
213+ F(CCS_MAC_USE_NETLINK_SOCKET) | \
214+ F(CCS_MAC_USE_PACKET_SOCKET) | \
215+ F(CCS_MAC_USE_REBOOT) | \
216+ F(CCS_MAC_USE_VHANGUP) | \
217+ F(CCS_MAC_SET_TIME) | \
218+ F(CCS_MAC_SET_PRIORITY) | \
219+ F(CCS_MAC_SET_HOSTNAME) | \
220+ F(CCS_MAC_USE_KERNEL_MODULE) | \
221+ F(CCS_MAC_USE_NEW_KERNEL) | \
222+ F(CCS_MAC_AUTO_DOMAIN_TRANSITION) | \
223+ F(CCS_MAC_MANUAL_DOMAIN_TRANSITION))
224+
225+#define CCS_PATH_SELF_OK \
226+ (F(CCS_MAC_EXECUTE) | \
227+ F(CCS_MAC_READ) | \
228+ F(CCS_MAC_WRITE) | \
229+ F(CCS_MAC_APPEND) | \
230+ F(CCS_MAC_UNLINK) | \
231+ F(CCS_MAC_GETATTR) | \
232+ F(CCS_MAC_RMDIR) | \
233+ F(CCS_MAC_TRUNCATE) | \
234+ F(CCS_MAC_CHMOD) | \
235+ F(CCS_MAC_CHOWN) | \
236+ F(CCS_MAC_CHGRP) | \
237+ F(CCS_MAC_IOCTL) | \
238+ F(CCS_MAC_CHROOT) | \
239+ F(CCS_MAC_UMOUNT) | \
240+ F(CCS_MAC_ENVIRON))
241+
242+#define CCS_PATH_PARENT_OK \
243+ (F(CCS_MAC_CREATE) | \
244+ F(CCS_MAC_MKDIR) | \
245+ F(CCS_MAC_MKFIFO) | \
246+ F(CCS_MAC_MKSOCK) | \
247+ F(CCS_MAC_SYMLINK) | \
248+ F(CCS_MAC_MKBLOCK) | \
249+ F(CCS_MAC_MKCHAR))
250+
251+#define CCS_PATH_OK (CCS_PATH_SELF_OK | CCS_PATH_PARENT_OK)
252+
253+#define CCS_RENAME_OR_LINK_OK (F(CCS_MAC_LINK) | F(CCS_MAC_RENAME))
254+
255+#define CCS_EXECUTE_OR_ENVIRON_OK (F(CCS_MAC_EXECUTE) | F(CCS_MAC_ENVIRON))
256+
257+#define CCS_MKDEV_OK (F(CCS_MAC_MKBLOCK) | F(CCS_MAC_MKCHAR))
258+
259+#define CCS_PATH_PERM_OK \
260+ (F(CCS_MAC_MKDIR) | \
261+ F(CCS_MAC_MKBLOCK) | \
262+ F(CCS_MAC_MKCHAR) | \
263+ F(CCS_MAC_MKFIFO) | \
264+ F(CCS_MAC_MKSOCK) | \
265+ F(CCS_MAC_CREATE) | \
266+ F(CCS_MAC_CHMOD))
267+
268+#define CCS_IP_SOCKET_OK \
269+ (F(CCS_MAC_INET_STREAM_BIND) | \
270+ F(CCS_MAC_INET_STREAM_LISTEN) | \
271+ F(CCS_MAC_INET_STREAM_CONNECT) | \
272+ F(CCS_MAC_INET_STREAM_ACCEPT) | \
273+ F(CCS_MAC_INET_DGRAM_BIND) | \
274+ F(CCS_MAC_INET_DGRAM_SEND) | \
275+ F(CCS_MAC_INET_DGRAM_RECV))
276+
277+#define CCS_RAW_SOCKET_OK \
278+ (F(CCS_MAC_INET_RAW_BIND) | \
279+ F(CCS_MAC_INET_RAW_SEND) | \
280+ F(CCS_MAC_INET_RAW_RECV))
281+
282+#define CCS_INET_SOCKET_OK (CCS_IP_SOCKET_OK | CCS_RAW_SOCKET_OK)
283+
284+#define CCS_UNIX_SOCKET_OK \
285+ (F(CCS_MAC_UNIX_STREAM_BIND) | \
286+ F(CCS_MAC_UNIX_STREAM_LISTEN) | \
287+ F(CCS_MAC_UNIX_STREAM_CONNECT) | \
288+ F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
289+ F(CCS_MAC_UNIX_DGRAM_BIND) | \
290+ F(CCS_MAC_UNIX_DGRAM_SEND) | \
291+ F(CCS_MAC_UNIX_DGRAM_RECV) | \
292+ F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
293+ F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
294+ F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
295+ F(CCS_MAC_UNIX_SEQPACKET_ACCEPT))
296+
297+enum ccs_var_type {
298+ CCS_TYPE_INVALID,
299+ CCS_TYPE_NUMBER,
300+ CCS_TYPE_STRING,
301+ CCS_TYPE_IPADDR,
302+ CCS_TYPE_FILEPERM,
303+ CCS_TYPE_FILETYPE,
304+ CCS_TYPE_TASKTYPE,
305+ CCS_TYPE_ASSIGN,
306+};
307+
308+static const struct {
309+ const char * const keyword;
310+ const enum ccs_var_type left_type;
311+ const enum ccs_var_type right_type;
312+ const unsigned long long available;
313+} ccs_conditions[] = {
314+ { "addr", CCS_TYPE_STRING, CCS_TYPE_STRING,
315+ CCS_UNIX_SOCKET_OK },
316+ { "argc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
317+ CCS_EXECUTE_OR_ENVIRON_OK },
318+ { "block", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
319+ CCS_ALL_OK },
320+ { "char", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
321+ CCS_ALL_OK },
322+ { "cmd", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
323+ F(CCS_MAC_IOCTL) | F(CCS_MAC_PTRACE) },
324+ { "data", CCS_TYPE_STRING, CCS_TYPE_STRING,
325+ F(CCS_MAC_MOUNT) },
326+ { "dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
327+ CCS_MKDEV_OK },
328+ { "dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
329+ CCS_MKDEV_OK },
330+ { "directory", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
331+ CCS_ALL_OK },
332+ { "domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
333+ F(CCS_MAC_PTRACE) | F(CCS_MAC_MANUAL_DOMAIN_TRANSITION) },
334+ { "envc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
335+ CCS_EXECUTE_OR_ENVIRON_OK },
336+ { "exec", CCS_TYPE_STRING, CCS_TYPE_STRING,
337+ CCS_EXECUTE_OR_ENVIRON_OK },
338+ { "exec.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
339+ CCS_EXECUTE_OR_ENVIRON_OK },
340+ { "exec.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
341+ CCS_EXECUTE_OR_ENVIRON_OK },
342+ { "exec.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
343+ CCS_EXECUTE_OR_ENVIRON_OK },
344+ { "exec.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
345+ CCS_EXECUTE_OR_ENVIRON_OK },
346+ { "exec.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
347+ CCS_EXECUTE_OR_ENVIRON_OK },
348+ { "exec.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
349+ CCS_EXECUTE_OR_ENVIRON_OK },
350+ { "exec.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
351+ CCS_EXECUTE_OR_ENVIRON_OK },
352+ { "exec.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
353+ CCS_EXECUTE_OR_ENVIRON_OK },
354+ { "exec.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
355+ CCS_EXECUTE_OR_ENVIRON_OK },
356+ { "exec.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
357+ CCS_EXECUTE_OR_ENVIRON_OK },
358+ { "exec.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
359+ CCS_EXECUTE_OR_ENVIRON_OK },
360+ { "exec.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
361+ CCS_EXECUTE_OR_ENVIRON_OK },
362+ { "exec.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
363+ CCS_EXECUTE_OR_ENVIRON_OK },
364+ { "exec.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
365+ CCS_EXECUTE_OR_ENVIRON_OK },
366+ { "exec.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
367+ CCS_EXECUTE_OR_ENVIRON_OK },
368+ { "execute_handler", CCS_TYPE_INVALID, CCS_TYPE_TASKTYPE,
369+ CCS_ALL_OK },
370+ { "fifo", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
371+ CCS_ALL_OK },
372+ { "file", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
373+ CCS_ALL_OK },
374+ { "flags", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
375+ F(CCS_MAC_MOUNT) | F(CCS_MAC_UMOUNT) },
376+ { "fstype", CCS_TYPE_STRING, CCS_TYPE_STRING,
377+ F(CCS_MAC_MOUNT) },
378+ { "gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
379+ F(CCS_MAC_CHGRP) },
380+ { "group_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
381+ CCS_ALL_OK },
382+ { "group_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
383+ CCS_ALL_OK },
384+ { "group_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
385+ CCS_ALL_OK },
386+ { "handler", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
387+ F(CCS_MAC_EXECUTE) },
388+ { "ip", CCS_TYPE_IPADDR, CCS_TYPE_INVALID,
389+ CCS_INET_SOCKET_OK },
390+ { "name", CCS_TYPE_STRING, CCS_TYPE_STRING,
391+ F(CCS_MAC_ENVIRON) },
392+ { "new_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
393+ CCS_RENAME_OR_LINK_OK },
394+ { "new_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
395+ F(CCS_MAC_RENAME) },
396+ { "new_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
397+ F(CCS_MAC_RENAME) },
398+ { "new_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
399+ F(CCS_MAC_RENAME) },
400+ { "new_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
401+ F(CCS_MAC_RENAME) },
402+ { "new_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
403+ F(CCS_MAC_RENAME) },
404+ { "new_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
405+ F(CCS_MAC_RENAME) },
406+ { "new_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
407+ F(CCS_MAC_RENAME) },
408+ { "new_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
409+ CCS_RENAME_OR_LINK_OK },
410+ { "new_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
411+ CCS_RENAME_OR_LINK_OK },
412+ { "new_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
413+ CCS_RENAME_OR_LINK_OK },
414+ { "new_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
415+ CCS_RENAME_OR_LINK_OK },
416+ { "new_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
417+ CCS_RENAME_OR_LINK_OK },
418+ { "new_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
419+ CCS_RENAME_OR_LINK_OK },
420+ { "new_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
421+ CCS_RENAME_OR_LINK_OK },
422+ { "new_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
423+ F(CCS_MAC_RENAME) },
424+ { "new_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
425+ F(CCS_MAC_RENAME) },
426+ { "new_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
427+ F(CCS_MAC_RENAME) },
428+ { "new_root", CCS_TYPE_STRING, CCS_TYPE_STRING,
429+ F(CCS_MAC_PIVOT_ROOT) },
430+ { "new_root.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
431+ F(CCS_MAC_PIVOT_ROOT) },
432+ { "new_root.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
433+ F(CCS_MAC_PIVOT_ROOT) },
434+ { "new_root.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
435+ F(CCS_MAC_PIVOT_ROOT) },
436+ { "new_root.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
437+ F(CCS_MAC_PIVOT_ROOT) },
438+ { "new_root.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
439+ F(CCS_MAC_PIVOT_ROOT) },
440+ { "new_root.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
441+ F(CCS_MAC_PIVOT_ROOT) },
442+ { "new_root.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
443+ F(CCS_MAC_PIVOT_ROOT) },
444+ { "new_root.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
445+ F(CCS_MAC_PIVOT_ROOT) },
446+ { "new_root.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
447+ F(CCS_MAC_PIVOT_ROOT) },
448+ { "new_root.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
449+ F(CCS_MAC_PIVOT_ROOT) },
450+ { "new_root.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
451+ F(CCS_MAC_PIVOT_ROOT) },
452+ { "new_root.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
453+ F(CCS_MAC_PIVOT_ROOT) },
454+ { "new_root.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
455+ F(CCS_MAC_PIVOT_ROOT) },
456+ { "new_root.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
457+ F(CCS_MAC_PIVOT_ROOT) },
458+ { "new_root.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
459+ F(CCS_MAC_PIVOT_ROOT) },
460+ { "new_root.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
461+ F(CCS_MAC_PIVOT_ROOT) },
462+ { "new_root.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
463+ F(CCS_MAC_PIVOT_ROOT) },
464+ { "old_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
465+ CCS_RENAME_OR_LINK_OK },
466+ { "old_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
467+ CCS_RENAME_OR_LINK_OK },
468+ { "old_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
469+ CCS_RENAME_OR_LINK_OK },
470+ { "old_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
471+ CCS_RENAME_OR_LINK_OK },
472+ { "old_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
473+ CCS_RENAME_OR_LINK_OK },
474+ { "old_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
475+ CCS_RENAME_OR_LINK_OK },
476+ { "old_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
477+ CCS_RENAME_OR_LINK_OK },
478+ { "old_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
479+ CCS_RENAME_OR_LINK_OK },
480+ { "old_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
481+ CCS_RENAME_OR_LINK_OK },
482+ { "old_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
483+ CCS_RENAME_OR_LINK_OK },
484+ { "old_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
485+ CCS_RENAME_OR_LINK_OK },
486+ { "old_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
487+ CCS_RENAME_OR_LINK_OK },
488+ { "old_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
489+ CCS_RENAME_OR_LINK_OK },
490+ { "old_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
491+ CCS_RENAME_OR_LINK_OK },
492+ { "old_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
493+ CCS_RENAME_OR_LINK_OK },
494+ { "old_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
495+ CCS_RENAME_OR_LINK_OK },
496+ { "old_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
497+ CCS_RENAME_OR_LINK_OK },
498+ { "old_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
499+ CCS_RENAME_OR_LINK_OK },
500+ { "others_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
501+ CCS_ALL_OK },
502+ { "others_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
503+ CCS_ALL_OK },
504+ { "others_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
505+ CCS_ALL_OK },
506+ { "owner_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
507+ CCS_ALL_OK },
508+ { "owner_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
509+ CCS_ALL_OK },
510+ { "owner_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
511+ CCS_ALL_OK },
512+ { "path", CCS_TYPE_STRING, CCS_TYPE_STRING,
513+ CCS_PATH_OK },
514+ { "path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
515+ CCS_PATH_SELF_OK },
516+ { "path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
517+ CCS_PATH_SELF_OK },
518+ { "path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
519+ CCS_PATH_SELF_OK },
520+ { "path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
521+ CCS_PATH_SELF_OK },
522+ { "path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
523+ CCS_PATH_SELF_OK },
524+ { "path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
525+ CCS_PATH_SELF_OK },
526+ { "path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
527+ CCS_PATH_SELF_OK },
528+ { "path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
529+ CCS_PATH_OK },
530+ { "path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
531+ CCS_PATH_OK },
532+ { "path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
533+ CCS_PATH_OK },
534+ { "path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
535+ CCS_PATH_OK },
536+ { "path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
537+ CCS_PATH_OK },
538+ { "path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
539+ CCS_PATH_OK },
540+ { "path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
541+ CCS_PATH_OK },
542+ { "path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
543+ CCS_PATH_SELF_OK },
544+ { "path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
545+ CCS_PATH_SELF_OK },
546+ { "path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
547+ CCS_PATH_SELF_OK },
548+ { "perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
549+ CCS_PATH_PERM_OK },
550+ { "port", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
551+ CCS_IP_SOCKET_OK },
552+ { "proto", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
553+ CCS_RAW_SOCKET_OK },
554+ { "put_old", CCS_TYPE_STRING, CCS_TYPE_STRING,
555+ F(CCS_MAC_PIVOT_ROOT) },
556+ { "put_old.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
557+ F(CCS_MAC_PIVOT_ROOT) },
558+ { "put_old.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
559+ F(CCS_MAC_PIVOT_ROOT) },
560+ { "put_old.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
561+ F(CCS_MAC_PIVOT_ROOT) },
562+ { "put_old.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
563+ F(CCS_MAC_PIVOT_ROOT) },
564+ { "put_old.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
565+ F(CCS_MAC_PIVOT_ROOT) },
566+ { "put_old.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
567+ F(CCS_MAC_PIVOT_ROOT) },
568+ { "put_old.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
569+ F(CCS_MAC_PIVOT_ROOT) },
570+ { "put_old.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
571+ F(CCS_MAC_PIVOT_ROOT) },
572+ { "put_old.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
573+ F(CCS_MAC_PIVOT_ROOT) },
574+ { "put_old.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
575+ F(CCS_MAC_PIVOT_ROOT) },
576+ { "put_old.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
577+ F(CCS_MAC_PIVOT_ROOT) },
578+ { "put_old.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
579+ F(CCS_MAC_PIVOT_ROOT) },
580+ { "put_old.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
581+ F(CCS_MAC_PIVOT_ROOT) },
582+ { "put_old.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
583+ F(CCS_MAC_PIVOT_ROOT) },
584+ { "put_old.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
585+ F(CCS_MAC_PIVOT_ROOT) },
586+ { "put_old.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
587+ F(CCS_MAC_PIVOT_ROOT) },
588+ { "put_old.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
589+ F(CCS_MAC_PIVOT_ROOT) },
590+ { "setgid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
591+ CCS_ALL_OK },
592+ { "setuid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
593+ CCS_ALL_OK },
594+ { "sig", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
595+ F(CCS_MAC_SIGNAL) },
596+ { "socket", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
597+ CCS_ALL_OK },
598+ { "source", CCS_TYPE_STRING, CCS_TYPE_STRING,
599+ F(CCS_MAC_MOUNT) },
600+ { "source.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
601+ F(CCS_MAC_MOUNT) },
602+ { "source.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
603+ F(CCS_MAC_MOUNT) },
604+ { "source.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
605+ F(CCS_MAC_MOUNT) },
606+ { "source.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
607+ F(CCS_MAC_MOUNT) },
608+ { "source.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
609+ F(CCS_MAC_MOUNT) },
610+ { "source.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
611+ F(CCS_MAC_MOUNT) },
612+ { "source.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
613+ F(CCS_MAC_MOUNT) },
614+ { "source.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
615+ F(CCS_MAC_MOUNT) },
616+ { "source.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
617+ F(CCS_MAC_MOUNT) },
618+ { "source.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
619+ F(CCS_MAC_MOUNT) },
620+ { "source.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
621+ F(CCS_MAC_MOUNT) },
622+ { "source.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
623+ F(CCS_MAC_MOUNT) },
624+ { "source.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
625+ F(CCS_MAC_MOUNT) },
626+ { "source.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
627+ F(CCS_MAC_MOUNT) },
628+ { "source.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
629+ F(CCS_MAC_MOUNT) },
630+ { "source.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
631+ F(CCS_MAC_MOUNT) },
632+ { "source.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
633+ F(CCS_MAC_MOUNT) },
634+ { "sticky", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
635+ CCS_ALL_OK },
636+ { "symlink", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
637+ CCS_ALL_OK },
638+ { "target", CCS_TYPE_STRING, CCS_TYPE_STRING,
639+ F(CCS_MAC_MOUNT) | F(CCS_MAC_SYMLINK) },
640+ { "target.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
641+ F(CCS_MAC_MOUNT) },
642+ { "target.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
643+ F(CCS_MAC_MOUNT) },
644+ { "target.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
645+ F(CCS_MAC_MOUNT) },
646+ { "target.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
647+ F(CCS_MAC_MOUNT) },
648+ { "target.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
649+ F(CCS_MAC_MOUNT) },
650+ { "target.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
651+ F(CCS_MAC_MOUNT) },
652+ { "target.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
653+ F(CCS_MAC_MOUNT) },
654+ { "target.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
655+ F(CCS_MAC_MOUNT) },
656+ { "target.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
657+ F(CCS_MAC_MOUNT) },
658+ { "target.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
659+ F(CCS_MAC_MOUNT) },
660+ { "target.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
661+ F(CCS_MAC_MOUNT) },
662+ { "target.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
663+ F(CCS_MAC_MOUNT) },
664+ { "target.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
665+ F(CCS_MAC_MOUNT) },
666+ { "target.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
667+ F(CCS_MAC_MOUNT) },
668+ { "target.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
669+ F(CCS_MAC_MOUNT) },
670+ { "target.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
671+ F(CCS_MAC_MOUNT) },
672+ { "target.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
673+ F(CCS_MAC_MOUNT) },
674+ { "task.domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
675+ CCS_ALL_OK },
676+ { "task.egid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
677+ CCS_ALL_OK },
678+ { "task.euid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
679+ CCS_ALL_OK },
680+ { "task.exe", CCS_TYPE_STRING, CCS_TYPE_STRING,
681+ CCS_ALL_OK },
682+ { "task.fsgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
683+ CCS_ALL_OK },
684+ { "task.fsuid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
685+ CCS_ALL_OK },
686+ { "task.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
687+ CCS_ALL_OK },
688+ { "task.pid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
689+ CCS_ALL_OK },
690+ { "task.ppid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
691+ CCS_ALL_OK },
692+ { "task.sgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
693+ CCS_ALL_OK },
694+ { "task.suid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
695+ CCS_ALL_OK },
696+ { "task.type", CCS_TYPE_TASKTYPE, CCS_TYPE_INVALID,
697+ CCS_ALL_OK },
698+ { "task.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
699+ CCS_ALL_OK },
700+ { "transition", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
701+ F(CCS_MAC_EXECUTE) | F(CCS_MAC_AUTO_DOMAIN_TRANSITION) },
702+ { "uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
703+ F(CCS_MAC_CHOWN) },
704+ { "value", CCS_TYPE_STRING, CCS_TYPE_STRING,
705+ F(CCS_MAC_ENVIRON) },
706+ { "argv[0]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
707+ CCS_EXECUTE_OR_ENVIRON_OK },
708+ { "argv[4294967295]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
709+ CCS_EXECUTE_OR_ENVIRON_OK },
710+ { "envp[\"PATH\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
711+ CCS_EXECUTE_OR_ENVIRON_OK },
712+ { "envp[\"\\*\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
713+ CCS_EXECUTE_OR_ENVIRON_OK },
714+ { "NULL", CCS_TYPE_INVALID, CCS_TYPE_STRING,
715+ CCS_ALL_OK },
716+ { "\"word\"", CCS_TYPE_INVALID, CCS_TYPE_ASSIGN,
717+ CCS_ALL_OK },
718+ { "\"/\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
719+ CCS_ALL_OK },
720+ { "\"/\\*\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
721+ CCS_ALL_OK },
722+ { "@STRING_GROUP", CCS_TYPE_INVALID, CCS_TYPE_STRING,
723+ CCS_ALL_OK },
724+ { "0", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
725+ CCS_ALL_OK },
726+ { "0-4294967295", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
727+ CCS_ALL_OK },
728+ { "@NUMBER_GROUP", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
729+ CCS_ALL_OK },
730+ { "127.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
731+ CCS_ALL_OK },
732+ { "0.0.0.0-0.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
733+ CCS_ALL_OK },
734+ { "::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
735+ CCS_ALL_OK },
736+ { "::-::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
737+ CCS_ALL_OK },
738+ { "@IP_GROUP", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
739+ CCS_ALL_OK },
740+};
741+
742+static char *policy = NULL;
743+static int policy_len = 0;
744+
745+static inline void truncate_policy(void)
746+{
747+ policy_len = 0;
748+}
749+
750+static void add_policy(const char *data)
751+{
752+ const int len = strlen(data);
753+ char *tmp = realloc(policy, policy_len + len + 1);
754+ if (!tmp) {
755+ fprintf(stderr, "Out of memory\n");
756+ exit(1);
757+ }
758+ policy = tmp;
759+ memmove(policy + policy_len, data, len + 1);
760+ policy_len += len;
761+}
762+
763+static unsigned int tests_now = 0;
764+
765+static void check_policy_written(const _Bool valid)
766+{
767+ int fd1 = open("/proc/caitsith/policy", O_RDWR);
768+ int fd2 = open("/proc/caitsith/policy", O_RDWR);
769+ int len = strlen(policy);
770+ int ret;
771+ char *buffer;
772+ if (fd1 == EOF || fd2 == EOF) {
773+ printf("%s", policy);
774+ return;
775+ }
776+ ret = write(fd1, policy, len);
777+ if (ret != len) {
778+ fprintf(stderr, "Write error (%d, %d)\n", ret, len);
779+ exit(1);
780+ }
781+ buffer = calloc(len + 4096, 1);
782+ if (!buffer) {
783+ fprintf(stderr, "Out of memory\n");
784+ exit(1);
785+ }
786+ ret = read(fd1, buffer, len + 4095);
787+ if (!strstr(buffer, policy) != !valid) {
788+ fprintf(stderr, "Test %u: FAILED(add) '%s' : '%s' valid=%u\n",
789+ tests_now - 1, buffer, policy, valid);
790+ exit(1);
791+ }
792+ printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
793+ if (write(fd2, "delete ", 7) != 7 || write(fd2, policy, len) != len) {
794+ fprintf(stderr, "Write error\n");
795+ exit(1);
796+ }
797+ memset(buffer, 0, len + 1024);
798+ ret = read(fd2, buffer, len + 1023);
799+ if (strstr(buffer, policy)) {
800+ fprintf(stderr, "Test %u: FAILED(remove) '%s' : '%s'\n",
801+ tests_now - 1, buffer, policy);
802+ exit(1);
803+ }
804+ printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
805+ free(buffer);
806+ close(fd1);
807+ close(fd2);
808+}
809+
810+static inline void add_policy2(const char *data1, const char *data2)
811+{
812+ add_policy(data1);
813+ add_policy(data2);
814+}
815+
816+static inline void add_policy3(const char *data1, const char *data2,
817+ const char *data3)
818+{
819+ add_policy(data1);
820+ add_policy(data2);
821+ add_policy(data3);
822+}
823+
824+static _Bool adjust_exception(const int mac, const int p1, const int p2)
825+{
826+ if (ccs_conditions[p1].left_type == CCS_TYPE_ASSIGN)
827+ return !strcmp(ccs_conditions[p2].keyword, "NULL") ||
828+ !strcmp(ccs_conditions[p2].keyword,"\"/\"");
829+ if (ccs_conditions[p2].keyword[0] == '@')
830+ return ccs_conditions[p1].left_type == CCS_TYPE_STRING ||
831+ ccs_conditions[p1].left_type == CCS_TYPE_NUMBER ||
832+ ccs_conditions[p1].left_type == CCS_TYPE_IPADDR ||
833+ ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM;
834+ if (ccs_conditions[p1].left_type == CCS_TYPE_STRING)
835+ return !strcmp(ccs_conditions[p2].keyword, "\"word\"");
836+ if (ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM &&
837+ ccs_conditions[p2].right_type == CCS_TYPE_NUMBER)
838+ return 1;
839+ return 0;
840+}
841+
842+static unsigned int tests_start = 0;
843+
844+static void check_righthand(const int mac, const int p1, const _Bool org_valid)
845+{
846+ int p2;
847+ const enum ccs_var_type type = ccs_conditions[p1].left_type;
848+ for (p2 = 0; p2 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
849+ p2++) {
850+ _Bool valid = org_valid;
851+ if (tests_now++ < tests_start)
852+ continue;
853+ if (valid) {
854+ if (!(ccs_conditions[p2].available & F(mac)))
855+ continue;
856+ else if (ccs_conditions[p2].right_type != type)
857+ if (!adjust_exception(mac, p1, p2))
858+ continue;
859+ }
860+ truncate_policy();
861+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
862+ " audit 0\n 0 allow");
863+ add_policy2(" ", ccs_conditions[p1].keyword);
864+ add_policy2("=", ccs_conditions[p2].keyword);
865+ if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
866+ strcmp(ccs_conditions[p1].keyword, "transition"))
867+ add_policy(" transition=\"word\"");
868+ add_policy("\n");
869+ check_policy_written(valid);
870+ if (type == CCS_TYPE_ASSIGN)
871+ valid = 0;
872+ truncate_policy();
873+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
874+ " audit 0\n 0 allow");
875+ add_policy2(" ", ccs_conditions[p1].keyword);
876+ add_policy2("!=", ccs_conditions[p2].keyword);
877+ if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
878+ strcmp(ccs_conditions[p1].keyword, "transition"))
879+ add_policy(" transition=\"word\"");
880+ add_policy("\n");
881+ check_policy_written(valid);
882+ {
883+ static time_t last = 0;
884+ time_t now = time(NULL);
885+ if (now - last >= (time_t) 10) {
886+ last = now;
887+ fprintf(stderr, "Test %u passed\n",
888+ tests_now - 1);
889+ }
890+ }
891+ }
892+}
893+
894+int main(int argc, char *argv[]) {
895+ int mac;
896+ if (argc > 1)
897+ tests_start = atoi(argv[1]);
898+ for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
899+ truncate_policy();
900+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
901+ " audit 0\n");
902+ check_policy_written(1);
903+ }
904+ for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
905+ int p1;
906+ for (p1 = 0;
907+ p1 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
908+ p1++) {
909+ _Bool valid = 1;
910+ if (ccs_conditions[p1].left_type == CCS_TYPE_INVALID ||
911+ !(ccs_conditions[p1].available & F(mac)))
912+ continue;
913+ check_righthand(mac, p1, valid);
914+ }
915+ }
916+ fprintf(stderr, "Test %u passed\n", tests_now - 1);
917+ return 0;
918+}
--- trunk/caitsith-tools/kernel_test/caitsith_lsm_test.c (nonexistent)
+++ trunk/caitsith-tools/kernel_test/caitsith_lsm_test.c (revision 76)
@@ -0,0 +1,1800 @@
1+/*
2+ * caitsith_lsm_test.c
3+ *
4+ * Copyright (C) 2012-2013 Tetsuo Handa
5+ *
6+ * Version: 0.1 2013/01/06
7+ *
8+ * This program is free software; you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License v2 as published by the
10+ * Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful, but WITHOUT
13+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15+ * more details.
16+ *
17+ * You should have received a copy of the GNU General Public License along with
18+ * this program; if not, write to the Free Software Foundation, Inc.,
19+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+ */
21+
22+#include <stdio.h>
23+#include <stdlib.h>
24+#include <string.h>
25+#include <unistd.h>
26+#include <sys/types.h>
27+#include <sys/stat.h>
28+#include <sys/socket.h>
29+#include <netinet/in.h>
30+#include <sys/wait.h>
31+#include <linux/ip.h>
32+#include <fcntl.h>
33+#include <errno.h>
34+
35+static FILE *fp = NULL;
36+
37+static void set(const char *str)
38+{
39+ fprintf(fp, "%s\n", str);
40+ fflush(fp);
41+}
42+
43+static void unset(const char *str)
44+{
45+ fprintf(fp, "delete %s\n", str);
46+ fflush(fp);
47+}
48+
49+static void unset2(const char *str)
50+{
51+ const char *cp = str;
52+ while (*cp) {
53+ if (*cp++ != '\n')
54+ continue;
55+ fprintf(fp, "delete ");
56+ fwrite(str, cp - str, 1, fp);
57+ str = cp;
58+ }
59+ fprintf(fp, "delete %s\n", str);
60+ fflush(fp);
61+}
62+
63+static void check(const char *prompt, int result)
64+{
65+ int err = errno;
66+ printf("%s%s\n", prompt, result ? "Success" : "Failed");
67+ if (!result) {
68+ fprintf(stderr, "Err: %s(%d)\n", strerror(err), err);
69+ {
70+ int fd2 = open("/proc/caitsith/self_domain", O_RDONLY);
71+ char c;
72+ fprintf(stderr, "task.domain=\"");
73+ while (read(fd2, &c, 1) == 1)
74+ fprintf(stderr, "%c", c);
75+ close(fd2);
76+ fprintf(stderr, "\"\n");
77+ }
78+ exit(1);
79+ }
80+ printf("\n");
81+ fflush(stdout);
82+}
83+
84+static void check_init(const char *prompt, const char *expected)
85+{
86+ int result;
87+ int fd = open("/proc/caitsith/.process_status", O_RDWR);
88+ char buffer[1024];
89+ char *cp;
90+ memset(buffer, 0, sizeof(buffer));
91+ kill(1, SIGHUP);
92+ sleep(1);
93+ write(fd, "1\n", 2);
94+ read(fd, buffer, sizeof(buffer) - 1);
95+ close(fd);
96+ cp = strchr(buffer, ' ');
97+ if (cp++)
98+ memmove(buffer, cp, strlen(cp) + 1);
99+ result = !strcmp(buffer, expected);
100+ printf("%s%s\n", prompt, result ? "Success" : "Failed");
101+ if (!result) {
102+ fprintf(stderr, "Err: expected='%s' result='%s'\n",
103+ expected, buffer);
104+ exit(1);
105+ }
106+ printf("\n");
107+ fflush(stdout);
108+}
109+
110+static void test_task_transition(void)
111+{
112+ int fd = open("/proc/caitsith/self_domain", O_WRONLY);
113+ char *policy;
114+
115+ policy = "100 acl manual_domain_transition\n"
116+ "0 allow domain=\"domain\\$\"\n";
117+ set(policy);
118+ check(policy, write(fd, "domain0", 7) != EOF);
119+ check(policy, write(fd, "domain10", 8) != EOF);
120+ check(policy, write(fd, "domainXYX", 9) == EOF);
121+ check(policy, write(fd, "domain200", 9) != EOF);
122+ unset(policy);
123+
124+ policy = "100 acl auto_domain_transition\n"
125+ "0 allow task.pid=1 transition=\"<init3>\"\n";
126+ set(policy);
127+ check_init(policy, "<init3>");
128+ unset(policy);
129+
130+ policy = "100 acl auto_domain_transition\n"
131+ "0 allow task.pid=1 task.uid!=0 transition=\"<init2>\"\n";
132+ set(policy);
133+ check_init(policy, "<init3>");
134+ unset(policy);
135+
136+ policy = "100 acl auto_domain_transition\n"
137+ "0 allow task.pid=1 transition=\"<init>\"\n";
138+ set(policy);
139+ check_init(policy, "<init>");
140+ unset(policy);
141+
142+ close(fd);
143+}
144+
145+static void test_file_read(void)
146+{
147+ int fd;
148+ char *policy;
149+
150+ policy = "100 acl read\n";
151+ set(policy);
152+ fd = open("/dev/null", O_RDONLY);
153+ check(policy, fd != EOF);
154+ close(fd);
155+ unset(policy);
156+
157+ policy = "100 acl read\n"
158+ "0 allow\n"
159+ "1 deny\n";
160+ set(policy);
161+ fd = open("/dev/null", O_RDONLY);
162+ check(policy, fd != EOF);
163+ close(fd);
164+ unset(policy);
165+
166+ policy = "100 acl read\n"
167+ "0 deny\n"
168+ "1 allow\n";
169+ set(policy);
170+ fd = open("/dev/null", O_RDONLY);
171+ check(policy, fd == EOF);
172+ close(fd);
173+ unset(policy);
174+
175+ policy = "100 acl read path=\"/dev/null\"\n"
176+ "0 allow\n"
177+ "1 deny\n";
178+ set(policy);
179+ fd = open("/dev/null", O_RDONLY);
180+ check(policy, fd != EOF);
181+ close(fd);
182+ unset(policy);
183+
184+ policy = "100 acl read path=\"/dev/null\"\n"
185+ "0 deny\n"
186+ "1 allow\n";
187+ set(policy);
188+ fd = open("/dev/null", O_RDONLY);
189+ check(policy, fd == EOF);
190+ close(fd);
191+ unset(policy);
192+
193+ policy = "100 acl read\n"
194+ "0 allow path=\"/dev/null\"\n"
195+ "1 deny\n";
196+ set(policy);
197+ fd = open("/dev/null", O_RDONLY);
198+ check(policy, fd != EOF);
199+ close(fd);
200+ unset(policy);
201+
202+ policy = "100 acl read\n"
203+ "0 deny path=\"/dev/null\"\n"
204+ "1 allow\n";
205+ set(policy);
206+ fd = open("/dev/null", O_RDONLY);
207+ check(policy, fd == EOF);
208+ close(fd);
209+ unset(policy);
210+
211+ policy = "100 acl read\n"
212+ "0 allow path.type=char path.dev_major=1 path.dev_minor=3\n"
213+ "1 deny\n";
214+ set(policy);
215+ fd = open("/dev/null", O_RDONLY);
216+ check(policy, fd != EOF);
217+ close(fd);
218+ unset(policy);
219+
220+ policy = "100 acl read\n"
221+ "0 deny path.type=char path.dev_major=1 path.dev_minor=3\n"
222+ "1 allow\n";
223+ set(policy);
224+ fd = open("/dev/null", O_RDONLY);
225+ check(policy, fd == EOF);
226+ close(fd);
227+ unset(policy);
228+
229+ policy = "100 acl read\n"
230+ "0 allow path.type=char path.dev_major=1 path.dev_minor!=3\n"
231+ "1 deny\n";
232+ set(policy);
233+ fd = open("/dev/null", O_RDONLY);
234+ check(policy, fd == EOF);
235+ close(fd);
236+ unset(policy);
237+
238+ policy = "100 acl read\n"
239+ "0 deny path.type=char path.dev_major=1 path.dev_minor!=3\n"
240+ "1 allow\n";
241+ set(policy);
242+ fd = open("/dev/null", O_RDONLY);
243+ check(policy, fd != EOF);
244+ close(fd);
245+ unset(policy);
246+
247+ policy = "string_group GROUP1 /dev/null\n"
248+ "100 acl read\n"
249+ "0 allow path=@GROUP1\n"
250+ "1 deny\n";
251+ set(policy);
252+ fd = open("/dev/null", O_RDONLY);
253+ check(policy, fd != EOF);
254+ close(fd);
255+ unset2(policy);
256+
257+ policy = "string_group GROUP1 /dev/null\n"
258+ "100 acl read\n"
259+ "0 deny path=@GROUP1\n"
260+ "1 allow\n";
261+ set(policy);
262+ fd = open("/dev/null", O_RDONLY);
263+ check(policy, fd == EOF);
264+ close(fd);
265+ unset2(policy);
266+
267+ policy = "string_group GROUP1 /dev/null\n"
268+ "100 acl read\n"
269+ "0 allow path!=@GROUP1\n"
270+ "1 deny\n";
271+ set(policy);
272+ fd = open("/dev/null", O_RDONLY);
273+ check(policy, fd == EOF);
274+ close(fd);
275+ unset2(policy);
276+
277+ policy = "string_group GROUP1 /dev/null\n"
278+ "100 acl read\n"
279+ "0 deny path!=@GROUP1\n"
280+ "1 allow\n";
281+ set(policy);
282+ fd = open("/dev/null", O_RDONLY);
283+ check(policy, fd != EOF);
284+ close(fd);
285+ unset2(policy);
286+
287+ policy = "string_group GROUP1 /dev/null\n"
288+ "number_group MAJOR 1\n"
289+ "number_group MINOR 3\n"
290+ "100 acl read\n"
291+ "0 allow path=@GROUP1 path.dev_major=@MAJOR"
292+ " path.dev_minor=@MINOR\n"
293+ "1 deny\n";
294+ set(policy);
295+ fd = open("/dev/null", O_RDONLY);
296+ check(policy, fd != EOF);
297+ close(fd);
298+ unset2(policy);
299+
300+ policy = "string_group GROUP1 /dev/null\n"
301+ "number_group MAJOR 1\n"
302+ "number_group MINOR 3\n"
303+ "100 acl read\n"
304+ "0 deny path=@GROUP1 path.dev_major=@MAJOR"
305+ " path.dev_minor=@MINOR\n"
306+ "1 allow\n";
307+ set(policy);
308+ fd = open("/dev/null", O_RDONLY);
309+ check(policy, fd == EOF);
310+ close(fd);
311+ unset2(policy);
312+
313+ policy = "string_group GROUP1 /dev/zero\n"
314+ "string_group GROUP1 /dev/null\n"
315+ "string_group GROUP1 /dev/urandom\n"
316+ "number_group MAJOR 0\n"
317+ "number_group MAJOR 2-255\n"
318+ "number_group MINOR 00-0x2\n"
319+ "number_group MINOR 255\n"
320+ "100 acl read\n"
321+ "0 allow path=@GROUP1 path.dev_major=@MAJOR"
322+ " path.dev_minor=@MINOR\n"
323+ "1 deny\n";
324+ set(policy);
325+ fd = open("/dev/null", O_RDONLY);
326+ check(policy, fd == EOF);
327+ close(fd);
328+ unset2(policy);
329+
330+ policy = "string_group GROUP1 /dev/zero\n"
331+ "string_group GROUP1 /dev/null\n"
332+ "string_group GROUP1 /dev/urandom\n"
333+ "number_group MAJOR 0\n"
334+ "number_group MAJOR 2-255\n"
335+ "number_group MINOR 00-0x2\n"
336+ "number_group MINOR 255\n"
337+ "100 acl read\n"
338+ "0 allow path=@GROUP1 path.dev_major!=@MAJOR"
339+ " path.dev_minor!=@MINOR\n"
340+ "1 deny\n";
341+ set(policy);
342+ fd = open("/dev/null", O_RDONLY);
343+ check(policy, fd != EOF);
344+ close(fd);
345+ unset2(policy);
346+}
347+
348+static void test_file_write(void)
349+{
350+ int fd;
351+ char *policy;
352+
353+ policy = "100 acl write\n"
354+ "0 allow\n"
355+ "100 acl append\n"
356+ "0 deny\n";
357+ set(policy);
358+ fd = open("/dev/null", O_WRONLY);
359+ check(policy, fd != EOF);
360+ close(fd);
361+ unset2(policy);
362+
363+ policy = "100 acl write\n"
364+ "0 deny\n"
365+ "100 acl append\n"
366+ "0 allow\n";
367+ set(policy);
368+ fd = open("/dev/null", O_WRONLY);
369+ check(policy, fd == EOF);
370+ close(fd);
371+ unset2(policy);
372+
373+ policy = "100 acl write\n"
374+ "0 allow\n"
375+ "100 acl append\n"
376+ "0 deny\n";
377+ set(policy);
378+ fd = open("/dev/null", O_WRONLY | O_APPEND);
379+ check(policy, fd == EOF);
380+ close(fd);
381+ unset2(policy);
382+
383+ policy = "100 acl write\n"
384+ "0 deny\n"
385+ "100 acl append\n"
386+ "0 append\n";
387+ set(policy);
388+ fd = open("/dev/null", O_WRONLY | O_APPEND);
389+ check(policy, fd != EOF);
390+ close(fd);
391+ unset2(policy);
392+
393+ policy = "100 acl write\n"
394+ "0 allow path.type=char path.dev_major=1 path.dev_minor=3\n"
395+ "1 deny\n";
396+ set(policy);
397+ fd = open("/dev/null", O_WRONLY | O_TRUNC);
398+ check(policy, fd != EOF);
399+ close(fd);
400+ unset(policy);
401+
402+ policy = "100 acl write\n"
403+ "0 allow path.type=char path.dev_major=1"
404+ " path.dev_minor=@MINOR\n"
405+ "1 deny\n";
406+ set(policy);
407+ fd = open("/dev/null", O_WRONLY | O_TRUNC);
408+ check(policy, fd == EOF);
409+ close(fd);
410+ unset(policy);
411+
412+ policy = "100 acl write\n"
413+ "0 allow path.parent.uid=0 path.parent.perm=0755\n"
414+ "1 deny\n";
415+ set(policy);
416+ fd = open("/dev/null", O_WRONLY);
417+ check(policy, fd != EOF);
418+ close(fd);
419+ unset(policy);
420+
421+ policy = "100 acl write\n"
422+ "0 allow path.parent.uid=task.uid path.parent.gid=task.gid\n"
423+ "1 deny\n";
424+ set(policy);
425+ fd = open("/dev/null", O_WRONLY);
426+ check(policy, fd != EOF);
427+ close(fd);
428+ unset(policy);
429+
430+ policy = "100 acl write\n"
431+ "0 allow task.uid=path.parent.uid task.gid=path.parent.gid\n"
432+ "1 deny\n";
433+ set(policy);
434+ fd = open("/dev/null", O_WRONLY);
435+ check(policy, fd != EOF);
436+ close(fd);
437+ unset(policy);
438+}
439+
440+static void test_file_create(void)
441+{
442+ int fd;
443+ char *policy;
444+
445+ policy = "100 acl create\n"
446+ "0 allow path.uid=0\n"
447+ "1 deny\n";
448+ set(policy);
449+ unlink("/tmp/file");
450+ fd = open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600);
451+ check(policy, fd == EOF);
452+ close(fd);
453+ unset(policy);
454+
455+ policy = "100 acl create\n"
456+ "0 allow path=\"dev(8,1):/tmp/file\" path.parent.uid=0\n"
457+ "1 deny\n";
458+ set(policy);
459+ unlink("/tmp/file");
460+ fd = open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600);
461+ check(policy, fd != EOF);
462+ close(fd);
463+ unset(policy);
464+
465+ policy = "number_group GROUP1 1-0xFFFFFFFF\n"
466+ "100 acl create\n"
467+ "0 allow path.parent.uid!=@GROUP1 perm=0600\n"
468+ "1 deny\n";
469+ set(policy);
470+ unlink("/tmp/file");
471+ fd = open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600);
472+ check(policy, fd != EOF);
473+ close(fd);
474+ unset2(policy);
475+
476+ policy = "number_group GROUP1 1-0xFFFFFFFF\n"
477+ "100 acl create\n"
478+ "0 allow path.parent.uid!=@GROUP1 perm!=0600\n"
479+ "1 deny\n";
480+ set(policy);
481+ unlink("/tmp/file");
482+ fd = open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600);
483+ check(policy, fd == EOF);
484+ close(fd);
485+ unset2(policy);
486+
487+ policy = "100 acl create\n"
488+ "0 allow path.parent.uid=task.uid\n"
489+ "1 deny\n";
490+ set(policy);
491+ unlink("/tmp/file");
492+ fd = open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600);
493+ check(policy, fd != EOF);
494+ close(fd);
495+ unset(policy);
496+}
497+
498+static void test_file_unlink(void)
499+{
500+ char *policy;
501+
502+ policy = "100 acl unlink\n"
503+ "0 allow path.uid=0 path.uid=path.parent.uid\n"
504+ "1 deny\n";
505+ set(policy);
506+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
507+ check(policy, unlink("/tmp/file") == 0);
508+ unset(policy);
509+
510+ policy = "100 acl unlink\n"
511+ "0 deny path.uid=0 path.uid=path.parent.uid\n"
512+ "1 allow\n";
513+ set(policy);
514+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
515+ check(policy, unlink("/tmp/file") == EOF);
516+ unset(policy);
517+}
518+
519+static void test_file_link(void)
520+{
521+ char *policy;
522+
523+ policy = "100 acl link\n"
524+ "0 allow old_path.uid=0 old_path.uid=old_path.parent.uid"
525+ " old_path.parent.ino=new_path.parent.ino\n"
526+ "1 deny\n";
527+ set(policy);
528+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
529+ unlink("/tmp/file2");
530+ check(policy, link("/tmp/file", "/tmp/file2") == 0);
531+ unset(policy);
532+
533+ policy = "100 acl link\n"
534+ "0 deny old_path.uid=0 old_path.uid=old_path.parent.uid\n"
535+ "1 allow\n";
536+ set(policy);
537+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
538+ unlink("/tmp/file2");
539+ check(policy, link("/tmp/file", "/tmp/file2") == EOF);
540+ unset(policy);
541+}
542+
543+static void test_file_rename(void)
544+{
545+ char *policy;
546+
547+ policy = "100 acl rename\n"
548+ "0 allow old_path.uid=0 old_path.uid=old_path.parent.uid"
549+ " old_path.parent.ino=new_path.parent.ino\n"
550+ "1 deny\n";
551+ set(policy);
552+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
553+ unlink("/tmp/file2");
554+ check(policy, rename("/tmp/file", "/tmp/file2") == 0);
555+ unset(policy);
556+
557+ policy = "100 acl rename\n"
558+ "0 deny old_path.uid=0 old_path.uid=old_path.parent.uid\n"
559+ "1 allow\n";
560+ set(policy);
561+ close(open("/tmp/file", O_CREAT | O_WRONLY | O_EXCL, 0600));
562+ unlink("/tmp/file2");
563+ check(policy, rename("/tmp/file", "/tmp/file2") == EOF);
564+ unset(policy);
565+}
566+
567+static void test_network_inet_stream(void)
568+{
569+ struct sockaddr_in addr1 = { };
570+ struct sockaddr_in addr2 = { };
571+ socklen_t size = sizeof(addr1);
572+ int fd1;
573+ int fd2;
574+ int fd3;
575+ char *policy;
576+ char buffer[1024];
577+ memset(buffer, 0, sizeof(buffer));
578+
579+ fd1 = socket(PF_INET, SOCK_STREAM, 0);
580+ fd2 = socket(PF_INET, SOCK_STREAM, 0);
581+ addr1.sin_family = AF_INET;
582+ addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
583+
584+ policy = "100 acl inet_stream_bind\n"
585+ "0 allow ip=127.0.0.1 port!=0\n"
586+ "1 deny\n";
587+ set(policy);
588+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
589+ EOF);
590+ unset(policy);
591+
592+ policy = "100 acl inet_stream_bind\n"
593+ "0 allow ip!=127.0.0.1 port=0\n"
594+ "1 deny\n";
595+ set(policy);
596+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
597+ EOF);
598+ unset(policy);
599+
600+ policy = "100 acl inet_stream_bind\n"
601+ "0 allow ip=127.0.0.1 port=0 path.uid=task.uid\n"
602+ "1 deny\n";
603+ set(policy);
604+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
605+ EOF);
606+ unset(policy);
607+
608+ policy = "100 acl inet_stream_bind\n"
609+ "0 allow ip=127.0.0.1 port=0\n"
610+ "1 deny\n";
611+ set(policy);
612+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
613+ 0);
614+ unset(policy);
615+
616+ getsockname(fd1, (struct sockaddr *) &addr1, &size);
617+
618+ snprintf(buffer, sizeof(buffer) - 1,
619+ "100 acl inet_stream_listen\n"
620+ "0 allow ip=127.0.0.1 port!=%u\n"
621+ "1 deny\n", ntohs(addr1.sin_port));
622+ policy = buffer;
623+ set(policy);
624+ check(policy, listen(fd1, 5) == EOF);
625+ unset(policy);
626+
627+ snprintf(buffer, sizeof(buffer) - 1,
628+ "100 acl inet_stream_listen\n"
629+ "0 allow ip=127.0.0.1 port=%u\n"
630+ "1 deny\n", ntohs(addr1.sin_port));
631+ policy = buffer;
632+ set(policy);
633+ check(policy, listen(fd1, 5) == 0);
634+ unset(policy);
635+
636+ snprintf(buffer, sizeof(buffer) - 1,
637+ "100 acl inet_stream_connect\n"
638+ "0 allow ip=127.0.0.1 port!=%u\n"
639+ "1 deny\n", ntohs(addr1.sin_port));
640+ policy = buffer;
641+ set(policy);
642+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
643+ == EOF);
644+ unset(policy);
645+
646+ snprintf(buffer, sizeof(buffer) - 1,
647+ "100 acl inet_stream_connect\n"
648+ "0 allow ip=127.0.0.1 port=%u\n"
649+ "1 deny\n", ntohs(addr1.sin_port));
650+ policy = buffer;
651+ set(policy);
652+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
653+ == 0);
654+ unset(policy);
655+
656+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
657+
658+ snprintf(buffer, sizeof(buffer) - 1,
659+ "100 acl inet_stream_accept\n"
660+ "0 allow ip=127.0.0.1 port=%u\n"
661+ "1 deny\n", ntohs(addr2.sin_port));
662+ policy = buffer;
663+ set(policy);
664+ fd3 = accept(fd1, NULL, 0);
665+ check(policy, write(fd3, "", 1) == 1);
666+ close(fd3);
667+ unset(policy);
668+
669+ snprintf(buffer, sizeof(buffer) - 1,
670+ "100 acl inet_stream_connect\n"
671+ "0 allow ip=127.0.0.1 port=%u\n"
672+ "1 deny\n", ntohs(addr1.sin_port));
673+ policy = buffer;
674+ set(policy);
675+ close(fd2);
676+ fd2 = socket(PF_INET, SOCK_STREAM, 0);
677+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
678+ == 0);
679+ unset(policy);
680+
681+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
682+
683+ snprintf(buffer, sizeof(buffer) - 1,
684+ "100 acl inet_stream_accept\n"
685+ "0 allow ip=127.0.0.1 port!=%u\n"
686+ "1 deny\n", ntohs(addr2.sin_port));
687+ policy = buffer;
688+ set(policy);
689+ fd3 = accept(fd1, NULL, 0);
690+ check(policy, write(fd3, "", 1) == EOF);
691+ close(fd3);
692+ unset(policy);
693+
694+ close(fd1);
695+ close(fd2);
696+}
697+
698+static void test_network_inet_dgram(void)
699+{
700+ struct sockaddr_in addr1 = { };
701+ struct sockaddr_in addr2 = { };
702+ socklen_t size = sizeof(addr1);
703+ int fd1;
704+ int fd2;
705+ char *policy;
706+ char buffer[1024];
707+ memset(buffer, 0, sizeof(buffer));
708+
709+ fd1 = socket(PF_INET, SOCK_DGRAM, 0);
710+ fd2 = socket(PF_INET, SOCK_DGRAM, 0);
711+ addr1.sin_family = AF_INET;
712+ addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
713+
714+ policy = "100 acl inet_dgram_bind\n"
715+ "0 allow ip=127.0.0.1 port!=0\n"
716+ "1 deny\n";
717+ set(policy);
718+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
719+ EOF);
720+ unset(policy);
721+
722+ policy = "100 acl inet_dgram_bind\n"
723+ "0 allow ip!=127.0.0.1 port=0\n"
724+ "1 deny\n";
725+ set(policy);
726+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
727+ EOF);
728+ unset(policy);
729+
730+ policy = "100 acl inet_dgram_bind\n"
731+ "0 allow ip=127.0.0.1 port=0 path.uid=task.uid\n"
732+ "1 deny\n";
733+ set(policy);
734+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
735+ EOF);
736+ unset(policy);
737+
738+ policy = "100 acl inet_dgram_bind\n"
739+ "0 allow ip=127.0.0.1 port=0\n"
740+ "1 deny\n";
741+ set(policy);
742+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
743+ 0);
744+ unset(policy);
745+
746+ getsockname(fd1, (struct sockaddr *) &addr1, &size);
747+
748+ snprintf(buffer, sizeof(buffer) - 1,
749+ "100 acl inet_dgram_send\n"
750+ "0 allow ip=127.0.0.1 port!=%u\n"
751+ "1 deny\n", ntohs(addr1.sin_port));
752+ policy = buffer;
753+ set(policy);
754+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
755+ == EOF);
756+ unset(policy);
757+
758+ snprintf(buffer, sizeof(buffer) - 1,
759+ "100 acl inet_dgram_send\n"
760+ "0 allow ip=127.0.0.1 port=%u\n"
761+ "1 deny\n", ntohs(addr1.sin_port));
762+ policy = buffer;
763+ set(policy);
764+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
765+ == 0);
766+ unset(policy);
767+
768+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
769+
770+ snprintf(buffer, sizeof(buffer) - 1,
771+ "100 acl inet_dgram_send\n"
772+ "0 allow ip=127.0.0.1 port=%u\n"
773+ "1 deny\n", ntohs(addr1.sin_port));
774+ policy = buffer;
775+ set(policy);
776+ check(policy, send(fd2, "", 1, 0) != EOF);
777+ unset(policy);
778+
779+ snprintf(buffer, sizeof(buffer) - 1,
780+ "100 acl inet_dgram_send\n"
781+ "0 allow ip=127.0.0.1 port=%u\n"
782+ "1 deny\n", ntohs(addr1.sin_port));
783+ policy = buffer;
784+ set(policy);
785+ check(policy, send(fd2, "", 1, 0) != EOF);
786+ unset(policy);
787+
788+ snprintf(buffer, sizeof(buffer) - 1,
789+ "ip_group LOCALHOST 127.0.0.0-127.255.255.255\n"
790+ "100 acl inet_dgram_send\n"
791+ "0 allow ip=@LOCALHOST port=%u\n"
792+ "1 deny\n", ntohs(addr1.sin_port));
793+ policy = buffer;
794+ set(policy);
795+ check(policy, send(fd2, "", 1, 0) != EOF);
796+ unset2(policy);
797+
798+ close(fd1);
799+ close(fd2);
800+}
801+
802+static void test_network_inet_raw(void)
803+{
804+ struct sockaddr_in addr = { };
805+ static struct iphdr ip = { };
806+ int fd1;
807+ int fd2;
808+ char *policy;
809+ fd1 = socket(PF_INET, SOCK_RAW, 1);
810+ fd2 = socket(PF_INET, SOCK_RAW, 1);
811+ addr.sin_family = AF_INET;
812+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
813+ ip.version = 4;
814+ ip.ihl = sizeof(struct iphdr) / 4;
815+ ip.protocol = IPPROTO_RAW;
816+ ip.daddr = htonl(INADDR_LOOPBACK);
817+ ip.saddr = ip.daddr;
818+
819+ policy = "100 acl inet_raw_bind\n"
820+ "0 allow ip=127.0.0.1 proto!=1\n"
821+ "1 deny\n";
822+ set(policy);
823+ check(policy, bind(fd1, (struct sockaddr *) &addr, sizeof(addr)) ==
824+ EOF);
825+ unset(policy);
826+
827+ policy = "100 acl inet_raw_bind\n"
828+ "0 allow ip!=127.0.0.1 proto=1\n"
829+ "1 deny\n";
830+ set(policy);
831+ check(policy, bind(fd1, (struct sockaddr *) &addr, sizeof(addr)) ==
832+ EOF);
833+ unset(policy);
834+
835+ policy = "100 acl inet_raw_bind\n"
836+ "0 allow ip=127.0.0.1 proto=1 path.uid=task.uid\n"
837+ "1 deny\n";
838+ set(policy);
839+ check(policy, bind(fd1, (struct sockaddr *) &addr, sizeof(addr)) ==
840+ EOF);
841+ unset(policy);
842+
843+ policy = "100 acl inet_raw_bind\n"
844+ "0 allow ip=127.0.0.1 proto=1\n"
845+ "1 deny\n";
846+ set(policy);
847+ check(policy, bind(fd2, (struct sockaddr *) &addr, sizeof(addr)) ==
848+ 0);
849+ unset(policy);
850+
851+ policy = "100 acl inet_raw_send\n"
852+ "0 allow ip=127.0.0.1 proto!=1\n"
853+ "1 deny\n";
854+ set(policy);
855+ check(policy, connect(fd2, (struct sockaddr *) &addr, sizeof(addr))
856+ == EOF);
857+ unset(policy);
858+
859+ policy = "100 acl inet_raw_send\n"
860+ "0 allow ip=127.0.0.1 proto=1\n"
861+ "1 deny\n";
862+ set(policy);
863+ check(policy, connect(fd2, (struct sockaddr *) &addr, sizeof(addr))
864+ == 0);
865+ unset(policy);
866+
867+ policy = "100 acl inet_raw_send\n"
868+ "0 allow ip=127.0.0.1 proto=1\n"
869+ "1 deny\n";
870+ set(policy);
871+ check(policy, send(fd2, &ip, sizeof(ip), 0) != EOF);
872+ unset(policy);
873+
874+ policy = "100 acl inet_raw_send\n"
875+ "0 allow ip=127.0.0.1 proto=1\n"
876+ "1 deny\n";
877+ set(policy);
878+ check(policy, send(fd2, &ip, sizeof(ip), 0) != EOF);
879+ unset(policy);
880+
881+ policy = "ip_group LOCALHOST 127.0.0.0-127.255.255.255\n"
882+ "100 acl inet_raw_send\n"
883+ "0 allow ip=@LOCALHOST proto=1\n"
884+ "1 deny\n";
885+ set(policy);
886+ check(policy, send(fd2, &ip, sizeof(ip), 0) != EOF);
887+ unset2(policy);
888+
889+ close(fd1);
890+ close(fd2);
891+}
892+
893+static void test_network_inet6_stream(void)
894+{
895+ struct sockaddr_in6 addr1 = { };
896+ struct sockaddr_in6 addr2 = { };
897+ socklen_t size = sizeof(addr1);
898+ int fd1;
899+ int fd2;
900+ int fd3;
901+ char *policy;
902+ char buffer[1024];
903+ memset(buffer, 0, sizeof(buffer));
904+
905+ fd1 = socket(PF_INET6, SOCK_STREAM, 0);
906+ fd2 = socket(PF_INET6, SOCK_STREAM, 0);
907+ addr1.sin6_family = AF_INET6;
908+ addr1.sin6_addr = in6addr_loopback;
909+
910+ policy = "100 acl inet_stream_bind\n"
911+ "0 allow ip=::1 port!=0\n"
912+ "1 deny\n";
913+ set(policy);
914+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
915+ EOF);
916+ unset(policy);
917+
918+ policy = "100 acl inet_stream_bind\n"
919+ "0 allow ip!=::1 port=0\n"
920+ "1 deny\n";
921+ set(policy);
922+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
923+ EOF);
924+ unset(policy);
925+
926+ policy = "100 acl inet_stream_bind\n"
927+ "0 allow ip=::1 port=0 path.uid=task.uid\n"
928+ "1 deny\n";
929+ set(policy);
930+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
931+ EOF);
932+ unset(policy);
933+
934+ policy = "100 acl inet_stream_bind\n"
935+ "0 allow ip=::1 port=0\n"
936+ "1 deny\n";
937+ set(policy);
938+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
939+ 0);
940+ unset(policy);
941+
942+ getsockname(fd1, (struct sockaddr *) &addr1, &size);
943+
944+ snprintf(buffer, sizeof(buffer) - 1,
945+ "100 acl inet_stream_listen\n"
946+ "0 allow ip=::1 port!=%u\n"
947+ "1 deny\n", ntohs(addr1.sin6_port));
948+ policy = buffer;
949+ set(policy);
950+ check(policy, listen(fd1, 5) == EOF);
951+ unset(policy);
952+
953+ snprintf(buffer, sizeof(buffer) - 1,
954+ "100 acl inet_stream_listen\n"
955+ "0 allow ip=::1 port=%u\n"
956+ "1 deny\n", ntohs(addr1.sin6_port));
957+ policy = buffer;
958+ set(policy);
959+ check(policy, listen(fd1, 5) == 0);
960+ unset(policy);
961+
962+ snprintf(buffer, sizeof(buffer) - 1,
963+ "100 acl inet_stream_connect\n"
964+ "0 allow ip=::1 port!=%u\n"
965+ "1 deny\n", ntohs(addr1.sin6_port));
966+ policy = buffer;
967+ set(policy);
968+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
969+ == EOF);
970+ unset(policy);
971+
972+ snprintf(buffer, sizeof(buffer) - 1,
973+ "100 acl inet_stream_connect\n"
974+ "0 allow ip=::1 port=%u\n"
975+ "1 deny\n", ntohs(addr1.sin6_port));
976+ policy = buffer;
977+ set(policy);
978+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
979+ == 0);
980+ unset(policy);
981+
982+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
983+
984+ snprintf(buffer, sizeof(buffer) - 1,
985+ "100 acl inet_stream_accept\n"
986+ "0 allow ip=::1 port=%u\n"
987+ "1 deny\n", ntohs(addr2.sin6_port));
988+ policy = buffer;
989+ set(policy);
990+ fd3 = accept(fd1, NULL, 0);
991+ check(policy, write(fd3, "", 1) == 1);
992+ close(fd3);
993+ unset(policy);
994+
995+ snprintf(buffer, sizeof(buffer) - 1,
996+ "100 acl inet_stream_connect\n"
997+ "0 allow ip=::1 port=%u\n"
998+ "1 deny\n", ntohs(addr1.sin6_port));
999+ policy = buffer;
1000+ set(policy);
1001+ close(fd2);
1002+ fd2 = socket(PF_INET6, SOCK_STREAM, 0);
1003+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
1004+ == 0);
1005+ unset(policy);
1006+
1007+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
1008+
1009+ snprintf(buffer, sizeof(buffer) - 1,
1010+ "100 acl inet_stream_accept\n"
1011+ "0 allow ip=::1 port!=%u\n"
1012+ "1 deny\n", ntohs(addr2.sin6_port));
1013+ policy = buffer;
1014+ set(policy);
1015+ fd3 = accept(fd1, NULL, 0);
1016+ check(policy, write(fd3, "", 1) == EOF);
1017+ close(fd3);
1018+ unset(policy);
1019+
1020+ close(fd1);
1021+ close(fd2);
1022+}
1023+
1024+static void test_network_inet6_dgram(void)
1025+{
1026+ struct sockaddr_in6 addr1 = { };
1027+ struct sockaddr_in6 addr2 = { };
1028+ socklen_t size = sizeof(addr1);
1029+ int fd1;
1030+ int fd2;
1031+ char *policy;
1032+ char buffer[1024];
1033+ memset(buffer, 0, sizeof(buffer));
1034+
1035+ fd1 = socket(PF_INET6, SOCK_DGRAM, 0);
1036+ fd2 = socket(PF_INET6, SOCK_DGRAM, 0);
1037+ addr1.sin6_family = AF_INET6;
1038+ addr1.sin6_addr = in6addr_loopback;
1039+
1040+ policy = "100 acl inet_dgram_bind\n"
1041+ "0 allow ip=::1 port!=0\n"
1042+ "1 deny\n";
1043+ set(policy);
1044+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
1045+ EOF);
1046+ unset(policy);
1047+
1048+ policy = "100 acl inet_dgram_bind\n"
1049+ "0 allow ip!=::1 port=0\n"
1050+ "1 deny\n";
1051+ set(policy);
1052+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
1053+ EOF);
1054+ unset(policy);
1055+
1056+ policy = "100 acl inet_dgram_bind\n"
1057+ "0 allow ip=::1 port=0 path.uid=task.uid\n"
1058+ "1 deny\n";
1059+ set(policy);
1060+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
1061+ EOF);
1062+ unset(policy);
1063+
1064+ policy = "100 acl inet_dgram_bind\n"
1065+ "0 allow ip=::1 port=0\n"
1066+ "1 deny\n";
1067+ set(policy);
1068+ check(policy, bind(fd1, (struct sockaddr *) &addr1, sizeof(addr1)) ==
1069+ 0);
1070+ unset(policy);
1071+
1072+ getsockname(fd1, (struct sockaddr *) &addr1, &size);
1073+
1074+ snprintf(buffer, sizeof(buffer) - 1,
1075+ "100 acl inet_dgram_send\n"
1076+ "0 allow ip=::1 port!=%u\n"
1077+ "1 deny\n", ntohs(addr1.sin6_port));
1078+ policy = buffer;
1079+ set(policy);
1080+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
1081+ == EOF);
1082+ unset(policy);
1083+
1084+ snprintf(buffer, sizeof(buffer) - 1,
1085+ "100 acl inet_dgram_send\n"
1086+ "0 allow ip=::1 port=%u\n"
1087+ "1 deny\n", ntohs(addr1.sin6_port));
1088+ policy = buffer;
1089+ set(policy);
1090+ check(policy, connect(fd2, (struct sockaddr *) &addr1, sizeof(addr1))
1091+ == 0);
1092+ unset(policy);
1093+
1094+ getsockname(fd2, (struct sockaddr *) &addr2, &size);
1095+
1096+ snprintf(buffer, sizeof(buffer) - 1,
1097+ "100 acl inet_dgram_send\n"
1098+ "0 allow ip=::1 port=%u\n"
1099+ "1 deny\n", ntohs(addr1.sin6_port));
1100+ policy = buffer;
1101+ set(policy);
1102+ check(policy, send(fd2, "", 1, 0) != EOF);
1103+ unset(policy);
1104+
1105+ snprintf(buffer, sizeof(buffer) - 1,
1106+ "100 acl inet_dgram_send\n"
1107+ "0 allow ip=::1 port=%u\n"
1108+ "1 deny\n", ntohs(addr1.sin6_port));
1109+ policy = buffer;
1110+ set(policy);
1111+ check(policy, send(fd2, "", 1, 0) != EOF);
1112+ unset(policy);
1113+
1114+ snprintf(buffer, sizeof(buffer) - 1,
1115+ "ip_group LOCALHOST ::-::ffff\n"
1116+ "100 acl inet_dgram_send\n"
1117+ "0 allow ip=@LOCALHOST port=%u\n"
1118+ "1 deny\n", ntohs(addr1.sin6_port));
1119+ policy = buffer;
1120+ set(policy);
1121+ check(policy, send(fd2, "", 1, 0) != EOF);
1122+ unset2(policy);
1123+
1124+ close(fd1);
1125+ close(fd2);
1126+}
1127+
1128+static int fork_exec(char *envp[])
1129+{
1130+ int ret_ignored;
1131+ int pipe_fd[2] = { EOF, EOF };
1132+ int err = 0;
1133+ pid_t pid;
1134+ if (pipe(pipe_fd)) {
1135+ fprintf(stderr, "Err: %s(%d)\n", strerror(err), err);
1136+ exit(1);
1137+ }
1138+ pid = fork();
1139+ if (pid == 0) {
1140+ char *argv[2] = { "/bin/true", NULL };
1141+ execve("/bin/true", argv, envp);
1142+ err = errno;
1143+ ret_ignored = write(pipe_fd[1], &err, sizeof(err));
1144+ _exit(0);
1145+ }
1146+ close(pipe_fd[1]);
1147+ ret_ignored = read(pipe_fd[0], &err, sizeof(err));
1148+ close(pipe_fd[0]);
1149+ wait(NULL);
1150+ errno = err;
1151+ return err ? EOF : 0;
1152+}
1153+
1154+static void test_environ(void)
1155+{
1156+ char *policy;
1157+ char *envp[2];
1158+ envp[1] = NULL;
1159+
1160+ policy = "100 acl environ name=\"PATH2\"\n"
1161+ "0 allow value=\"/\"\n"
1162+ "1 deny\n";
1163+ set(policy);
1164+ envp[0] = "PATH2=/";
1165+ check(policy, fork_exec(envp) == 0);
1166+ unset(policy);
1167+
1168+ policy = "100 acl environ name=\"PATH2\"\n"
1169+ "0 allow value!=\"/\"\n"
1170+ "1 deny\n";
1171+ set(policy);
1172+ envp[0] = "PATH2=/";
1173+ check(policy, fork_exec(envp) == EOF);
1174+ unset(policy);
1175+
1176+ policy = "100 acl environ name=\"PATH2\"\n"
1177+ "0 deny value!=\"/\"\n"
1178+ "1 allow\n";
1179+ set(policy);
1180+ envp[0] = "PATH2=/";
1181+ check(policy, fork_exec(envp) == 0);
1182+ unset(policy);
1183+
1184+ policy = "100 acl environ name=\"PATH2\"\n"
1185+ "0 deny value=\"/\"\n"
1186+ "1 allow\n";
1187+ set(policy);
1188+ envp[0] = "PATH2=/";
1189+ check(policy, fork_exec(envp) == EOF);
1190+ unset(policy);
1191+
1192+ policy = "100 acl execute path=\"/bin/true\"\n"
1193+ "0 allow envp[\"PATH2\"]=\"/\"\n"
1194+ "1 deny\n";
1195+ set(policy);
1196+ envp[0] = "PATH2=/";
1197+ check(policy, fork_exec(envp) == 0);
1198+ unset(policy);
1199+
1200+ policy = "100 acl execute path=\"/bin/true\"\n"
1201+ "0 allow envp[\"PATH2\"]!=\"/\"\n"
1202+ "1 deny\n";
1203+ set(policy);
1204+ envp[0] = "PATH2=/";
1205+ check(policy, fork_exec(envp) == EOF);
1206+ unset(policy);
1207+
1208+ policy = "100 acl execute path=\"/bin/true\"\n"
1209+ "0 allow envp[\"PATH2\"]!=NULL\n"
1210+ "1 deny\n";
1211+ set(policy);
1212+ envp[0] = "PATH2";
1213+ check(policy, fork_exec(envp) == 0);
1214+ unset(policy);
1215+
1216+ policy = "100 acl execute path=\"/bin/true\"\n"
1217+ "0 allow envp[\"PATH2\"]!=NULL\n"
1218+ "1 deny\n";
1219+ set(policy);
1220+ envp[0] = "PATH2=";
1221+ check(policy, fork_exec(envp) == 0);
1222+ unset(policy);
1223+
1224+ policy = "100 acl execute path=\"/bin/true\"\n"
1225+ "0 allow envp[\"PATH2\"]!=NULL\n"
1226+ "1 deny\n";
1227+ set(policy);
1228+ envp[0] = "PATH2=/";
1229+ check(policy, fork_exec(envp) == 0);
1230+ unset(policy);
1231+
1232+ policy = "100 acl execute path=\"/bin/true\"\n"
1233+ "0 allow envp[\"PATH2\"]=NULL\n"
1234+ "1 deny\n";
1235+ set(policy);
1236+ envp[0] = "PATH2";
1237+ check(policy, fork_exec(envp) == EOF);
1238+ unset(policy);
1239+
1240+ policy = "100 acl execute path=\"/bin/true\"\n"
1241+ "0 allow envp[\"PATH2\"]=NULL\n"
1242+ "1 deny\n";
1243+ set(policy);
1244+ envp[0] = "PATH2=";
1245+ check(policy, fork_exec(envp) == EOF);
1246+ unset(policy);
1247+
1248+ policy = "100 acl execute path=\"/bin/true\"\n"
1249+ "0 allow envp[\"PATH2\"]=NULL\n"
1250+ "1 deny\n";
1251+ set(policy);
1252+ envp[0] = "PATH2=/";
1253+ check(policy, fork_exec(envp) == EOF);
1254+ unset(policy);
1255+
1256+ policy = "100 acl execute path=\"/bin/true\"\n"
1257+ "0 allow envp[\"\"]=NULL\n"
1258+ "1 deny\n";
1259+ set(policy);
1260+ envp[0] = "";
1261+ check(policy, fork_exec(envp) == EOF);
1262+ unset(policy);
1263+
1264+ policy = "100 acl execute path=\"/bin/true\"\n"
1265+ "0 allow envp[\"\"]!=NULL\n"
1266+ "1 deny\n";
1267+ set(policy);
1268+ envp[0] = "";
1269+ check(policy, fork_exec(envp) == 0);
1270+ unset(policy);
1271+
1272+ policy = "100 acl execute path=\"/bin/true\"\n"
1273+ "0 allow envp[\"\"]!=NULL\n"
1274+ "1 deny\n";
1275+ set(policy);
1276+ envp[0] = "=";
1277+ check(policy, fork_exec(envp) == 0);
1278+ unset(policy);
1279+
1280+ policy = "100 acl execute path=\"/bin/true\"\n"
1281+ "0 allow envp[\"\"]!=NULL\n"
1282+ "1 deny\n";
1283+ set(policy);
1284+ envp[0] = "=/";
1285+ check(policy, fork_exec(envp) == 0);
1286+ unset(policy);
1287+}
1288+
1289+static int fork_exec2(char *argv[], char *envp[])
1290+{
1291+ int ret_ignored;
1292+ int pipe_fd[2] = { EOF, EOF };
1293+ int err = 0;
1294+ pid_t pid;
1295+ if (pipe(pipe_fd)) {
1296+ fprintf(stderr, "Err: %s(%d)\n", strerror(err), err);
1297+ exit(1);
1298+ }
1299+ pid = fork();
1300+ if (pid == 0) {
1301+ execve("/bin/true", argv, envp);
1302+ err = errno;
1303+ ret_ignored = write(pipe_fd[1], &err, sizeof(err));
1304+ _exit(0);
1305+ }
1306+ close(pipe_fd[1]);
1307+ ret_ignored = read(pipe_fd[0], &err, sizeof(err));
1308+ close(pipe_fd[0]);
1309+ wait(NULL);
1310+ errno = err;
1311+ return err ? EOF : 0;
1312+}
1313+
1314+static void test_file_execute(void)
1315+{
1316+ char *policy;
1317+ char *argv[5];
1318+ char *envp[5];
1319+ memset(argv, 0, sizeof(argv));
1320+ memset(envp, 0, sizeof(envp));
1321+
1322+ policy = "100 acl execute path=\"/bin/true\"\n"
1323+ "0 allow argc=1\n"
1324+ "1 deny\n";
1325+ set(policy);
1326+ argv[0]="true";
1327+ check(policy, fork_exec2(argv, envp) == 0);
1328+ unset(policy);
1329+
1330+ policy = "100 acl execute path=\"/bin/true\"\n"
1331+ "0 allow argc!=1\n"
1332+ "1 deny\n";
1333+ set(policy);
1334+ check(policy, fork_exec2(argv, envp) == EOF);
1335+ unset(policy);
1336+
1337+ policy = "100 acl execute path=\"/bin/true\"\n"
1338+ "0 deny argc!=1\n"
1339+ "1 allow\n";
1340+ set(policy);
1341+ check(policy, fork_exec2(argv, envp) == 0);
1342+ unset(policy);
1343+
1344+ policy = "100 acl execute path=\"/bin/true\"\n"
1345+ "0 deny argc=1\n"
1346+ "1 allow\n";
1347+ set(policy);
1348+ check(policy, fork_exec2(argv, envp) == EOF);
1349+ unset(policy);
1350+
1351+ policy = "100 acl execute path=\"/bin/true\"\n"
1352+ "0 deny argv[0]!=\"true\"\n"
1353+ "1 allow\n";
1354+ set(policy);
1355+ check(policy, fork_exec2(argv, envp) == 0);
1356+ unset(policy);
1357+
1358+ policy = "100 acl execute path=\"/bin/true\"\n"
1359+ "0 deny argv[0]=\"true\"\n"
1360+ "1 allow\n";
1361+ set(policy);
1362+ check(policy, fork_exec2(argv, envp) == EOF);
1363+ unset(policy);
1364+
1365+ policy = "100 acl execute path=\"/bin/true\"\n"
1366+ "0 allow argv[0]!=\"true\"\n"
1367+ "1 deny\n";
1368+ set(policy);
1369+ check(policy, fork_exec2(argv, envp) == EOF);
1370+ unset(policy);
1371+
1372+ policy = "100 acl execute path=\"/bin/true\"\n"
1373+ "0 allow argv[0]=\"true\"\n"
1374+ "1 deny\n";
1375+ set(policy);
1376+ check(policy, fork_exec2(argv, envp) == 0);
1377+ unset(policy);
1378+
1379+ policy = "string_group EXEC_ARGV0 false\n"
1380+ "string_group EXEC_ARGV0 true\n"
1381+ "100 acl execute path=\"/bin/true\"\n"
1382+ "0 deny argv[0]!=@EXEC_ARGV0\n"
1383+ "1 allow\n";
1384+ set(policy);
1385+ check(policy, fork_exec2(argv, envp) == 0);
1386+ unset2(policy);
1387+
1388+ policy = "string_group EXEC_ARGV0 false\n"
1389+ "string_group EXEC_ARGV0 true\n"
1390+ "100 acl execute path=\"/bin/true\"\n"
1391+ "0 deny argv[0]=@EXEC_ARGV0\n"
1392+ "1 allow\n";
1393+ set(policy);
1394+ check(policy, fork_exec2(argv, envp) == EOF);
1395+ unset2(policy);
1396+
1397+ policy = "string_group EXEC_ARGV0 false\n"
1398+ "string_group EXEC_ARGV0 true\n"
1399+ "100 acl execute path=\"/bin/true\"\n"
1400+ "0 allow argv[0]!=@EXEC_ARGV0\n"
1401+ "1 deny\n";
1402+ set(policy);
1403+ check(policy, fork_exec2(argv, envp) == EOF);
1404+ unset2(policy);
1405+
1406+ policy = "string_group EXEC_ARGV0 false\n"
1407+ "string_group EXEC_ARGV0 true\n"
1408+ "100 acl execute path=\"/bin/true\"\n"
1409+ "0 allow argv[0]=@EXEC_ARGV0\n"
1410+ "1 deny\n";
1411+ set(policy);
1412+ check(policy, fork_exec2(argv, envp) == 0);
1413+ unset2(policy);
1414+
1415+
1416+ policy = "100 acl execute path=\"/bin/true\"\n"
1417+ "0 allow envc=1\n"
1418+ "1 deny\n";
1419+ set(policy);
1420+ envp[0]="PATH=/";
1421+ check(policy, fork_exec2(argv, envp) == 0);
1422+ unset(policy);
1423+
1424+ policy = "100 acl execute path=\"/bin/true\"\n"
1425+ "0 allow envc!=1\n"
1426+ "1 deny\n";
1427+ set(policy);
1428+ check(policy, fork_exec2(argv, envp) == EOF);
1429+ unset(policy);
1430+
1431+ policy = "100 acl execute path=\"/bin/true\"\n"
1432+ "0 deny envc!=1\n"
1433+ "1 allow\n";
1434+ set(policy);
1435+ check(policy, fork_exec2(argv, envp) == 0);
1436+ unset(policy);
1437+
1438+ policy = "100 acl execute path=\"/bin/true\"\n"
1439+ "0 deny envc=1\n"
1440+ "1 allow\n";
1441+ set(policy);
1442+ check(policy, fork_exec2(argv, envp) == EOF);
1443+ unset(policy);
1444+
1445+ policy = "100 acl execute path=\"/bin/true\"\n"
1446+ "0 deny envp[\"PATH\"]!=\"/\"\n"
1447+ "1 allow\n";
1448+ set(policy);
1449+ check(policy, fork_exec2(argv, envp) == 0);
1450+ unset(policy);
1451+
1452+ policy = "100 acl execute path=\"/bin/true\"\n"
1453+ "0 deny envp[\"PATH\"]=\"/\"\n"
1454+ "1 allow\n";
1455+ set(policy);
1456+ check(policy, fork_exec2(argv, envp) == EOF);
1457+ unset(policy);
1458+
1459+ policy = "100 acl execute path=\"/bin/true\"\n"
1460+ "0 allow envp[\"PATH\"]!=\"/\"\n"
1461+ "1 deny\n";
1462+ set(policy);
1463+ check(policy, fork_exec2(argv, envp) == EOF);
1464+ unset(policy);
1465+
1466+ policy = "100 acl execute path=\"/bin/true\"\n"
1467+ "0 allow envp[\"PATH\"]=\"/\"\n"
1468+ "1 deny\n";
1469+ set(policy);
1470+ check(policy, fork_exec2(argv, envp) == 0);
1471+ unset(policy);
1472+
1473+ policy = "string_group PATH_VALUES /bin\n"
1474+ "string_group PATH_VALUES /\n"
1475+ "string_group PATH_VALUES /sbin\n"
1476+ "100 acl execute path=\"/bin/true\"\n"
1477+ "0 deny envp[\"PATH\"]!=@PATH_VALUES\n"
1478+ "1 allow\n";
1479+ set(policy);
1480+ check(policy, fork_exec2(argv, envp) == 0);
1481+ unset2(policy);
1482+
1483+ policy = "string_group PATH_VALUES /bin\n"
1484+ "string_group PATH_VALUES /\n"
1485+ "string_group PATH_VALUES /sbin\n"
1486+ "100 acl execute path=\"/bin/true\"\n"
1487+ "0 deny envp[\"PATH\"]=@PATH_VALUES\n"
1488+ "1 allow\n";
1489+ set(policy);
1490+ check(policy, fork_exec2(argv, envp) == EOF);
1491+ unset2(policy);
1492+
1493+ policy = "string_group PATH_VALUES /bin\n"
1494+ "string_group PATH_VALUES /\n"
1495+ "string_group PATH_VALUES /sbin\n"
1496+ "100 acl execute path=\"/bin/true\"\n"
1497+ "0 allow envp[\"PATH\"]!=@PATH_VALUES\n"
1498+ "1 deny\n";
1499+ set(policy);
1500+ check(policy, fork_exec2(argv, envp) == EOF);
1501+ unset2(policy);
1502+
1503+ policy = "string_group PATH_VALUES /bin\n"
1504+ "string_group PATH_VALUES /\n"
1505+ "string_group PATH_VALUES /sbin\n"
1506+ "100 acl execute path=\"/bin/true\"\n"
1507+ "0 allow envp[\"PATH\"]=@PATH_VALUES\n"
1508+ "1 deny\n";
1509+ set(policy);
1510+ check(policy, fork_exec2(argv, envp) == 0);
1511+ unset2(policy);
1512+
1513+ policy = "100 acl execute path=\"/bin/true\"\n"
1514+ "0 deny envp[\"PATH\"]!=NULL\n"
1515+ "1 allow\n";
1516+ set(policy);
1517+ check(policy, fork_exec2(argv, envp) == EOF);
1518+ unset(policy);
1519+
1520+ policy = "100 acl execute path=\"/bin/true\"\n"
1521+ "0 deny envp[\"PATH\"]=NULL\n"
1522+ "1 allow\n";
1523+ set(policy);
1524+ check(policy, fork_exec2(argv, envp) == 0);
1525+ unset(policy);
1526+
1527+ policy = "100 acl execute path=\"/bin/true\"\n"
1528+ "0 allow envp[\"PATH\"]!=NULL\n"
1529+ "1 deny\n";
1530+ set(policy);
1531+ check(policy, fork_exec2(argv, envp) == 0);
1532+ unset(policy);
1533+
1534+ policy = "100 acl execute path=\"/bin/true\"\n"
1535+ "0 allow envp[\"PATH\"]=NULL\n"
1536+ "1 deny\n";
1537+ set(policy);
1538+ check(policy, fork_exec2(argv, envp) == EOF);
1539+ unset(policy);
1540+}
1541+
1542+static void test_file_misc(void)
1543+{
1544+ int fd;
1545+ const pid_t pid = getpid();
1546+ char buffer[1024];
1547+ memset(buffer, 0, sizeof(buffer));
1548+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1549+ "10 allow path!=NULL\n"
1550+ "20 deny\n", pid);
1551+ set(buffer);
1552+ fd = open("/dev/null", O_RDONLY);
1553+ check(buffer, fd != EOF);
1554+ close(fd);
1555+ unset(buffer);
1556+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1557+ "10 allow path=NULL\n"
1558+ "20 deny\n", pid);
1559+ set(buffer);
1560+ fd = open("/dev/null", O_RDONLY);
1561+ check(buffer, fd == EOF);
1562+ close(fd);
1563+ unset(buffer);
1564+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1565+ "10 deny path=NULL\n"
1566+ "20 allow\n", pid);
1567+ set(buffer);
1568+ fd = open("/dev/null", O_RDONLY);
1569+ check(buffer, fd != EOF);
1570+ close(fd);
1571+ unset(buffer);
1572+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1573+ "10 deny path!=NULL\n"
1574+ "20 allow\n", pid);
1575+ set(buffer);
1576+ fd = open("/dev/null", O_RDONLY);
1577+ check(buffer, fd == EOF);
1578+ close(fd);
1579+ unset(buffer);
1580+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1581+ "10 allow path=path\n"
1582+ "20 deny\n", pid);
1583+ set(buffer);
1584+ fd = open("/dev/null", O_RDONLY);
1585+ check(buffer, fd != EOF);
1586+ close(fd);
1587+ unset(buffer);
1588+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1589+ "10 allow path!=path\n"
1590+ "20 deny\n", pid);
1591+ set(buffer);
1592+ fd = open("/dev/null", O_RDONLY);
1593+ check(buffer, fd == EOF);
1594+ close(fd);
1595+ unset(buffer);
1596+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1597+ "10 deny path!=path\n"
1598+ "20 allow\n", pid);
1599+ set(buffer);
1600+ fd = open("/dev/null", O_RDONLY);
1601+ check(buffer, fd != EOF);
1602+ close(fd);
1603+ unset(buffer);
1604+ snprintf(buffer, sizeof(buffer) - 1, "100 acl read task.pid=%u\n"
1605+ "10 deny path=path\n"
1606+ "20 allow\n", pid);
1607+ set(buffer);
1608+ fd = open("/dev/null", O_RDONLY);
1609+ check(buffer, fd == EOF);
1610+ close(fd);
1611+ unset(buffer);
1612+ snprintf(buffer, sizeof(buffer) - 1,
1613+ "string_group STRING_GROUP1 /dev/null\n"
1614+ "100 acl read task.pid=%u\n"
1615+ "10 allow path=@STRING_GROUP1\n"
1616+ "20 deny\n", pid);
1617+ set(buffer);
1618+ fd = open("/dev/null", O_RDONLY);
1619+ check(buffer, fd != EOF);
1620+ close(fd);
1621+ unset2(buffer);
1622+ snprintf(buffer, sizeof(buffer) - 1,
1623+ "string_group STRING_GROUP1 /dev/null\n"
1624+ "100 acl read task.pid=%u\n"
1625+ "10 allow path!=@STRING_GROUP1\n"
1626+ "20 deny\n", pid);
1627+ set(buffer);
1628+ fd = open("/dev/null", O_RDONLY);
1629+ check(buffer, fd == EOF);
1630+ close(fd);
1631+ unset2(buffer);
1632+ snprintf(buffer, sizeof(buffer) - 1,
1633+ "string_group STRING_GROUP1 /dev/null\n"
1634+ "100 acl read task.pid=%u\n"
1635+ "10 deny path!=@STRING_GROUP1\n"
1636+ "20 allow\n", pid);
1637+ set(buffer);
1638+ fd = open("/dev/null", O_RDONLY);
1639+ check(buffer, fd != EOF);
1640+ close(fd);
1641+ unset2(buffer);
1642+ snprintf(buffer, sizeof(buffer) - 1,
1643+ "string_group STRING_GROUP1 /dev/null\n"
1644+ "100 acl read task.pid=%u\n"
1645+ "10 deny path=@STRING_GROUP1\n"
1646+ "20 allow\n", pid);
1647+ set(buffer);
1648+ fd = open("/dev/null", O_RDONLY);
1649+ check(buffer, fd == EOF);
1650+ close(fd);
1651+ unset2(buffer);
1652+ snprintf(buffer, sizeof(buffer) - 1,
1653+ "number_group NUMBER_GROUP1 0666\n"
1654+ "100 acl read task.pid=%u\n"
1655+ "10 deny path.perm!=@NUMBER_GROUP1\n"
1656+ "20 allow\n", pid);
1657+ set(buffer);
1658+ fd = open("/dev/null", O_RDONLY);
1659+ check(buffer, fd != EOF);
1660+ close(fd);
1661+ unset2(buffer);
1662+ snprintf(buffer, sizeof(buffer) - 1,
1663+ "number_group NUMBER_GROUP1 0666\n"
1664+ "100 acl read task.pid=%u\n"
1665+ "10 deny path.perm=@NUMBER_GROUP1\n"
1666+ "20 allow\n", pid);
1667+ set(buffer);
1668+ fd = open("/dev/null", O_RDONLY);
1669+ check(buffer, fd == EOF);
1670+ close(fd);
1671+ unset2(buffer);
1672+ snprintf(buffer, sizeof(buffer) - 1,
1673+ "100 acl read task.pid=%u\n"
1674+ "10 deny path.perm!=owner_read\n"
1675+ "20 allow\n", pid);
1676+ set(buffer);
1677+ fd = open("/dev/null", O_RDONLY);
1678+ check(buffer, fd != EOF);
1679+ close(fd);
1680+ unset2(buffer);
1681+ snprintf(buffer, sizeof(buffer) - 1,
1682+ "100 acl read task.pid=%u\n"
1683+ "10 deny path.perm=owner_read\n"
1684+ "20 allow\n", pid);
1685+ set(buffer);
1686+ fd = open("/dev/null", O_RDONLY);
1687+ check(buffer, fd == EOF);
1688+ close(fd);
1689+ unset2(buffer);
1690+ snprintf(buffer, sizeof(buffer) - 1,
1691+ "100 acl read task.pid=%u\n"
1692+ "10 deny path.perm!=group_write\n"
1693+ "20 allow\n", pid);
1694+ set(buffer);
1695+ fd = open("/dev/null", O_RDONLY);
1696+ check(buffer, fd != EOF);
1697+ close(fd);
1698+ unset2(buffer);
1699+ snprintf(buffer, sizeof(buffer) - 1,
1700+ "100 acl read task.pid=%u\n"
1701+ "10 deny path.perm=group_write\n"
1702+ "20 allow\n", pid);
1703+ set(buffer);
1704+ fd = open("/dev/null", O_RDONLY);
1705+ check(buffer, fd == EOF);
1706+ close(fd);
1707+ unset2(buffer);
1708+ snprintf(buffer, sizeof(buffer) - 1,
1709+ "100 acl read task.pid=%u\n"
1710+ "10 deny path.perm!=others_read\n"
1711+ "20 allow\n", pid);
1712+ set(buffer);
1713+ fd = open("/dev/null", O_RDONLY);
1714+ check(buffer, fd != EOF);
1715+ close(fd);
1716+ unset2(buffer);
1717+ snprintf(buffer, sizeof(buffer) - 1,
1718+ "100 acl read task.pid=%u\n"
1719+ "10 deny path.perm=others_read\n"
1720+ "20 allow\n", pid);
1721+ set(buffer);
1722+ fd = open("/dev/null", O_RDONLY);
1723+ check(buffer, fd == EOF);
1724+ close(fd);
1725+ unset2(buffer);
1726+ snprintf(buffer, sizeof(buffer) - 1,
1727+ "100 acl read task.pid=%u\n"
1728+ "10 deny path.perm=path.parent.perm\n"
1729+ "20 allow\n", pid);
1730+ set(buffer);
1731+ fd = open("/dev/null", O_RDONLY);
1732+ check(buffer, fd != EOF);
1733+ close(fd);
1734+ unset2(buffer);
1735+ snprintf(buffer, sizeof(buffer) - 1,
1736+ "100 acl read task.pid=%u\n"
1737+ "10 deny path.perm!=path.parent.perm\n"
1738+ "20 allow\n", pid);
1739+ set(buffer);
1740+ fd = open("/dev/null", O_RDONLY);
1741+ check(buffer, fd == EOF);
1742+ close(fd);
1743+ unset2(buffer);
1744+ snprintf(buffer, sizeof(buffer) - 1,
1745+ "100 acl execute task.ppid=%u\n"
1746+ "10 allow path=exec\n"
1747+ "20 deny\n", pid);
1748+ set(buffer);
1749+ check(buffer, fork_exec(NULL) == 0);
1750+ unset(buffer);
1751+ snprintf(buffer, sizeof(buffer) - 1,
1752+ "100 acl execute task.ppid=%u\n"
1753+ "10 allow path!=exec\n"
1754+ "20 deny\n", pid);
1755+ set(buffer);
1756+ check(buffer, fork_exec(NULL) == EOF);
1757+ unset(buffer);
1758+ snprintf(buffer, sizeof(buffer) - 1,
1759+ "100 acl execute task.ppid=%u\n"
1760+ "10 deny path=exec\n"
1761+ "20 allow\n", pid);
1762+ set(buffer);
1763+ check(buffer, fork_exec(NULL) == EOF);
1764+ unset(buffer);
1765+ snprintf(buffer, sizeof(buffer) - 1,
1766+ "100 acl execute task.ppid=%u\n"
1767+ "10 deny path!=exec\n"
1768+ "20 allow\n", pid);
1769+ set(buffer);
1770+ check(buffer, fork_exec(NULL) == 0);
1771+ unset(buffer);
1772+}
1773+
1774+int main(int argc, char *argv[])
1775+{
1776+ fp = fopen("/proc/caitsith/policy", "w");
1777+ if (!fp) {
1778+ fprintf(stderr, " Can't open /proc/caitsith/policy\n");
1779+ return 1;
1780+ }
1781+ fprintf(fp, "quota audit[0]"
1782+ " allowed=1024 unmatched=1024 denied=1024\n");
1783+
1784+ test_task_transition();
1785+ test_file_read();
1786+ test_file_write();
1787+ test_file_create();
1788+ test_file_unlink();
1789+ test_file_link();
1790+ test_file_rename();
1791+ test_network_inet_stream();
1792+ test_network_inet_dgram();
1793+ test_network_inet_raw();
1794+ test_network_inet6_stream();
1795+ test_network_inet6_dgram();
1796+ test_environ();
1797+ test_file_execute();
1798+ test_file_misc();
1799+ return 0;
1800+}
--- trunk/caitsith-tools/kernel_test/caitsith_audit2cond_test.c (nonexistent)
+++ trunk/caitsith-tools/kernel_test/caitsith_audit2cond_test.c (revision 76)
@@ -0,0 +1,1379 @@
1+/*
2+ * caitsith_audit2cond_test.c
3+ *
4+ * Copyright (C) 2012-2013 Tetsuo Handa
5+ *
6+ * Version: 0.1 2013/01/06
7+ *
8+ * This program is free software; you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License v2 as published by the
10+ * Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful, but WITHOUT
13+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15+ * more details.
16+ *
17+ * You should have received a copy of the GNU General Public License along with
18+ * this program; if not, write to the Free Software Foundation, Inc.,
19+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+ */
21+
22+#include <errno.h>
23+#include <fcntl.h>
24+#include <linux/ip.h>
25+#include <linux/kdev_t.h>
26+#include <linux/reboot.h>
27+#include <netinet/in.h>
28+#include <poll.h>
29+#include <pty.h>
30+#include <sched.h>
31+#include <stdio.h>
32+#include <stdlib.h>
33+#include <string.h>
34+#include <sys/mount.h>
35+#include <sys/ptrace.h>
36+#include <sys/socket.h>
37+#include <sys/stat.h>
38+#include <sys/syscall.h>
39+#include <sys/timex.h>
40+#include <sys/types.h>
41+#include <sys/un.h>
42+#include <sys/wait.h>
43+#include <time.h>
44+#include <unistd.h>
45+int reboot(int cmd);
46+struct module;
47+int init_module(const char *name, struct module *image);
48+int delete_module(const char *name);
49+int pivot_root(const char *new_root, const char *put_old);
50+struct kexec_segment;
51+static inline long sys_kexec_load(unsigned long entry,
52+ unsigned long nr_segments,
53+ struct kexec_segment *segments,
54+ unsigned long flags)
55+{
56+ return (long) syscall(__NR_kexec_load, entry, nr_segments,
57+ segments, flags);
58+}
59+
60+static char *args[512];
61+static int audit_fd = EOF;
62+static int policy_fd = EOF;
63+static const char *bin_true_location = "/bin/true";
64+static int one = 1;
65+
66+static const char *make_variable(const char *name, const unsigned int type)
67+{
68+ const char *cp = name + strlen(name) + 1;
69+ if (type == 0)
70+ return cp;
71+ if (*cp == '"') {
72+ /* Name variables. */
73+ if (type == 1)
74+ return "NULL";
75+ if (type == 2)
76+ return "!@EMPTY_NAME_GROUP";
77+ //if (type == 3)
78+ // return "task.exe"; // How can this match?
79+ } else if (!strcmp(name, "ip")) {
80+ /* IP address variables */
81+ if (type == 1)
82+ return "!@EMPTY_IP_GROUP";
83+ } else if (strstr(name, ".type")) {
84+ /* task.type or path.type */
85+ /* No variables supported. */
86+ } else {
87+ /* Numeric variables */
88+ const int zero = !strcmp(cp, "0") || !strcmp(cp, "00") ||
89+ !strcmp(cp, "0x0");
90+ if (type == 1)
91+ return "!@EMPTY_NUMBER_GROUP";
92+ if (type == 2)
93+ return "!@ZERO" + zero;
94+ if (type == 3)
95+ return "!task.uid" + zero;
96+ if (strstr(name, ".perm")) {
97+ unsigned int perm = 0;
98+ sscanf(cp, "%o", &perm);
99+ if (type == 4)
100+ return "!setuid" + ((perm & 04000) != 0);
101+ if (type == 5)
102+ return "!setgid" + ((perm & 02000) != 0);
103+ if (type == 6)
104+ return "!sticky" + ((perm & 01000) != 0);
105+ if (type == 7)
106+ return "!owner_read" + ((perm & 0400) != 0);
107+ if (type == 8)
108+ return "!owner_write" + ((perm & 0200) != 0);
109+ if (type == 9)
110+ return "!owner_execute" + ((perm & 0100) != 0);
111+ if (type == 10)
112+ return "!group_read" + ((perm & 040) != 0);
113+ if (type == 11)
114+ return "!group_write" + ((perm & 020) != 0);
115+ if (type == 12)
116+ return "!group_execute" + ((perm & 010) != 0);
117+ if (type == 13)
118+ return "!others_read" + ((perm & 04) != 0);
119+ if (type == 14)
120+ return "!others_write" + ((perm & 02) != 0);
121+ if (type == 15)
122+ return "!others_execute" + ((perm & 01) != 0);
123+ }
124+ }
125+ return NULL;
126+}
127+
128+static int make_policy(const char *action, const unsigned int loop,
129+ const int check, const int max)
130+{
131+ static char buffer[1048576];
132+ int pos;
133+ int i;
134+ const char *var = "";
135+ int not_equals = (loop & 1);
136+ if (max) {
137+ /* Nothing more to test if there is no more variables. */
138+ var = make_variable(args[check], loop >> 1);
139+ if (!var)
140+ return 0;
141+ /* NULL has inverse semantics. */
142+ if (!strcmp(var, "NULL"))
143+ not_equals = !not_equals;
144+ /* Handle other inversed conditions. */
145+ else if (*var == '!') {
146+ var++;
147+ not_equals = !not_equals;
148+ }
149+ }
150+ memset(buffer, 0, sizeof(buffer));
151+ pos = snprintf(buffer, sizeof(buffer) - 1, "0 acl %s task.ppid=%u\n"
152+ "\t0 allow", action, getpid());
153+ for (i = 0; i < max; i++) {
154+ /* Change only one argument at a time. */
155+ if (i != check)
156+ pos += snprintf(buffer + pos, sizeof(buffer) - 1 - pos,
157+ " %s=%s", args[i],
158+ args[i] + strlen(args[i]) + 1);
159+ else
160+ pos += snprintf(buffer + pos, sizeof(buffer) - 1 - pos,
161+ " %s%s=%s", args[i],
162+ not_equals ? "!" : "", var);
163+ }
164+ pos += snprintf(buffer + pos, sizeof(buffer) - 1 - pos, "\n"
165+ "\t1 deny\n");
166+ write(policy_fd, buffer, strlen(buffer));
167+ printf("Expecting %s: %s", (loop & 1) ? "denied" : "allowed",
168+ buffer);
169+ return 1;
170+}
171+
172+static int do_test(int (*func) (void))
173+{
174+ int error = 0;
175+ const pid_t pid = fork();
176+ switch (pid) {
177+ case 0:
178+ if (unshare(CLONE_NEWNS)) {
179+ fprintf(stderr, "***** Can't unshare.\n");
180+ _exit(1);
181+ }
182+ errno = 0;
183+ _exit(func());
184+ case -1:
185+ fprintf(stderr, "***** Can't fork.\n");
186+ return 1;
187+ }
188+ while (waitpid(pid, &error, 0) == EOF && errno == EINTR);
189+ return WIFEXITED(error) ? WEXITSTATUS(error) : -1;
190+}
191+
192+static int check_result(const char *action, int (*func) (void),
193+ const unsigned int loop)
194+{
195+ static char buffer[1048576];
196+ char *cp1;
197+ char *cp2;
198+ int retries = 0;
199+retry:
200+ do_test(func);
201+ memset(buffer, 0, sizeof(buffer));
202+ read(audit_fd, buffer, sizeof(buffer) - 1);
203+ cp1 = strchr(buffer, '\n');
204+ if (!cp1) {
205+ if (retries++ < 100)
206+ goto retry;
207+ fprintf(stderr, "***** Missing audit log for '%s': %s\n",
208+ action, buffer);
209+ return 1;
210+ }
211+ *cp1 = '\0';
212+ cp1 = strstr(buffer, " / ");
213+ if (!cp1) {
214+ fprintf(stderr, "***** Corrupted audit log for '%s': %s\n",
215+ action, buffer);
216+ return 1;
217+ }
218+ cp1 += 3;
219+ cp2 = strchr(cp1, ' ');
220+ if (!cp2) {
221+ fprintf(stderr, "***** Corrupted audit log for '%s': %s\n",
222+ action, buffer);
223+ return 1;
224+ }
225+ *cp2 = '\0';
226+ if (strcmp(cp1, action)) {
227+ if (retries++ < 100)
228+ goto retry;
229+ *cp2 = ' ';
230+ fprintf(stderr, "***** Unexpected audit log for '%s': %s\n",
231+ action, buffer);
232+ return 1;
233+ }
234+ *cp2 = ' ';
235+ if (!(loop & 1)) {
236+ if (!strstr(buffer, " result=allowed ")) {
237+ fprintf(stderr, "***** result=allowed expected: %s\n",
238+ buffer);
239+ exit(1);
240+ return 1;
241+ }
242+ } else {
243+ if (!strstr(buffer, " result=denied ")) {
244+ fprintf(stderr, "***** result=denied expected: %s\n",
245+ buffer);
246+ exit(1);
247+ return 1;
248+ }
249+ }
250+ snprintf(buffer, sizeof(buffer) - 1, "delete 0 acl %s task.ppid=%u\n",
251+ action, getpid());
252+ write(policy_fd, buffer, strlen(buffer));
253+ while (read(audit_fd, buffer, sizeof(buffer) - 1) > 0);
254+ return 0;
255+}
256+
257+static void test_action(const char *action, int (*func) (void))
258+{
259+ static char buffer[1048576];
260+ int pos;
261+ int i;
262+ char *cp1;
263+ char *cp2;
264+ int retries = 0;
265+ memset(args, 0, sizeof(args));
266+ make_policy(action, 0, 0, 0);
267+retry:
268+ do_test(func);
269+ memset(buffer, 0, sizeof(buffer));
270+ read(audit_fd, buffer, sizeof(buffer) - 1);
271+ cp1 = strchr(buffer, '\n');
272+ if (!cp1) {
273+ if (retries++ < 100)
274+ goto retry;
275+ fprintf(stderr, "+++++ Missing audit log for '%s': %s\n",
276+ action, buffer);
277+ return;
278+ }
279+ *cp1 = '\0';
280+ cp1 = strstr(buffer, " / ");
281+ if (!cp1) {
282+ fprintf(stderr, "+++++ Corrupted audit log for '%s': %s\n",
283+ action, buffer);
284+ return;
285+ }
286+ cp1 += 3;
287+ cp2 = strchr(cp1, ' ');
288+ if (!cp2) {
289+ fprintf(stderr, "+++++ Corrupted audit log for '%s': %s\n",
290+ action, buffer);
291+ return;
292+ }
293+ *cp2++ = '\0';
294+ if (strcmp(cp1, action)) {
295+ if (retries++ < 100)
296+ goto retry;
297+ fprintf(stderr, "+++++ Unexpected audit log for '%s': %s\n",
298+ action, cp1);
299+ return;
300+ }
301+ cp1 = cp2;
302+ pos = 0;
303+ while (pos < (sizeof(args) / sizeof(args[0]))) {
304+ char *cp3;
305+ args[pos++] = cp1;
306+ cp2 = strchr(cp1, ' ');
307+ if (cp2)
308+ *cp2++ = '\0';
309+ cp3 = strchr(cp1, '=');
310+ if (!cp3 || !*(cp3 + 1)) {
311+ fprintf(stderr, "+++++ Corrupted audit log.\n");
312+ return;
313+ }
314+ *cp3 = '\0';
315+ /*
316+ * Ignore task.pid which cannot be matched due to tesing under
317+ * fork()ed process.
318+ */
319+ if (!strcmp(cp1, "task.pid"))
320+ pos--;
321+ /*
322+ * Ignore .ino which might change for each test.
323+ */
324+ else if (strstr(cp1, ".ino"))
325+ pos--;
326+ cp1 = cp2;
327+ if (!cp1)
328+ break;
329+ }
330+ if (pos == (sizeof(args) / sizeof(args[0]))) {
331+ fprintf(stderr, "+++++ Line too long.\n");
332+ return;
333+ }
334+ {
335+ static char buffer2[1024];
336+ while (read(audit_fd, buffer2, sizeof(buffer2)) > 0);
337+ }
338+ for (i = 0; i < pos; i++) {
339+ unsigned int loop;
340+ for (loop = 0; make_policy(action, loop, i, pos); loop++)
341+ check_result(action, func, loop);
342+ }
343+ return;
344+}
345+
346+static void startup(void)
347+{
348+ int pipe_fd[2] = { EOF, EOF };
349+ static char buffer[1048576];
350+ FILE *fp = fopen("/proc/caitsith/policy", "r");
351+ policy_fd = open("/proc/caitsith/policy", O_WRONLY);
352+ audit_fd = open("/proc/caitsith/audit", O_RDONLY);
353+ if (access(bin_true_location, X_OK))
354+ bin_true_location = "/usr/bin/true";
355+ if (access(bin_true_location, X_OK)) {
356+ fprintf(stderr, "***** Can't find /bin/true program.\n");
357+ exit(1);
358+ }
359+ if (!fp || policy_fd == EOF || audit_fd == EOF) {
360+ fprintf(stderr,
361+ "***** Can't open /proc/caitsith/ interface.\n");
362+ exit(1);
363+ }
364+ if (pipe(pipe_fd)) {
365+ fprintf(stderr, "***** Can't pipe.\n");
366+ exit(1);
367+ }
368+ mkdir("/tmp/caitsith.tmp", 0700);
369+ if (chown("/tmp/caitsith.tmp", 0, 0) ||
370+ chmod("/tmp/caitsith.tmp", 0700)) {
371+ fprintf(stderr, "***** Can't chown/chmod.\n");
372+ exit(1);
373+ }
374+ while (memset(buffer, 0, sizeof(buffer)),
375+ fgets(buffer, sizeof(buffer) - 1, fp)) {
376+ if (!strchr(buffer, '\n')) {
377+ fprintf(stderr, "***** Line too long.\n");
378+ exit(1);
379+ }
380+ write(policy_fd, "delete ", 7);
381+ write(policy_fd, buffer, strlen(buffer));
382+ }
383+ fclose(fp);
384+ {
385+ const char *config = "quota Memory used by audit: 1048576\n"
386+ "quota audit[0] allowed=1024 denied=1024 "
387+ "unmatched=1024\n" "number_group ZERO 0\n";
388+ write(policy_fd, config, strlen(config));
389+ }
390+ while (read(audit_fd, buffer, sizeof(buffer)) > 0);
391+ switch (fork()) {
392+ int fd;
393+ case 0:
394+ close(policy_fd);
395+ close(audit_fd);
396+ close(pipe_fd[1]);
397+ fd = open("/proc/caitsith/query", O_RDWR);
398+ while (1) {
399+ unsigned int serial;
400+ unsigned int retry;
401+ struct pollfd pfd[2] = {
402+ { fd, POLLIN, 0 },
403+ { pipe_fd[0], POLLIN, 0 }
404+ };
405+ poll(pfd, 2, -1);
406+ if (pfd[0].revents & POLLIN)
407+ break;
408+ if (read(fd, buffer, sizeof(buffer) - 1) <= 0)
409+ continue;
410+ if (sscanf(buffer, "Q%u-%u", &serial, &retry) != 2) {
411+ fprintf(stderr, "***** Corrupted query: %s\n",
412+ buffer);
413+ break;
414+ }
415+ snprintf(buffer, sizeof(buffer) - 1, "A%u=%u\n",
416+ serial,
417+ retry < 5 ? 3 /* Retry */ : 2 /* No */);
418+ write(fd, buffer, strlen(buffer));
419+ }
420+ _exit(0);
421+ case -1:
422+ fprintf(stderr, "***** Can't fork.\n");
423+ exit(1);
424+ }
425+ close(pipe_fd[0]);
426+}
427+
428+static int test_execute(void)
429+{
430+ execlp(bin_true_location, "true", NULL);
431+ return errno;
432+}
433+
434+static int test_read(void)
435+{
436+ const int fd = open("/dev/null", O_RDONLY);
437+ const int err = errno;
438+ close(fd);
439+ return err;
440+}
441+
442+static int test_write(void)
443+{
444+ const int fd = open("/dev/null", O_WRONLY);
445+ const int err = errno;
446+ close(fd);
447+ return err;
448+}
449+
450+static int test_create_no_append(void)
451+{
452+ const int fd = open("/tmp/caitsith.tmp/file",
453+ O_CREAT | O_RDWR | O_TRUNC, 0600);
454+ const int err = errno;
455+ close(fd);
456+ unlink("/tmp/caitsith.tmp/file");
457+ return err;
458+}
459+
460+static int test_create_append(void)
461+{
462+ const int fd = open("/tmp/caitsith.tmp/file",
463+ O_CREAT | O_RDWR | O_TRUNC | O_APPEND, 0600);
464+ const int err = errno;
465+ close(fd);
466+ unlink("/tmp/caitsith.tmp/file");
467+ return err;
468+}
469+
470+static int test_fcntl_clear_append(void)
471+{
472+ const int fd = open("/dev/null", O_WRONLY | O_APPEND);
473+ int err;
474+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND);
475+ err = errno;
476+ close(fd);
477+ return err;
478+}
479+
480+static int test_fcntl_set_append(void)
481+{
482+ const int fd = open("/dev/null", O_WRONLY);
483+ int err;
484+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_APPEND);
485+ err = errno;
486+ close(fd);
487+ return err;
488+}
489+
490+static int test_unlink(void)
491+{
492+ mknod("/tmp/caitsith.tmp/file", S_IFREG | 0600, 0);
493+ errno = 0;
494+ unlink("/tmp/caitsith.tmp/file");
495+ return errno;
496+}
497+
498+static int test_getattr(void)
499+{
500+ struct stat buf;
501+ stat("/dev/null", &buf);
502+ return errno;
503+}
504+
505+static int test_mkdir(void)
506+{
507+ int err;
508+ mkdir("/tmp/caitsith.tmp/dir", 0755);
509+ err = errno;
510+ rmdir("/tmp/caitsith.tmp/dir");
511+ return err;
512+}
513+
514+static int test_rmdir(void)
515+{
516+ mkdir("/tmp/caitsith.tmp/dir", 0755);
517+ errno = 0;
518+ rmdir("/tmp/caitsith.tmp/dir");
519+ return errno;
520+}
521+
522+static int test_mkfifo(void)
523+{
524+ int err;
525+ mknod("/tmp/caitsith.tmp/fifo", S_IFIFO | 0600, 0);
526+ err = errno;
527+ unlink("/tmp/caitsith.tmp/fifo");
528+ return err;
529+}
530+
531+static int test_mksock_by_mknod(void)
532+{
533+ int err;
534+ mknod("/tmp/caitsith.tmp/sock", S_IFSOCK | 0600, 0);
535+ err = errno;
536+ unlink("/tmp/caitsith.tmp/sock");
537+ return err;
538+}
539+
540+static int test_mksock_by_bind(void)
541+{
542+ struct sockaddr_un addr;
543+ int err;
544+ int fd = socket(PF_UNIX, SOCK_STREAM, 0);
545+ memset(&addr, 0, sizeof(addr));
546+ addr.sun_family = AF_UNIX;
547+ snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,
548+ "/tmp/caitsith.tmp/sock");
549+ errno = 0;
550+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
551+ err = errno;
552+ close(fd);
553+ unlink(addr.sun_path);
554+ return err;
555+}
556+
557+static int test_truncate(void)
558+{
559+ mknod("/tmp/caitsith.tmp/truncate", S_IFREG | 0600, 0);
560+ errno = 0;
561+ truncate("/tmp/caitsith.tmp/truncate", 0);
562+ return errno;
563+}
564+
565+static int test_symlink(void)
566+{
567+ int err;
568+ symlink(".", "/tmp/caitsith.tmp/symlink");
569+ err = errno;
570+ unlink("/tmp/caitsith.tmp/symlink");
571+ return err;
572+}
573+
574+static int test_mkchar(void)
575+{
576+ int err;
577+ mknod("/tmp/caitsith.tmp/char", S_IFCHR | 0600, MKDEV(1, 3));
578+ err = errno;
579+ unlink("/tmp/caitsith.tmp/char");
580+ return err;
581+}
582+
583+static int test_mkblock(void)
584+{
585+ int err;
586+ mknod("/tmp/caitsith.tmp/block", S_IFBLK | 0600, MKDEV(1, 0));
587+ err = errno;
588+ unlink("/tmp/caitsith.tmp/block");
589+ return err;
590+}
591+
592+static int test_link(void)
593+{
594+ int err;
595+ mknod("/tmp/caitsith.tmp/old_path", S_IFREG | 0600, 0);
596+ errno = 0;
597+ link("/tmp/caitsith.tmp/old_path", "/tmp/caitsith.tmp/new_path");
598+ err = errno;
599+ unlink("/tmp/caitsith.tmp/old_path");
600+ unlink("/tmp/caitsith.tmp/new_path");
601+ return err;
602+}
603+
604+static int test_rename(void)
605+{
606+ int err;
607+ mknod("/tmp/caitsith.tmp/old_path", S_IFREG | 0600, 0);
608+ errno = 0;
609+ rename("/tmp/caitsith.tmp/old_path", "/tmp/caitsith.tmp/new_path");
610+ err = errno;
611+ unlink("/tmp/caitsith.tmp/old_path");
612+ unlink("/tmp/caitsith.tmp/new_path");
613+ return err;
614+}
615+
616+static int test_chmod(void)
617+{
618+ chmod("/dev/null", 0666);
619+ return errno;
620+}
621+
622+static int test_chown(void)
623+{
624+ chown("/dev/null", 0, -1);
625+ return errno;
626+}
627+
628+static int test_chgrp(void)
629+{
630+ chown("/dev/null", -1, 0);
631+ return errno;
632+}
633+
634+static int test_ioctl(void)
635+{
636+ const int fd = open("/dev/null", O_WRONLY);
637+ int err;
638+ ioctl(fd, 0, 0);
639+ err = errno;
640+ close(fd);
641+ return err;
642+}
643+
644+static int test_chroot(void)
645+{
646+ chroot("/tmp/caitsith.tmp");
647+ return errno;
648+}
649+
650+static int test_mount(void)
651+{
652+ int err;
653+ mount(NULL, "/tmp/caitsith.tmp", "tmpfs", 0, NULL);
654+ err = errno;
655+ umount("/tmp/caitsith.tmp");
656+ return err;
657+}
658+
659+static int test_unmount(void)
660+{
661+ mount(NULL, "/tmp/caitsith.tmp", "tmpfs", 0, NULL);
662+ errno = 0;
663+ umount("/tmp/caitsith.tmp");
664+ return errno;
665+}
666+
667+static int test_pivot_root(void)
668+{
669+ pivot_root("/proc/", "/proc/caitsith/");
670+ return errno;
671+}
672+
673+static void inet_bind(const int fd, const unsigned short int port)
674+{
675+ struct sockaddr_in addr = { };
676+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
677+ addr.sin_family = AF_INET;
678+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
679+ addr.sin_port = htons(port);
680+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
681+}
682+
683+static int test_inet_stream_bind(void)
684+{
685+ int fd = socket(PF_INET, SOCK_STREAM, 0);
686+ int err;
687+ struct sockaddr_in addr = { };
688+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
689+ addr.sin_family = AF_INET;
690+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
691+ addr.sin_port = htons(10000);
692+ errno = 0;
693+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
694+ err = errno;
695+ close(fd);
696+ return err;
697+}
698+
699+static int test_inet_stream_listen(void)
700+{
701+ int fd = socket(PF_INET, SOCK_STREAM, 0);
702+ int err;
703+ inet_bind(fd, 10000);
704+ errno = 0;
705+ listen(fd, 5);
706+ err = errno;
707+ close(fd);
708+ return err;
709+}
710+
711+static int test_inet_stream_connect(void)
712+{
713+ int fd1 = socket(PF_INET, SOCK_STREAM, 0);
714+ int fd2 = socket(PF_INET, SOCK_STREAM, 0);
715+ int err;
716+ struct sockaddr_in addr = { };
717+ socklen_t size = sizeof(addr);
718+ inet_bind(fd1, 10000);
719+ listen(fd1, 0);
720+ inet_bind(fd2, 10001);
721+ getsockname(fd1, (struct sockaddr *) &addr, &size);
722+ errno = 0;
723+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
724+ err = errno;
725+ close(fd1);
726+ close(fd2);
727+ return err;
728+}
729+
730+static int test_inet_stream_accept(void)
731+{
732+ int fd1 = socket(PF_INET, SOCK_STREAM, 0);
733+ int fd2 = socket(PF_INET, SOCK_STREAM, 0);
734+ int fd3;
735+ int err;
736+ struct sockaddr_in addr = { };
737+ socklen_t size = sizeof(addr);
738+ inet_bind(fd1, 10000);
739+ listen(fd1, 0);
740+ inet_bind(fd2, 10001);
741+ getsockname(fd1, (struct sockaddr *) &addr, &size);
742+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
743+ errno = 0;
744+ fd3 = accept(fd1, (struct sockaddr *) &addr, &size);
745+ if (fd3 != EOF)
746+ getsockname(fd3, (struct sockaddr *) &addr, &size);
747+ err = errno;
748+ close(fd1);
749+ close(fd2);
750+ close(fd3);
751+ return err;
752+}
753+
754+static int test_inet_dgram_bind(void)
755+{
756+ int fd = socket(PF_INET, SOCK_DGRAM, 0);
757+ int err;
758+ struct sockaddr_in addr = { };
759+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
760+ addr.sin_family = AF_INET;
761+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
762+ addr.sin_port = htons(10000);
763+ errno = 0;
764+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
765+ err = errno;
766+ close(fd);
767+ return err;
768+}
769+
770+static int test_inet_dgram_connect(void)
771+{
772+ int fd1 = socket(PF_INET, SOCK_DGRAM, 0);
773+ int fd2 = socket(PF_INET, SOCK_DGRAM, 0);
774+ int err;
775+ struct sockaddr_in addr = { };
776+ socklen_t size = sizeof(addr);
777+ inet_bind(fd1, 10000);
778+ inet_bind(fd2, 10001);
779+ getsockname(fd1, (struct sockaddr *) &addr, &size);
780+ errno = 0;
781+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
782+ err = errno;
783+ close(fd1);
784+ close(fd2);
785+ return err;
786+}
787+
788+static int test_inet_dgram_send(void)
789+{
790+ int fd1 = socket(PF_INET, SOCK_DGRAM, 0);
791+ int fd2 = socket(PF_INET, SOCK_DGRAM, 0);
792+ int err;
793+ struct sockaddr_in addr = { };
794+ socklen_t size = sizeof(addr);
795+ inet_bind(fd1, 10000);
796+ inet_bind(fd2, 10001);
797+ getsockname(fd1, (struct sockaddr *) &addr, &size);
798+ errno = 0;
799+ sendto(fd2, "", 1, 0, (struct sockaddr *) &addr, sizeof(addr));
800+ err = errno;
801+ close(fd1);
802+ close(fd2);
803+ return err;
804+}
805+
806+static int test_inet_dgram_recv(void)
807+{
808+ int fd1 = socket(PF_INET, SOCK_DGRAM, 0);
809+ int fd2 = socket(PF_INET, SOCK_DGRAM, 0);
810+ int err;
811+ char c;
812+ struct sockaddr_in addr = { };
813+ socklen_t size = sizeof(addr);
814+ inet_bind(fd1, 10000);
815+ inet_bind(fd2, 10001);
816+ getsockname(fd1, (struct sockaddr *) &addr, &size);
817+ sendto(fd2, "", 1, 0, (struct sockaddr *) &addr, sizeof(addr));
818+ errno = 0;
819+ recvfrom(fd1, &c, 1, MSG_DONTWAIT, (struct sockaddr *) &addr, &size);
820+ err = errno;
821+ close(fd1);
822+ close(fd2);
823+ return err;
824+}
825+
826+static int test_inet_raw_bind(void)
827+{
828+ int fd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
829+ int err;
830+ struct sockaddr_in addr = { };
831+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
832+ addr.sin_family = AF_INET;
833+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
834+ addr.sin_port = htons(10000);
835+ errno = 0;
836+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
837+ err = errno;
838+ close(fd);
839+ return err;
840+}
841+
842+static int test_inet_raw_connect(void)
843+{
844+ int fd1 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
845+ int fd2 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
846+ int err;
847+ struct sockaddr_in addr = { };
848+ socklen_t size = sizeof(addr);
849+ inet_bind(fd1, 10000);
850+ inet_bind(fd2, 10001);
851+ getsockname(fd1, (struct sockaddr *) &addr, &size);
852+ errno = 0;
853+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
854+ err = errno;
855+ close(fd1);
856+ close(fd2);
857+ return err;
858+}
859+
860+static int test_inet_raw_send(void)
861+{
862+ int fd1 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
863+ int fd2 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
864+ int err;
865+ struct sockaddr_in addr = { };
866+ socklen_t size = sizeof(addr);
867+ static struct iphdr ip = { };
868+ inet_bind(fd1, 10000);
869+ inet_bind(fd2, 10001);
870+ getsockname(fd1, (struct sockaddr *) &addr, &size);
871+ ip.version = 4;
872+ ip.ihl = sizeof(struct iphdr) / 4;
873+ ip.protocol = IPPROTO_RAW;
874+ ip.daddr = htonl(INADDR_LOOPBACK);
875+ ip.saddr = ip.daddr;
876+ errno = 0;
877+ sendto(fd2, &ip, sizeof(ip), 0, (struct sockaddr *) &addr,
878+ sizeof(addr));
879+ err = errno;
880+ close(fd1);
881+ close(fd2);
882+ return err;
883+}
884+
885+static int test_inet_raw_recv(void)
886+{
887+ int fd1 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
888+ int fd2 = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
889+ int err;
890+ struct sockaddr_in addr = { };
891+ socklen_t size = sizeof(addr);
892+ static struct iphdr ip = { };
893+ inet_bind(fd1, 10000);
894+ inet_bind(fd2, 10000);
895+ getsockname(fd1, (struct sockaddr *) &addr, &size);
896+ ip.version = 4;
897+ ip.ihl = sizeof(struct iphdr) / 4;
898+ ip.protocol = IPPROTO_RAW;
899+ ip.daddr = htonl(INADDR_LOOPBACK);
900+ ip.saddr = ip.daddr;
901+ sendto(fd2, &ip, sizeof(ip), 0, (struct sockaddr *) &addr,
902+ sizeof(addr));
903+ errno = 0;
904+ recvfrom(fd1, &ip, sizeof(ip), MSG_DONTWAIT, (struct sockaddr *) &addr,
905+ &size);
906+ err = errno;
907+ close(fd1);
908+ close(fd2);
909+ return err;
910+}
911+
912+static void unix_bind(const int fd, const _Bool listener)
913+{
914+ struct sockaddr_un addr = { };
915+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
916+ addr.sun_family = AF_UNIX;
917+ snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,
918+ "/tmp/caitsith.tmp/%s", listener ? "server" : "client");
919+ unlink(addr.sun_path);
920+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
921+}
922+
923+static int test_unix_stream_bind(void)
924+{
925+ int fd = socket(PF_UNIX, SOCK_STREAM, 0);
926+ int err;
927+ struct sockaddr_un addr = { };
928+ addr.sun_family = AF_UNIX;
929+ errno = 0;
930+ bind(fd, (struct sockaddr *) &addr, sizeof(addr.sun_family));
931+ err = errno;
932+ close(fd);
933+ return err;
934+}
935+
936+static int test_unix_stream_listen(void)
937+{
938+ int fd = socket(PF_UNIX, SOCK_STREAM, 0);
939+ int err;
940+ unix_bind(fd, 1);
941+ errno = 0;
942+ listen(fd, 5);
943+ err = errno;
944+ close(fd);
945+ return err;
946+}
947+
948+static int test_unix_stream_connect(void)
949+{
950+ int fd1 = socket(PF_UNIX, SOCK_STREAM, 0);
951+ int fd2 = socket(PF_UNIX, SOCK_STREAM, 0);
952+ int err;
953+ struct sockaddr_un addr = { };
954+ socklen_t size = sizeof(addr);
955+ unix_bind(fd1, 1);
956+ unix_bind(fd2, 0);
957+ listen(fd1, 0);
958+ getsockname(fd1, (struct sockaddr *) &addr, &size);
959+ errno = 0;
960+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
961+ err = errno;
962+ close(fd1);
963+ close(fd2);
964+ return err;
965+}
966+
967+static int test_unix_stream_accept(void)
968+{
969+ int fd1 = socket(PF_UNIX, SOCK_STREAM, 0);
970+ int fd2 = socket(PF_UNIX, SOCK_STREAM, 0);
971+ int fd3;
972+ int err;
973+ struct sockaddr_un addr = { };
974+ socklen_t size = sizeof(addr);
975+ unix_bind(fd1, 1);
976+ unix_bind(fd2, 0);
977+ listen(fd1, 0);
978+ getsockname(fd1, (struct sockaddr *) &addr, &size);
979+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
980+ errno = 0;
981+ fd3 = accept(fd1, (struct sockaddr *) &addr, &size);
982+ if (fd3 != EOF)
983+ getsockname(fd3, (struct sockaddr *) &addr, &size);
984+ err = errno;
985+ close(fd1);
986+ close(fd2);
987+ close(fd3);
988+ return err;
989+}
990+
991+static int test_unix_dgram_bind(void)
992+{
993+ int fd = socket(PF_UNIX, SOCK_DGRAM, 0);
994+ int err;
995+ struct sockaddr_un addr = { };
996+ addr.sun_family = AF_UNIX;
997+ errno = 0;
998+ bind(fd, (struct sockaddr *) &addr, sizeof(addr));
999+ err = errno;
1000+ close(fd);
1001+ return err;
1002+}
1003+
1004+static int test_unix_dgram_connect(void)
1005+{
1006+ int fd1 = socket(PF_UNIX, SOCK_DGRAM, 0);
1007+ int fd2 = socket(PF_UNIX, SOCK_DGRAM, 0);
1008+ int err;
1009+ struct sockaddr_un addr = { };
1010+ socklen_t size = sizeof(addr);
1011+ unix_bind(fd1, 1);
1012+ unix_bind(fd2, 0);
1013+ getsockname(fd1, (struct sockaddr *) &addr, &size);
1014+ errno = 0;
1015+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
1016+ err = errno;
1017+ close(fd1);
1018+ close(fd2);
1019+ return err;
1020+}
1021+
1022+static int test_unix_dgram_send(void)
1023+{
1024+ int fd1 = socket(PF_UNIX, SOCK_DGRAM, 0);
1025+ int fd2 = socket(PF_UNIX, SOCK_DGRAM, 0);
1026+ int err;
1027+ struct sockaddr_un addr = { };
1028+ socklen_t size = sizeof(addr);
1029+ unix_bind(fd1, 1);
1030+ unix_bind(fd2, 0);
1031+ getsockname(fd1, (struct sockaddr *) &addr, &size);
1032+ errno = 0;
1033+ sendto(fd2, "", 1, 0, (struct sockaddr *) &addr, sizeof(addr));
1034+ err = errno;
1035+ close(fd1);
1036+ close(fd2);
1037+ return err;
1038+}
1039+
1040+static int test_unix_dgram_recv(void)
1041+{
1042+ int fd1 = socket(PF_UNIX, SOCK_DGRAM, 0);
1043+ int fd2 = socket(PF_UNIX, SOCK_DGRAM, 0);
1044+ int err;
1045+ char c;
1046+ struct sockaddr_un addr = { };
1047+ socklen_t size = sizeof(addr);
1048+ unix_bind(fd1, 1);
1049+ unix_bind(fd2, 0);
1050+ getsockname(fd1, (struct sockaddr *) &addr, &size);
1051+ sendto(fd2, "", 1, 0, (struct sockaddr *) &addr, sizeof(addr));
1052+ errno = 0;
1053+ recvfrom(fd1, &c, 1, MSG_DONTWAIT, (struct sockaddr *) &addr, &size);
1054+ err = errno;
1055+ close(fd1);
1056+ close(fd2);
1057+ return err;
1058+}
1059+
1060+static int test_unix_seqpacket_bind(void)
1061+{
1062+ int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1063+ int err;
1064+ struct sockaddr_un addr = { };
1065+ addr.sun_family = AF_UNIX;
1066+ errno = 0;
1067+ bind(fd, (struct sockaddr *) &addr, sizeof(addr.sun_family));
1068+ err = errno;
1069+ close(fd);
1070+ return err;
1071+}
1072+
1073+static int test_unix_seqpacket_listen(void)
1074+{
1075+ int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1076+ int err;
1077+ unix_bind(fd, 1);
1078+ errno = 0;
1079+ listen(fd, 5);
1080+ err = errno;
1081+ close(fd);
1082+ return err;
1083+}
1084+
1085+static int test_unix_seqpacket_connect(void)
1086+{
1087+ int fd1 = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1088+ int fd2 = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1089+ int err;
1090+ struct sockaddr_un addr = { };
1091+ socklen_t size = sizeof(addr);
1092+ unix_bind(fd1, 1);
1093+ unix_bind(fd2, 0);
1094+ listen(fd1, 0);
1095+ getsockname(fd1, (struct sockaddr *) &addr, &size);
1096+ errno = 0;
1097+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
1098+ err = errno;
1099+ close(fd1);
1100+ close(fd2);
1101+ return err;
1102+}
1103+
1104+static int test_unix_seqpacket_accept(void)
1105+{
1106+ int fd1 = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1107+ int fd2 = socket(PF_UNIX, SOCK_SEQPACKET, 0);
1108+ int fd3;
1109+ int err;
1110+ struct sockaddr_un addr = { };
1111+ socklen_t size = sizeof(addr);
1112+ unix_bind(fd1, 1);
1113+ unix_bind(fd2, 0);
1114+ listen(fd1, 0);
1115+ getsockname(fd1, (struct sockaddr *) &addr, &size);
1116+ connect(fd2, (struct sockaddr *) &addr, sizeof(addr));
1117+ errno = 0;
1118+ fd3 = accept(fd1, (struct sockaddr *) &addr, &size);
1119+ if (fd3 != EOF)
1120+ getsockname(fd3, (struct sockaddr *) &addr, &size);
1121+ err = errno;
1122+ close(fd1);
1123+ close(fd2);
1124+ close(fd3);
1125+ return err;
1126+}
1127+
1128+static int test_environ(void)
1129+{
1130+ char * const argv[2] = { "true", NULL };
1131+ char * const envp[2] = { "HOME=/", NULL };
1132+ execve(bin_true_location, argv, envp);
1133+ return errno;
1134+}
1135+
1136+static int test_ptrace(void)
1137+{
1138+ ptrace(PTRACE_ATTACH, 1, NULL, NULL);
1139+ return errno;
1140+}
1141+
1142+static int test_signal(void)
1143+{
1144+ kill(1, 1);
1145+ return errno;
1146+}
1147+
1148+static int test_modify_policy(void)
1149+{
1150+ const char *policy = "1 acl modify_policy\n";
1151+ /*
1152+ * Try to execute a non-executable in order to clear cached policy
1153+ * manager attribute.
1154+ */
1155+ const int fd = open("/tmp/caitsith.tmp/exec",
1156+ O_CREAT | O_TRUNC | O_WRONLY, 0600);
1157+ fchmod(fd, 0700);
1158+ close(fd);
1159+ execl("/tmp/caitsith.tmp/exec", "exec", NULL);
1160+ /* Now policy manager attribute was cleared. */
1161+ errno = 0;
1162+ write(policy_fd, policy, strlen(policy));
1163+ return errno;
1164+}
1165+
1166+static int test_use_netlink_socket(void)
1167+{
1168+ const int fd = socket(AF_ROUTE, SOCK_RAW, 0);
1169+ const int err = errno;
1170+ close(fd);
1171+ return err;
1172+}
1173+
1174+static int test_use_packet_socket(void)
1175+{
1176+ const int fd = socket(AF_PACKET, SOCK_RAW, 0);
1177+ const int err = errno;
1178+ close(fd);
1179+ return err;
1180+}
1181+
1182+static int test_use_reboot(void)
1183+{
1184+ FILE *fp = fopen("/proc/sys/kernel/ctrl-alt-del", "a+");
1185+ unsigned int c;
1186+ int err;
1187+ if (fp && fscanf(fp, "%u", &c) == 1) {
1188+ errno = 0;
1189+ reboot(LINUX_REBOOT_CMD_CAD_ON);
1190+ err = errno;
1191+ fprintf(fp, "%u\n", c);
1192+ } else {
1193+ errno = 0;
1194+ /* Use invalid value */
1195+ reboot(0x0000C0DE);
1196+ err = errno;
1197+ }
1198+ if (fp)
1199+ fclose(fp);
1200+ return err;
1201+}
1202+
1203+static int test_use_vhangup(void)
1204+{
1205+ setsid();
1206+ errno = 0;
1207+ vhangup();
1208+ return errno;
1209+}
1210+
1211+static int test_set_time_by_stime(void)
1212+{
1213+ const time_t now = time(NULL);
1214+ errno = 0;
1215+ stime(&now);
1216+ return errno;
1217+}
1218+
1219+static int test_set_time_by_settimeofday(void)
1220+{
1221+ struct timeval tv;
1222+ struct timezone tz;
1223+ gettimeofday(&tv, &tz);
1224+ errno = 0;
1225+ settimeofday(&tv, &tz);
1226+ return errno;
1227+}
1228+
1229+static int test_set_time_by_adjtimex(void)
1230+{
1231+ struct timex buf = { };
1232+ buf.modes = 0x100; /* Use invalid value so that the clock
1233+ won't change. */
1234+ adjtimex(&buf);
1235+ return errno;
1236+}
1237+
1238+static int test_set_priority_by_nice(void)
1239+{
1240+ nice(0);
1241+ return errno;
1242+}
1243+
1244+static int test_set_priority_by_setpriority(void)
1245+{
1246+ const int priority = getpriority(PRIO_PROCESS, getpid());
1247+ errno = 0;
1248+ setpriority(PRIO_PROCESS, getpid(), priority);
1249+ return errno;
1250+}
1251+
1252+static int test_set_hostname_by_sethostname(void)
1253+{
1254+ char buffer[4096] = { };
1255+ gethostname(buffer, sizeof(buffer) - 1);
1256+ errno = 0;
1257+ sethostname(buffer, strlen(buffer));
1258+ return errno;
1259+}
1260+
1261+static int test_set_hostname_by_setdomainname(void)
1262+{
1263+ char buffer[4096] = { };
1264+ getdomainname(buffer, sizeof(buffer) - 1);
1265+ errno = 0;
1266+ setdomainname(buffer, strlen(buffer));
1267+ return errno;
1268+}
1269+
1270+static int test_use_kernel_module_by_init_module(void)
1271+{
1272+ init_module("", NULL);
1273+ return errno;
1274+}
1275+
1276+static int test_use_kernel_module_by_delete_module(void)
1277+{
1278+ delete_module("");
1279+ return errno;
1280+}
1281+
1282+static int test_use_new_kernel(void)
1283+{
1284+ sys_kexec_load(0, 0, NULL, 0);
1285+ return errno;
1286+}
1287+
1288+int main(int argc, char *argv[])
1289+{
1290+ int i;
1291+ static const struct {
1292+ const char *action;
1293+ int (*func) (void);
1294+ } testcases[] = {
1295+ { "execute", test_execute },
1296+ { "read", test_read },
1297+ { "write", test_write },
1298+ { "create", test_create_no_append },
1299+ { "read", test_create_no_append },
1300+ { "write", test_create_no_append },
1301+ /* { "truncate", test_create_no_append }, */
1302+ { "create", test_create_append },
1303+ { "read", test_create_append },
1304+ { "append", test_create_append },
1305+ /* { "truncate", test_create_append }, */
1306+ { "write", test_fcntl_clear_append },
1307+ { "append", test_fcntl_set_append },
1308+ { "unlink", test_unlink },
1309+ { "getattr", test_getattr },
1310+ { "mkdir", test_mkdir },
1311+ { "rmdir", test_rmdir },
1312+ { "mkfifo", test_mkfifo },
1313+ { "mksock", test_mksock_by_mknod },
1314+ { "mksock", test_mksock_by_bind },
1315+ { "truncate", test_truncate },
1316+ { "symlink", test_symlink },
1317+ { "mkchar", test_mkchar },
1318+ { "mkblock", test_mkblock },
1319+ { "link", test_link },
1320+ { "rename", test_rename },
1321+ { "chmod", test_chmod },
1322+ { "chown", test_chown },
1323+ { "chgrp", test_chgrp },
1324+ { "ioctl", test_ioctl },
1325+ { "chroot", test_chroot },
1326+ { "mount", test_mount },
1327+ { "unmount", test_unmount },
1328+ { "pivot_root", test_pivot_root },
1329+ { "inet_stream_bind", test_inet_stream_bind },
1330+ { "inet_stream_listen", test_inet_stream_listen },
1331+ { "inet_stream_connect", test_inet_stream_connect },
1332+ { "inet_stream_accept", test_inet_stream_accept },
1333+ { "inet_dgram_bind", test_inet_dgram_bind },
1334+ { "inet_dgram_send", test_inet_dgram_connect },
1335+ { "inet_dgram_send", test_inet_dgram_send },
1336+ { "inet_dgram_recv", test_inet_dgram_recv },
1337+ { "inet_raw_bind", test_inet_raw_bind },
1338+ { "inet_raw_send", test_inet_raw_connect },
1339+ { "inet_raw_send", test_inet_raw_send },
1340+ { "inet_raw_recv", test_inet_raw_recv },
1341+ { "unix_stream_bind", test_unix_stream_bind },
1342+ { "unix_stream_listen", test_unix_stream_listen },
1343+ { "unix_stream_connect", test_unix_stream_connect },
1344+ { "unix_stream_accept", test_unix_stream_accept },
1345+ { "unix_dgram_bind", test_unix_dgram_bind },
1346+ { "unix_dgram_send", test_unix_dgram_connect },
1347+ { "unix_dgram_send", test_unix_dgram_send },
1348+ { "unix_dgram_recv", test_unix_dgram_recv },
1349+ { "unix_seqpacket_bind", test_unix_seqpacket_bind },
1350+ { "unix_seqpacket_listen", test_unix_seqpacket_listen },
1351+ { "unix_seqpacket_connect", test_unix_seqpacket_connect },
1352+ { "unix_seqpacket_accept", test_unix_seqpacket_accept },
1353+ { "environ", test_environ },
1354+ { "ptrace", test_ptrace },
1355+ { "signal", test_signal },
1356+ { "modify_policy", test_modify_policy },
1357+ { "use_netlink_socket", test_use_netlink_socket },
1358+ { "use_packet_socket", test_use_packet_socket },
1359+ { "use_reboot", test_use_reboot },
1360+ { "use_vhangup", test_use_vhangup },
1361+ { "set_time", test_set_time_by_stime },
1362+ { "set_time", test_set_time_by_settimeofday },
1363+ { "set_time", test_set_time_by_adjtimex },
1364+ { "set_priority", test_set_priority_by_nice },
1365+ { "set_priority", test_set_priority_by_setpriority },
1366+ { "set_hostname", test_set_hostname_by_sethostname },
1367+ { "set_hostname", test_set_hostname_by_setdomainname },
1368+ { "use_kernel_module", test_use_kernel_module_by_init_module },
1369+ { "use_kernel_module",
1370+ test_use_kernel_module_by_delete_module },
1371+ { "use_new_kernel", test_use_new_kernel },
1372+ { NULL, NULL }
1373+ };
1374+ startup();
1375+ for (i = 0; testcases[i].action; i++)
1376+ test_action(testcases[i].action, testcases[i].func);
1377+ fprintf(stderr, "Done.\n");
1378+ return 0;
1379+}
--- trunk/caitsith-tools/kernel_test/caitsith_parser_test.c (nonexistent)
+++ trunk/caitsith-tools/kernel_test/caitsith_parser_test.c (revision 76)
@@ -0,0 +1,916 @@
1+/*
2+ * caitsith-parser-test.c
3+ *
4+ * Copyright (C) 2012 Tetsuo Handa
5+ *
6+ * Version: 0.1 2012/09/17
7+ *
8+ * This program is free software; you can redistribute it and/or modify it
9+ * under the terms of the GNU General Public License v2 as published by the
10+ * Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful, but WITHOUT
13+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15+ * more details.
16+ *
17+ * You should have received a copy of the GNU General Public License along with
18+ * this program; if not, write to the Free Software Foundation, Inc.,
19+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+ */
21+
22+#include <stdio.h>
23+#include <string.h>
24+#include <stdlib.h>
25+#include <sys/types.h>
26+#include <sys/stat.h>
27+#include <fcntl.h>
28+#include <unistd.h>
29+#include <time.h>
30+
31+enum ccs_mac_index {
32+ CCS_MAC_EXECUTE,
33+ CCS_MAC_READ,
34+ CCS_MAC_WRITE,
35+ CCS_MAC_APPEND,
36+ CCS_MAC_CREATE,
37+ CCS_MAC_UNLINK,
38+ CCS_MAC_GETATTR,
39+ CCS_MAC_MKDIR,
40+ CCS_MAC_RMDIR,
41+ CCS_MAC_MKFIFO,
42+ CCS_MAC_MKSOCK,
43+ CCS_MAC_TRUNCATE,
44+ CCS_MAC_SYMLINK,
45+ CCS_MAC_MKBLOCK,
46+ CCS_MAC_MKCHAR,
47+ CCS_MAC_LINK,
48+ CCS_MAC_RENAME,
49+ CCS_MAC_CHMOD,
50+ CCS_MAC_CHOWN,
51+ CCS_MAC_CHGRP,
52+ CCS_MAC_IOCTL,
53+ CCS_MAC_CHROOT,
54+ CCS_MAC_MOUNT,
55+ CCS_MAC_UMOUNT,
56+ CCS_MAC_PIVOT_ROOT,
57+ CCS_MAC_INET_STREAM_BIND,
58+ CCS_MAC_INET_STREAM_LISTEN,
59+ CCS_MAC_INET_STREAM_CONNECT,
60+ CCS_MAC_INET_STREAM_ACCEPT,
61+ CCS_MAC_INET_DGRAM_BIND,
62+ CCS_MAC_INET_DGRAM_SEND,
63+ CCS_MAC_INET_DGRAM_RECV,
64+ CCS_MAC_INET_RAW_BIND,
65+ CCS_MAC_INET_RAW_SEND,
66+ CCS_MAC_INET_RAW_RECV,
67+ CCS_MAC_UNIX_STREAM_BIND,
68+ CCS_MAC_UNIX_STREAM_LISTEN,
69+ CCS_MAC_UNIX_STREAM_CONNECT,
70+ CCS_MAC_UNIX_STREAM_ACCEPT,
71+ CCS_MAC_UNIX_DGRAM_BIND,
72+ CCS_MAC_UNIX_DGRAM_SEND,
73+ CCS_MAC_UNIX_DGRAM_RECV,
74+ CCS_MAC_UNIX_SEQPACKET_BIND,
75+ CCS_MAC_UNIX_SEQPACKET_LISTEN,
76+ CCS_MAC_UNIX_SEQPACKET_CONNECT,
77+ CCS_MAC_UNIX_SEQPACKET_ACCEPT,
78+ CCS_MAC_ENVIRON,
79+ CCS_MAC_PTRACE,
80+ CCS_MAC_SIGNAL,
81+ CCS_MAC_MODIFY_POLICY,
82+ CCS_MAC_USE_NETLINK_SOCKET,
83+ CCS_MAC_USE_PACKET_SOCKET,
84+ CCS_MAC_USE_REBOOT,
85+ CCS_MAC_USE_VHANGUP,
86+ CCS_MAC_SET_TIME,
87+ CCS_MAC_SET_PRIORITY,
88+ CCS_MAC_SET_HOSTNAME,
89+ CCS_MAC_USE_KERNEL_MODULE,
90+ CCS_MAC_USE_NEW_KERNEL,
91+ CCS_MAC_AUTO_DOMAIN_TRANSITION,
92+ CCS_MAC_MANUAL_DOMAIN_TRANSITION,
93+ CCS_MAX_MAC_INDEX
94+};
95+
96+static const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX] = {
97+ [CCS_MAC_EXECUTE] = "execute",
98+ [CCS_MAC_READ] = "read",
99+ [CCS_MAC_WRITE] = "write",
100+ [CCS_MAC_APPEND] = "append",
101+ [CCS_MAC_CREATE] = "create",
102+ [CCS_MAC_UNLINK] = "unlink",
103+ [CCS_MAC_GETATTR] = "getattr",
104+ [CCS_MAC_MKDIR] = "mkdir",
105+ [CCS_MAC_RMDIR] = "rmdir",
106+ [CCS_MAC_MKFIFO] = "mkfifo",
107+ [CCS_MAC_MKSOCK] = "mksock",
108+ [CCS_MAC_TRUNCATE] = "truncate",
109+ [CCS_MAC_SYMLINK] = "symlink",
110+ [CCS_MAC_MKBLOCK] = "mkblock",
111+ [CCS_MAC_MKCHAR] = "mkchar",
112+ [CCS_MAC_LINK] = "link",
113+ [CCS_MAC_RENAME] = "rename",
114+ [CCS_MAC_CHMOD] = "chmod",
115+ [CCS_MAC_CHOWN] = "chown",
116+ [CCS_MAC_CHGRP] = "chgrp",
117+ [CCS_MAC_IOCTL] = "ioctl",
118+ [CCS_MAC_CHROOT] = "chroot",
119+ [CCS_MAC_MOUNT] = "mount",
120+ [CCS_MAC_UMOUNT] = "unmount",
121+ [CCS_MAC_PIVOT_ROOT] = "pivot_root",
122+ [CCS_MAC_INET_STREAM_BIND] = "inet_stream_bind",
123+ [CCS_MAC_INET_STREAM_LISTEN] = "inet_stream_listen",
124+ [CCS_MAC_INET_STREAM_CONNECT] = "inet_stream_connect",
125+ [CCS_MAC_INET_STREAM_ACCEPT] = "inet_stream_accept",
126+ [CCS_MAC_INET_DGRAM_BIND] = "inet_dgram_bind",
127+ [CCS_MAC_INET_DGRAM_SEND] = "inet_dgram_send",
128+ [CCS_MAC_INET_DGRAM_RECV] = "inet_dgram_recv",
129+ [CCS_MAC_INET_RAW_BIND] = "inet_raw_bind",
130+ [CCS_MAC_INET_RAW_SEND] = "inet_raw_send",
131+ [CCS_MAC_INET_RAW_RECV] = "inet_raw_recv",
132+ [CCS_MAC_UNIX_STREAM_BIND] = "unix_stream_bind",
133+ [CCS_MAC_UNIX_STREAM_LISTEN] = "unix_stream_listen",
134+ [CCS_MAC_UNIX_STREAM_CONNECT] = "unix_stream_connect",
135+ [CCS_MAC_UNIX_STREAM_ACCEPT] = "unix_stream_accept",
136+ [CCS_MAC_UNIX_DGRAM_BIND] = "unix_dgram_bind",
137+ [CCS_MAC_UNIX_DGRAM_SEND] = "unix_dgram_send",
138+ [CCS_MAC_UNIX_DGRAM_RECV] = "unix_dgram_recv",
139+ [CCS_MAC_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind",
140+ [CCS_MAC_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen",
141+ [CCS_MAC_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
142+ [CCS_MAC_UNIX_SEQPACKET_ACCEPT] = "unix_seqpacket_accept",
143+ [CCS_MAC_ENVIRON] = "environ",
144+ [CCS_MAC_PTRACE] = "ptrace",
145+ [CCS_MAC_SIGNAL] = "signal",
146+ [CCS_MAC_MODIFY_POLICY] = "modify_policy",
147+ [CCS_MAC_USE_NETLINK_SOCKET] = "use_netlink_socket",
148+ [CCS_MAC_USE_PACKET_SOCKET] = "use_packet_socket",
149+ [CCS_MAC_USE_REBOOT] = "use_reboot",
150+ [CCS_MAC_USE_VHANGUP] = "use_vhangup",
151+ [CCS_MAC_SET_TIME] = "set_time",
152+ [CCS_MAC_SET_PRIORITY] = "set_priority",
153+ [CCS_MAC_SET_HOSTNAME] = "set_hostname",
154+ [CCS_MAC_USE_KERNEL_MODULE] = "use_kernel_module",
155+ [CCS_MAC_USE_NEW_KERNEL] = "use_new_kernel",
156+ [CCS_MAC_AUTO_DOMAIN_TRANSITION] = "auto_domain_transition",
157+ [CCS_MAC_MANUAL_DOMAIN_TRANSITION] = "manual_domain_transition",
158+};
159+
160+#define F(bit) (1ULL << bit)
161+
162+#define CCS_ALL_OK \
163+ (F(CCS_MAC_EXECUTE) | \
164+ F(CCS_MAC_READ) | \
165+ F(CCS_MAC_WRITE) | \
166+ F(CCS_MAC_APPEND) | \
167+ F(CCS_MAC_CREATE) | \
168+ F(CCS_MAC_UNLINK) | \
169+ F(CCS_MAC_GETATTR) | \
170+ F(CCS_MAC_MKDIR) | \
171+ F(CCS_MAC_RMDIR) | \
172+ F(CCS_MAC_MKFIFO) | \
173+ F(CCS_MAC_MKSOCK) | \
174+ F(CCS_MAC_TRUNCATE) | \
175+ F(CCS_MAC_SYMLINK) | \
176+ F(CCS_MAC_MKBLOCK) | \
177+ F(CCS_MAC_MKCHAR) | \
178+ F(CCS_MAC_LINK) | \
179+ F(CCS_MAC_RENAME) | \
180+ F(CCS_MAC_CHMOD) | \
181+ F(CCS_MAC_CHOWN) | \
182+ F(CCS_MAC_CHGRP) | \
183+ F(CCS_MAC_IOCTL) | \
184+ F(CCS_MAC_CHROOT) | \
185+ F(CCS_MAC_MOUNT) | \
186+ F(CCS_MAC_UMOUNT) | \
187+ F(CCS_MAC_PIVOT_ROOT) | \
188+ F(CCS_MAC_INET_STREAM_BIND) | \
189+ F(CCS_MAC_INET_STREAM_LISTEN) | \
190+ F(CCS_MAC_INET_STREAM_CONNECT) | \
191+ F(CCS_MAC_INET_STREAM_ACCEPT) | \
192+ F(CCS_MAC_INET_DGRAM_BIND) | \
193+ F(CCS_MAC_INET_DGRAM_SEND) | \
194+ F(CCS_MAC_INET_DGRAM_RECV) | \
195+ F(CCS_MAC_INET_RAW_BIND) | \
196+ F(CCS_MAC_INET_RAW_SEND) | \
197+ F(CCS_MAC_INET_RAW_RECV) | \
198+ F(CCS_MAC_UNIX_STREAM_BIND) | \
199+ F(CCS_MAC_UNIX_STREAM_LISTEN) | \
200+ F(CCS_MAC_UNIX_STREAM_CONNECT) | \
201+ F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
202+ F(CCS_MAC_UNIX_DGRAM_BIND) | \
203+ F(CCS_MAC_UNIX_DGRAM_SEND) | \
204+ F(CCS_MAC_UNIX_DGRAM_RECV) | \
205+ F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
206+ F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
207+ F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
208+ F(CCS_MAC_UNIX_SEQPACKET_ACCEPT) | \
209+ F(CCS_MAC_ENVIRON) | \
210+ F(CCS_MAC_PTRACE) | \
211+ F(CCS_MAC_SIGNAL) | \
212+ F(CCS_MAC_MODIFY_POLICY) | \
213+ F(CCS_MAC_USE_NETLINK_SOCKET) | \
214+ F(CCS_MAC_USE_PACKET_SOCKET) | \
215+ F(CCS_MAC_USE_REBOOT) | \
216+ F(CCS_MAC_USE_VHANGUP) | \
217+ F(CCS_MAC_SET_TIME) | \
218+ F(CCS_MAC_SET_PRIORITY) | \
219+ F(CCS_MAC_SET_HOSTNAME) | \
220+ F(CCS_MAC_USE_KERNEL_MODULE) | \
221+ F(CCS_MAC_USE_NEW_KERNEL) | \
222+ F(CCS_MAC_AUTO_DOMAIN_TRANSITION) | \
223+ F(CCS_MAC_MANUAL_DOMAIN_TRANSITION))
224+
225+#define CCS_PATH_SELF_OK \
226+ (F(CCS_MAC_EXECUTE) | \
227+ F(CCS_MAC_READ) | \
228+ F(CCS_MAC_WRITE) | \
229+ F(CCS_MAC_APPEND) | \
230+ F(CCS_MAC_UNLINK) | \
231+ F(CCS_MAC_GETATTR) | \
232+ F(CCS_MAC_RMDIR) | \
233+ F(CCS_MAC_TRUNCATE) | \
234+ F(CCS_MAC_CHMOD) | \
235+ F(CCS_MAC_CHOWN) | \
236+ F(CCS_MAC_CHGRP) | \
237+ F(CCS_MAC_IOCTL) | \
238+ F(CCS_MAC_CHROOT) | \
239+ F(CCS_MAC_UMOUNT))
240+
241+#define CCS_PATH_PARENT_OK \
242+ (F(CCS_MAC_CREATE) | \
243+ F(CCS_MAC_MKDIR) | \
244+ F(CCS_MAC_MKFIFO) | \
245+ F(CCS_MAC_MKSOCK) | \
246+ F(CCS_MAC_SYMLINK) | \
247+ F(CCS_MAC_MKBLOCK) | \
248+ F(CCS_MAC_MKCHAR))
249+
250+#define CCS_PATH_OK (CCS_PATH_SELF_OK | CCS_PATH_PARENT_OK)
251+
252+#define CCS_RENAME_OR_LINK_OK (F(CCS_MAC_LINK) | F(CCS_MAC_RENAME))
253+
254+#define CCS_EXECUTE_OR_ENVIRON_OK (F(CCS_MAC_EXECUTE) | F(CCS_MAC_ENVIRON))
255+
256+#define CCS_MKDEV_OK (F(CCS_MAC_MKBLOCK) | F(CCS_MAC_MKCHAR))
257+
258+#define CCS_PATH_PERM_OK \
259+ (F(CCS_MAC_MKDIR) | \
260+ F(CCS_MAC_MKBLOCK) | \
261+ F(CCS_MAC_MKCHAR) | \
262+ F(CCS_MAC_MKFIFO) | \
263+ F(CCS_MAC_MKSOCK) | \
264+ F(CCS_MAC_CREATE) | \
265+ F(CCS_MAC_CHMOD))
266+
267+#define CCS_IP_SOCKET_OK \
268+ (F(CCS_MAC_INET_STREAM_BIND) | \
269+ F(CCS_MAC_INET_STREAM_LISTEN) | \
270+ F(CCS_MAC_INET_STREAM_CONNECT) | \
271+ F(CCS_MAC_INET_STREAM_ACCEPT) | \
272+ F(CCS_MAC_INET_DGRAM_BIND) | \
273+ F(CCS_MAC_INET_DGRAM_SEND) | \
274+ F(CCS_MAC_INET_DGRAM_RECV))
275+
276+#define CCS_RAW_SOCKET_OK \
277+ (F(CCS_MAC_INET_RAW_BIND) | \
278+ F(CCS_MAC_INET_RAW_SEND) | \
279+ F(CCS_MAC_INET_RAW_RECV))
280+
281+#define CCS_INET_SOCKET_OK (CCS_IP_SOCKET_OK | CCS_RAW_SOCKET_OK)
282+
283+#define CCS_UNIX_SOCKET_OK \
284+ (F(CCS_MAC_UNIX_STREAM_BIND) | \
285+ F(CCS_MAC_UNIX_STREAM_LISTEN) | \
286+ F(CCS_MAC_UNIX_STREAM_CONNECT) | \
287+ F(CCS_MAC_UNIX_STREAM_ACCEPT) | \
288+ F(CCS_MAC_UNIX_DGRAM_BIND) | \
289+ F(CCS_MAC_UNIX_DGRAM_SEND) | \
290+ F(CCS_MAC_UNIX_DGRAM_RECV) | \
291+ F(CCS_MAC_UNIX_SEQPACKET_BIND) | \
292+ F(CCS_MAC_UNIX_SEQPACKET_LISTEN) | \
293+ F(CCS_MAC_UNIX_SEQPACKET_CONNECT) | \
294+ F(CCS_MAC_UNIX_SEQPACKET_ACCEPT))
295+
296+enum ccs_var_type {
297+ CCS_TYPE_INVALID,
298+ CCS_TYPE_NUMBER,
299+ CCS_TYPE_STRING,
300+ CCS_TYPE_IPADDR,
301+ CCS_TYPE_FILEPERM,
302+ CCS_TYPE_FILETYPE,
303+ CCS_TYPE_TASKTYPE,
304+ CCS_TYPE_ASSIGN,
305+};
306+
307+static const struct {
308+ const char * const keyword;
309+ const enum ccs_var_type left_type;
310+ const enum ccs_var_type right_type;
311+ const unsigned long long available;
312+} ccs_conditions[] = {
313+ { "addr", CCS_TYPE_STRING, CCS_TYPE_STRING,
314+ CCS_UNIX_SOCKET_OK },
315+ { "argc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
316+ CCS_EXECUTE_OR_ENVIRON_OK },
317+ { "block", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
318+ CCS_ALL_OK },
319+ { "char", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
320+ CCS_ALL_OK },
321+ { "cmd", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
322+ F(CCS_MAC_IOCTL) | F(CCS_MAC_PTRACE) },
323+ { "data", CCS_TYPE_STRING, CCS_TYPE_STRING,
324+ F(CCS_MAC_MOUNT) },
325+ { "dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
326+ CCS_MKDEV_OK },
327+ { "dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
328+ CCS_MKDEV_OK },
329+ { "directory", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
330+ CCS_ALL_OK },
331+ { "domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
332+ F(CCS_MAC_PTRACE) | F(CCS_MAC_MANUAL_DOMAIN_TRANSITION) },
333+ { "envc", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
334+ CCS_EXECUTE_OR_ENVIRON_OK },
335+ { "exec", CCS_TYPE_STRING, CCS_TYPE_STRING,
336+ CCS_EXECUTE_OR_ENVIRON_OK },
337+ { "exec.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
338+ CCS_EXECUTE_OR_ENVIRON_OK },
339+ { "exec.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
340+ CCS_EXECUTE_OR_ENVIRON_OK },
341+ { "exec.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
342+ CCS_EXECUTE_OR_ENVIRON_OK },
343+ { "exec.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
344+ CCS_EXECUTE_OR_ENVIRON_OK },
345+ { "exec.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
346+ CCS_EXECUTE_OR_ENVIRON_OK },
347+ { "exec.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
348+ CCS_EXECUTE_OR_ENVIRON_OK },
349+ { "exec.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
350+ CCS_EXECUTE_OR_ENVIRON_OK },
351+ { "exec.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
352+ CCS_EXECUTE_OR_ENVIRON_OK },
353+ { "exec.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
354+ CCS_EXECUTE_OR_ENVIRON_OK },
355+ { "exec.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
356+ CCS_EXECUTE_OR_ENVIRON_OK },
357+ { "exec.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
358+ CCS_EXECUTE_OR_ENVIRON_OK },
359+ { "exec.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
360+ CCS_EXECUTE_OR_ENVIRON_OK },
361+ { "exec.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
362+ CCS_EXECUTE_OR_ENVIRON_OK },
363+ { "exec.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
364+ CCS_EXECUTE_OR_ENVIRON_OK },
365+ { "exec.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
366+ CCS_EXECUTE_OR_ENVIRON_OK },
367+ { "execute_handler", CCS_TYPE_INVALID, CCS_TYPE_TASKTYPE,
368+ CCS_ALL_OK },
369+ { "fifo", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
370+ CCS_ALL_OK },
371+ { "file", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
372+ CCS_ALL_OK },
373+ { "flags", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
374+ F(CCS_MAC_MOUNT) | F(CCS_MAC_UMOUNT) },
375+ { "fstype", CCS_TYPE_STRING, CCS_TYPE_STRING,
376+ F(CCS_MAC_MOUNT) },
377+ { "gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
378+ F(CCS_MAC_CHGRP) },
379+ { "group_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
380+ CCS_ALL_OK },
381+ { "group_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
382+ CCS_ALL_OK },
383+ { "group_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
384+ CCS_ALL_OK },
385+ { "handler", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
386+ F(CCS_MAC_EXECUTE) },
387+ { "ip", CCS_TYPE_IPADDR, CCS_TYPE_INVALID,
388+ CCS_INET_SOCKET_OK },
389+ { "name", CCS_TYPE_STRING, CCS_TYPE_STRING,
390+ F(CCS_MAC_ENVIRON) },
391+ { "new_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
392+ CCS_RENAME_OR_LINK_OK },
393+ { "new_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
394+ F(CCS_MAC_RENAME) },
395+ { "new_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
396+ F(CCS_MAC_RENAME) },
397+ { "new_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
398+ F(CCS_MAC_RENAME) },
399+ { "new_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
400+ F(CCS_MAC_RENAME) },
401+ { "new_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
402+ F(CCS_MAC_RENAME) },
403+ { "new_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
404+ F(CCS_MAC_RENAME) },
405+ { "new_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
406+ F(CCS_MAC_RENAME) },
407+ { "new_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
408+ CCS_RENAME_OR_LINK_OK },
409+ { "new_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
410+ CCS_RENAME_OR_LINK_OK },
411+ { "new_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
412+ CCS_RENAME_OR_LINK_OK },
413+ { "new_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
414+ CCS_RENAME_OR_LINK_OK },
415+ { "new_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
416+ CCS_RENAME_OR_LINK_OK },
417+ { "new_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
418+ CCS_RENAME_OR_LINK_OK },
419+ { "new_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
420+ CCS_RENAME_OR_LINK_OK },
421+ { "new_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
422+ F(CCS_MAC_RENAME) },
423+ { "new_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
424+ F(CCS_MAC_RENAME) },
425+ { "new_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
426+ F(CCS_MAC_RENAME) },
427+ { "new_root", CCS_TYPE_STRING, CCS_TYPE_STRING,
428+ F(CCS_MAC_PIVOT_ROOT) },
429+ { "new_root.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
430+ F(CCS_MAC_PIVOT_ROOT) },
431+ { "new_root.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
432+ F(CCS_MAC_PIVOT_ROOT) },
433+ { "new_root.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
434+ F(CCS_MAC_PIVOT_ROOT) },
435+ { "new_root.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
436+ F(CCS_MAC_PIVOT_ROOT) },
437+ { "new_root.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
438+ F(CCS_MAC_PIVOT_ROOT) },
439+ { "new_root.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
440+ F(CCS_MAC_PIVOT_ROOT) },
441+ { "new_root.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
442+ F(CCS_MAC_PIVOT_ROOT) },
443+ { "new_root.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
444+ F(CCS_MAC_PIVOT_ROOT) },
445+ { "new_root.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
446+ F(CCS_MAC_PIVOT_ROOT) },
447+ { "new_root.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
448+ F(CCS_MAC_PIVOT_ROOT) },
449+ { "new_root.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
450+ F(CCS_MAC_PIVOT_ROOT) },
451+ { "new_root.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
452+ F(CCS_MAC_PIVOT_ROOT) },
453+ { "new_root.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
454+ F(CCS_MAC_PIVOT_ROOT) },
455+ { "new_root.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
456+ F(CCS_MAC_PIVOT_ROOT) },
457+ { "new_root.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
458+ F(CCS_MAC_PIVOT_ROOT) },
459+ { "new_root.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
460+ F(CCS_MAC_PIVOT_ROOT) },
461+ { "new_root.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
462+ F(CCS_MAC_PIVOT_ROOT) },
463+ { "old_path", CCS_TYPE_STRING, CCS_TYPE_STRING,
464+ CCS_RENAME_OR_LINK_OK },
465+ { "old_path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
466+ CCS_RENAME_OR_LINK_OK },
467+ { "old_path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
468+ CCS_RENAME_OR_LINK_OK },
469+ { "old_path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
470+ CCS_RENAME_OR_LINK_OK },
471+ { "old_path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
472+ CCS_RENAME_OR_LINK_OK },
473+ { "old_path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
474+ CCS_RENAME_OR_LINK_OK },
475+ { "old_path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
476+ CCS_RENAME_OR_LINK_OK },
477+ { "old_path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
478+ CCS_RENAME_OR_LINK_OK },
479+ { "old_path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
480+ CCS_RENAME_OR_LINK_OK },
481+ { "old_path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
482+ CCS_RENAME_OR_LINK_OK },
483+ { "old_path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
484+ CCS_RENAME_OR_LINK_OK },
485+ { "old_path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
486+ CCS_RENAME_OR_LINK_OK },
487+ { "old_path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
488+ CCS_RENAME_OR_LINK_OK },
489+ { "old_path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
490+ CCS_RENAME_OR_LINK_OK },
491+ { "old_path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
492+ CCS_RENAME_OR_LINK_OK },
493+ { "old_path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
494+ CCS_RENAME_OR_LINK_OK },
495+ { "old_path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
496+ CCS_RENAME_OR_LINK_OK },
497+ { "old_path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
498+ CCS_RENAME_OR_LINK_OK },
499+ { "others_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
500+ CCS_ALL_OK },
501+ { "others_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
502+ CCS_ALL_OK },
503+ { "others_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
504+ CCS_ALL_OK },
505+ { "owner_execute", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
506+ CCS_ALL_OK },
507+ { "owner_read", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
508+ CCS_ALL_OK },
509+ { "owner_write", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
510+ CCS_ALL_OK },
511+ { "path", CCS_TYPE_STRING, CCS_TYPE_STRING,
512+ CCS_PATH_OK },
513+ { "path.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
514+ CCS_PATH_SELF_OK },
515+ { "path.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
516+ CCS_PATH_SELF_OK },
517+ { "path.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
518+ CCS_PATH_SELF_OK },
519+ { "path.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
520+ CCS_PATH_SELF_OK },
521+ { "path.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
522+ CCS_PATH_SELF_OK },
523+ { "path.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
524+ CCS_PATH_SELF_OK },
525+ { "path.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
526+ CCS_PATH_SELF_OK },
527+ { "path.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
528+ CCS_PATH_OK },
529+ { "path.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
530+ CCS_PATH_OK },
531+ { "path.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
532+ CCS_PATH_OK },
533+ { "path.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
534+ CCS_PATH_OK },
535+ { "path.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
536+ CCS_PATH_OK },
537+ { "path.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
538+ CCS_PATH_OK },
539+ { "path.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
540+ CCS_PATH_OK },
541+ { "path.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
542+ CCS_PATH_SELF_OK },
543+ { "path.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
544+ CCS_PATH_SELF_OK },
545+ { "path.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
546+ CCS_PATH_SELF_OK },
547+ { "perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
548+ CCS_PATH_PERM_OK },
549+ { "port", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
550+ CCS_IP_SOCKET_OK },
551+ { "proto", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
552+ CCS_RAW_SOCKET_OK },
553+ { "put_old", CCS_TYPE_STRING, CCS_TYPE_STRING,
554+ F(CCS_MAC_PIVOT_ROOT) },
555+ { "put_old.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
556+ F(CCS_MAC_PIVOT_ROOT) },
557+ { "put_old.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
558+ F(CCS_MAC_PIVOT_ROOT) },
559+ { "put_old.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
560+ F(CCS_MAC_PIVOT_ROOT) },
561+ { "put_old.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
562+ F(CCS_MAC_PIVOT_ROOT) },
563+ { "put_old.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
564+ F(CCS_MAC_PIVOT_ROOT) },
565+ { "put_old.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
566+ F(CCS_MAC_PIVOT_ROOT) },
567+ { "put_old.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
568+ F(CCS_MAC_PIVOT_ROOT) },
569+ { "put_old.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
570+ F(CCS_MAC_PIVOT_ROOT) },
571+ { "put_old.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
572+ F(CCS_MAC_PIVOT_ROOT) },
573+ { "put_old.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
574+ F(CCS_MAC_PIVOT_ROOT) },
575+ { "put_old.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
576+ F(CCS_MAC_PIVOT_ROOT) },
577+ { "put_old.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
578+ F(CCS_MAC_PIVOT_ROOT) },
579+ { "put_old.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
580+ F(CCS_MAC_PIVOT_ROOT) },
581+ { "put_old.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
582+ F(CCS_MAC_PIVOT_ROOT) },
583+ { "put_old.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
584+ F(CCS_MAC_PIVOT_ROOT) },
585+ { "put_old.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
586+ F(CCS_MAC_PIVOT_ROOT) },
587+ { "put_old.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
588+ F(CCS_MAC_PIVOT_ROOT) },
589+ { "setgid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
590+ CCS_ALL_OK },
591+ { "setuid", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
592+ CCS_ALL_OK },
593+ { "sig", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
594+ F(CCS_MAC_SIGNAL) },
595+ { "socket", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
596+ CCS_ALL_OK },
597+ { "source", CCS_TYPE_STRING, CCS_TYPE_STRING,
598+ F(CCS_MAC_MOUNT) },
599+ { "source.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
600+ F(CCS_MAC_MOUNT) },
601+ { "source.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
602+ F(CCS_MAC_MOUNT) },
603+ { "source.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
604+ F(CCS_MAC_MOUNT) },
605+ { "source.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
606+ F(CCS_MAC_MOUNT) },
607+ { "source.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
608+ F(CCS_MAC_MOUNT) },
609+ { "source.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
610+ F(CCS_MAC_MOUNT) },
611+ { "source.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
612+ F(CCS_MAC_MOUNT) },
613+ { "source.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
614+ F(CCS_MAC_MOUNT) },
615+ { "source.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
616+ F(CCS_MAC_MOUNT) },
617+ { "source.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
618+ F(CCS_MAC_MOUNT) },
619+ { "source.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
620+ F(CCS_MAC_MOUNT) },
621+ { "source.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
622+ F(CCS_MAC_MOUNT) },
623+ { "source.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
624+ F(CCS_MAC_MOUNT) },
625+ { "source.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
626+ F(CCS_MAC_MOUNT) },
627+ { "source.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
628+ F(CCS_MAC_MOUNT) },
629+ { "source.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
630+ F(CCS_MAC_MOUNT) },
631+ { "source.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
632+ F(CCS_MAC_MOUNT) },
633+ { "sticky", CCS_TYPE_INVALID, CCS_TYPE_FILEPERM,
634+ CCS_ALL_OK },
635+ { "symlink", CCS_TYPE_INVALID, CCS_TYPE_FILETYPE,
636+ CCS_ALL_OK },
637+ { "target", CCS_TYPE_STRING, CCS_TYPE_STRING,
638+ F(CCS_MAC_MOUNT) | F(CCS_MAC_SYMLINK) },
639+ { "target.dev_major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
640+ F(CCS_MAC_MOUNT) },
641+ { "target.dev_minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
642+ F(CCS_MAC_MOUNT) },
643+ { "target.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
644+ F(CCS_MAC_MOUNT) },
645+ { "target.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
646+ F(CCS_MAC_MOUNT) },
647+ { "target.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
648+ F(CCS_MAC_MOUNT) },
649+ { "target.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
650+ F(CCS_MAC_MOUNT) },
651+ { "target.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
652+ F(CCS_MAC_MOUNT) },
653+ { "target.parent.fsmagic", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
654+ F(CCS_MAC_MOUNT) },
655+ { "target.parent.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
656+ F(CCS_MAC_MOUNT) },
657+ { "target.parent.ino", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
658+ F(CCS_MAC_MOUNT) },
659+ { "target.parent.major", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
660+ F(CCS_MAC_MOUNT) },
661+ { "target.parent.minor", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
662+ F(CCS_MAC_MOUNT) },
663+ { "target.parent.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
664+ F(CCS_MAC_MOUNT) },
665+ { "target.parent.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
666+ F(CCS_MAC_MOUNT) },
667+ { "target.perm", CCS_TYPE_FILEPERM, CCS_TYPE_FILEPERM,
668+ F(CCS_MAC_MOUNT) },
669+ { "target.type", CCS_TYPE_FILETYPE, CCS_TYPE_FILETYPE,
670+ F(CCS_MAC_MOUNT) },
671+ { "target.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
672+ F(CCS_MAC_MOUNT) },
673+ { "task.domain", CCS_TYPE_STRING, CCS_TYPE_STRING,
674+ CCS_ALL_OK },
675+ { "task.egid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
676+ CCS_ALL_OK },
677+ { "task.euid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
678+ CCS_ALL_OK },
679+ { "task.exe", CCS_TYPE_STRING, CCS_TYPE_STRING,
680+ CCS_ALL_OK },
681+ { "task.fsgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
682+ CCS_ALL_OK },
683+ { "task.fsuid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
684+ CCS_ALL_OK },
685+ { "task.gid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
686+ CCS_ALL_OK },
687+ { "task.pid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
688+ CCS_ALL_OK },
689+ { "task.ppid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
690+ CCS_ALL_OK },
691+ { "task.sgid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
692+ CCS_ALL_OK },
693+ { "task.suid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
694+ CCS_ALL_OK },
695+ { "task.type", CCS_TYPE_TASKTYPE, CCS_TYPE_INVALID,
696+ CCS_ALL_OK },
697+ { "task.uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
698+ CCS_ALL_OK },
699+ { "transition", CCS_TYPE_ASSIGN, CCS_TYPE_INVALID,
700+ F(CCS_MAC_EXECUTE) | F(CCS_MAC_AUTO_DOMAIN_TRANSITION) },
701+ { "uid", CCS_TYPE_NUMBER, CCS_TYPE_NUMBER,
702+ F(CCS_MAC_CHOWN) },
703+ { "value", CCS_TYPE_STRING, CCS_TYPE_STRING,
704+ F(CCS_MAC_ENVIRON) },
705+ { "argv[0]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
706+ CCS_EXECUTE_OR_ENVIRON_OK },
707+ { "argv[4294967295]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
708+ CCS_EXECUTE_OR_ENVIRON_OK },
709+ { "envp[\"PATH\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
710+ CCS_EXECUTE_OR_ENVIRON_OK },
711+ { "envp[\"\\*\"]", CCS_TYPE_STRING, CCS_TYPE_INVALID,
712+ CCS_EXECUTE_OR_ENVIRON_OK },
713+ { "NULL", CCS_TYPE_INVALID, CCS_TYPE_STRING,
714+ CCS_ALL_OK },
715+ { "\"word\"", CCS_TYPE_INVALID, CCS_TYPE_ASSIGN,
716+ CCS_ALL_OK },
717+ { "\"/\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
718+ CCS_ALL_OK },
719+ { "\"/\\*\"", CCS_TYPE_INVALID, CCS_TYPE_STRING,
720+ CCS_ALL_OK },
721+ { "@STRING_GROUP", CCS_TYPE_INVALID, CCS_TYPE_STRING,
722+ CCS_ALL_OK },
723+ { "0", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
724+ CCS_ALL_OK },
725+ { "0-4294967295", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
726+ CCS_ALL_OK },
727+ { "@NUMBER_GROUP", CCS_TYPE_INVALID, CCS_TYPE_NUMBER,
728+ CCS_ALL_OK },
729+ { "127.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
730+ CCS_ALL_OK },
731+ { "0.0.0.0-0.0.0.1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
732+ CCS_ALL_OK },
733+ { "::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
734+ CCS_ALL_OK },
735+ { "::-::1", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
736+ CCS_ALL_OK },
737+ { "@IP_GROUP", CCS_TYPE_INVALID, CCS_TYPE_IPADDR,
738+ CCS_ALL_OK },
739+};
740+
741+static char *policy = NULL;
742+static int policy_len = 0;
743+
744+static inline void truncate_policy(void)
745+{
746+ policy_len = 0;
747+}
748+
749+static void add_policy(const char *data)
750+{
751+ const int len = strlen(data);
752+ char *tmp = realloc(policy, policy_len + len + 1);
753+ if (!tmp) {
754+ fprintf(stderr, "Out of memory\n");
755+ exit(1);
756+ }
757+ policy = tmp;
758+ memmove(policy + policy_len, data, len + 1);
759+ policy_len += len;
760+}
761+
762+static unsigned int tests_now = 0;
763+
764+static void check_policy_written(const _Bool valid)
765+{
766+ int fd1 = open("/proc/caitsith/policy", O_RDWR);
767+ int fd2 = open("/proc/caitsith/policy", O_RDWR);
768+ int len = strlen(policy);
769+ int ret;
770+ char *buffer;
771+ if (fd1 == EOF || fd2 == EOF) {
772+ printf("%s", policy);
773+ return;
774+ }
775+ ret = write(fd1, policy, len);
776+ if (ret != len) {
777+ fprintf(stderr, "Write error (%d, %d)\n", ret, len);
778+ exit(1);
779+ }
780+ buffer = calloc(len + 4096, 1);
781+ if (!buffer) {
782+ fprintf(stderr, "Out of memory\n");
783+ exit(1);
784+ }
785+ ret = read(fd1, buffer, len + 4095);
786+ if (!strstr(buffer, policy) != !valid) {
787+ fprintf(stderr, "Test %u: FAILED(add) '%s' : '%s' valid=%u\n",
788+ tests_now - 1, buffer, policy, valid);
789+ exit(1);
790+ }
791+ printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
792+ if (write(fd2, "delete ", 7) != 7 || write(fd2, policy, len) != len) {
793+ fprintf(stderr, "Write error\n");
794+ exit(1);
795+ }
796+ memset(buffer, 0, len + 1024);
797+ ret = read(fd2, buffer, len + 1023);
798+ if (strstr(buffer, policy)) {
799+ fprintf(stderr, "Test %u: FAILED(remove) '%s' : '%s'\n",
800+ tests_now - 1, buffer, policy);
801+ exit(1);
802+ }
803+ printf("Test %u: OK '%s' : '%s'\n", tests_now - 1, buffer, policy);
804+ free(buffer);
805+ close(fd1);
806+ close(fd2);
807+}
808+
809+static inline void add_policy2(const char *data1, const char *data2)
810+{
811+ add_policy(data1);
812+ add_policy(data2);
813+}
814+
815+static inline void add_policy3(const char *data1, const char *data2,
816+ const char *data3)
817+{
818+ add_policy(data1);
819+ add_policy(data2);
820+ add_policy(data3);
821+}
822+
823+static _Bool adjust_exception(const int mac, const int p1, const int p2)
824+{
825+ if (ccs_conditions[p1].left_type == CCS_TYPE_ASSIGN)
826+ return !strcmp(ccs_conditions[p2].keyword, "NULL") ||
827+ !strcmp(ccs_conditions[p2].keyword,"\"/\"");
828+ if (ccs_conditions[p2].keyword[0] == '@')
829+ return ccs_conditions[p1].left_type == CCS_TYPE_STRING ||
830+ ccs_conditions[p1].left_type == CCS_TYPE_NUMBER ||
831+ ccs_conditions[p1].left_type == CCS_TYPE_IPADDR ||
832+ ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM;
833+ if (ccs_conditions[p1].left_type == CCS_TYPE_STRING)
834+ return !strcmp(ccs_conditions[p2].keyword, "\"word\"");
835+ if (ccs_conditions[p1].left_type == CCS_TYPE_FILEPERM &&
836+ ccs_conditions[p2].right_type == CCS_TYPE_NUMBER)
837+ return 1;
838+ return 0;
839+}
840+
841+static unsigned int tests_start = 0;
842+
843+static void check_righthand(const int mac, const int p1, const _Bool org_valid)
844+{
845+ int p2;
846+ const enum ccs_var_type type = ccs_conditions[p1].left_type;
847+ for (p2 = 0; p2 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
848+ p2++) {
849+ _Bool valid = org_valid;
850+ if (tests_now++ < tests_start)
851+ continue;
852+ if (valid) {
853+ if (!(ccs_conditions[p2].available & F(mac)))
854+ valid = 0;
855+ else if (ccs_conditions[p2].right_type != type)
856+ valid = adjust_exception(mac, p1, p2);
857+ }
858+ truncate_policy();
859+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
860+ " audit 0\n 0 allow");
861+ add_policy2(" ", ccs_conditions[p1].keyword);
862+ add_policy2("=", ccs_conditions[p2].keyword);
863+ if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
864+ strcmp(ccs_conditions[p1].keyword, "transition"))
865+ add_policy(" transition=\"word\"");
866+ add_policy("\n");
867+ check_policy_written(valid);
868+ if (type == CCS_TYPE_ASSIGN)
869+ valid = 0;
870+ truncate_policy();
871+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
872+ " audit 0\n 0 allow");
873+ add_policy2(" ", ccs_conditions[p1].keyword);
874+ add_policy2("!=", ccs_conditions[p2].keyword);
875+ if (mac == CCS_MAC_AUTO_DOMAIN_TRANSITION &&
876+ strcmp(ccs_conditions[p1].keyword, "transition"))
877+ add_policy(" transition=\"word\"");
878+ add_policy("\n");
879+ check_policy_written(valid);
880+ {
881+ static time_t last = 0;
882+ time_t now = time(NULL);
883+ if (now - last >= (time_t) 10) {
884+ last = now;
885+ fprintf(stderr, "Test %u passed\n",
886+ tests_now - 1);
887+ }
888+ }
889+ }
890+}
891+
892+int main(int argc, char *argv[]) {
893+ int mac;
894+ if (argc > 1)
895+ tests_start = atoi(argv[1]);
896+ for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
897+ truncate_policy();
898+ add_policy3("0 acl ", ccs_mac_keywords[mac], "\n"
899+ " audit 0\n");
900+ check_policy_written(1);
901+ }
902+ for (mac = 0; mac < CCS_MAX_MAC_INDEX; mac++) {
903+ int p1;
904+ for (p1 = 0;
905+ p1 < sizeof(ccs_conditions) / sizeof(ccs_conditions[0]);
906+ p1++) {
907+ _Bool valid = 1;
908+ if (ccs_conditions[p1].left_type == CCS_TYPE_INVALID ||
909+ !(ccs_conditions[p1].available & F(mac)))
910+ valid = 0;
911+ check_righthand(mac, p1, valid);
912+ }
913+ }
914+ fprintf(stderr, "Test %u passed\n", tests_now - 1);
915+ return 0;
916+}
--- trunk/caitsith-tools/kernel_test/Makefile (revision 75)
+++ trunk/caitsith-tools/kernel_test/Makefile (revision 76)
@@ -1,4 +1,4 @@
1-ALL_FILES = caitsith_param_test caitsith_log_test caitsith-parser-test
1+ALL_FILES = caitsith_param_test caitsith_log_test caitsith_parser_test caitsith_audit2cond_test
22
33 all: $(ALL_FILES)
44
旧リポジトリブラウザで表示