(メッセージはありません)
@@ -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 | -} |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | +} |
@@ -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 | |
2 | 2 | |
3 | 3 | all: $(ALL_FILES) |
4 | 4 |