Develop and Download Open Source Software

Browse Subversion Repository

Contents of /tags/htdocs/index.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 387 - (show annotations) (download) (as text)
Mon Dec 25 14:08:19 2023 UTC (3 months, 2 weeks ago) by kumaneko
File MIME type: text/html
File size: 186325 byte(s)


1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html lang="en-US">
3 <head>
4 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
5 <meta http-equiv="content-style-type" content="text/css">
6 <link rel="stylesheet" href="media/caitsith.css" media="all" type="text/css">
7 <title>CaitSith Documentation</title>
8 </head>
9 <body>
10
11 <h1>CaitSith -- A simplified access restriction module for system protection.</h1>
12
13 <p>CaitSith is an access restriction module for Linux systems. This module gives you ability to restrict access (e.g. opening files, executing programs) at the kernel level. This module is designed for ease of use.</p>
14
15 <hr>
16 <h2><a name="index">Index</a></h2>
17
18 <p><a href="#difference_with_tomoyo">1. Difference with TOMOYO (for existing TOMOYO users)</a></p>
19
20 <ul>
21 <li><a href="#1.1">1.1. About pathnames and management programs</a></li>
22 <li><a href="#1.2">1.2. About policy syntax</a></li>
23 <li><a href="#1.3">1.3. Why CaitSith was developed</a></li>
24 </ul>
25
26 <p><a href="#how_to_install">2. How to install</a></p>
27
28 <ul>
29 <li><a href="#2.1">2.1 How to install LKM-based LSM version</a><br>
30 <ul>
31 <li><a href="#2.1.1">2.1.1. Install dependencies</a></li>
32 <li><a href="#2.1.2">2.1.2. Extract source code</a></li>
33 <li><a href="#2.1.3">2.1.3. Edit build options</a></li>
34 <li><a href="#2.1.4">2.1.4. Compile and install the kernel module</a></li>
35 <li><a href="#2.1.5">2.1.5. Check whether CaitSith kernel module can be loaded or not (Optional)</a>
36 <li><a href="#2.1.6">2.1.6. Install the userspace tools</a></li>
37 <li><a href="#2.1.7">2.1.7. Initializing configuration</a></li>
38 <li><a href="#2.1.8">2.1.8. Configuring your bootloader</a></li>
39 <li><a href="#2.1.9">2.1.9. Rebooting your system</a></li>
40 <li><a href="#2.1.10">2.1.10. How can I disable/uninstall CaitSith?</a></li>
41 </ul>
42 </li>
43 <li><a href="#2.2">2.2. How to install fully featured version</a><br>
44 <ul>
45 <li><a href="#2.2.1">2.2.1. Install dependencies</a></li>
46 <li><a href="#2.2.2">2.2.2. Download and patch the kernel</a></li>
47 <li><a href="#2.2.3">2.2.3. Configure the kernel</a></li>
48 <li><a href="#2.2.4">2.2.4. Compile and install the kernel</a></li>
49 <li><a href="#2.2.5">2.2.5. Install the userspace tools</a></li>
50 <li><a href="#2.2.6">2.2.6. Initializing configuration</a></li>
51 <li><a href="#2.2.7">2.2.7. Configuring your bootloader</a></li>
52 <li><a href="#2.2.8">2.2.8. Rebooting your system</a></li>
53 <li><a href="#2.2.9">2.2.9. How can I disable/uninstall CaitSith?</a></li>
54 </ul>
55 </li>
56 </ul>
57
58 <p><a href="#how_to_develop_policy">3. How to develop policy</a></p>
59
60 <ul>
61 <li><a href="#3.1">3.1. Policy file structure</a></li>
62 <li><a href="#3.2">3.2. Updating policy configuration</a></li>
63 <li><a href="#3.3">3.3. Example of simple access restriction rule</a></li>
64 <li><a href="#3.4">3.4. Understanding two viewpoints</a></li>
65 <li><a href="#3.5">3.5. Steps for writing access restriction rules</a></li>
66 <li><a href="#3.6">3.6. Restricting access in various ways</a></li>
67 </ul>
68
69 <p><a href="#condition_list">4. List of conditions</a></p>
70
71 <ul>
72 <li><a href="#4.1">4.1. Using string arguments in conditions</a></li>
73 <li><a href="#4.2">4.2. Using numeric arguments in conditions</a></li>
74 <li><a href="#4.3">4.3. Using process's information in conditions</a></li>
75 <li><a href="#4.4">4.4. Using IP address arguments in conditions</a></li>
76 <li><a href="#4.5">4.5. Using command line arguments in conditions</a></li>
77 <li><a href="#4.6">4.6. Using environment variable arguments in conditions</a></li>
78 <li><a href="#4.7">4.7. Using file's DAC permissions in conditions</a></li>
79 <li><a href="#4.8">4.8. Using handle file's type in conditions</a></li>
80 <li><a href="#4.9">4.9. Using file's attributes in conditions</a></li>
81 </ul>
82
83 <p><a href="#syntax_list">5. List of syntaxes</a></p>
84
85 <ul>
86 <li><a href="#5.1">5.1. execute</a></li>
87 <li><a href="#5.2">5.2. read</a></li>
88 <li><a href="#5.3">5.3. write</a></li>
89 <li><a href="#5.4">5.4. append</a></li>
90 <li><a href="#5.5">5.5. create</a></li>
91 <li><a href="#5.6">5.6. unlink</a></li>
92 <li><a href="#5.7">5.7. getattr</a></li>
93 <li><a href="#5.8">5.8. mkdir</a></li>
94 <li><a href="#5.9">5.9. rmdir</a></li>
95 <li><a href="#5.10">5.10. mkfifo</a></li>
96 <li><a href="#5.11">5.11. mksock</a></li>
97 <li><a href="#5.12">5.12. truncate</a></li>
98 <li><a href="#5.13">5.13. symlink</a></li>
99 <li><a href="#5.14">5.14. mkblock</a></li>
100 <li><a href="#5.15">5.15. mkchar</a></li>
101 <li><a href="#5.16">5.16. link</a></li>
102 <li><a href="#5.17">5.17. rename</a></li>
103 <li><a href="#5.18">5.18. chmod</a></li>
104 <li><a href="#5.19">5.19. chown</a></li>
105 <li><a href="#5.20">5.20. chgrp</a></li>
106 <li><a href="#5.21">5.21. ioctl</a></li>
107 <li><a href="#5.22">5.22. chroot</a></li>
108 <li><a href="#5.23">5.23. mount</a></li>
109 <li><a href="#5.24">5.24. unmount</a></li>
110 <li><a href="#5.25">5.25. pivot_root</a></li>
111 <li><a href="#5.26">5.26. inet_stream_bind</a></li>
112 <li><a href="#5.27">5.27. inet_stream_listen</a></li>
113 <li><a href="#5.28">5.28. inet_stream_connect</a></li>
114 <li><a href="#5.29">5.29. inet_stream_accept</a></li>
115 <li><a href="#5.30">5.30. inet_dgram_bind</a></li>
116 <li><a href="#5.31">5.31. inet_dgram_send</a></li>
117 <li><a href="#5.32">5.32. inet_dgram_recv</a></li>
118 <li><a href="#5.33">5.33. inet_raw_bind</a></li>
119 <li><a href="#5.34">5.34. inet_raw_send</a></li>
120 <li><a href="#5.35">5.35. inet_raw_recv</a></li>
121 <li><a href="#5.36">5.36. unix_stream_bind</a></li>
122 <li><a href="#5.37">5.37. unix_stream_listen</a></li>
123 <li><a href="#5.38">5.38. unix_stream_connect</a></li>
124 <li><a href="#5.39">5.39. unix_stream_accept</a></li>
125 <li><a href="#5.40">5.40. unix_dgram_bind</a></li>
126 <li><a href="#5.41">5.41. unix_dgram_send</a></li>
127 <li><a href="#5.42">5.42. unix_dgram_recv</a></li>
128 <li><a href="#5.43">5.43. unix_seqpacket_bind</a></li>
129 <li><a href="#5.44">5.44. unix_seqpacket_listen</a></li>
130 <li><a href="#5.45">5.45. unix_seqpacket_connect</a></li>
131 <li><a href="#5.46">5.46. unix_seqpacket_accept</a></li>
132 <li><a href="#5.47">5.47. ptrace</a></li>
133 <li><a href="#5.48">5.48. signal</a></li>
134 <li><a href="#5.49">5.49. environ</a></li>
135 <li><a href="#5.50">5.50. modify_policy</a></li>
136 <li><a href="#5.51">5.51. use_netlink_socket</a></li>
137 <li><a href="#5.52">5.52. use_packet_socket</a></li>
138 <li><a href="#5.53">5.53. use_reboot</a></li>
139 <li><a href="#5.54">5.54. use_vhangup</a></li>
140 <li><a href="#5.55">5.55. set_time</a></li>
141 <li><a href="#5.56">5.56. set_priority</a></li>
142 <li><a href="#5.57">5.57. set_hostname</a></li>
143 <li><a href="#5.58">5.58. use_kernel_module</a></li>
144 <li><a href="#5.59">5.59. use_new_kernel</a></li>
145 <li><a href="#5.60">5.60. manual_domain_transition</a></li>
146 <li><a href="#5.61">5.61. auto_domain_transition</a></li>
147 </ul>
148
149 <p><a href="#advanced_usage">6. Advanced usage</a></p>
150 <ul>
151 <li><a href="#6.1">6.1. Controlling domain transition</a></li>
152 <li><a href="#6.2">6.2. Using execute handler</a></li>
153 </ul>
154
155 <hr>
156 <h2><a name="difference_with_tomoyo">1. Difference with TOMOYO (for existing TOMOYO users)</a></h2>
157
158 <p>CaitSith was derived from TOMOYO Linux, but usage of CaitSith would be too different to imagine that CaitSith was derived from TOMOYO Linux. If you are already using TOMOYO Linux, please read the difference described below.</p>
159
160 <hr>
161 <h3><a name="1.1">1.1. About pathnames and management programs</a></h3>
162
163 <p>/proc/ccs/domain_policy , /proc/ccs/exception_policy , /proc/ccs/profile , /proc/ccs/manager and /proc/ccs/stat have been aggregated into /sys/kernel/security/caitsith/policy .</p>
164
165 <p>/etc/ccs/policy/current/domain_policy.conf , /etc/ccs/policy/current/exception_policy.conf , /etc/ccs/policy/current/profile.conf , /etc/ccs/policy/current/manager.conf and /etc/ccs/policy/current/stat.conf have been aggregated into /etc/caitsith/policy/current .</p>
166
167 <p>Built-in policy files which are located under kernel source directory as security/ccsecurity/policy/domain_policy.conf , security/ccsecurity/policy/exception_policy.conf , security/ccsecurity/policy/profile.conf , security/ccsecurity/policy/manager.conf and security/ccsecurity/policy/stat.conf have been aggregated into security/caitsith/policy/policy.conf .</p>
168
169 <p>Only /sbin/caitsith-init , /usr/sbin/caitsith-auditd , /usr/sbin/caitsith-loadpolicy , /usr/sbin/caitsith-notifyd , /usr/sbin/caitsith-pstree , /usr/sbin/caitsith-queryd , /usr/sbin/caitsith-savepolicy , /usr/lib64/caitsith/audit-exec-param , /usr/lib64/caitsith/caitsith-agent and /usr/lib64/caitsith/init_policy are provided for managing policy. (In other words, programs such as /usr/sbin/ccs-editpolicy and /usr/sbin/ccs-setprofile have been removed.)</p>
170
171 <p>Command line arguments for specifying type of policy to load/save have been removed from /usr/sbin/caitsith-loadpolicy and /usr/sbin/caitsith-savepolicy .</p>
172
173 <p>Command line arguments for specifying profile type have been removed from /usr/lib64/caitsith/init_policy .</p>
174
175 <hr>
176 <h3><a name="1.2">1.2. About policy syntax</a></h3>
177
178 <p>Policy syntax has been drastically changed. TOMOYO Linux uses process's domainname as a key for grouping permissions to do some operations. In other words, TOMOYO Linux's policy is collection of "which domain can do ..." rules. On the other hand, CaitSith uses operation as a key for checking permission. In other words, CaitSith's policy is collection of "which operation can be done by ..." rules. This change is intended for allowing users to protect resources using denylisting approach. In CaitSith, process's domainname is nothing but one of optional parameters that can be used for controlling whether to allow or deny specific operations. Users can write rules without managing domainnames unless needed.</p>
179
180 <p>Process's domainname representation has changed from space delimited multiple words (e.g. "&lt;kernel&gt; /sbin/init /etc/rc.d/rc.sysinit") to a single word (e.g. "/sbin/init").</p>
181
182 <p>Domain transitions no longer happen unless explicitly specified by policy.</p>
183
184 <p>Distinction of disabled/learning/permissive/enforcing mode has been removed.</p>
185
186 <p>"path_group" keyword has been renamed to "string_group", and "address_group" keyword has been renamed to "ip_group".</p>
187
188 <p>Representation of \ character has been changed from \\ to \134.</p>
189
190 <p>Distinction between directory's pathname and non-directory's pathname has been removed by removing trailing / character from pathname.</p>
191
192 <p>A new wildcard /\(dir\)/ has been introduced for helping converting from (e.g.) "/tmp/\{\*\}/" to "/tmp/\(\*\)/\*", for directory's pathname (except the root directory itself) no longer ends with / character which previously matched /\{\*\}/ wildcard.</p>
193
194 <p>Category keywords (i.e. "file", "network", "ipc", "misc", "capability", "task") have been removed because access control levels which was specified using profile has been removed. Some of operation keywords have been renamed (e.g. "network inet stream connect" became "inet_stream_connect", "misc env" became "environ").</p>
195
196 <p>"task auto_execute_handler" keyword has been renamed to "handler=" argument of "execute" keyword. This is intended for using execute handler for preprocessing purpose when executing specific programs rather than when executing from specific domains. "task denied_execute_handler" keyword has been removed.</p>
197
198 <p>Domain argument has been removed from permission to send signals (i.e. "signal" directive), for kill() system call accepts negative number for specifying multiple processes. It is impossible to selectively deny sending signals because it is not permitted to sleep while sending signals.</p>
199
200 <p>Restriction granularity for ptrace operation has changed from boolean (i.e. "capability SYS_PTRACE") to command number + domainname.</p>
201
202 <p>Restriction granularity for environment variables has changed from name only to both name and values.</p>
203
204 <p>Several variables for referencing file's attributes have been added.</p>
205
206 <p>Local port reserve functionality (i.e. "deny_autobind" keyword) has been removed.</p>
207
208 <hr>
209 <h3><a name="1.3">1.3. Why CaitSith was developed?</a></h3>
210
211 <p>Presentation slides which I used at LinuxCon North America 2012 that explain why CaitSith was developed are available.</p>
212
213 <ul>
214 <li><a href="https://I-love.SAKURA.ne.jp/tomoyo/CaitSith-en.pdf">English</a></li>
215 <li><a href="https://I-love.SAKURA.ne.jp/tomoyo/CaitSith-ja.pdf">Japanese</a></li>
216 </ul>
217
218 <hr>
219 <h2><a name="how_to_install">2. How to install</a></h2>
220
221 <p>CaitSith supports Linux kernel 2.6.27 and later.</p>
222
223 <p>There are two ways to compile CaitSith kernel module. Please choose one, but please accept that you need to choose <a href="#2.2">fully featured version</a> if you can't choose <a href="#2.1">LKM-based LSM version</a>.</p>
224
225 <table border="1">
226 <tr><td></td><td><a href="#2.1">LKM-based LSM version</a></td><td><a href="#2.2">fully featured version</a></td></tr>
227 <tr><td>Advantages</td><td>No need to replace kernel package.</td><td>Complete functionality and syntax are supported.</td></tr>
228 <tr><td>Disadvantages</td><td>Supported functionality and syntax depend on kernel's version and kernel's configuration options.</td><td>Need to replace kernel package.</td></tr>
229 <tr><td>Dependency</td><td>
230 Kernel package must be built with below configuration options.<br>
231 <ul>
232 <li>CONFIG_SECURITY=y</li>
233 <li>CONFIG_KALLSYMS=y</li>
234 <li>CONFIG_PROC_FS=y</li>
235 <li>CONFIG_MODULES=y</li>
236 </ul>
237 The kernel package should be built with below configuration options in addition to above configuration options for supporting further functionality.<br>
238 <ul>
239 <li>CONFIG_SECURITY_NETWORK=y</li>
240 <li>CONFIG_SECURITY_PATH=y</li>
241 </ul>
242 Currently known to work on x86_32 x86_64 SH and ARM. Other architectures are not tested yet.
243 </td><td>
244 Requires patching against kernel's source and rebuilding from source.
245 </td></tr>
246 </table>
247
248 <hr>
249 <h2><a name="2.1">2.1. How to install LKM-based LSM version</a></h2>
250
251 <hr>
252 <h3><a name="2.1.1">2.1.1. Install dependencies</a></h3>
253
254 <p>These packages are required for compiling the kernel module and the userspace tools:</p>
255
256 <ul>
257 <li><strong>wget</strong>: to download sources</li>
258 <li><strong>gcc</strong>: to build the module and tools</li>
259 <li><strong>make</strong>: to build the module and tools</li>
260 <li><strong>ncurses-devel</strong> or <strong>libncurses-dev</strong>: to build the tools</li>
261 </ul>
262
263 <p>These can be installed with the following commands:</p>
264
265 <p><strong>RedHat distributions</strong></p>
266 <pre class="command">
267 # yum -y install wget gcc make ncurses-devel
268 </pre>
269 <p><strong>Debian distributions</strong></p>
270 <pre class="command">
271 # apt-get -y install wget gcc make libncurses-dev
272 </pre>
273 <p><strong>SUSE distributions</strong></p>
274 <pre class="command">
275 # yast -i wget gcc make ncurses-devel
276 </pre>
277
278 <hr>
279 <h3><a name="2.1.2">2.1.2. Extract source code</a></h3>
280
281 <p>Install the kernel development package and go to the directory that it has installed into:</p>
282
283 <p><strong>RedHat distributions</strong></p>
284 <pre class="command">
285 # VERSION=$(uname -r)
286 # yum -y install kernel-devel-${VERSION}
287 # cd /usr/src/kernels/${VERSION}*/
288 </pre>
289
290 <p><strong>Debian distributions</strong></p>
291 <pre class="command">
292 # VERSION=$(uname -r)
293 # apt-get -y install linux-headers-${VERSION}
294 # cd /usr/src/linux-headers-${VERSION}/
295 </pre>
296
297 <p><strong>SUSE distributions</strong></p>
298 <pre class="command">
299 # VERSION=$(uname -r)
300 # yast -i kernel-devel
301 # cd /lib/modules/${VERSION}/build/
302 </pre>
303
304 <p>Run the following commands in order to extract source code of CaitSith:</p>
305
306 <pre class="command">
307 # wget -O caitsith-patch-0.2-20231225.tar.gz 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66537/caitsith-patch-0.2-20231225.tar.gz'
308 # wget -O caitsith-patch-0.2-20231225.tar.gz.asc 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66537/caitsith-patch-0.2-20231225.tar.gz.asc'
309 # wget https://tomoyo.osdn.jp/kumaneko-key
310 # gpg --import kumaneko-key
311 # gpg caitsith-patch-0.2-20231225.tar.gz.asc
312 # tar -zxf caitsith-patch-0.2-20231225.tar.gz
313 </pre>
314
315 <hr>
316 <h3><a name="2.1.3">2.1.3. Edit build options</a></h3>
317
318 <h4><a name="2.1.3.1">2.1.3.1. Changing activation trigger</a></h3>
319
320 <p>On systemd environments, /usr/lib/systemd/systemd will be executed rather than /sbin/init . If your system is using systemd, please edit CONFIG_CAITSITH_ACTIVATION_TRIGGER line in caitsith/config.h like below unless you choose <a href="#2.1.8.2">Loading CaitSith's module from the init process</a>:</p>
321
322 <p>Before:</p>
323 <pre>#define CONFIG_CAITSITH_ACTIVATION_TRIGGER "/sbin/init"
324 </pre>
325
326 <p>After:</p>
327 <pre>#define CONFIG_CAITSITH_ACTIVATION_TRIGGER "/usr/lib/systemd/systemd"
328 </pre>
329
330 <h4><a name="2.1.3.2">2.1.3.2. Omitting userspace policy loader</a></h3>
331
332 <p>There are two types of CaitSith's policy configuration. The former is embedded into the kernel and the latter is saved as files on the filesystems (e.g. /etc/caitsith/ directory). You will need to rebuild the CaitSith kernel module whenever updating the former, but allows you to load policy without using userspace policy loader (e.g. /sbin/caitsith-init ). The latter is loaded by executing userspace policy loader when the access control by CaitSith is about to be activated (e.g. when /sbin/init or /usr/lib/systemd/systemd starts).</p>
333
334 <p>If you want to activate CaitSith as soon as the kernel module is loaded, you can define CONFIG_CAITSITH_OMIT_USERSPACE_LOADER line in caitsith/config.h like below. (But be sure to supply built-in policy configuration located at caitsith/policy/ directory if you define CONFIG_CAITSITH_OMIT_USERSPACE_LOADER, or the system will panic as soon as the kernel module is loaded.):</p>
335
336 <p>Before:</p>
337 <pre>//#define CONFIG_CAITSITH_OMIT_USERSPACE_LOADER
338 </pre>
339
340 <p>After:</p>
341 <pre
342 >#define CONFIG_CAITSITH_OMIT_USERSPACE_LOADER
343 </pre>
344
345 <hr>
346 <h3><a name="2.1.4">2.1.4. Compile and install the kernel module</a></h3>
347
348 <p>Run the following commands in order to build and install CaitSith:</p>
349
350 <pre class="command">
351 # make SUBDIRS=$PWD/caitsith modules
352 # make SUBDIRS=$PWD/caitsith modules_install
353 # depmod ${VERSION}
354 </pre>
355
356 <p>If you encountered one of errors listed below, you cannot use CaitSith for your kernel. Please jump to <a href="#2.2">2.2. How to install fully featured version</a>.
357 For other errors, please contact the author ( penguin-kernel@I-love.SAKURA.ne.jp ).</p>
358
359 <pre class="output">
360 You must choose CONFIG_SECURITY=y for building this module.
361 You must choose CONFIG_KALLSYMS=y for building this module.
362 You must choose CONFIG_PROC_FS=y for building this module.
363 You must choose CONFIG_MODULES=y for building this module.
364 </pre>
365
366 <hr>
367 <h3><a name="2.1.5">2.1.5. Check whether CaitSith kernel module can be loaded or not (Optional)</a></h3>
368
369 <p>Since registering CaitSith module depends on your environment, you might encounter problems. Therefore, I recommend you to confirm that CaitSith module can be loaded at this step.</p>
370
371 <p>Run the following commands in order to try to load caitsith_test.ko module:</p>
372
373 <pre class="command">
374 # dmesg -c &gt; /dev/null
375 # modprobe caitsith_test
376 # dmesg
377 </pre>
378 <pre class="output">
379 caitsith_test: module verification failed: signature and/or required key missing - tainting kernel
380 security_ops=ffffffff81df6c80
381 find_task_by_vpid=ffffffff810821a0
382 find_task_by_pid_ns=ffffffff81082170
383 d_absolute_path=ffffffff811c8f10
384 All dependent symbols have been guessed.
385 Please verify these addresses using System.map for this kernel (e.g. /boot/System.map-`uname -r` ).
386 If these addresses are correct, you can try loading CaitSith module on this kernel.
387 </pre>
388
389 <p>If caitsith_test.ko was loaded successfully, guessed addresses like above are printed. Therefore, please compare guessed addresses from caitsith_test.ko and actual addresses from System.map file. (Number of symbols and addresses printed depends on your environment.):</p>
390
391 <pre class="command">
392 # for i in ffffffff81df6c80 ffffffff810821a0 ffffffff81082170 ffffffff811c8f10; do grep $i /boot/System.map-${VERSION}; done
393 </pre>
394 <pre class="output">
395 ffffffff81df6c80 b security_ops
396 ffffffff810821a0 T find_task_by_vpid
397 ffffffff81082170 T find_task_by_pid_ns
398 ffffffff811c8f10 T d_absolute_path
399 </pre>
400
401 <p>Please proceed if these addresses are correct.</p>
402
403 <p>You might find some gap between guessed addresses from caitsith_test.ko and actual addresses from System.map file (like some examples shown below) if your kernel configuration uses CONFIG_RANDOMIZE_BASE=y. In this case, although guessed addresses will randomly change for every reboot, please proceed as long as the gap between guessed address and actual address is same for all guessed symbols. Otherwise, please contact the author since CaitSith module will not work even if you continue.</p>
404
405 <ul>
406 <li>Actual addresses from System.map file<br>
407 <pre class="command">
408 # for i in security_hook_heads find_task_by_vpid find_task_by_pid_ns d_absolute_path; do grep $i /boot/System.map-${VERSION}; done
409 </pre>
410 <pre class="output">ffffffff81cdac40 D security_hook_heads
411 ffffffff810b50a0 T find_task_by_vpid
412 ffffffff810b5030 T find_task_by_pid_ns
413 ffffffff812789f0 T d_absolute_path</pre></li>
414 <li>Guessed addresses from one reboot. (Gap for this boot is 0x21000000)<br>
415 <pre class="output">security_hook_heads=ffffffffa2cdac40
416 find_task_by_vpid=ffffffffa20b50a0
417 find_task_by_pid_ns=ffffffffa20b5030
418 d_absolute_path=ffffffffa22789f0</pre></li>
419 <li>Guessed addresses from another reboot. (Gap for this boot is 0x9000000)<br>
420 <pre class="output">security_hook_heads=ffffffff8acdac40
421 find_task_by_vpid=ffffffff8a0b50a0
422 find_task_by_pid_ns=ffffffff8a0b5030
423 d_absolute_path=ffffffff8a2789f0</pre></li>
424 <li>Guessed addresses from yet another reboot. (Gap for this boot is 0x2f000000)<br>
425 <pre class="output">security_hook_heads=ffffffffb0cdac40
426 find_task_by_vpid=ffffffffb00b50a0
427 find_task_by_pid_ns=ffffffffb00b5030
428 d_absolute_path=ffffffffb02789f0</pre></li>
429 </ul>
430
431 <p>If caitsith_test.ko was not loaded successfully, error messages like below are printed. In this case, please contact the author since CaitSith module will not work even if you continue:</p>
432
433 <pre class="command">
434 # dmesg -c &gt; /dev/null
435 # modprobe caitsith_test
436 </pre>
437 <pre class="output">FATAL: Error inserting caitsith_test (/lib/modules/2.6.32/extra/caitsith_test.ko): Invalid argument
438 </pre>
439 <pre class="command">
440 # dmesg
441 </pre>
442 <pre class="output">
443 Sorry, I couldn't guess dependent symbols.
444 I need some changes for supporting your environment.
445 Please contact the author.
446 </pre>
447
448 <p>If your kernel has /proc/sys/kernel/kptr_restrict sysctl parameter set to 2, loading of caitsith_test.ko will fail. In this case, please set /proc/sys/kernel/kptr_restrict to 0 before loading and restore /proc/sys/kernel/kptr_restrict to 2 after loading.</p>
449
450 <pre class="command">
451 # dmesg -c &gt; /dev/null
452 # echo 0 &gt; /proc/sys/kernel/kptr_restrict
453 # modprobe caitsith_test
454 # echo 2 &gt; /proc/sys/kernel/kptr_restrict
455 </pre>
456
457 <hr>
458 <h3><a name="2.1.6">2.1.6. Install the userspace tools</a></h3>
459
460 <p>Make sure the dependencies described above have been installed. Compile and install the tools with the following commands. (Please use USRLIBDIR=/usr/lib or USRLIBDIR=/usr/lib32 if needed):</p>
461
462 <pre class="command">
463 $ wget -O caitsith-tools-0.2-20210910.tar.gz 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66538/caitsith-tools-0.2-20210910.tar.gz'
464 $ wget -O caitsith-tools-0.2-20210910.tar.gz.asc 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66538/caitsith-tools-0.2-20210910.tar.gz.asc'
465 $ gpg caitsith-tools-0.2-20210910.tar.gz.asc
466 $ tar -zxf caitsith-tools-0.2-20210910.tar.gz
467 $ cd caitsith-tools/
468 $ make -s USRLIBDIR=/usr/lib64
469 $ su
470 # make -s USRLIBDIR=/usr/lib64 install
471 </pre>
472
473 <p>Programs listed below are main userspace tools used for administrating CaitSith.</p>
474
475 <ul>
476 <li>/sbin/caitsith-init</li>
477 <li>/usr/sbin/caitsith-auditd</li>
478 <li>/usr/sbin/caitsith-loadpolicy</li>
479 <li>/usr/sbin/caitsith-notifyd</li>
480 <li>/usr/sbin/caitsith-pstree</li>
481 <li>/usr/sbin/caitsith-queryd</li>
482 <li>/usr/sbin/caitsith-savepolicy</li>
483 </ul>
484
485 <p>FYI: If your system has rpm-build package installed, you can make a tools RPM package with the following commands:</p>
486
487 <pre class="command">
488 $ rpmbuild -tb caitsith-tools-0.2-20210910.tar.gz
489 </pre>
490
491 <hr>
492 <h3><a name="2.1.7">2.1.7. Initializing configuration</a></h3>
493
494 <p>Before you can make use of CaitSith, an initialization procedure must take place. This prepares the files in which policy information will be stored. All policy files are stored in the "/etc/caitsith/" directory.</p>
495
496 <p>Run the following command as root user to initialize. (Please use /usr/lib/caitsith/init_policy or /usr/lib32/caitsith/init_policy if needed):</p>
497
498 <pre class="command">
499 # /usr/lib64/caitsith/init_policy
500 </pre>
501 <pre class="output">
502 Creating policy directory... OK
503 Creating configuration directory... OK
504 Creating default policy... OK.
505 Creating module loader... OK.
506 Creating configuration file for caitsith-auditd ... OK.
507 Creating configuration file for caitsith-notifyd ... OK.
508 </pre>
509
510 <p>CaitSith can generate audit logs and allows you to read them via /sys/kernel/security/caitsith/audit interface. To save /sys/kernel/security/caitsith/audit automatically, start /usr/sbin/caitsith-auditd from somewhere. Default setting (specified in /etc/caitsith/tools/auditd.conf ) sends access allowed logs to /dev/null , access unmatched logs to /var/log/caitsith/unmatched.log , access denied logs to /var/log/caitsith/denied.log . (The meaning and example of allowed/unmatched/denied will be explained in <a href="#3.3">Example of simple access restriction rule</a>.)</p>
511
512 <p>CaitSith can ask for your decision about access requests which will be denied unless you allow them via /sys/kernel/security/caitsith/query interface. To notify immediately the occurrence of access requests which CaitSith is about to deny, start /usr/sbin/caitsith-notifyd from somewhere. Default setting (specified in /etc/caitsith/tools/notifyd.conf ) sends mails to root@localhost with subject "Notification from caitsith-notifyd" up to once per a minute.</p>
513
514 <p>Below example launches /usr/sbin/caitsith-auditd and /usr/sbin/caitsith-notifyd from /etc/rc.d/rc.local script:</p>
515
516 <pre>
517 #!/bin/bash
518 # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
519 #
520 # It is highly advisable to create own systemd services or udev rules
521 # to run scripts during boot instead of using this file.
522 #
523 # In contrast to previous versions due to parallel execution during boot
524 # this script will NOT be run after all other services.
525 #
526 # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
527 # that this script will be executed during boot.
528
529 touch /var/lock/subsys/local
530 /usr/sbin/caitsith-auditd
531 /usr/sbin/caitsith-notifyd
532 </pre>
533
534 <hr>
535 <h3><a name="2.1.8">2.1.8. Configuring your bootloader</a></h3>
536
537 <p>On systems where use of init= kernel boot option causes boot failures (e.g. earlier versions of RHEL 7), you need to choose <a href="#2.1.8.1">Loading CaitSith's module from initramfs</a>. On systems where it does not cause boot failures (e.g. RHEL 6), you can choose <a href="#2.1.8.2">Loading CaitSith's module from the init process</a>.</p>
538
539 <h4><a name="2.1.8.1">2.1.8.1. Loading CaitSith's module from initramfs</a></h4>
540
541 <p>This section assumes that you are using dracut and GRUB2.</p>
542
543 <p>Create /etc/dracut.conf.d/caitsith.conf like below and rebuild the initramfs:</p>
544
545 <pre class="command">
546 # echo 'add_drivers+=" caitsith "' &gt; /etc/dracut.conf.d/caitsith.conf
547 # dracut -f
548 </pre>
549
550 <p>Edit your bootloader to add "rd.driver.pre=caitsith" to the kernel boot options. An example is shown below:</p>
551
552 <p>Before:</p>
553 <pre>linux16 /boot/vmlinuz-3.10.0-123.9.3.el7.x86_64 ro root=LABEL=/
554 </pre>
555
556 <p>After:</p>
557 <pre>linux16 /boot/vmlinuz-3.10.0-123.9.3.el7.x86_64 ro root=LABEL=/ rd.driver.pre=caitsith
558 </pre>
559
560 <p>It is recommended that you also modify GRUB_CMDLINE_LINUX line in /etc/default/grub file like below in case you update kernel packages in the future:</p>
561
562 <p>Before:</p>
563 <pre>
564 GRUB_CMDLINE_LINUX="vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 rhgb quiet"
565 </pre>
566
567 <p>After:</p>
568 <pre>
569 GRUB_CMDLINE_LINUX="vconsole.keymap=us crashkernel=auto vconsole.font=latarcyrheb-sun16 rhgb quiet rd.driver.pre=caitsith"
570 </pre>
571
572 <h4><a name="2.1.8.2">2.1.8.2. Loading CaitSith's module from the init process</a></h4>
573 <p>Edit your bootloader (e.g. GRUB) to add "init=/sbin/caitsith-init" to the kernel boot options. An example is shown below:</p>
574
575 <p>Before:</p>
576 <pre>kernel /boot/vmlinuz-2.6.32-431.17.1.el6.x86_64 ro root=LABEL=/
577 </pre>
578
579 <p>After:</p>
580 <pre>kernel /boot/vmlinuz-2.6.32-431.17.1.el6.x86_64 ro root=LABEL=/ init=/sbin/caitsith-init
581 </pre>
582
583 <hr>
584 <h3><a name="2.1.9">2.1.9. Rebooting your system</a></h3>
585
586 <p>Now you have finished all preparation. Reboot your system.</p>
587
588 <p>If everything was installed properly and the bootloader was correctly configured, the kernel should boot as normal and CaitSith should be activated:</p>
589
590 <img src="media/caitsith-lsm-activated.png" alt="caitsith-lsm-activated.png" title="CaitSith(LSM) activated" width="872" height="512">
591
592 <p>Note that you won't be able to see CaitSith's messages if you are using "quiet" or "rhgb" kernel boot option because these options prevent most of kernel messages from being printed.</p>
593
594 <p>Although CaitSith is a LSM module, CaitSith can coexist with other LSM modules. However, you need to also add "selinux=0" to the kernel boot options if you disable SELinux by specifying SELINUX=disabled in /etc/selinux/config . This is because the init process unregisters LSM hooks which CaitSith module depends on if SELINUX=disabled is specified in /etc/selinux/config .</p>
595
596 <hr>
597 <h3><a name="2.1.10">2.1.10. How can I disable/uninstall CaitSith?</a></h3>
598
599 <p>If your system becomes unable to boot during the course of this guide or any time in the future, it may be due to policy configuration or something related to CaitSith. If this is the case, it is possible that the kernel can still be booted by disabling CaitSith. This can be done by removing "rd.driver.pre=caitsith" or "init=/sbin/caitsith-init" from the kernel boot options.</p>
600
601 <p>CaitSith fortunately does not require the modification of any existing Linux binaries, libraries or applications. Thus, uninstalling CaitSith is very easy. It is simply a matter of removing "rd.driver.pre=caitsith" or "init=/sbin/caitsith-init" from the kernel boot options and uninstalling the userspace tools that you installed above.</p>
602
603 <hr>
604 <h2><a name="2.2">2.2. How to install fully featured version</a></h2>
605
606 <hr>
607 <h3><a name="2.2.1">2.2.1. Install dependencies</a></h3>
608
609 <p>These packages are required for compiling the kernel and the userspace tools:</p>
610
611 <ul>
612 <li><strong>wget</strong>: to download sources</li>
613 <li><strong>patch</strong>: to patch the kernel</li>
614 <li><strong>gcc</strong>: to build the kernel and tools</li>
615 <li><strong>make</strong>: to build the kernel and tools</li>
616 <li><strong>ncurses-devel</strong> or <strong>libncurses-dev</strong>: to build the tools</li>
617 </ul>
618
619 <p>These can be installed with the following commands:</p>
620
621 <p><strong>RedHat distributions</strong></p>
622 <pre class="command">
623 # yum -y install wget patch gcc make ncurses-devel
624 </pre>
625 <p><strong>Debian distributions</strong></p>
626 <pre class="command">
627 # apt-get -y install wget patch gcc make libncurses-dev
628 </pre>
629 <p><strong>SUSE distributions</strong></p>
630 <pre class="command">
631 # yast -i wget patch gcc make ncurses-devel
632 </pre>
633
634 <hr>
635 <h3><a name="2.2.2">2.2.2. Download and patch the kernel</a></h3>
636
637 <p>Download the kernel source from <a href="https://www.kernel.org/pub/linux/kernel/v2.6/">linux-2.6</a> or <a href="https://www.kernel.org/pub/linux/kernel/v3.x/">linux-3</a> or <a href="https://www.kernel.org/pub/linux/kernel/v4.x/">linux-4</a> or <a href="https://www.kernel.org/pub/linux/kernel/v5.x/">linux-5</a> or <a href="https://www.kernel.org/pub/linux/kernel/v6.x/">linux-6</a>.<br>
638 Linux kernel 2.6.27 and later are supported from the linux-2.6 tree.<br>
639 Linux kernel 3.0 and later are supported from the linux-3 tree.<br>
640 Linux kernel 4.0 and later are supported from the linux-4 tree.<br>
641 Linux kernel 5.0 and later are supported from the linux-5 tree.<br>
642 Linux kernel 6.0 and later are supported from the linux-6 tree.</p>
643
644 <p>Extract the kernel source and go to the extracted directory.<br>
645 In the operations below, "$VERSION" should be replaced with appropriate kernel version. For example "6.1" if using Linux kernel 6.1.1, "2.6.27" if using Linux kernel 2.6.27.62.<br>
646 Also, there are several patches which can be applied to distributor's latest kernels. For example "3.10-centos-7" if using CentOS 7's latest kernel:</p>
647
648 <pre class="command">
649 $ wget -O caitsith-patch-0.2-20231225.tar.gz 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66537/caitsith-patch-0.2-20231225.tar.gz'
650 $ wget -O caitsith-patch-0.2-20231225.tar.gz.asc 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66537/caitsith-patch-0.2-20231225.tar.gz.asc'
651 $ wget https://tomoyo.osdn.jp/kumaneko-key
652 $ gpg --import kumaneko-key
653 $ gpg caitsith-patch-0.2-20231225.tar.gz.asc
654 $ tar -zxf caitsith-patch-0.2-20231225.tar.gz
655 $ sed -i -e 's/CCSECURITY/CAITSITH/g' -e 's/ccsecurity/caitsith/g' -e 's/ccs_domain_info/cs_domain_info/g' -e 's/ccs_flags/cs_flags/g' -- patches/ccs-patch-*.diff
656 $ patch -sp1 &lt; patches/ccs-patch-$VERSION.diff
657 </pre>
658
659 <hr>
660 <h3><a name="2.2.3">2.2.3. Configure the kernel</a></h3>
661
662 <pre class="command">
663 $ make -s menuconfig
664 </pre>
665
666 <p>Choose the following options in "Security options" section:</p>
667
668 <ul>
669 <li>[*] CaitSith support</li>
670 <li>[ ] &nbsp;&nbsp;Compile as loadable kernel module</li>
671 <li>[ ] &nbsp;&nbsp;Disable by default</li>
672 <li>[ ] &nbsp;&nbsp;Do not modify 'struct task_struct' in order to keep KABI</li>
673 <li>[ ] &nbsp;&nbsp;Activate without calling userspace policy loader.</li>
674 <li>(/sbin/caitsith-init) Location of userspace policy loader</li>
675 <li>(/sbin/init) Trigger for calling userspace policy loader</li>
676 <li>[*] &nbsp;&nbsp;Enable readdir operation restriction.</li>
677 <li>[*] &nbsp;&nbsp;Enable getattr operation restriction.</li>
678 <li>[*] &nbsp;&nbsp;Enable socket operation restriction.</li>
679 <li>[*] &nbsp;&nbsp;Enable non-POSIX capability operation restriction.</li>
680 <li>[*] &nbsp;&nbsp;Enable ptrace operation restriction.</li>
681 <li>[*] &nbsp;&nbsp;Enable kill operation restriction.</li>
682 <li>[*] &nbsp;&nbsp;Enable environment variable names/values restriction.</li>
683 <li>[*] &nbsp;&nbsp;Enable execute handler functionality.</li>
684 <li>[*] &nbsp;&nbsp;Enable domain transition without program execution request.</li>
685 <li>[*] &nbsp;&nbsp;Enable automatic domain transition.</li>
686 </ul>
687
688 <p><em>"Compile as loadable kernel module"</em> is useful when there is a file size limitation for vmlinux (e.g. embedded systems).</p>
689
690 <p><em>"Disable by default"</em> will enable CaitSith only when "caitsith=on" is passed to the kernel boot options. If this option is not selected, "caitsith=off" will disable CaitSith.</p>
691
692 <p><em>"Do not modify 'struct task_struct' in order to keep KABI"</em> will manage "struct task_struct" variables outside "struct task_struct" in order to avoid Kernel Application Binary Interface (KABI) breakage. Choose this option if wanting to patch against distributor's kernels without breaking KABI. However, since "struct caitsith_operations" must be exported to loadable kernel modules (LKMs) in order to allow them to call CaitSith's functions, build scripts may still print warning messages.</p>
693
694 <p>There are two types of CaitSith's policy configuration. The former is embedded into the kernel and the latter is saved as files on the filesystems (e.g. /etc/caitsith/ directory). You will need to rebuild the kernel whenever updating the former, but allows you to load policy without using userspace policy loader (e.g. /sbin/caitsith-init). The latter is loaded by executing userspace policy loader when the access control by CaitSith is about to be activated (e.g. when /sbin/init or /usr/lib/systemd/systemd starts). <em>"Activate without calling userspace policy loader."</em> allows you to activate access control by CaitSith as soon as the former is loaded. This option is useful when it is difficult to call policy loader (e.g. embedded systems).</p>
695
696 <p><em>"Location of userspace policy loader"</em> is available only when <em>"Activate without calling userspace policy loader."</em> is not selected. This option specifies the default pathname of the userspace policy loader. You can override this setting via the "CS_loader=" kernel boot option.</p>
697
698 <p><em>"Trigger for calling userspace policy loader"</em> is available only when <em>"Activate without calling userspace policy loader."</em> is not selected. This option specifies the default pathname of the activation trigger. You can override this setting via the "CS_trigger=" kernel boot option. For example, if you pass "init=/usr/lib/systemd/systemd" option, you may also want to pass "CS_trigger=/usr/lib/systemd/systemd" option.</p>
699
700 <hr>
701 <h3><a name="2.2.4">2.2.4. Compile and install the kernel</a></h3>
702
703 <p>The policy configuration which will be embedded into the kernel needs to exist as security/caitsith/policy/policy.conf . But you can proceed without creating that file because you don't have the policy configuration to embed as of this step. (You may come back here after you developed policy configuration to embed.)</p>
704
705 <p>Once the kernel has been configured, compile and install the kernel with the following commands:</p>
706
707 <pre class="command">
708 $ make -s
709 $ su
710 # make -s modules_install install
711 </pre>
712
713 <p>Create initrd/initramfs if required.</p>
714
715 <hr>
716 <h3><a name="2.2.5">2.2.5. Install the userspace tools</a></h3>
717
718 <p>Make sure the dependencies described above have been installed. Compile and install the tools with the following commands. (Please use USRLIBDIR=/usr/lib or USRLIBDIR=/usr/lib32 if needed):</p>
719
720 <pre class="command">
721 $ wget -O caitsith-tools-0.2-20210910.tar.gz 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66538/caitsith-tools-0.2-20210910.tar.gz'
722 $ wget -O caitsith-tools-0.2-20210910.tar.gz.asc 'https://osdn.jp/frs/redir.php?m=jaist&amp;f=/caitsith/66538/caitsith-tools-0.2-20210910.tar.gz.asc'
723 $ gpg caitsith-tools-0.2-20210910.tar.gz.asc
724 $ tar -zxf caitsith-tools-0.2-20210910.tar.gz
725 $ cd caitsith-tools/
726 $ make -s USRLIBDIR=/usr/lib64
727 $ su
728 # make -s USRLIBDIR=/usr/lib64 install
729 </pre>
730
731 <p>Programs listed below are main userspace tools used for administrating CaitSith.</p>
732
733 <ul>
734 <li>/sbin/caitsith-init</li>
735 <li>/usr/sbin/caitsith-auditd</li>
736 <li>/usr/sbin/caitsith-loadpolicy</li>
737 <li>/usr/sbin/caitsith-notifyd</li>
738 <li>/usr/sbin/caitsith-pstree</li>
739 <li>/usr/sbin/caitsith-queryd</li>
740 <li>/usr/sbin/caitsith-savepolicy</li>
741 </ul>
742
743 <p>FYI: If your system has rpm-build package installed, you can make a tools RPM package with the following commands:</p>
744
745 <pre class="command">
746 $ rpmbuild -tb caitsith-tools-0.2-20210910.tar.gz
747 </pre>
748
749 <hr>
750 <h3><a name="2.2.6">2.2.6. Initializing configuration</a></h3>
751
752 <p>Before you can make use of CaitSith, an initialization procedure must take place. This prepares the files in which policy information will be stored. All policy files are stored in the "/etc/caitsith/" directory.</p>
753
754 <p>Run the following command as root user to initialize. (Please use /usr/lib/caitsith/init_policy or /usr/lib32/caitsith/init_policy if needed):</p>
755
756 <pre class="command">
757 # /usr/lib64/caitsith/init_policy
758 </pre>
759 <pre class="output">
760 Creating policy directory... OK
761 Creating configuration directory... OK
762 Creating default policy... OK.
763 Creating module loader... OK.
764 Creating configuration file for caitsith-auditd ... OK.
765 Creating configuration file for caitsith-notifyd ... OK.
766 </pre>
767
768 <p>CaitSith can generate audit logs and allows you to read them via /sys/kernel/security/caitsith/audit interface. To save /sys/kernel/security/caitsith/audit automatically, start /usr/sbin/caitsith-auditd from somewhere. Default setting (specified in /etc/caitsith/tools/auditd.conf ) sends access allowed logs to /dev/null , access unmatched logs to /var/log/caitsith/unmatched.log , access denied logs to /var/log/caitsith/denied.log . (The meaning and example of allowed/unmatched/denied will be explained in <a href="#3.3">Example of simple access restriction rule</a>.)</p>
769
770 <p>CaitSith can ask for your decision about access requests which will be denied unless you allow them via /sys/kernel/security/caitsith/query interface. To notify immediately the occurrence of access requests which CaitSith is about to deny, start /usr/sbin/caitsith-notifyd from somewhere. Default setting (specified in /etc/caitsith/tools/notifyd.conf ) sends mails to root@localhost with subject "Notification from caitsith-notifyd" up to once per a minute.</p>
771
772 <p>Below example launches /usr/sbin/caitsith-auditd and /usr/sbin/caitsith-notifyd from /etc/rc.d/rc.local script:</p>
773
774 <pre>
775 #!/bin/bash
776 # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
777 #
778 # It is highly advisable to create own systemd services or udev rules
779 # to run scripts during boot instead of using this file.
780 #
781 # In contrast to previous versions due to parallel execution during boot
782 # this script will NOT be run after all other services.
783 #
784 # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
785 # that this script will be executed during boot.
786
787 touch /var/lock/subsys/local
788 /usr/sbin/caitsith-auditd
789 /usr/sbin/caitsith-notifyd
790 </pre>
791
792 <hr>
793 <h3><a name="2.2.7">2.2.7. Configuring your bootloader</a></h3>
794
795 <p>Edit your bootloader (e.g. GRUB) to include the kernel you have just compiled. If the <em>"Disable by default"</em> option was selected during kernel configuration, remember to include "caitsith=on" in the kernel boot options. Consult the documentation for your distribution and bootloader to find out how to include your CaitSith kernel.</p>
796
797 <hr>
798 <h3><a name="2.2.8">2.2.8. Rebooting your system</a></h3>
799
800 <p>Now you have finished all preparation. Reboot your system.</p>
801
802 <p>If everything was installed properly and the bootloader was correctly configured, the kernel should boot as normal and CaitSith should be activated:</p>
803
804 <img src="media/caitsith-activated.png" alt="caitsith-activated.png" title="CaitSith activated" width="928" height="496">
805
806 <p>Note that you won't be able to see CaitSith's messages if you are using "quiet" or "rhgb" kernel boot option because these options prevent most of kernel messages from being printed.</p>
807
808 <hr>
809 <h3><a name="2.2.9">2.2.9. How can I disable/uninstall CaitSith?</a></h3>
810
811 <p>If your system becomes unable to boot during the course of this guide or any time in the future, it may be due to policy configuration or something related to CaitSith. If this is the case, it is possible that the kernel can still be booted by disabling CaitSith. This can be done by appending "caitsith=off" to the kernel boot options.</p>
812
813 <p>CaitSith fortunately does not require the modification of any existing Linux binaries, libraries or applications. Thus, uninstalling CaitSith is very easy. It is simply a matter of uninstalling the kernel and userspace tools that you installed above. You can reboot with the kernel provided by your distribution and then remove the entry from your bootloader.</p>
814
815 <hr>
816 <h2><a name="how_to_develop_policy">3. How to develop policy</a></h2>
817
818 <hr>
819 <h3><a name="3.1">3.1. Policy file structure</a></h3>
820
821 <p>CaitSith's policy file consists with "Header part" and "ACL part".</p>
822
823 <h4><a name="3.1.1">3.1.1. Header part of policy file</a></h4>
824
825 <p>Header part consists with below lines.</p>
826
827 <pre>
828 POLICY_VERSION=20120401
829 stat $stat_name $stat_value
830 quota memory policy $max_byte_for_policy
831 quota memory audit $max_byte_for_audit_logs
832 quota memory query $max_byte_for_query
833 quota audit[$audit_index] allowed=$max_logs_for_allowed_request denied=$max_logs_for_denied_request unmatched=$max_logs_for_unmatched_request
834 string_group $string_group_name $string_group_member
835 number_group $number_group_name $number_group_member
836 ip_group $ip_group_name $ip_group_member
837 </pre>
838
839 <ul>
840 <li>POLICY_VERSION line defines policy version.</li>
841 <li>stat lines are for showing statistics information such as memory usage. $stat_name and $stat_value are simply ignored.</li>
842 <li>$max_byte_for_policy is max amount of memory in byte which can be allocated for policy. Default is unlimited.</li>
843 <li>$max_byte_for_audit_logs is max amount of memory in byte which can be allocated for audit logs. Default is unlimited. $max_byte_for_audit_logs=16777216 should be sufficient.</li>
844 <li>$max_byte_for_query is max amount of memory in byte which can be allocated for interactive enforcement. Default is unlimited. $max_byte_for_audit_logs=1048576 should be sufficient.</li>
845 <li>quota audit[$audit_index] lines (0 &lt;= $audit_index &lt;= 255) are max number of audit logs which can be held in the kernel space. $max_logs_for_allowed_request is for allowed requests. $max_logs_for_denied_request is for denied requests. $max_logs_for_unmatched_request is for unmatched requests. Default is 0. Unless you have special reasons, you should set 0 to $max_logs_for_allowed_request. Regarding $max_logs_for_unmatched_request and $max_logs_for_denied_request, 1024 should be sufficient.</li>
846 <li>string_group $string_group_name lines define group of strings. $string_group_member is a member for $string_group_name group.</li>
847 <li>number_group $number_group_name lines define group of numbers. $number_group_member is a member for $number_group_name group.</li>
848 <li>ip_group $ip_group_name lines define group of IP addresses. $ip_group_member is a member for $ip_group_name group.</li>
849 </ul>
850
851 <h4><a name="3.1.2">3.1.2. ACL part of policy file</a></h4>
852
853 <p>ACL part consists with 0 or more repetitions of below block.</p>
854
855 <pre>
856 $acl_priority acl $operation $conditions_to_filter
857 audit $audit_index
858 $cond_priority $decision $conditions_to_allow_or_deny
859 </pre>
860
861 <ul>
862 <li>A block which starts with $acl_priority determines whether to evaluate rules in this block or not.</li>
863 <li>Blocks which start with $acl_priority can be defined as many as you need.</li>
864 <li>$acl_priority is a priority (an integer between 0 and 65535) which controls which block should be evaluated first (among all blocks defined in the policy).</li>
865 <li>Blocks are evaluated from smaller $acl_priority values to larger $acl_priority values.</li>
866 <li>If two blocks have same $acl_priority value, the block which is defined first is evaluated first.</li>
867 <li>$operation is "operation".</li>
868 <li>$conditions_to_filter is "conditional expressions" which can be applied to "operation". Omit $conditions_to_filter to evaluate this block unconditionally.</li>
869 <li>Access requests will be denied if one of deny lines (among all blocks defined in the policy) matches.</li>
870 </ul>
871
872 <p>$decision lines in a block is evaluated only when the block's $acl_priority line matched.</p>
873
874 <ul>
875 <li>A line which starts with $cond_priority determines whether to allow the access request or not.</li>
876 <li>Lines which start with $cond_priority can be defined as many as you need.</li>
877 <li>$cond_priority is a priority (an integer between 0 and 65535) which controls which line should be checked first (among all lines defined in the block).</li>
878 <li>Lines are checked from smaller $cond_priority values to larger priority values.</li>
879 <li>If two lines have same $cond_priority value, the line which is defined first is checked first.</li>
880 <li>$decision is either allow or deny.</li>
881 <li>$conditions_to_allow_or_deny is "conditional expressions" which can be applied to "operation". Omit $conditions_to_allow_or_deny to match this line unconditionally.</li>
882 </ul>
883
884 <p>Checking of $decision lines in a block lasts until it matches a $decision line or it reaches to the end of block.</p>
885
886 <ul>
887 <li>If $conditions_to_allow_or_deny of a deny line matches, the access request is denied. At the same time, access denied log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of denied logs which is in the kernel is smaller than $max_logs_for_denied_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
888 <li>If $conditions_to_allow_or_deny of an allow line matches, the evaluation of this block ends and proceeds to next block. At the same time, access allowed log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of allowed logs which is in the kernel is smaller than $max_logs_for_allowed_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
889 <li>If none of $conditions_to_allow_or_deny matches, the evaluation of this block ends and proceeds to next block. At the same time, access unmatched log is generated if memory used for audit logs is smaller than $max_byte_for_audit_logs bytes and number of unmatched logs which is in the kernel is smaller than $max_logs_for_unmatched_request of quota audit[$audit_index] line where $audit_index is specified by audit line of this block.</li>
890 </ul>
891
892 <p>Access requests will be denied only when "deny" line of "acl" block matched. (There are two exceptions. Regarding permission to change domains manually (i.e. <a href="#5.60">acl manual_domain_transition</a> blocks) and permission to change domains automatically (i.e. <a href="#5.61">acl auto_domain_transition</a> blocks), access requests will be granted only when "allow" line of all blocks match, in order to avoid unintended domain transition.)</p>
893
894 <p>$acl_priority and $cond_priority values are used for two purposes. One is for selectively deny operations using "deny" lines. For example,</p>
895
896 <pre>
897 10 acl read path.fsmagic=0x9FA0
898 audit 0
899 10 deny path="proc:/cmdline"
900 20 allow
901 </pre>
902
903 <p>denies opening /proc/cmdline on the proc filesystem (proc filesystem's magic number is 0x9FA0) for reading while allowing opening all other files.</p>
904
905 <p>The other is for controlling which "transition=" and "handler=" arguments should be used when these arguments matched more than once. This will be explained in <a href="#advanced_usage">advanced usage</a>.</p>
906
907 <h4><a name="3.1.3">3.1.3. An example policy file</a></h4>
908
909 <p>Below is an example of /etc/caitsith/policy/current file on CentOS. The content of this file varies depending on environments you are using, and will be updated as you develop policy.</p>
910
911 <pre>
912 POLICY_VERSION=20120401
913
914 quota memory audit 16777216
915 quota memory query 1048576
916 quota audit[1] allowed=0 denied=1024 unmatched=1024
917
918 10000 acl execute
919 audit 0
920 10 allow path="/sbin/modprobe" transition="/sbin/modprobe"
921 10 allow path="/sbin/init" transition="/sbin/init"
922 10 allow path="/sbin/mingetty" transition="/sbin/mingetty"
923 10 allow path="/sbin/udevd" transition="/sbin/udevd"
924 10 allow path="/usr/sbin/anacron" transition="/usr/sbin/anacron"
925 10 allow path="/usr/sbin/crond" transition="/usr/sbin/crond"
926 10 allow path="/usr/sbin/httpd" transition="/usr/sbin/httpd"
927 10 allow path="/usr/sbin/logrotate" transition="/usr/sbin/logrotate"
928 10 allow path="/usr/sbin/nmbd" transition="/usr/sbin/nmbd"
929 10 allow path="/usr/sbin/smbd" transition="/usr/sbin/smbd"
930 10 allow path="/usr/sbin/sshd" transition="/usr/sbin/sshd"
931 10 allow path="/etc/rc.d/init.d/ntpd" transition="/etc/rc.d/init.d/ntpd"
932 10 allow path="/etc/rc.d/init.d/single" transition="/etc/rc.d/init.d/single"
933 10 allow path="/etc/rc.d/init.d/killall" transition="/etc/rc.d/init.d/killall"
934 10 allow path="/etc/rc.d/init.d/ip6tables" transition="/etc/rc.d/init.d/ip6tables"
935 10 allow path="/etc/rc.d/init.d/halt" transition="/etc/rc.d/init.d/halt"
936 10 allow path="/etc/rc.d/init.d/netfs" transition="/etc/rc.d/init.d/netfs"
937 10 allow path="/etc/rc.d/init.d/messagebus" transition="/etc/rc.d/init.d/messagebus"
938 10 allow path="/etc/rc.d/init.d/sandbox" transition="/etc/rc.d/init.d/sandbox"
939 10 allow path="/etc/rc.d/init.d/rsyslog" transition="/etc/rc.d/init.d/rsyslog"
940 10 allow path="/etc/rc.d/init.d/smb" transition="/etc/rc.d/init.d/smb"
941 10 allow path="/etc/rc.d/init.d/sshd" transition="/etc/rc.d/init.d/sshd"
942 10 allow path="/etc/rc.d/init.d/cgconfig" transition="/etc/rc.d/init.d/cgconfig"
943 10 allow path="/etc/rc.d/init.d/udev-post" transition="/etc/rc.d/init.d/udev-post"
944 10 allow path="/etc/rc.d/init.d/firstboot" transition="/etc/rc.d/init.d/firstboot"
945 10 allow path="/etc/rc.d/init.d/ntpdate" transition="/etc/rc.d/init.d/ntpdate"
946 10 allow path="/etc/rc.d/init.d/crond" transition="/etc/rc.d/init.d/crond"
947 10 allow path="/etc/rc.d/init.d/restorecond" transition="/etc/rc.d/init.d/restorecond"
948 10 allow path="/etc/rc.d/init.d/httpd" transition="/etc/rc.d/init.d/httpd"
949 10 allow path="/etc/rc.d/init.d/rdisc" transition="/etc/rc.d/init.d/rdisc"
950 10 allow path="/etc/rc.d/init.d/postfix" transition="/etc/rc.d/init.d/postfix"
951 10 allow path="/etc/rc.d/init.d/saslauthd" transition="/etc/rc.d/init.d/saslauthd"
952 10 allow path="/etc/rc.d/init.d/netconsole" transition="/etc/rc.d/init.d/netconsole"
953 10 allow path="/etc/rc.d/init.d/network" transition="/etc/rc.d/init.d/network"
954 10 allow path="/etc/rc.d/init.d/avahi-daemon" transition="/etc/rc.d/init.d/avahi-daemon"
955 10 allow path="/etc/rc.d/init.d/auditd" transition="/etc/rc.d/init.d/auditd"
956 10 allow path="/etc/rc.d/init.d/nmb" transition="/etc/rc.d/init.d/nmb"
957 10 allow path="/etc/rc.d/init.d/iptables" transition="/etc/rc.d/init.d/iptables"
958 10 allow path="/etc/rc.d/init.d/cgred" transition="/etc/rc.d/init.d/cgred"
959
960 0 acl modify_policy
961 audit 1
962 1 deny task.uid!=0
963 1 deny task.euid!=0
964 100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
965 100 allow task.exe="/usr/sbin/caitsith-queryd"
966 10000 deny
967 </pre>
968
969 <hr>
970 <h3><a name="3.2">3.2. Updating policy configuration</a></h3>
971
972 <p>There are two ways to update policy configuration.</p>
973
974 <p>One is to use /sbin/caitsith-init which is automatically called when /sbin/init starts. /sbin/caitsith-init reads policy from /etc/caitsith/policy/current and writes to /sys/kernel/security/caitsith/policy interface. Therefore, you can update policy configuration by updating /etc/caitsith/policy/current and rebooting your system.</p>
975
976 <p>The other is to use /usr/sbin/caitsith-loadpolicy which is defined for loading policy after your system has booted. /usr/sbin/caitsith-loadpolicy reads policy from standard input and writes to /sys/kernel/security/caitsith/policy interface. Therefore, you can update policy configuration without updating /etc/caitsith/policy/current and rebooting your system. For example, if you want to append a "string_group mygroup1 /" line to /sys/kernel/security/caitsith/policy interface, run below command:</p>
977
978 <pre class="command">
979 # echo 'string_group mygroup1 /' | /usr/sbin/caitsith-loadpolicy
980 </pre>
981
982 <p>If you want to delete the "string_group mygroup1 /" line from /sys/kernel/security/caitsith/policy interface, run below command:</p>
983
984 <pre class="command">
985 # echo 'delete string_group mygroup1 /' | /usr/sbin/caitsith-loadpolicy
986 </pre>
987
988 <p>The contents in /sys/kernel/security/caitsith/policy will be lost when your system shuts down or reboots. To save /sys/kernel/security/caitsith/policy as /etc/caitsith/policy/current , run below command:</p>
989
990 <pre class="command">
991 # /usr/sbin/caitsith-savepolicy
992 </pre>
993
994 <hr>
995 <h3><a name="3.3">3.3. Example of simple access restriction rule</a></h3>
996
997 <p>Let's experience how CaitSith restricts access using simple examples.</p>
998
999 <h4><a name="3.3.1">3.3.1. Telling CaitSith which access requests should be checked</a></h4>
1000
1001 <p>By default, CaitSith does not deny access requests. To restrict access requests, you need to tell CaitSith which access requests should be denied.</p>
1002
1003 <p>Below rule will check access requests which open /tmp/file1 for reading.</p>
1004
1005 <pre>
1006 100 acl read path="/tmp/file1"
1007 audit 1
1008 </pre>
1009
1010 <p>Append above rule using /usr/sbin/caitsith-loadpolicy . Since /usr/sbin/caitsith-loadpolicy reads policy from standard input, you can use ^D (Ctrl-D) to indicate end of input:</p>
1011
1012 <pre class="command">
1013 # /usr/sbin/caitsith-loadpolicy
1014 </pre>
1015 <pre>
1016 100 acl read path="/tmp/file1"
1017 audit 1
1018 ^D
1019 </pre>
1020
1021 <p>You may use a temporary file if you worry typos.</p>
1022
1023 <pre class="command">
1024 # cat &gt; ~/policy.tmp
1025 </pre>
1026 <pre>
1027 100 acl read path="/tmp/file1"
1028 audit 1
1029 ^D
1030 </pre>
1031 <pre class="command">
1032 # /usr/sbin/caitsith-loadpolicy &lt; ~/policy.tmp
1033 # rm ~/policy.tmp
1034 </pre>
1035
1036 <p>You can confirm that above rule is appended to /sys/kernel/security/caitsith/policy by reading /sys/kernel/security/caitsith/policy .</p>
1037
1038 <pre class="command">
1039 # cat /sys/kernel/security/caitsith/policy
1040 </pre>
1041 <pre>
1042 POLICY_VERSION=20120401
1043 stat Policy updated: 7 (Last: 2012/04/08 04:56:45)
1044 stat Requests denied: 0
1045 stat Memory used by policy: 6048
1046 stat Memory used by audit: 0
1047 stat Memory used by query: 0
1048 quota memory audit 16777216
1049 quota memory query 1048576
1050 quota audit[1] allowed=0 denied=1024 unmatched=1024
1051
1052 10000 acl execute
1053 audit 0
1054 10 allow path="/sbin/modprobe" transition="/sbin/modprobe"
1055 10 allow path="/sbin/init" transition="/sbin/init"
1056 10 allow path="/sbin/mingetty" transition="/sbin/mingetty"
1057 10 allow path="/sbin/udevd" transition="/sbin/udevd"
1058 10 allow path="/usr/sbin/anacron" transition="/usr/sbin/anacron"
1059 10 allow path="/usr/sbin/crond" transition="/usr/sbin/crond"
1060 10 allow path="/usr/sbin/httpd" transition="/usr/sbin/httpd"
1061 10 allow path="/usr/sbin/logrotate" transition="/usr/sbin/logrotate"
1062 10 allow path="/usr/sbin/nmbd" transition="/usr/sbin/nmbd"
1063 10 allow path="/usr/sbin/smbd" transition="/usr/sbin/smbd"
1064 10 allow path="/usr/sbin/sshd" transition="/usr/sbin/sshd"
1065 10 allow path="/etc/rc.d/init.d/ntpd" transition="/etc/rc.d/init.d/ntpd"
1066 10 allow path="/etc/rc.d/init.d/single" transition="/etc/rc.d/init.d/single"
1067 10 allow path="/etc/rc.d/init.d/killall" transition="/etc/rc.d/init.d/killall"
1068 10 allow path="/etc/rc.d/init.d/ip6tables" transition="/etc/rc.d/init.d/ip6tables"
1069 10 allow path="/etc/rc.d/init.d/halt" transition="/etc/rc.d/init.d/halt"
1070 10 allow path="/etc/rc.d/init.d/netfs" transition="/etc/rc.d/init.d/netfs"
1071 10 allow path="/etc/rc.d/init.d/messagebus" transition="/etc/rc.d/init.d/messagebus"
1072 10 allow path="/etc/rc.d/init.d/sandbox" transition="/etc/rc.d/init.d/sandbox"
1073 10 allow path="/etc/rc.d/init.d/rsyslog" transition="/etc/rc.d/init.d/rsyslog"
1074 10 allow path="/etc/rc.d/init.d/smb" transition="/etc/rc.d/init.d/smb"
1075 10 allow path="/etc/rc.d/init.d/sshd" transition="/etc/rc.d/init.d/sshd"
1076 10 allow path="/etc/rc.d/init.d/cgconfig" transition="/etc/rc.d/init.d/cgconfig"
1077 10 allow path="/etc/rc.d/init.d/udev-post" transition="/etc/rc.d/init.d/udev-post"
1078 10 allow path="/etc/rc.d/init.d/firstboot" transition="/etc/rc.d/init.d/firstboot"
1079 10 allow path="/etc/rc.d/init.d/ntpdate" transition="/etc/rc.d/init.d/ntpdate"
1080 10 allow path="/etc/rc.d/init.d/crond" transition="/etc/rc.d/init.d/crond"
1081 10 allow path="/etc/rc.d/init.d/restorecond" transition="/etc/rc.d/init.d/restorecond"
1082 10 allow path="/etc/rc.d/init.d/httpd" transition="/etc/rc.d/init.d/httpd"
1083 10 allow path="/etc/rc.d/init.d/rdisc" transition="/etc/rc.d/init.d/rdisc"
1084 10 allow path="/etc/rc.d/init.d/postfix" transition="/etc/rc.d/init.d/postfix"
1085 10 allow path="/etc/rc.d/init.d/saslauthd" transition="/etc/rc.d/init.d/saslauthd"
1086 10 allow path="/etc/rc.d/init.d/netconsole" transition="/etc/rc.d/init.d/netconsole"
1087 10 allow path="/etc/rc.d/init.d/network" transition="/etc/rc.d/init.d/network"
1088 10 allow path="/etc/rc.d/init.d/avahi-daemon" transition="/etc/rc.d/init.d/avahi-daemon"
1089 10 allow path="/etc/rc.d/init.d/auditd" transition="/etc/rc.d/init.d/auditd"
1090 10 allow path="/etc/rc.d/init.d/nmb" transition="/etc/rc.d/init.d/nmb"
1091 10 allow path="/etc/rc.d/init.d/iptables" transition="/etc/rc.d/init.d/iptables"
1092 10 allow path="/etc/rc.d/init.d/cgred" transition="/etc/rc.d/init.d/cgred"
1093
1094 100 acl read path="/tmp/file1"
1095 audit 1
1096
1097 0 acl modify_policy
1098 audit 1
1099 1 deny task.uid!=0
1100 1 deny task.euid!=0
1101 100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
1102 100 allow task.exe="/usr/sbin/caitsith-queryd"
1103 10000 deny
1104 </pre>
1105
1106 <h4><a name="3.3.2">3.3.2. Access requests which will be implicitly allowed by CaitSith</a></h4>
1107
1108 <p>Make sure that /usr/sbin/caitsith-auditd is running.</p>
1109
1110 <pre class="command">
1111 # pidof caitsith-auditd
1112 </pre>
1113 <pre>
1114 3627
1115 </pre>
1116
1117 <p>Now, create /tmp/file1 file.</p>
1118
1119 <pre class="command">
1120 # touch /tmp/file1
1121 </pre>
1122
1123 <p>Then, open /tmp/file1 for reading.</p>
1124
1125 <pre class="command">
1126 # cat /tmp/file1
1127 </pre>
1128
1129 <p>Check /var/log/caitsith/unmatched.log for access unmatched log of this access request. You will find an entry like below:</p>
1130
1131 <pre class="command">
1132 # grep /tmp/file1 /var/log/caitsith/unmatched.log
1133 </pre>
1134 <pre>
1135 #2012/04/08 04:58:40# global-pid=3678 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3678 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1136 </pre>
1137
1138 <p>Note the <strong>result=unmatched</strong> part of the entry. This indicates that access request was checked but matched neither "allow" nor "deny" rule.</p>
1139
1140 <p>Note the <strong>priority=100</strong> part of the entry. This indicates that this entry was generated by rules which have 100 as priority.</p>
1141
1142 <p>Note the <strong>read path="/tmp/file1"</strong> part of the entry. This indicates that this entry was generated by access request of opening /tmp/file1 for reading.</p>
1143
1144 <h4><a name="3.3.3">3.3.3. Access requests which will be explicitly denied by CaitSith</a></h4>
1145
1146 <p>Now, let's add a rule to explicitly deny this request.</p>
1147
1148 <pre>
1149 100 acl read path="/tmp/file1"
1150 1000 deny
1151 </pre>
1152
1153 <p>Append above rule using /usr/sbin/caitsith-loadpolicy :</p>
1154
1155 <pre class="command">
1156 # /usr/sbin/caitsith-loadpolicy
1157 </pre>
1158 <pre>
1159 100 acl read path="/tmp/file1"
1160 1000 deny
1161 ^D
1162 </pre>
1163
1164 <p>Rules that have same priority (in this rule, 100) and same operation (in this rule, read) and same condition (in this rule, path="/tmp/file1") are automatically merged. Therefore, you will find</p>
1165
1166 <pre>
1167 100 acl read path="/tmp/file1"
1168 audit 1
1169 1000 deny
1170 </pre>
1171
1172 <p>rather than</p>
1173
1174 <pre>
1175 100 acl read path="/tmp/file1"
1176 audit 1
1177
1178 100 acl read path="/tmp/file1"
1179 1000 deny
1180 </pre>
1181
1182 <p>when you read /sys/kernel/security/caitsith/policy .</p>
1183
1184 <p>Then, open /tmp/file1 for reading.</p>
1185
1186 <pre class="command">
1187 # cat /tmp/file1
1188 </pre>
1189 <pre>
1190 cat: /tmp/file1: Operation not permitted
1191 </pre>
1192
1193 <p>This time, access request was denied by CaitSith.</p>
1194
1195 <p>Check /var/log/caitsith/denied.log for access denied log of this access request. You will find an entry like below:</p>
1196
1197 <pre class="command">
1198 # grep /tmp/file1 /var/log/caitsith/denied.log
1199 </pre>
1200 <pre>
1201 #2012/04/08 04:59:53# global-pid=3682 result=denied priority=100 / read path="/tmp/file1" task.pid=3682 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1202 </pre>
1203
1204 <p>Note the <strong>result=denied</strong> part of the entry. This indicates that access request was checked and matched "deny" rule.</p>
1205
1206 <p>If /usr/sbin/caitsith-notifyd is running, you will receive a notification mail. The content is same with access denied logs.</p>
1207
1208 <pre class="command">
1209 # mail
1210 </pre>
1211 <pre>
1212 Heirloom Mail version 12.4 7/29/08. Type ? for help.
1213 "/var/spool/mail/root": 1 message 1 new
1214 &gt;N 1 root Sun Apr 8 13:59 20/1231 "Notification from caitsith-notifyd"
1215 &amp;
1216 Message 1:
1217 From root@ccsecurity.localdomain Sun Apr 8 13:59:53 2012
1218 Return-Path: &lt;root@ccsecurity.localdomain&gt;
1219 X-Original-To: root@localhost
1220 Delivered-To: root@localhost.localdomain
1221 Date: Sun, 08 Apr 2012 13:59:53 +0900
1222 To: root@localhost.localdomain
1223 Subject: Notification from caitsith-notifyd
1224 User-Agent: Heirloom mailx 12.4 7/29/08
1225 Content-Type: text/plain; charset=us-ascii
1226 From: root@caitsith.localdomain (root)
1227 Status: R
1228
1229 Q0-0
1230 #2012/04/08 04:59:53# global-pid=3682 result=denied priority=100 / read path="/tmp/file1" task.pid=3682 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1231 </pre>
1232
1233 <p>Now, let's remove a rule to explicitly deny this request.</p>
1234
1235 <pre>
1236 100 acl read path="/tmp/file1"
1237 delete 1000 deny
1238 </pre>
1239
1240 <p>Append above rule using /usr/sbin/caitsith-loadpolicy :</p>
1241
1242 <pre class="command">
1243 # /usr/sbin/caitsith-loadpolicy
1244 </pre>
1245 <pre>
1246 100 acl read path="/tmp/file1"
1247 delete 1000 deny
1248 ^D
1249 </pre>
1250
1251 <p>You will find</p>
1252
1253 <pre>
1254 100 acl read path="/tmp/file1"
1255 audit 1
1256 </pre>
1257
1258 <p>rather than</p>
1259
1260 <pre>
1261 100 acl read path="/tmp/file1"
1262 audit 1
1263 1000 deny
1264 delete 1000 deny
1265 </pre>
1266
1267 <p>when you read /sys/kernel/security/caitsith/policy .</p>
1268
1269 <h4><a name="3.3.4">3.3.4. Filtering audit logs</a></h4>
1270
1271 <p>Now, open /tmp/file1 for reading.</p>
1272
1273 <pre class="command">
1274 # cat /tmp/file1
1275 </pre>
1276
1277 <p>Check /var/log/caitsith/unmatched.log for access unmatched log of this access request. You will find entries like below:</p>
1278
1279 <pre class="command">
1280 # grep /tmp/file1 /var/log/caitsith/unmatched.log
1281 </pre>
1282 <pre>
1283 #2012/04/08 04:58:40# global-pid=3678 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3678 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1284 #2012/04/08 05:01:00# global-pid=3695 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3695 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1285 </pre>
1286
1287 <p>The former entry was generated before adding explicit "deny" rule. The latter entry was generated after removing explicit "deny" rule. You might want to filter the output using tail command:</p>
1288
1289 <pre class="command">
1290 # grep /tmp/file1 /var/log/caitsith/unmatched.log | tail -n 1
1291 </pre>
1292 <pre>
1293 #2012/04/08 05:01:00# global-pid=3695 result=unmatched priority=100 / read path="/tmp/file1" task.pid=3695 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1294 </pre>
1295
1296 <h4><a name="3.3.5">3.3.5. Access requests which will be explicitly allowed by CaitSith</a></h4>
1297
1298 <p>Next, let's see audit logs with explicitly matching "allow" rules.</p>
1299
1300 <p>By default CaitSith does not generate audit logs with explicitly matching "allow" rules. Change policy configuration to generate such logs.</p>
1301
1302 <pre>
1303 quota audit[1] allowed=1024
1304 </pre>
1305
1306 <p>Append above rule using /usr/sbin/caitsith-loadpolicy :</p>
1307
1308 <pre class="command">
1309 # echo 'quota audit[1] allowed=1024' | /usr/sbin/caitsith-loadpolicy
1310 </pre>
1311
1312 <p>Preferences that have same name (in this rule, audit[1]) are automatically merged. Therefore, you will find</p>
1313
1314 <pre>
1315 quota audit[1] allowed=1024 denied=1024 unmatched=1024
1316 </pre>
1317
1318 <p>rather than</p>
1319
1320 <pre>
1321 quota audit[1] allowed=0 denied=1024 unmatched=1024
1322 quota audit[1] allowed=1024
1323 </pre>
1324
1325 <p>when you read /sys/kernel/security/caitsith/policy .</p>
1326
1327 <pre>
1328 100 acl read path="/tmp/file1"
1329 1000 allow
1330 </pre>
1331
1332 <p>Append above rule using /usr/sbin/caitsith-loadpolicy :</p>
1333
1334 <pre class="command">
1335 # /usr/sbin/caitsith-loadpolicy
1336 </pre>
1337 <pre>
1338 100 acl read path="/tmp/file1"
1339 1000 allow
1340 ^D
1341 </pre>
1342
1343 <p>Since audit logs with explicitly matching "allow" rules tend to grow rapidly, by default /usr/sbin/caitsith-auditd discards such logs by writing to /dev/null (specified in /etc/caitsith/tools/auditd.conf ).
1344 Therefore, temporarily stop /usr/sbin/caitsith-auditd process in order to read audit logs from /sys/kernel/security/caitsith/audit interface.</p>
1345
1346 <pre class="command">
1347 # killall -KILL caitsith-auditd
1348 </pre>
1349
1350 <p>Then, open /tmp/file1 for reading.</p>
1351
1352 <pre class="command">
1353 # cat /tmp/file1
1354 </pre>
1355
1356 <p>Check /sys/kernel/security/caitsith/audit for audit log of this access request. This time, you will find an entry like below:</p>
1357
1358 <pre class="command">
1359 # cat -v /sys/kernel/security/caitsith/audit
1360 </pre>
1361 <pre>
1362 #2012/04/08 05:03:03# global-pid=3720 result=allowed priority=100 / read path="/tmp/file1" task.pid=3720 task.ppid=3653 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=0 path.ino=2113451 path.major=8 path.minor=1 path.perm=0644 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=2097153 path.parent.major=8 path.parent.minor=1 path.parent.perm=01777 path.parent.type=directory path.parent.fsmagic=0xEF53
1363 ^@
1364 </pre>
1365
1366 <p>Note the <strong>result=allowed</strong> part of the entry. This indicates that access request was checked and matched "allow" rule.</p>
1367
1368 <p>Restart /usr/sbin/caitsith-auditd process.</p>
1369
1370 <pre class="command">
1371 # /usr/sbin/caitsith-auditd
1372 </pre>
1373
1374 <p>Also, restore the audit logs configuration:</p>
1375
1376 <pre>
1377 quota audit[1] allowed=0
1378 </pre>
1379
1380 <p>Append above rule using /usr/sbin/caitsith-loadpolicy :</p>
1381
1382 <pre class="command">
1383 # echo 'quota audit[1] allowed=0' | /usr/sbin/caitsith-loadpolicy
1384 </pre>
1385
1386 <hr>
1387 <h3><a name="3.4">3.4. Understanding two viewpoints</a></h3>
1388
1389 <p>CaitSith supports writing access restriction rules from two viewpoints. One is from the point of view of "subject" (a resource which requests access on object). The other is from the point of view of "object" (a resource which subject requests access).</p>
1390
1391 <p>The advantage of the former approach is that the rules clearly explains and restricts what each subject is allowed to access which object.
1392 This approach is powerful when you can afford identifying all possible subjects and defining the rules for each subject.
1393 But the disadvantage is that it is difficult to identify all possible subjects and define the rules for each subject.
1394 Therefore, in reality, this approach tends to restrict only specific subjects.
1395 If one of subjects which is not restricted by this approach is cracked or misbehaved, nothing can protect objects you want to protect.</p>
1396
1397 <p>The advantage of the latter approach is that the rules clearly explains and restricts what object might be accessed by which subject.
1398 This approach is powerful when you can afford identifying objects you want to protect and defining rules for each object.
1399 This approach can compensate for the disadvantage of the former approach because this approach can restrict access even when it is difficult to
1400 identify all possible subjects and define the rules for each possible subject.</p>
1401
1402 <h4><a name="3.4.1">3.4.1. Writing access restriction rules from the point of view of "subject".</a></h4>
1403
1404 <p>Below entry is an example of restricting programs which can be executed from /usr/sbin/httpd program.</p>
1405
1406 <pre>
1407 0 acl execute task.exe="/usr/sbin/httpd"
1408 audit 1
1409 1 allow path="/var/www/cgi-bin/counter.cgi"
1410 100 deny
1411 </pre>
1412
1413 <p>The <strong>0 acl execute task.exe="/usr/sbin/httpd"</strong> line means check rules for executing programs from /usr/sbin/httpd program. Since <strong>task.exe="/usr/sbin/httpd"</strong> is specified in this line, this line tells CaitSith <strong>check rules for executing programs only if current thread's program name is /usr/sbin/httpd</strong>.</p>
1414
1415 <p>The line <strong>1 allow path="/var/www/cgi-bin/counter.cgi"</strong> means that allow if the pathname of the program to execute is /var/www/cgi-bin/counter.cgi . This line tells CaitSith "allow execution of /var/www/cgi-bin/counter.cgi".</p>
1416
1417 <p>The line <strong>100 deny</strong> means deny unconditionally. This tells CaitSith "unconditionally deny execution of programs".</p>
1418
1419 <p>Since the line starting with <strong>1 allow</strong> has higher priority than the line starting with <strong>100 deny</strong>, CaitSith will allow execution of /var/www/cgi-bin/counter.cgi .</p>
1420
1421 <p>To summarize this rule, /usr/sbin/httpd can execute <strong>only</strong> /var/www/cgi-bin/counter.cgi .</p>
1422
1423 <p>The line <strong>audit 1</strong> means that use audit rules defined in the <strong>quota audit[1]</strong> line. This line tells CaitSith generate audit logs up to entries defined in the <strong>quota audit[1]</strong> line. The default configuration generated by executing /usr/lib64/caitsith/init_policy command is</p>
1424
1425 <pre>
1426 quota audit[1] allowed=0 denied=1024 unmatched=1024
1427 </pre>
1428
1429 <p>which means do not generate audit logs if matched an "allow" line and generate audit logs up to 1024 entries if matched a "deny" line and generate audit logs up to 1024 lines if matched neither an "allow" line nor a "deny" line. Though, since the block starting with <strong>0 acl execute task.exe="/usr/sbin/httpd"</strong> is terminated with explicit <strong>100 deny</strong> line, this block shall match either an "allow" line or a "deny" line.</p>
1430
1431 <h4><a name="3.4.2">3.4.2. Writing access restriction rules from the point of view of "object".</a></h4>
1432
1433 <p>Below entry is default configuration generated by executing /usr/lib64/caitsith/init_policy command.</p>
1434
1435 <pre>
1436 0 acl modify_policy
1437 audit 1
1438 1 deny task.uid!=0
1439 1 deny task.euid!=0
1440 100 allow task.exe="/usr/sbin/caitsith-loadpolicy"
1441 100 allow task.exe="/usr/sbin/caitsith-queryd"
1442 10000 deny
1443 </pre>
1444
1445 <p>The <strong>0 acl modify_policy</strong> line means check rules for modifying policy configuration via /sys/kernel/security/caitsith/policy interface. Since no additional conditions are specified in this line, this line tells CaitSith <strong>unconditionally check</strong> rules for modifying policy configuration via /sys/kernel/security/caitsith/policy interface.</p>
1446
1447 <p>The line <strong>1 deny task.uid!=0</strong> means that deny if current thread's user ID is not 0. This line tells CaitSith "deny modification of policy configuration via /sys/kernel/security/caitsith/policy interface if current thread's user ID is not 0".</p>
1448
1449 <p>The line <strong>1 deny task.euid!=0</strong> means that deny if current thread's effective user ID is not 0. This line tells CaitSith "deny modification of policy configuration via /sys/kernel/security/caitsith/policy interface if current thread's effective user ID is not 0".</p>
1450
1451 <p>Note the difference between</p>
1452
1453 <pre>
1454 1 deny task.uid!=0
1455 1 deny task.euid!=0
1456 </pre>
1457
1458 <p>and</p>
1459
1460 <pre>
1461 1 deny task.uid!=0 task.euid!=0
1462 </pre>
1463
1464 <p>. The former conditions tell CaitSith "deny if current thread's user ID is not 0 <strong>or</strong> current thread's effective user ID is not 0", while the latter conditions tell CaitSith "deny if current thread's user ID is not 0 <strong>and</strong> current thread's effective user ID is not 0".</p>
1465
1466 <p>The line <strong>100 allow task.exe="/usr/sbin/caitsith-loadpolicy"</strong> means that allow if current thread's program name is /usr/sbin/caitsith-loadpolicy . This tells CaitSith finish evaluation of this block starting with the <strong>0 acl modify_policy</strong> line if current thread's program name is /usr/sbin/caitsith-loadpolicy . If there are more blocks, CaitSith will evaluate them. If there are no more blocks, CaitSith will allow modifying policy configuration via /sys/kernel/security/caitsith/policy interface.</p>
1467
1468 <p>The line <strong>100 allow task.exe="/usr/sbin/caitsith-queryd"</strong> means that allow if current thread's program name is /usr/sbin/caitsith-queryd . This tells CaitSith finish evaluation of this block starting with the <strong>0 acl modify_policy</strong> line if current thread's program name is /usr/sbin/caitsith-queryd . The usage of /usr/sbin/caitsith-queryd will be explained later.</p>
1469
1470 <p>The line <strong>10000 deny</strong> means deny unconditionally. This tells CaitSith "unconditionally deny modification of policy configuration via /sys/kernel/security/caitsith/policy interface".</p>
1471
1472 <p>Since lines starting with <strong>1 deny</strong> have higher priority than lines starting with <strong>100 allow</strong>, CaitSith will deny modifying policy configuration via /sys/kernel/security/caitsith/policy interface if current thread's user ID is not 0 or current thread's effective user ID is not 0. In other words, only root user (where current thread's user ID and effective user ID are both 0) can modify policy configuration via /sys/kernel/security/caitsith/policy interface.</p>
1473
1474 <p>Since lines starting with <strong>100 allow</strong> have higher priority than a line starting with <strong>10000 deny</strong>, CaitSith will allow modifying policy configuration via /sys/kernel/security/caitsith/policy interface if current thread's program name is /usr/sbin/caitsith-loadpolicy or current thread's program name is /usr/sbin/caitsith-queryd . In other words, other programs such as /bin/sh , /bin/echo , /bin/cat are not allowed to modify policy configuration via /sys/kernel/security/caitsith/policy interface.</p>
1475
1476 <p>To summarize this rule, only /usr/sbin/caitsith-loadpolicy or /usr/sbin/caitsith-queryd command running as root user can modify policy configuration via /sys/kernel/security/caitsith/policy interface.</p>
1477
1478 <p>Note the difference between</p>
1479
1480 <pre>
1481 0 acl execute task.exe="/usr/sbin/httpd"
1482 audit 1
1483 1 allow path="/var/www/cgi-bin/counter.cgi"
1484 100 deny
1485 </pre>
1486
1487 <p>and</p>
1488
1489 <pre>
1490 0 acl execute path="/var/www/cgi-bin/counter.cgi"
1491 audit 1
1492 1 allow task.exe="/usr/sbin/httpd"
1493 100 deny
1494 </pre>
1495
1496 <p>. The former means "/usr/sbin/httpd can execute <strong>only</strong> /var/www/cgi-bin/counter.cgi", while the latter means "<strong>only</strong> /usr/sbin/httpd can execute /var/www/cgi-bin/counter.cgi".</p>
1497
1498 <p>CaitSith supports restricting other arguments such as command line arguments and environment variables. Syntax for restricting other arguments will be explained later.</p>
1499
1500 <h4><a name="3.4.3">3.4.3. Writing access restriction rules from the point of view of both "subject" and "object".</a></h4>
1501
1502 <p>It is possible to write access restriction rules like</p>
1503
1504 <pre>
1505 0 acl execute task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1506 audit 1
1507 1 allow task.uid!=0
1508 100 deny
1509 </pre>
1510
1511 <p>and</p>
1512
1513 <pre>
1514 0 acl execute task.uid!=0
1515 audit 1
1516 1 allow task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1517 100 deny
1518 </pre>
1519
1520 <p>. The former means "/usr/sbin/httpd is allowed to execute /var/www/cgi-bin/counter.cgi only if current thread's user ID is not 0", while the latter means "only execution of /var/www/cgi-bin/counter.cgi from /usr/sbin/httpd is allowed if current thread's user ID is not 0".</p>
1521
1522 <p>Also, it is possible to write access restriction rules like</p>
1523
1524 <pre>
1525 0 acl execute
1526 audit 1
1527 1 allow task.exe="/usr/sbin/httpd" path="/var/www/cgi-bin/counter.cgi"
1528 100 deny
1529 </pre>
1530
1531 <p>which means "any execute requests other than execution of /var/www/cgi-bin/counter.cgi from /usr/sbin/httpd are denied" (DO NOT TRY THIS EXAMPLE, or you will no longer be able to run any commands).</p>
1532
1533 <hr>
1534 <h3><a name="3.5">3.5. Steps for writing access restriction rules</a></h3>
1535
1536 <p>An example of steps for writing access restriction rules using pathnames is shown here.</p>
1537
1538 <p>Step 1: Determine resource to restrict access.</p>
1539
1540 <p>Below example restricts opening /etc/shadow for reading.</p>
1541
1542 <pre>
1543 100 acl read path="/etc/shadow"
1544 audit 1
1545 </pre>
1546
1547 <p>Step 2: Gather logs of accessing resources.</p>
1548
1549 <p>As you operate the system with above example, access unmatched logs are generated and spooled in /sys/kernel/security/caitsith/audit interface when access request of opening /etc/shadow for reading happens. If /usr/sbin/caitsith-auditd is running, access unmatched logs will be moved to /var/log/caitsith/unmatched.log .</p>
1550
1551 <pre>
1552 #2012/03/02 08:11:51# global-pid=2826 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2826 task.ppid=2814 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/usr/bin/passwd" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33708 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1553 </pre>
1554
1555 <p>Step 3: Decide whether to allow or deny.</p>
1556
1557 <p>Examine the log and decide whether to allow this access request or not. To allow this request, add an allow line. Below example allows this request to /usr/bin/passwd program.</p>
1558
1559 <pre>
1560 100 acl read path="/etc/shadow"
1561 audit 1
1562 100 allow task.exe="/usr/bin/passwd"
1563 </pre>
1564
1565 <p>Step 4: Gather again logs of accessing resources.</p>
1566
1567 <p>Operate the system again. For example, /usr/sbin/sshd program and /bin/cat program have requested opening /etc/shadow for reading.</p>
1568
1569 <pre>
1570 #2012/03/02 08:13:06# global-pid=2831 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2831 task.ppid=2691 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/usr/sbin/sshd" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1571 #2012/03/02 08:13:12# global-pid=2837 result=unmatched priority=100 / read path="/etc/shadow" task.pid=2837 task.ppid=2833 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1572 </pre>
1573
1574 <p>Step 5: Decide again whether to allow or deny.</p>
1575
1576 <p>Add an allow line with /usr/sbin/sshd program in order to allow access by /usr/sbin/sshd program. Also, add a deny line with /bin/cat program in order to deny access by /bin/cat program. Give higher priority (i.e. smaller $cond_priority value) to deny line than allow line so that deny lines are checked before allow lines are checked.</p>
1577
1578 <pre>
1579 100 acl read path="/etc/shadow"
1580 audit 1
1581 10 deny task.exe="/bin/cat"
1582 100 allow task.exe="/usr/bin/passwd"
1583 100 allow task.exe="/usr/sbin/sshd"
1584 </pre>
1585
1586 <p>From now on, attempt to read /etc/shadow using /bin/cat should be denied and access denied logs should be generated. If /usr/sbin/caitsith-auditd is running, access denied logs will be moved to /var/log/caitsith/denied.log .</p>
1587
1588 <pre>
1589 #2012/03/02 08:14:38# global-pid=2842 result=denied priority=100 / read path="/etc/shadow" task.pid=2842 task.ppid=2833 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/bin/cat" task.domain="/usr/sbin/sshd" path.uid=0 path.gid=42 path.ino=33716 path.major=8 path.minor=1 path.perm=0640 path.type=file path.fsmagic=0xEF53 path.parent.uid=0 path.parent.gid=0 path.parent.ino=32769 path.parent.major=8 path.parent.minor=1 path.parent.perm=0755 path.parent.type=directory path.parent.fsmagic=0xEF53
1590 </pre>
1591
1592 <p>Step 6: Finish up a rule.</p>
1593
1594 <p>After you have finished enumerating all allow lines and deny lines, add a deny line with lowest priority (i.e. largest $cond_priority value within this block).</p>
1595
1596 <pre>
1597 100 acl read path="/etc/shadow"
1598 audit 1
1599 10 deny task.exe="/bin/cat"
1600 100 allow task.exe="/usr/bin/passwd"
1601 100 allow task.exe="/usr/sbin/sshd"
1602 10000 deny
1603 </pre>
1604
1605 <p>A rule for restricting /etc/shadow for opening is now completed. Please do not copy and paste this example, for there must be other programs which need to open /etc/shadow for reading.</p>
1606
1607 <hr>
1608 <h3><a name="3.6">3.6. Restricting access in various ways</a></h3>
1609
1610 <p>The rule demonstrated in <a href="#3.5">3.5. Steps for writing access restriction rules</a> alone cannot prevent diverted accesses such as creating a hard link of /etc/shadow . CaitSith supports various variables for writing access restriction rules. If the resource to protect has characteristic attribute, it is recommended to utilize such attributes. (The full list of available variables/attributes will be explained in <a href="#condition_list">4. List of conditions</a>.)</p>
1611
1612 <p>On several distributions, /etc/shadow is owned by shadow group. In that case, this rule can be modified to below. (Below example assumes that shadow group's group ID is 42.)</p>
1613
1614 <pre>
1615 100 acl read path.gid=42
1616 audit 1
1617 10 deny task.exe="/bin/cat"
1618 100 allow task.exe="/usr/bin/passwd"
1619 100 allow task.exe="/usr/sbin/sshd"
1620 10000 deny
1621 </pre>
1622
1623 <p>On several distributions, /etc/shadow is owned by root user and root group and has DAC permissions 0400. In that case, you might want to use a rule like below. (You should check whether there are other files with such attributes.)</p>
1624
1625 <pre>
1626 100 acl read path.uid=0 path.gid=0 path.perm=0400
1627 audit 1
1628 10 deny task.exe="/bin/cat"
1629 100 allow task.exe="/usr/bin/passwd"
1630 100 allow task.exe="/usr/sbin/sshd"
1631 10000 deny
1632 </pre>
1633
1634 <p>It is recommended to restrict other operations such as mount, link and rename. For example, a rule to deny creation of hard links which is not owned by the user would look like below. (Note that the variable which refers source pathname of link operation is "old_path" rather than "path" because the operation is "link".)</p>
1635
1636 <pre>
1637 100 acl link old_path.uid!=task.uid
1638 audit 1
1639 100 deny
1640 </pre>
1641
1642 <p>If you can split files into different filesystems or different partitions, you might be able to utilize more variables. For example, rules for denying creation of hard links on tmpfs filesystem (tmpfs filesystem's magic number is 0x01021994) would look like below.</p>
1643
1644 <pre>
1645 100 acl link old_path.fsmagic=0x01021994
1646 audit 1
1647 10 deny
1648 </pre>
1649
1650 <p>Splitting into different partitions and defining rules based on partition's attributes will help preventing diverted access via creating hard links, for hard links cannot be created across partitions. Separating /home partition from / partition will be useful when protecting resources in /home partition.</p>
1651
1652 <hr>
1653 <h2><a name="condition_list">4. List of conditions</a></h2>
1654
1655 <hr>
1656 <h3><a name="4.1">4.1. Using string arguments in conditions</a></h3>
1657
1658 <p>Arguments such as file's pathnames and command line arguments and environment variables are handled as string argument.</p>
1659
1660 <h4><a name="4.1.1">4.1.1. About string argument representation rule</a></h4>
1661
1662 <p>All ASCII printable characters other than \ character (i.e. from 33 to 91 and from 93 to 126) are represented as is.</p>
1663
1664 <p>All other characters (i.e. from 0 to 32, 92 and from 127 to 255) are represented using \ooo style octal form.</p>
1665
1666 <table border="1">
1667 <tr>
1668 <td>
1669 <table><tr><td></td><td>Lower 4 bits</td></tr><tr><td>Upper 4 bits</td><td></td></tr></table>
1670 </td>
1671 <th><p>0x0</p></th>
1672 <th><p>0x1</p></th>
1673 <th><p>0x2</p></th>
1674 <th><p>0x3</p></th>
1675 <th><p>0x4</p></th>
1676 <th><p>0x5</p></th>
1677 <th><p>0x6</p></th>
1678 <th><p>0x7</p></th>
1679 <th><p>0x8</p></th>
1680 <th><p>0x9</p></th>
1681 <th><p>0xA</p></th>
1682 <th><p>0xB</p></th>
1683 <th><p>0xC</p></th>
1684 <th><p>0xD</p></th>
1685 <th><p>0xE</p></th>
1686 <th><p>0xF</p></th>
1687 </tr>
1688 <tr>
1689 <th><p>0x0</p></th>
1690 <td><p>\000</p></td>
1691 <td><p>\001</p></td>
1692 <td><p>\002</p></td>
1693 <td><p>\003</p></td>
1694 <td><p>\004</p></td>
1695 <td><p>\005</p></td>
1696 <td><p>\006</p></td>
1697 <td><p>\007</p></td>
1698 <td><p>\010</p></td>
1699 <td><p>\011</p></td>
1700 <td><p>\012</p></td>
1701 <td><p>\013</p></td>
1702 <td><p>\014</p></td>
1703 <td><p>\015</p></td>
1704 <td><p>\016</p></td>
1705 <td><p>\017</p></td>
1706 </tr>
1707 <tr>
1708 <th><p>0x1</p></th>
1709 <td><p>\020</p></td>
1710 <td><p>\021</p></td>
1711 <td><p>\022</p></td>
1712 <td><p>\023</p></td>
1713 <td><p>\024</p></td>
1714 <td><p>\025</p></td>
1715 <td><p>\026</p></td>
1716 <td><p>\027</p></td>
1717 <td><p>\030</p></td>
1718 <td><p>\031</p></td>
1719 <td><p>\032</p></td>
1720 <td><p>\033</p></td>
1721 <td><p>\034</p></td>
1722 <td><p>\035</p></td>
1723 <td><p>\036</p></td>
1724 <td><p>\037</p></td>
1725 </tr>
1726 <tr>
1727 <th><p>0x2</p></th>
1728 <td><p>\040</p></td>
1729 <td><p>!</p></td>
1730 <td><p>"</p></td>
1731 <td><p>#</p></td>
1732 <td><p>$</p></td>
1733 <td><p>%</p></td>
1734 <td><p>&amp;</p></td>
1735 <td><p>'</p></td>
1736 <td><p>(</p></td>
1737 <td><p>)</p></td>
1738 <td><p>*</p></td>
1739 <td><p>+</p></td>
1740 <td><p>,</p></td>
1741 <td><p>-</p></td>
1742 <td><p>.</p></td>
1743 <td><p>/</p></td>
1744 </tr>
1745 <tr>
1746 <th><p>0x3</p></th>
1747 <td><p>0</p></td>
1748 <td><p>1</p></td>
1749 <td><p>2</p></td>
1750 <td><p>3</p></td>
1751 <td><p>4</p></td>
1752 <td><p>5</p></td>
1753 <td><p>6</p></td>
1754 <td><p>7</p></td>
1755 <td><p>8</p></td>
1756 <td><p>9</p></td>
1757 <td><p>:</p></td>
1758 <td><p>;</p></td>
1759 <td><p>&lt;</p></td>
1760 <td><p>=</p></td>
1761 <td><p>&gt;</p></td>
1762 <td><p>?</p></td>
1763 </tr>
1764 <tr>
1765 <th><p>0x4</p></th>
1766 <td><p>@</p></td>
1767 <td><p>A</p></td>
1768 <td><p>B</p></td>
1769 <td><p>C</p></td>
1770 <td><p>D</p></td>
1771 <td><p>E</p></td>
1772 <td><p>F</p></td>
1773 <td><p>G</p></td>
1774 <td><p>H</p></td>
1775 <td><p>I</p></td>
1776 <td><p>J</p></td>
1777 <td><p>K</p></td>
1778 <td><p>L</p></td>
1779 <td><p>M</p></td>
1780 <td><p>N</p></td>
1781 <td><p>O</p></td>
1782 </tr>
1783 <tr>
1784 <th><p>0x5</p></th>
1785 <td><p>P</p></td>
1786 <td><p>Q</p></td>
1787 <td><p>R</p></td>
1788 <td><p>S</p></td>
1789 <td><p>T</p></td>
1790 <td><p>U</p></td>
1791 <td><p>V</p></td>
1792 <td><p>W</p></td>
1793 <td><p>X</p></td>
1794 <td><p>Y</p></td>
1795 <td><p>Z</p></td>
1796 <td><p>[</p></td>
1797 <td><p>\134</p></td>
1798 <td><p>]</p></td>
1799 <td><p>^</p></td>
1800 <td><p>_</p></td>
1801 </tr>
1802 <tr>
1803 <th><p>0x6</p></th>
1804 <td><p>`</p></td>
1805 <td><p>a</p></td>
1806 <td><p>b</p></td>
1807 <td><p>c</p></td>
1808 <td><p>d</p></td>
1809 <td><p>e</p></td>
1810 <td><p>f</p></td>
1811 <td><p>g</p></td>
1812 <td><p>h</p></td>
1813 <td><p>i</p></td>
1814 <td><p>j</p></td>
1815 <td><p>k</p></td>
1816 <td><p>l</p></td>
1817 <td><p>m</p></td>
1818 <td><p>n</p></td>
1819 <td><p>o</p></td>
1820 </tr>
1821 <tr>
1822 <th><p>0x7</p></th>
1823 <td><p>p</p></td>
1824 <td><p>q</p></td>
1825 <td><p>r</p></td>
1826 <td><p>s</p></td>
1827 <td><p>t</p></td>
1828 <td><p>u</p></td>
1829 <td><p>v</p></td>
1830 <td><p>w</p></td>
1831 <td><p>x</p></td>
1832 <td><p>y</p></td>
1833 <td><p>z</p></td>
1834 <td><p>{</p></td>
1835 <td><p>|</p></td>
1836 <td><p>}</p></td>
1837 <td><p>~</p></td>
1838 <td><p>\177</p></td>
1839 </tr>
1840 <tr>
1841 <th><p>0x8</p></th>
1842 <td><p>\200</p></td>
1843 <td><p>\201</p></td>
1844 <td><p>\202</p></td>
1845 <td><p>\203</p></td>
1846 <td><p>\204</p></td>
1847 <td><p>\205</p></td>
1848 <td><p>\206</p></td>
1849 <td><p>\207</p></td>
1850 <td><p>\210</p></td>
1851 <td><p>\211</p></td>
1852 <td><p>\212</p></td>
1853 <td><p>\213</p></td>
1854 <td><p>\214</p></td>
1855 <td><p>\215</p></td>
1856 <td><p>\216</p></td>
1857 <td><p>\217</p></td>
1858 </tr>
1859 <tr>
1860 <th><p>0x9</p></th>
1861 <td><p>\220</p></td>
1862 <td><p>\221</p></td>
1863 <td><p>\222</p></td>
1864 <td><p>\223</p></td>
1865 <td><p>\224</p></td>
1866 <td><p>\225</p></td>
1867 <td><p>\226</p></td>
1868 <td><p>\227</p></td>
1869 <td><p>\230</p></td>
1870 <td><p>\231</p></td>
1871 <td><p>\232</p></td>
1872 <td><p>\233</p></td>
1873 <td><p>\234</p></td>
1874 <td><p>\235</p></td>
1875 <td><p>\236</p></td>
1876 <td><p>\237</p></td>
1877 </tr>
1878 <tr>
1879 <th><p>0xA</p></th>
1880 <td><p>\240</p></td>
1881 <td><p>\241</p></td>
1882 <td><p>\242</p></td>
1883 <td><p>\243</p></td>
1884 <td><p>\244</p></td>
1885 <td><p>\245</p></td>
1886 <td><p>\246</p></td>
1887 <td><p>\247</p></td>
1888 <td><p>\250</p></td>
1889 <td><p>\251</p></td>
1890 <td><p>\252</p></td>
1891 <td><p>\253</p></td>
1892 <td><p>\254</p></td>
1893 <td><p>\255</p></td>
1894 <td><p>\256</p></td>
1895 <td><p>\257</p></td>
1896 </tr>
1897 <tr>
1898 <th><p>0xB</p></th>
1899 <td><p>\260</p></td>
1900 <td><p>\261</p></td>
1901 <td><p>\262</p></td>
1902 <td><p>\263</p></td>
1903 <td><p>\264</p></td>
1904 <td><p>\265</p></td>
1905 <td><p>\266</p></td>
1906 <td><p>\267</p></td>
1907 <td><p>\270</p></td>
1908 <td><p>\271</p></td>
1909 <td><p>\272</p></td>
1910 <td><p>\273</p></td>
1911 <td><p>\274</p></td>
1912 <td><p>\275</p></td>
1913 <td><p>\276</p></td>
1914 <td><p>\277</p></td>
1915 </tr>
1916 <tr>
1917 <th><p>0xC</p></th>
1918 <td><p>\300</p></td>
1919 <td><p>\301</p></td>
1920 <td><p>\302</p></td>
1921 <td><p>\303</p></td>
1922 <td><p>\304</p></td>
1923 <td><p>\305</p></td>
1924 <td><p>\306</p></td>
1925 <td><p>\307</p></td>
1926 <td><p>\310</p></td>
1927 <td><p>\311</p></td>
1928 <td><p>\312</p></td>
1929 <td><p>\313</p></td>
1930 <td><p>\314</p></td>
1931 <td><p>\315</p></td>
1932 <td><p>\316</p></td>
1933 <td><p>\317</p></td>
1934 </tr>
1935 <tr>
1936 <th><p>0xD</p></th>
1937 <td><p>\320</p></td>
1938 <td><p>\321</p></td>
1939 <td><p>\322</p></td>
1940 <td><p>\323</p></td>
1941 <td><p>\324</p></td>
1942 <td><p>\325</p></td>
1943 <td><p>\326</p></td>
1944 <td><p>\327</p></td>
1945 <td><p>\330</p></td>
1946 <td><p>\331</p></td>
1947 <td><p>\332</p></td>
1948 <td><p>\333</p></td>
1949 <td><p>\334</p></td>
1950 <td><p>\335</p></td>
1951 <td><p>\336</p></td>
1952 <td><p>\337</p></td>
1953 </tr>
1954 <tr>
1955 <th><p>0xE</p></th>
1956 <td><p>\340</p></td>
1957 <td><p>\341</p></td>
1958 <td><p>\342</p></td>
1959 <td><p>\343</p></td>
1960 <td><p>\344</p></td>
1961 <td><p>\345</p></td>
1962 <td><p>\346</p></td>
1963 <td><p>\347</p></td>
1964 <td><p>\350</p></td>
1965 <td><p>\351</p></td>
1966 <td><p>\352</p></td>
1967 <td><p>\353</p></td>
1968 <td><p>\354</p></td>
1969 <td><p>\355</p></td>
1970 <td><p>\356</p></td>
1971 <td><p>\357</p></td>
1972 </tr>
1973 <tr>
1974 <th><p>0xF</p></th>
1975 <td><p>\360</p></td>
1976 <td><p>\361</p></td>
1977 <td><p>\362</p></td>
1978 <td><p>\363</p></td>
1979 <td><p>\364</p></td>
1980 <td><p>\365</p></td>
1981 <td><p>\366</p></td>
1982 <td><p>\367</p></td>
1983 <td><p>\370</p></td>
1984 <td><p>\371</p></td>
1985 <td><p>\372</p></td>
1986 <td><p>\373</p></td>
1987 <td><p>\374</p></td>
1988 <td><p>\375</p></td>
1989 <td><p>\376</p></td>
1990 <td><p>\377</p></td>
1991 </tr>
1992 </table>
1993
1994 <p>Some examples are shown below.</p>
1995
1996 <pre>
1997 /bin/sh
1998 /home/demo/Documents\040and\040Settings
1999 </pre>
2000
2001 <h4><a name="4.1.2">4.1.2. Grouping string arguments using wildcard expressions.</a></h4>
2002
2003 <p>It is possible to use wildcards listed below in order to match string patterns.</p>
2004
2005 <table border="1">
2006 <tr>
2007 <th><p>Wildcard</p></th>
2008 <th><p>Pattern match</p></th>
2009 <th><p>Examples</p></th>
2010 </tr>
2011 <tr>
2012 <td><p>\*</p></td>
2013 <td><p>0 or more repetitions of characters other than "/"</p></td>
2014 <td><p>/var/log/samba/\*</p></td>
2015 </tr>
2016 <tr>
2017 <td><p>\@</p></td>
2018 <td><p>0 or more repetitions of characters other than "/" or "."</p></td>
2019 <td><p>/var/www/html/\@.html</p></td>
2020 </tr>
2021 <tr>
2022 <td><p>\?</p></td>
2023 <td><p>1 byte character other than "/"</p></td>
2024 <td><p>/tmp/mail.\?\?\?\?\?\?</p></td>
2025 </tr>
2026 <tr>
2027 <td><p>\$</p></td>
2028 <td><p>1 or more repetitions of decimal digits</p></td>
2029 <td><p>/proc/\$/cmdline</p></td>
2030 </tr>
2031 <tr>
2032 <td><p>\+</p></td>
2033 <td><p>1 decimal digit</p></td>
2034 <td><p>/var/tmp/my_work.\+</p></td>
2035 </tr>
2036 <tr>
2037 <td><p>\X</p></td>
2038 <td><p>1 or more repetitions of hexadecimal digits</p></td>
2039 <td><p>/var/tmp/my-work.\X</p></td>
2040 </tr>
2041 <tr>
2042 <td><p>\x</p></td>
2043 <td><p>1 hexadecimal digit</p></td>
2044 <td><p>/tmp/my-work.\x</p></td>
2045 </tr>
2046 <tr>
2047 <td><p>\A</p></td>
2048 <td><p>1 or more repetitions of alphabet characters</p></td>
2049 <td><p>/var/log/my-work/\$-\A-\$.log</p></td>
2050 </tr>
2051 <tr>
2052 <td><p>\a</p></td>
2053 <td><p>1 alphabet character</p></td>
2054 <td><p>/home/users/\a/\*/public_html/\*.html</p></td>
2055 </tr>
2056 <tr>
2057 <td><p>\-</p></td>
2058 <td><p>Pathname subtraction operator (negative match)</p></td>
2059 <td>
2060 <p>/\*\-proc\-sys</p>
2061 <p>This will match /\* except "/proc" and "/sys".</p>
2062 </td>
2063 </tr>
2064 <tr>
2065 <td><p>/\{dir\}/</p></td>
2066 <td><p>Recursive directory matching operator.</p>
2067 <p>Matches "/" and 1 or more repetitions of "dir/".</p></td>
2068 <td>
2069 <p>/var/www/html/\{\*\}/\*.html</p>
2070 <p>This will match all *.html files in subdirectories under /var/www/html/ directory. Note that /var/www/html/\*.html will not match.</p>
2071 </td>
2072 </tr>
2073 <tr>
2074 <td><p>/\(dir\)/</p></td>
2075 <td><p>Recursive directory matching operator.</p>
2076 <p>Matches "/" and 0 or more repetitions of "dir/".</p></td>
2077 <td>
2078 <p>/var/www/html/\(\*\)/\*.html</p>
2079 <p>This will match all *.html files under /var/www/html/ directory. Note that /var/www/html/\*.html will match.</p>
2080 </td>
2081 </tr>
2082 </table>
2083
2084 <h4><a name="4.1.3">4.1.3. Grouping string arguments using string_group keyword.</a></h4>
2085
2086 <p>It is possible to define groups of string arguments using string_group keyword followed by $string_group_name and $string_group_member.</p>
2087
2088 <pre>
2089 string_group TMPDIR /tmp
2090 string_group TMPDIR /tmp/\(\*\)/\*
2091 </pre>
2092
2093 <h4><a name="4.1.4">4.1.4. Example of conditions that use string arguments.</a></h4>
2094
2095 <p>When string argument is specified in condition part, it is quoted by " character in order to clarify that the argument is a string argument rather than name of variable.</p>
2096
2097 <table border="1">
2098 <tr><td>Conditions example</td><td>Value of variable "path"</td><td>Comparison result</td></tr>
2099 <tr><td rowspan="5">path="/tmp/\*"</td>
2100 <td>/</td><td>Does not match</td></tr>
2101 <tr><td>/tmp</td><td>Does not match</td></tr>
2102 <tr><td>/tmp/</td><td>Matches</td></tr>
2103 <tr><td>/tmp/rt6bh84t</td><td>Matches</td></tr>
2104 <tr><td>/tmp/349gy08t/y8024fgf</td><td>Does not match</td></tr>
2105 <tr><td rowspan="5">path!="/tmp/\*"</td>
2106 <td>/</td><td>Matches</td></tr>
2107 <tr><td>/tmp</td><td>Matches</td></tr>
2108 <tr><td>/tmp/</td><td>Does not match</td></tr>
2109 <tr><td>/tmp/rt6bh84t</td><td>Does not match</td></tr>
2110 <tr><td>/tmp/349gy08t/y8024fgf</td><td>Matches</td></tr>
2111 </table>
2112
2113 <p>When string_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is a string_group argument rather than name of variable.</p>
2114
2115 <table border="1">
2116 <tr><td>Conditions example</td><td>Value of variable "path"</td><td>Values in TMPDIR group</td><td>Comparison result</td></tr>
2117 <tr><td rowspan="4">path=@TMPDIR</td>
2118 <td>/</td><td rowspan="4">/tmp<br>/tmp/\(\*\)/\*</td><td>Does not match</td></tr>
2119 <tr><td>/tmp</td><td>Matches</td></tr>
2120 <tr><td>/tmp/rt6bh84t</td><td>Matches</td></tr>
2121 <tr><td>/tmp/349gy08t/y8024fgf</td><td>Matches</td></tr>
2122 <tr><td rowspan="4">path!=@TMPDIR</td>
2123 <td>/</td><td rowspan="4">/tmp<br>/tmp/\(\*\)/\*</td><td>Matches</td></tr>
2124 <tr><td>/tmp</td><td>Does not match</td></tr>
2125 <tr><td>/tmp/rt6bh84t</td><td>Does not match</td></tr>
2126 <tr><td>/tmp/349gy08t/y8024fgf</td><td>Does not match</td></tr>
2127 </table>
2128
2129 <p>List of name of variables which reference string data is explained later.</p>
2130
2131 <hr>
2132 <h3><a name="4.2">4.2. Using numeric arguments in conditions</a></h3>
2133
2134 <p>Arguments such as user ID and process ID are handled as numeric argument.</p>
2135
2136 <h4><a name="4.2.1">4.2.1. About numeric argument representation rule</a></h4>
2137
2138 <p>Decimal form, octal form and hexadecimal form are supported. Octal form is prefixed with 0 and Hexadecimal form is prefixed with 0x. For example, 010 in octal form is equivalent with 8 in decimal form, 0x10 in hexadecimal form is equivalent with 16 in decimal form.</p>
2139
2140 <p>Since numeric data is handled using C language's "unsigned long" type, minimal value is 0 and maximal value is 0xFFFFFFFF (for 32 bit environments) or 0xFFFFFFFFFFFFFFFF (for 64 bit environments).</p>
2141
2142 <p>It is possible to specify numeric data ranges in $min_value-$max_value form. If specifying in range, $min_value has to be smaller or equals to $max_value. For example, 0-100 is valid but 100-0 is invalid.</p>
2143
2144 <p>Some examples are shown below.</p>
2145
2146 <pre>
2147 0
2148 100
2149 0xFFFF
2150 0777
2151 500-1000
2152 0x0-0xFFFFFFFF
2153 00-07777
2154 </pre>
2155
2156 <h4><a name="4.2.2">4.2.2. Grouping numeric arguments using number_group keyword.</a></h4>
2157
2158 <p>It is possible to define groups of numeric arguments using number_group keyword followed by $number_group_name and $number_group_member.</p>
2159
2160 <pre>
2161 number_group ID_GROUP 100
2162 number_group ID_GROUP 200-500
2163 </pre>
2164
2165 <h4><a name="4.2.3">4.2.3. Example of conditions that use numeric arguments.</a></h4>
2166
2167 <p>Comparison with numeric value is defined as below.</p>
2168
2169 <table border="1">
2170 <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Comparison result</td></tr>
2171 <tr><td rowspan="3">task.uid=0</td>
2172 <td>0</td><td>Matches</td></tr>
2173 <tr><td>100</td><td>Does not match</td></tr>
2174 <tr><td>500</td><td>Does not match</td></tr>
2175 <tr><td rowspan="3">task.uid!=0</td>
2176 <td>0</td><td>Does not match</td></tr>
2177 <tr><td>100</td><td>Matches</td></tr>
2178 <tr><td>500</td><td>Matches</td></tr>
2179 </table>
2180
2181 <p>Comparison with numeric value range is defined as below.</p>
2182
2183 <table border="1">
2184 <tr><td>Conditions example</td><td>Value of variable "task.gid"</td><td>Comparison result</td></tr>
2185 <tr><td rowspan="3">task.gid=0-100</td>
2186 <td>0</td><td>Matches</td></tr>
2187 <tr><td>100</td><td>Matches</td></tr>
2188 <tr><td>500</td><td>Does not match</td></tr>
2189 <tr><td rowspan="3">task.gid!=0-100</td><td>0</td><td>Does not match</td></tr>
2190 <tr><td>100</td><td>Does not match</td></tr>
2191 <tr><td>500</td><td>Matches</td></tr>
2192 </table>
2193
2194 <p>It is possible to compare one variable which references numeric value with another variable which references numeric value.</p>
2195
2196 <table border="1">
2197 <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Value of variable "task.gid"</td><td>Comparison result</td></tr>
2198 <tr><td rowspan="4">task.uid=task.gid</td>
2199 <td>0</td><td>0</td><td>Matches</td></tr>
2200 <tr><td>0</td><td>100</td><td>Does not match</td></tr>
2201 <tr><td>100</td><td>0</td><td>Does not match</td></tr>
2202 <tr><td>100</td><td>100</td><td>Matches</td></tr>
2203 <tr><td rowspan="4">task.uid!=task.gid</td>
2204 <td>0</td><td>0</td><td>Does not match</td></tr>
2205 <tr><td>0</td><td>100</td><td>Matches</td></tr>
2206 <tr><td>100</td><td>0</td><td>Matches</td></tr>
2207 <tr><td>100</td><td>100</td><td>Does not match</td></tr>
2208 </table>
2209
2210 <p>When number_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is a number_group argument rather than name of variable.</p>
2211
2212 <table border="1">
2213 <tr><td>Conditions example</td><td>Value of variable "task.uid"</td><td>Values in ID_GROUP group</td><td>Comparison result</td></tr>
2214 <tr><td rowspan="4">task.uid=@ID_GROUP</td>
2215 <td>0</td><td rowspan="4">100<br>200-500</td><td>Does not match</td></tr>
2216 <tr><td>100</td><td>Matches</td></tr>
2217 <tr><td>500</td><td>Matches</td></tr>
2218 <tr><td>1000</td><td>Does not match</td></tr>
2219 <tr><td rowspan="4">task.uid!=@ID_GROUP</td>
2220 <td>0</td><td rowspan="4">100<br>200-500</td><td>Matches</td></tr>
2221 <tr><td>100</td><td>Does not match</td></tr>
2222 <tr><td>500</td><td>Does not match</td></tr>
2223 <tr><td>1000</td><td>Matches</td></tr>
2224 </table>
2225
2226 <p>List of name of variables which reference numeric data is explained later.</p>
2227
2228 <hr>
2229 <h3><a name="4.3">4.3. Using process's information in conditions</a></h3>
2230
2231 <p>By using current thread's attributes as part of conditions, you can write complicated access restriction rules.</p>
2232
2233 <h4><a name="4.3.1">4.3.1. About available variables</a></h4>
2234
2235 <p>Below variables are available for referring current thread's attributes.</p>
2236
2237 <table border="1">
2238 <tr><td>Variable's name</td><td>Comparison method</td><td>Meaning</td><td></td></tr>
2239 <tr><td>task.uid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's user ID</td></tr>
2240 <tr><td>task.gid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's group ID</td></tr>
2241 <tr><td>task.euid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's effective user ID</td></tr>
2242 <tr><td>task.egid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's effective group ID</td></tr>
2243 <tr><td>task.suid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's saved user ID</td></tr>
2244 <tr><td>task.sgid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's saved group ID</td></tr>
2245 <tr><td>task.fsuid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's filesystem user ID</td></tr>
2246 <tr><td>task.fsgid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's filesystem group ID</td></tr>
2247 <tr><td>task.pid</td><td><a href="#4.2">Numeric</a></td><td>Current thread's process ID </td></tr>
2248 <tr><td>task.ppid</td><td><a href="#4.2">Numeric</a></td><td>Process ID of current thread's parent process</td></tr>
2249 <tr><td>task.exe</td><td><a href="#4.1">String</a></td><td>Current thread's program name (the content of /proc/self/exe)</td></tr>
2250 <tr><td>task.domain</td><td><a href="#4.1">String</a></td><td>Current thread's domainname (the content of /sys/kernel/security/caitsith/self_domain)</td></tr>
2251 <tr><td>task.type</td><td>Literal</td><td>Matches execute_handler if running as an execute handler, does not match execute_handler otherwise</td></tr>
2252 </table>
2253
2254 <p>Details of task.domain is explained in <a href="#6.1">6.1. Controlling domain transition</a> and task.type is explained in <a href="#6.2">6.2. Using execute handler</a>.</p>
2255
2256 <hr>
2257 <h3><a name="4.4">4.4. Using IP address arguments in conditions</a></h3>
2258
2259 <p>Any operation which handles IPv4/IPv6 network address can check IP address.</p>
2260
2261 <h4><a name="4.4.1">4.4.1. About IP address argument representation rule</a></h4>
2262
2263 <p>It is possible to handle IPv4 address and IPv6 address. IPv4 address (32 bit) is represented using dot separated decimal form. and IPv6 address (128 bit) is represented using forms defined in RFC 2373.</p>
2264
2265 <p>It is possible to specify IP address ranges in $min_address-$max_address form. If specifying in range, $min_address has to be smaller or equals to $max_address. For example, 1.2.3.4-5.6.7.8 is valid but 5.6.7.8-1.2.3.4 is invalid.</p>
2266
2267 <p>Some examples are shown below.</p>
2268
2269 <pre>
2270 127.0.0.1
2271 10.0.0.0-10.255.255.255
2272 ::1
2273 fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2274 </pre>
2275
2276 <h4><a name="4.4.2">4.4.2. Grouping IP address arguments using ip_group keyword.</a></h4>
2277
2278 <p>It is possible to define groups of IP address arguments using ip_group keyword followed by $ip_group_name and $ip_group_member.</p>
2279
2280 <pre>
2281 ip_group PRIVATE_ADDRESS 10.0.0.0-10.255.255.255
2282 ip_group PRIVATE_ADDRESS 172.16.0.0-172.31.255.255
2283 ip_group PRIVATE_ADDRESS 192.168.0.0-192.168.255.255
2284 ip_group PRIVATE_ADDRESS fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
2285 </pre>
2286
2287 <h4><a name="4.4.3">4.4.3. Example of conditions that use IP address arguments.</a></h4>
2288
2289 <p>Comparison with IP address value is defined as below. Note that comparison between an IPv4 address and an IPv6 address does not match.</p>
2290
2291 <table border="1">
2292 <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Comparison result</td></tr>
2293 <tr><td rowspan="4">ip=127.0.0.1</td><td>127.0.0.1</td><td>Matches</td></tr>
2294 <tr><td>0.0.0.0</td><td>Does not match</td></tr>
2295 <tr><td>::1</td><td>Does not match</td></tr>
2296 <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2297 <tr><td rowspan="4">ip!=127.0.0.1</td><td>127.0.0.1</td><td>Does not match</td></tr>
2298 <tr><td>0.0.0.0</td><td>Matches</td></tr>
2299 <tr><td>::1</td><td>Does not match</td></tr>
2300 <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2301 <tr><td rowspan="4">ip=::1</td><td>127.0.0.1</td><td>Does not match</td></tr>
2302 <tr><td>0.0.0.0</td><td>Does not match</td></tr>
2303 <tr><td>::1</td><td>Matches</td></tr>
2304 <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2305 <tr><td rowspan="4">ip!=::1</td><td>127.0.0.1</td><td>Does not match</td></tr>
2306 <tr><td>0.0.0.0</td><td>Does not match</td></tr>
2307 <tr><td>::1</td><td>Does not match</td></tr>
2308 <tr><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
2309 </table>
2310
2311 <p>Comparison with IP address range is defined as below.</p>
2312
2313 <table border="1">
2314 <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Comparison result</td></tr>
2315 <tr><td rowspan="3">ip=127.0.0.0-127.255.255.255</td>
2316 <td>127.0.0.1</td><td>Matches</td></tr>
2317 <tr><td>10.0.0.1</td><td>Does not match</td></tr>
2318 <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2319 <tr><td rowspan="3">ip!=127.0.0.0-127.255.255.255</td>
2320 <td>127.0.0.1</td><td>Does not match</td></tr>
2321 <tr><td>10.0.0.1</td><td>Matches</td></tr>
2322 <tr><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2323 <tr><td rowspan="3">ip=::-::1</td><td>::ffff:127.0.0.1</td><td>Does not match</td></tr>
2324 <tr><td>127.0.0.1</td><td>Does not match</td></tr>
2325 <tr><td>::1</td><td>Matches</td></tr>
2326 <tr><td rowspan="3">ip!=::-::1</td><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
2327 <tr><td>127.0.0.1</td><td>Does not match</td></tr>
2328 <tr><td>::1</td><td>Does not match</td></tr>
2329 </table>
2330
2331 <p>When ip_group argument is specified in condition part, it is prefixed by @ character in order to clarify that the argument is an ip_group argument rather than name of variable.</p>
2332
2333 <table border="1">
2334 <tr><td>Conditions example</td><td>Value of variable "ip"</td><td>Values in PRIVATE_ADDRESS group</td><td>Comparison result</td></tr>
2335 <tr><td rowspan="5">ip=@PRIVATE_ADDRESS</td>
2336 <td>127.0.0.1</td><td rowspan="5">10.0.0.0-10.255.255.255<br>172.16.0.0-172.31.255.255<br>192.168.0.0-192.168.255.255<br>fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff</td><td>Does not match</td></tr>
2337 <tr><td>10.0.0.1</td><td>Matches</td></tr>
2338 <tr><td>192.168.0.1</td><td>Matches</td></tr>
2339 <tr><td>::ffff:172.16.0.1</td><td>Does not match</td></tr>
2340 <tr><td>fd01::</td><td>Matches</td></tr>
2341 <tr><td rowspan="5">ip!=@PRIVATE_ADDRESS</td><td>127.0.0.1</td><td rowspan="5">10.0.0.0-10.255.255.255<br>172.16.0.0-172.31.255.255<br>192.168.0.0-192.168.255.255<br>fd00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff</td><td>Matches</td></tr>
2342 <tr><td>10.0.0.1</td><td>Does not match</td></tr>
2343 <tr><td>::ffff:192.168.0.1</td><td>Matches</td></tr>
2344 <tr><td>::ffff:127.0.0.1</td><td>Matches</td></tr>
2345 <tr><td>fd01::</td><td>Does not match</td></tr>
2346 </table>
2347
2348 <p>List of operations which handles IP address is explained later.</p>
2349
2350 <hr>
2351 <h3><a name="4.5">4.5. Using command line arguments in conditions</a></h3>
2352
2353 <p>It is possible to check command line arguments (a.k.a. argv[]) when checking permissions for program execution.</p>
2354
2355 <table border="1">
2356 <tr><td>Conditions example</td><td>Comparison method</td><td>Meaning</td><td></td></tr>
2357 <tr><td>argv[0]="true"</td><td><a href="#4.1">String</a></td><td>argv[0] matches "true"</td></tr>
2358 <tr><td>argv[0]!="false"</td><td><a href="#4.1">String</a></td><td>argv[0] does not match "false"</td></tr>
2359 <tr><td>argv[1]=@ARGV1_GROUPS</td><td><a href="#4.1">String</a></td><td>argv[0] matches one of strings in string_group ARGV1_GROUPS group</td></tr>
2360 <tr><td>argv[1]!=@ARGV1_GROUPS</td><td><a href="#4.1">String</a></td><td>argv[0] matches none of strings in string_group ARGV1_GROUPS group</td></tr>
2361 </table>
2362
2363 <p>Applications can pass a string data up to 32 * PAGE_SIZE bytes to each argv[]. But due to difficulty of allocating contiguous memory in the kernel, only up to 4085 bytes can be checked using variable "argv[$index]". If you want to check strictly, please consider using handler= argument of "allow " lines in "acl execute" block.</p>
2364
2365 <hr>
2366 <h3><a name="4.6">4.6. Using environment variable arguments in conditions</a></h3>
2367
2368 <p>It is possible to check environment variables (a.k.a. envp[]) when checking permissions for program execution.</p>
2369
2370 <table border="1">
2371 <tr><td>Conditions example</td><td>Comparison method</td><td>Meaning</td><td></td></tr>
2372 <tr><td>envp["PATH"]="/"</td><td><a href="#4.1">String</a></td><td>Environment variable PATH is defined and its value is "/"</td></tr>
2373 <tr><td>envp["PATH"]!="/"</td><td><a href="#4.1">String</a></td><td>Either<br>&nbsp;&nbsp;&nbsp;&nbsp;Environment variable PATH is not defined<br>or<br>&nbsp;&nbsp;&nbsp;&nbsp;Environment variable PATH is defined but its value is not "/"</td></tr>
2374 <tr><td>envp["PATH"]=@ENV_PATH_VALUES</td><td><a href="#4.1">String</a></td><td>Environment variable PATH is defined and its value matches one of strings in string_group ENVP_PATH_VALUES group</td></tr>
2375 <tr><td>envp["PATH"]!=@ENV_PATH_VALUES</td><td><a href="#4.1">String</a></td><td>Either<br>&nbsp;&nbsp;&nbsp;&nbsp;Environment variable PATH is not defined<br>or<br>&nbsp;&nbsp;&nbsp;&nbsp;Environment variable PATH is defined but its value matches none of strings in string_group ENVP_PATH_VALUES group</td></tr>
2376 <tr><td>envp["PATH"]=NULL</td><td>None</td><td>Environment variable PATH is not defined</td></tr>
2377 <tr><td>envp["PATH"]!=NULL</td><td>None</td><td>Environment variable PATH is defined</td></tr>
2378 </table>
2379
2380 <p>Applications can pass a string data up to 32 * PAGE_SIZE bytes to each envp[]. But due to difficulty of allocating contiguous memory in the kernel, only up to 4085 bytes can be checked using variable "envp["$name"]". If you want to check strictly, please consider using handler= argument of "allow " lines in "acl execute" block.</p>
2381
2382 <hr>
2383 <h3><a name="4.7">4.7. Using file's DAC permissions in conditions</a></h3>
2384
2385 <p>When checking permissions for file related operations, it is possible to check its DAC permissions if the file already exists as of permission check.
2386 Below table assumes that the variable name for referencing the requested pathname is "path".</p>
2387
2388 <p>Value of DAC permissions can be referenced using variable "path.perm", and its value is between 0 and 07777. Although it is possible to do normal <a href="#4.2">numeric comparison</a>, below constants are provided in order to make it easier to compare whether specific bit is set or not.</p>
2389
2390 <table border="1">
2391 <tr><td>Constant</td><td>Value ranges that match </td></tr>
2392 <tr><td>setuid</td><td>Values where bitwise AND between path.perm and 04000 are 04000. (i.e. 04000-07777)</td></tr>
2393 <tr><td>setgid</td><td>Values where bitwise AND between path.perm and 02000 are 02000. (i.e. 02000-03777 06000-07777)</td></tr>
2394 <tr><td>sticky</td><td>Values where bitwise AND between path.perm and 01000 are 01000. (i.e. 01000-01777 03000-03777 05000-05777 07000-07777)</td></tr>
2395 <tr><td>owner_read</td><td>Values where bitwise AND between path.perm and 00400 are 00400. (e.g. 00400-00777 01400-01777 02400-02777)</td></tr>
2396 <tr><td>owner_write</td><td>Values where bitwise AND between path.perm and 00200 are 00200. (e.g. 00200-00377 00600-00777 01200-01377)</td></tr>
2397 <tr><td>owner_execute</td><td>Values where bitwise AND between path.perm and 00100 are 00100. (e.g. 00100-00177 00300-00377 00500-00577)</td></tr>
2398 <tr><td>group_read</td><td>Values where bitwise AND between path.perm and 00040 are 00040. (e.g. 00040-00077 00140-00177 00240-00277)</td></tr>
2399 <tr><td>group_write</td><td>Values where bitwise AND between path.perm and 00020 are 00020. (e.g. 00020-00037 00060-00077 00120-00137)</td></tr>
2400 <tr><td>group_execute</td><td>Values where bitwise AND between path.perm and 00010 are 00010. (e.g. 00010-00017 00030-00037 00050-00057)</td></tr>
2401 <tr><td>others_read</td><td>Values where bitwise AND between path.perm and 00004 are 00004. (e.g. 00004-00007 00014-00017 00024-00027)</td></tr>
2402 <tr><td>others_write</td><td>Values where bitwise AND between path.perm and 00002 are 00002. (e.g. 00002-00003 00006-00007 00012-00013)</td></tr>
2403 <tr><td>others_execute</td><td>Values where bitwise AND between path.perm and 00001 are 00001. (e.g. 00001 00003 00005 00007 00011 00013)</td></tr>
2404 </table>
2405
2406 <p>Below are some examples that use constants.</p>
2407
2408 <table border="1">
2409 <tr><td>Conditions example</td><td>Permissions of file referenced by variable "path"</td><td>Comparison result</td></tr>
2410 <tr><td>path.perm=setuid</td><td>04755</td><td>Matches</td></tr>
2411 <tr><td>path.perm!=setuid</td><td>04755</td><td>Does not match</td></tr>
2412 <tr><td>path.perm=setuid path.perm=setgid path.perm=sticky</td><td>0755</td><td>Does not match</td></tr>
2413 <tr><td>path.perm!=setuid path.perm!=setgid path.perm!=sticky</td><td>0755</td><td>Matches</td></tr>
2414 </table>
2415
2416 <hr>
2417 <h3><a name="4.8">4.8. Using handle file's type in conditions</a></h3>
2418
2419 <p>When checking permissions for file related operations, it is possible to check its type if the file already exists as of permission check.
2420 Below table assumes that the variable name for referencing the requested pathname is "path".</p>
2421
2422 <p>Type of a file can be referenced using variable "path.type", and its value takes one of "file", "directory", "socket", "fifo", "block", "char", "symlink".</p>
2423
2424 <table border="1">
2425 <tr><td>Possible conditions</td><td>Type of file referenced by variable "path"</td><td>Comparison result</td></tr>
2426 <tr><td>path.type=file</td><td>Regular file</td><td>Matches</td></tr>
2427 <tr><td>path.type!=file</td><td>Other than regular file</td><td>Matches</td></tr>
2428 <tr><td>path.type=directory</td><td>Directory</td><td>Matches</td></tr>
2429 <tr><td>path.type!=directory</td><td>Other than directory</td><td>Matches</td></tr>
2430 <tr><td>path.type=socket</td><td>Unix domain socket</td><td>Matches</td></tr>
2431 <tr><td>path.type!=socket</td><td>Other than Unix domain socket</td><td>Matches</td></tr>
2432 <tr><td>path.type=fifo</td><td>FIFO</td><td>Matches</td></tr>
2433 <tr><td>path.type!=fifo</td><td>Other than FIFO</td><td>Matches</td></tr>
2434 <tr><td>path.type=block</td><td>Block device file</td><td>Matches</td></tr>
2435 <tr><td>path.type!=block</td><td>Other than block device file</td><td>Matches</td></tr>
2436 <tr><td>path.type=char</td><td>Character device file</td><td>Matches</td></tr>
2437 <tr><td>path.type!=char</td><td>Other than character device file</td><td>Matches</td></tr>
2438 <tr><td>path.type=symlink</td><td>Symbolic link</td><td>Matches</td></tr>
2439 <tr><td>path.type!=symlink</td><td>Other than symbolic link</td><td>Matches</td></tr>
2440 </table>
2441
2442 <hr>
2443 <h3><a name="4.9">4.9. Using file's attributes in conditions</a></h3>
2444
2445 <p>When checking permissions for file related operations, it is possible to check its attributes if the file already exists as of permission check.
2446 Below table assumes that the variable name for referencing the requested pathname is "path".</p>
2447
2448 <table border="1">
2449 <tr><td>Variable's name</td><td>Comparison method</td><td>Meaning</td></tr>
2450 <tr><td>path.uid</td><td><a href="#4.2">Numeric</a></td><td>Owner ID</td></tr>
2451 <tr><td>path.gid</td><td><a href="#4.2">Numeric</a></td><td>Group ID</td></tr>
2452 <tr><td>path.ino</td><td><a href="#4.2">Numeric</a></td><td>i-node number on the filesystem</td></tr>
2453 <tr><td>path.major</td><td><a href="#4.2">Numeric</a></td><td>Device major number on the filesystem</td></tr>
2454 <tr><td>path.minor</td><td><a href="#4.2">Numeric</a></td><td>Device minor number on the filesystem</td></tr>
2455 <tr><td>path.perm</td><td><a href="#4.7">Permission</a></td><td>DAC permissions</td></tr>
2456 <tr><td>path.type</td><td><a href="#4.8">File's type</a></td><td>Type of the file</td></tr>
2457 <tr><td>path.dev_major</td><td><a href="#4.2">Numeric</a></td><td>Device major number of the file if path.type=block or path.type=char</td></tr>
2458 <tr><td>path.dev_minor</td><td><a href="#4.2">Numeric</a></td><td>Device minor number of the file if path.type=block or path.type=char</td></tr>
2459 <tr><td>path.fsmagic</td><td><a href="#4.2">Numeric</a></td><td>Magic number of filesystem</td></tr>
2460 </table>
2461
2462 <p>When checking permissions for file related operations, it is possible to also check its parent directory's attributes.
2463 Below table assumes that the variable name for referencing the requested pathname is "path".</p>
2464
2465 <table border="1">
2466 <tr><td>Variable's name</td><td>Comparison method</td><td>Meaning</td></tr>
2467 <tr><td>path.parent.uid</td><td><a href="#4.2">Numeric</a></td><td>Owner ID</td></tr>
2468 <tr><td>path.parent.gid</td><td><a href="#4.2">Numeric</a></td><td>Group ID</td></tr>
2469 <tr><td>path.parent.ino</td><td><a href="#4.2">Numeric</a></td><td>i-node number on the filesystem</td></tr>
2470 <tr><td>path.parent.major</td><td><a href="#4.2">Numeric</a></td><td>Device major number on the filesystem</td></tr>
2471 <tr><td>path.parent.minor</td><td><a href="#4.2">Numeric</a></td><td>Device minor number on the filesystem</td></tr>
2472 <tr><td>path.parent.perm</td><td><a href="#4.7">Permission</a></td><td>DAC permissions</td></tr>
2473 <tr><td>path.parent.fsmagic</td><td><a href="#4.2">Numeric</a></td><td>Magic number of filesystem</td></tr>
2474 </table>
2475
2476 <p>It does not make sense to use path.parent.type path.parent.dev_major path.parent.dev_minor because path.parent is always a directory.</p>
2477
2478 <p>If path refers a mount point (root of directory entry tree within that partition), path.parent refers the same path rather than referring mount point's parent.</p>
2479
2480 <hr>
2481 <h2><a name="syntax_list">5. List of syntaxes</a></h2>
2482
2483 <hr>
2484 <h3><a name="5.1">5.1. execute</a></h3>
2485
2486 <h4><a name="5.1.1">5.1.1. Description</a></h4>
2487
2488 <p>Execute a program</p>
2489
2490 <h4><a name="5.1.2">5.1.2. Available variables</a></h4>
2491
2492 <table border="1">
2493 <tr><td><a href="#4.1">path</a></td><td>Requested program's pathname</td></tr>
2494 <tr><td><a href="#4.9">path.$attribute</a></td><td>Attributes of an object referenced by variable "path"</td></tr>
2495 <tr><td><a href="#4.9">path.parent.$attribute</a></td><td>Parent directory's attributes</tr>
2496 <tr><td><a href="#4.1">exec</a></td><td>Requested program's pathname, but maybe a symbolic link</td></tr>
2497 <tr><td><a href="#4.9">exec.$attribute</a></td><td>Attributes of an object referenced by variable "exec"</td></tr>
2498 <tr><td><a href="#4.9">exec.parent.$attribute</a></td><td>Parent directory's attributes</tr>
2499 <tr><td><a href="#4.2">argc</a></td><td>Number of command line arguments passed to this request</td></tr>
2500 <tr><td><a href="#4.2">envc</a></td><td>Number of environment variables arguments</td></tr>
2501 <tr><td><a href="#4.5">argv[$index]</a></td><td>$index'th (0 &lt;= $index &lt; argc) value of command line arguments</td></tr>
2502 <tr><td><a href="#4.6">envp["$name"]</a></td><td>Value of environment variable named $name</td></tr>
2503 <tr><td><a href="#4.3">task.$attribute</a></td><td>Current thread's attributes</td></tr>
2504 <tr><td>handler</td><td>Pathname of a wrapper program for preprocessing (note that this assignment is optional and valid to only "allow" lines)</td></tr>
2505 <tr><td>transition</td><td>New domainname to transit to if operation was successful (note that this assignment is optional and valid to only "allow" lines)</td></tr>
2506 </table>
2507
2508 <h4><a name="5.1.3">5.1.3. Examples</a></h4>
2509
2510 <ul>
2511 <li>
2512 <p>Allow everybody to execute any program.<br>
2513 Note that this example makes no sense except for auditing purpose.</p>
2514
2515 <table border="1">
2516 <tr><td>
2517 100 acl execute<br>
2518 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2519 &nbsp;&nbsp;&nbsp;&nbsp;1 allow
2520 </td></tr>
2521 </table>
2522 </li>
2523
2524 <li>
2525 <p>Allow nobody to execute any program.<br>
2526 Note that you should not try this example, or your system will lock up.</p>
2527
2528 <table border="1">
2529 <tr><td>
2530 100 acl execute<br>
2531 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2532 &nbsp;&nbsp;&nbsp;&nbsp;1 deny
2533 </td></tr>
2534 </table>
2535 </li>
2536
2537 <li>
2538 <p>Deny execution of any program by threads running with UID = 500.</p>
2539
2540 <table border="1">
2541 <tr><td>
2542 100 acl execute task.uid=500<br>
2543 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2544 &nbsp;&nbsp;&nbsp;&nbsp;1 deny
2545 </td></tr>
2546 </table>
2547 </li>
2548
2549 <li>
2550 <p>Restrict execution of /sbin/init to only threads running with UID = 0 and GID = 0.<br>
2551 Note that both exec= and path= are checked in this example in case /sbin/init is a symbolic link.</p>
2552
2553 <table border="1">
2554 <tr><td>
2555 100 acl execute exec="/sbin/init"<br>
2556 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2557 &nbsp;&nbsp;&nbsp;&nbsp;1 allow task.uid=0 task.gid=0<br>
2558 &nbsp;&nbsp;&nbsp;&nbsp;2 deny<br>
2559 <br>
2560 200 acl execute path="/sbin/init"<br>
2561 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2562 &nbsp;&nbsp;&nbsp;&nbsp;1 allow task.uid=0 task.gid=0<br>
2563 &nbsp;&nbsp;&nbsp;&nbsp;2 deny
2564 </td></tr>
2565 </table>
2566
2567 </li>
2568
2569 <li>
2570 <p>Deny execution of programs if current thread's UID != the UID of the program to execute.<br>
2571 Note that both exec.uid= and path.uid= are checked in this example in case the program is not owned by current thread's UID
2572 but the symbolic link to the program is owned by current thread's UID (or vice versa).</p>
2573
2574 <table border="1">
2575 <tr><td>
2576 100 acl execute<br>
2577 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2578 &nbsp;&nbsp;&nbsp;&nbsp;1 deny task.uid!=exec.uid<br>
2579 &nbsp;&nbsp;&nbsp;&nbsp;2 deny task.uid!=path.uid<br>
2580 &nbsp;&nbsp;&nbsp;&nbsp;3 allow
2581 </td></tr>
2582 </table>
2583
2584 </li>
2585
2586 <li>
2587 <p>Deny execution of programs if current thread's UID = 0 and the UID of the program to execute != 0.</p>
2588
2589 <table border="1">
2590 <tr><td>
2591 100 acl execute task.uid=0<br>
2592 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2593 &nbsp;&nbsp;&nbsp;&nbsp;1 deny exec.uid!=0<br>
2594 &nbsp;&nbsp;&nbsp;&nbsp;2 deny path.uid!=0<br>
2595 &nbsp;&nbsp;&nbsp;&nbsp;3 allow
2596 </td></tr>
2597 </table>
2598 </li>
2599
2600 <li>
2601 <p>Deny execution of /bin/true if the first command line argument is --help .</p>
2602
2603 <table border="1">
2604 <tr><td>
2605 100 acl execute exec="/bin/true" argv[1]="--help"<br>
2606 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2607 &nbsp;&nbsp;&nbsp;&nbsp;1 deny<br>
2608 <br>
2609 200 acl execute path="/bin/true" argv[1]="--help"<br>
2610 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2611 &nbsp;&nbsp;&nbsp;&nbsp;1 deny
2612 </td></tr>
2613 </table>
2614
2615 <p>Note that above example can be written like below example. But be careful with audit log flooding.<br>
2616 Below example generates more audit logs than above example because the rule in below example is unconditionally checked.</p>
2617
2618 <table border="1">
2619 <tr><td>
2620 100 acl execute<br>
2621 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2622 &nbsp;&nbsp;&nbsp;&nbsp;1 deny exec="/bin/true" argv[1]="--help"<br>
2623 &nbsp;&nbsp;&nbsp;&nbsp;2 deny path="/bin/true" argv[1]="--help"<br>
2624 &nbsp;&nbsp;&nbsp;&nbsp;3 allow
2625 </td></tr>
2626 </table>
2627 </li>
2628
2629 <li>
2630 <p>Deny /usr/sbin/httpd to execute /bin/sh .</p>
2631
2632 <table border="1">
2633 <tr><td>
2634 2000 acl execute task.exe="/usr/sbin/httpd"<br>
2635 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2636 &nbsp;&nbsp;&nbsp;&nbsp;100 deny exec="/bin/sh"<br>
2637 &nbsp;&nbsp;&nbsp;&nbsp;200 allow
2638 </td></tr>
2639 </table>
2640 </li>
2641
2642 <li>
2643 <p>Restrict /usr/sbin/httpd to execute only /usr/sbin/suexec .</p>
2644
2645 <table border="1">
2646 <tr><td>
2647 1000 acl execute task.exe="/usr/sbin/httpd"<br>
2648 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2649 &nbsp;&nbsp;&nbsp;&nbsp;100 allow exec="/usr/sbin/suexec"<br>
2650 &nbsp;&nbsp;&nbsp;&nbsp;200 deny
2651 </td></tr>
2652 </table>
2653 </li>
2654
2655 <li>
2656 <p>Restrict execution of /usr/sbin/suexec to only /usr/sbin/httpd .</p>
2657
2658 <table border="1">
2659 <tr><td>
2660 2000 acl execute exec="/usr/sbin/suexec"<br>
2661 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2662 &nbsp;&nbsp;&nbsp;&nbsp;100 allow task.exe="/usr/sbin/httpd"<br>
2663 &nbsp;&nbsp;&nbsp;&nbsp;200 deny
2664 </td></tr>
2665 </table>
2666 </li>
2667 </ul>
2668
2669 <h4><a name="5.1.4">5.1.4. Related man pages</a></h4>
2670
2671 <p>execve(2)</p>
2672
2673 <h4><a name="5.1.5">5.1.5. Availability</a></h4>
2674
2675 <p>Checking handler argument is available only when built with CONFIG_CAITSITH_EXECUTE_HANDLER=y.</p>
2676
2677 <p>Checking other arguments are always available.</p>
2678
2679 <hr>
2680 <h3><a name="5.2">5.2. read</a></h3>
2681
2682 <h4><a name="5.2.1">5.2.1. Description</a></h4>
2683
2684 <p>Open a pathname for reading</p>
2685
2686 <h4><a name="5.2.2">5.2.2. Available variables</a></h4>
2687
2688 <table border="1">
2689 <tr><td><a href="#4.1">path</a></td><td>Requested pathname</td></tr>
2690 <tr><td><a href="#4.9">path.$attribute</a></td><td>Attributes of an object referenced by variable "path"</td></tr>
2691 <tr><td><a href="#4.9">path.parent.$attribute</a></td><td>Parent directory's attributes</td></tr>
2692 <tr><td><a href="#4.3">task.$attribute</a></td><td>Current thread's attributes</td></tr>
2693 </table>
2694
2695 <h4><a name="5.2.3">5.2.3. Examples</a></h4>
2696
2697 <ul>
2698
2699 <li>
2700 <p>Allow only /usr/bin/passwd and /usr/sbin/httpd to open /etc/shadow\* for reading.<br>
2701 Note that this rule cannot prevent diverted accesses such as creating a hard link of /etc/shadow .</p>
2702
2703 <table border="1">
2704 <tr><td>
2705 100 acl read path="/etc/shadow\*"<br>
2706 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2707 &nbsp;&nbsp;&nbsp;&nbsp;1 allow task.exe="/usr/bin/passwd"<br>
2708 &nbsp;&nbsp;&nbsp;&nbsp;1 allow task.exe="/usr/sbin/sshd"<br>
2709 &nbsp;&nbsp;&nbsp;&nbsp;10 deny
2710 </td></tr>
2711 </table>
2712 </li>
2713
2714 <li>
2715 <p>Restrict threads in "web-server" domain to open only files in "web-contents" group for reading.<br>
2716 Note that you need to append other files because this rule cannot cover all files used by web servers.</p>
2717
2718 <table border="1">
2719 <tr><td>
2720 string_group web-contents /var/www/html/\(\*\)/\*<br>
2721 string_group web-contents /home/\*/public_html/\(\*\)/\*<br>
2722 <br>
2723 100 acl read task.domain="web-server"<br>
2724 &nbsp;&nbsp;&nbsp;&nbsp;audit 1<br>
2725 &nbsp;&nbsp;&nbsp;&nbsp;1 allow path=@web-contents<br>
2726 &nbsp;&nbsp;&nbsp;&nbsp;10 deny
2727 </td></tr>
2728 </table>
2729 </li>
2730
2731 <li>
2732 <p>Allow only threads in "web-server" domain to open files in "web-contents" group for reading.<br>
2733 Note that this rule cannot prevent diverted accesses such as creating a hard link of files in "web-contents" group.</p>
2734
2735 <table border="1">