Info: Version 1.7.x is available.

Japanese Page

# Policy Specifications of TOMOYO Linux

Last modified: $Date: 2011-07-01 13:55:23 +0900 (Fri, 01 Jul 2011) $

# Index

## 1. Keywords Index

## 2. Introduction

2.1 Word Expression Rules

2.2 Wildcard Expression Rules

2.3 Word Length Rules

2.4 Line Length Rules

2.5 Memory Allocation Rules

## 3. Policy Files

3.1 Policy File's Location

3.2 Policy File's Modification

## 4. Domain Rules

4.1 Domain Definition

4.2 Domain Transition

4.3 Access Logs

## 5. Syntax Details

## 6. Advanced Features

6.1 Allowing policy modification by non root user.

6.2 Enabling quota for memory used for holding policy.

6.3 Using conditional ACL.

6.4 Using stateful ACL.

6.5 Sleep penalty for policy violation.

6.6 Judging execute request outside the kernel.

6.7 Invoking alternative program for execute requests that are not permitted by policy.

# 1. Keywords Index

Used by /proc/ccs/profile and /etc/ccs/profile.conf

- MAC_FOR_FILE
- MAC_FOR_IOCTL
- MAC_FOR_ARGV0
- MAC_FOR_ENV
- MAC_FOR_CAPABILITY::inet_tcp_create
- MAC_FOR_CAPABILITY::inet_tcp_listen
- MAC_FOR_CAPABILITY::inet_tcp_connect
- MAC_FOR_CAPABILITY::use_inet_udp
- MAC_FOR_CAPABILITY::use_inet_ip
- MAC_FOR_CAPABILITY::use_route
- MAC_FOR_CAPABILITY::use_packet
- MAC_FOR_CAPABILITY::use_kernel_module
- MAC_FOR_CAPABILITY::create_fifo
- MAC_FOR_CAPABILITY::create_block_dev
- MAC_FOR_CAPABILITY::create_char_dev
- MAC_FOR_CAPABILITY::create_unix_socket
- MAC_FOR_CAPABILITY::SYS_MOUNT
- MAC_FOR_CAPABILITY::SYS_UMOUNT
- MAC_FOR_CAPABILITY::SYS_REBOOT
- MAC_FOR_CAPABILITY::SYS_CHROOT
- MAC_FOR_CAPABILITY::SYS_KILL
- MAC_FOR_CAPABILITY::SYS_VHANGUP
- MAC_FOR_CAPABILITY::SYS_TIME
- MAC_FOR_CAPABILITY::SYS_NICE
- MAC_FOR_CAPABILITY::SYS_SETHOSTNAME
- MAC_FOR_CAPABILITY::SYS_LINK
- MAC_FOR_CAPABILITY::SYS_SYMLINK
- MAC_FOR_CAPABILITY::SYS_RENAME
- MAC_FOR_CAPABILITY::SYS_UNLINK
- MAC_FOR_CAPABILITY::SYS_CHMOD
- MAC_FOR_CAPABILITY::SYS_CHOWN
- MAC_FOR_CAPABILITY::SYS_IOCTL
- MAC_FOR_CAPABILITY::SYS_KEXEC_LOAD
- MAC_FOR_CAPABILITY::SYS_PIVOT_ROOT
- MAC_FOR_CAPABILITY::SYS_PTRACE
- MAC_FOR_NETWORK
- MAC_FOR_SIGNAL
- DENY_CONCEAL_MOUNT
- RESTRICT_CHROOT
- RESTRICT_MOUNT
- RESTRICT_UNMOUNT
- RESTRICT_PIVOT_ROOT
- RESTRICT_AUTOBIND
- MAX_ACCEPT_ENTRY
- MAX_GRANT_LOG
- MAX_REJECT_LOG
- TOMOYO_VERBOSE
- ALLOW_ENFORCE_GRACE
- SLEEP_PERIOD

Used by /proc/ccs/system_policy and /etc/ccs/system_policy.conf

- allow_mount
- deny_unmount
- allow_chroot
- allow_pivot_root
- deny_autobind

Used by /proc/ccs/exception_policy and /etc/ccs/exception_policy.conf

- aggregator
- initialize_domain
- no_initialize_domain
- keep_domain
- no_keep_domain
- file_pattern
- path_group
- address_group
- allow_read
- allow_env
- deny_rewrite
- alias

Used by /proc/ccs/domain_policy and /etc/ccs/domain_policy.conf

- allow_execute
- allow_read
- allow_write
- allow_read/write
- allow_create
- allow_unlink
- allow_mkdir
- allow_rmdir
- allow_mkfifo
- allow_mksock
- allow_mkblock
- allow_mkchar
- allow_truncate
- allow_symlink
- allow_link
- allow_rename
- allow_rewrite
- allow_ioctl
- allow_argv0
- allow_env
- allow_network
- allow_capability
- allow_signal
- use_profile
- ignore_global_allow_read
- ignore_global_allow_env
- execute_handler
- denied_execute_handler
- quota_exceeded
- transition_failed

Used by /proc/ccs/manager and /etc/ccs/manager.conf

- manage_by_non_root

# 2. Introduction

## 2.1 Word Expression Rules

TOMOYO Linux performs pathname based access control. A pathname may contain not only alphabet and number but also space and carriage return and multibyte (e.g. kanji) characters. Thus, to be able to handle any characters correctly, TOMOYO Linux follows the rules shown below to represent a word. A word means all tokens that are treated as string data, such as pathnames, comments, environment variable's names, parameters for program execution.

- NUL character (0x00) is used for indicating end of string. Thus you cannot include \000 in a word.
- \ character (0x5C) is used for indicating octal expression. Thus, you need to use \\ to represent a \.
- Characters 0x01 - 0x20 and 0x7F - 0xFF are represented using octal expression \ooo .
- The rest characters (i.e. 0x21 - 0x5B and 0x5D - 0x7E) are represented as is.

| Lower 4 bits
Higher 4 bits |
| 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | 0x7 | 0x8 | 0x9 | 0xA | 0xB | 0xC | 0xD | 0xE | 0xF
0x0 |  | \001 | \002 | \003 | \004 | \005 | \006 | \007 | \010 | \011 | \012 | \013 | \014 | \015 | \016 | \017
0x1 | \020 | \021 | \022 | \023 | \024 | \025 | \026 | \027 | \030 | \031 | \032 | \033 | \034 | \035 | \036 | \037
0x2 | \040 | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | /
0x3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ?
0x4 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
0x5 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \\ | ] | ^ | _
0x6 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
0x7 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | \177
0x8 | \200 | \201 | \202 | \203 | \204 | \205 | \206 | \207 | \210 | \211 | \212 | \213 | \214 | \215 | \216 | \217
0x9 | \220 | \221 | \222 | \223 | \224 | \225 | \226 | \227 | \230 | \231 | \232 | \233 | \234 | \235 | \236 | \237
0xA | \240 | \241 | \242 | \243 | \244 | \245 | \246 | \247 | \250 | \251 | \252 | \253 | \254 | \255 | \256 | \257
0xB | \260 | \261 | \262 | \263 | \264 | \265 | \266 | \267 | \270 | \271 | \272 | \273 | \274 | \275 | \276 | \277
0xC | \300 | \301 | \302 | \303 | \304 | \305 | \306 | \307 | \310 | \311 | \312 | \313 | \314 | \315 | \316 | \317
0xD | \320 | \321 | \322 | \323 | \324 | \325 | \326 | \327 | \330 | \331 | \332 | \333 | \334 | \335 | \336 | \337
0xE | \340 | \341 | \342 | \343 | \344 | \345 | \346 | \347 | \350 | \351 | \352 | \353 | \354 | \355 | \356 | \357
0xF | \360 | \361 | \362 | \363 | \364 | \365 | \366 | \367 | \370 | \371 | \372 | \373 | \374 | \375 | \376 | \377

- Space character (0x20) is used as a delimiter that separates words. Line feed character (0x0A) is used as a delimiter that separates lines.
- Only words that follow the rule above and the delimiters (i.e. space character and line feed characters) are valid. All other characters are regarded as space character. Multiple spaces are automatically compressed into one space. Leading and trailing spaces are automatically deleted.

Some examples are shown below.

Word | Correct expression | Wrong expression
Hello world! | Hello\040world! | "Hello world!"
/home/user/Documents and Settings/ | /home/user/Documents\040and\040Settings/ | /home/user/Documents and Settings/

Pathname must start with / character. Pathnames that end with / character are interpreted as directories, and that don't end with / character are interpreted as non-directories.

Pathname | Interpretation
/ | A directory
/tmp/ | A directory
/tmp | Not a directory
tmp/ | Invalid pathname

Exceptions are pipes and sockets. Pipes begin with "pipe:" and sockets begin with "socket:" when these pathnames are accessed via /proc/PID/fd/ directory.

## 2.2 Wildcard Expression Rules

Like temporary files, pathnames may contain randomly selected characters. Thus, you often need to define pathnames using wildcards. TOMOYO Linux supports wildcards shown below.

Wildcard | Meaning | Example
\* | Zero or more repetitions of characters other than '/'. | /var/log/samba/\*
\@ | Zero or more repetitions of characters other than '/' or '.'. | /var/www/html/\@.html
\? | 1 byte character other than '/'. | /tmp/mail.\?\?\?\?\?\?
\$ | One or more repetitions of decimal digits. | /proc/\$/cmdline
\+ | 1 decimal digit. | /var/tmp/my_work.\+
\X | One or more repetitions of hexadecimal digits. | /var/tmp/my-work.\X
\x | 1 hexadecimal digit. | /tmp/my-work.\x
\A | One or more repetitions of alphabet characters. | /var/log/my-work/\$-\A-\$.log
\a | 1 alphabet character. | /home/users/\a/\*/public_html/\*.html
\- | Pathname subtraction operator. |
Example | Meaning
/etc/\* | All files in /etc/ directory.
/etc/\*\-\*shadow\* | /etc/\* other than /etc/\*shadow\*
/\*\-proc\-sys/ | /\*/ other than /proc/ /sys/

## 2.3 Word Length Rules

There is no limitation regarding the length of pathnames in Linux. But to perform pathname based access control, it is impossible to support pathnames with infinite length. Thus, in TOMOYO Linux, the length of a word is limited to 4000 bytes including trailing NUL character.

## 2.4 Line Length Rules

In TOMOYO Linux, the length of a line is limited to 8192 bytes including trailing NUL character.

## 2.5 Memory Allocation Rules

In TOMOYO Linux, memory allocated for holding access permissions and words are never freed. There is no way except rebooting the system that can free unneeded memory.

But don't worry. The policy seldom changes after you start production mode. By tuning policy before starting production mode, you can reduce memory usage to (usually) less than 1 MB.

The memory used by TOMOYO Linux can be obtained via /proc/ccs/meminfo . The unit is byte. "Shared:" indicates memory used for holding words. "Private:" indicates memory used for holding access permissions. These memories never decrease. "Dynamic:" indicates memory used for temporary purpose such as access permission checks and access logs. This memory decreases when it became unneeded.

    # cat /proc/ccs/meminfo

    Shared:          65536
    Private:         49152
    Dynamic:          5106
    Total:          119794

# 3. Policy Files

## 3.1 Policy File's Location

Policy files are files that contain access permissions. These files are automatically loaded into the kernel upon boot.

When a system boots, /sbin/init is executed. When the execution of /sbin/init is requested and if /sbin/ccs-init exists, /sbin/ccs-init is executed, and /sbin/init is executed after /sbin/ccs-init terminates.

/sbin/ccs-init loads policy files in /etc/ccs/ directory via the kernel's /proc/ccs/ interface.

The kernel's interface | Policy file | Contents
/proc/ccs/profile | /etc/ccs/profile.conf | Profiles (Collection of access control levels)
/proc/ccs/manager | /etc/ccs/manager.conf | Managers (Programs that can modify policy via /proc/ccs/ interface)
/proc/ccs/system_policy | /etc/ccs/system_policy.conf | System policy (Access permissions given to system)
/proc/ccs/exception_policy | /etc/ccs/exception_policy.conf | Exception policy (Collection of exceptions for domain policy)
/proc/ccs/domain_policy | /etc/ccs/domain_policy.conf | Domain policy (Access permissions given to individual domains)

There are more interfaces for obtaining information. These interfaces don't have corresponding policy files.

The kernel's interface | Meaning
/proc/ccs/query | Access requests that are waiting for administrator's decision.
/proc/ccs/.domain_status | The list of domainnames and profile numbers currently defined in domain policy.
/proc/ccs/meminfo | Memory usage.
/proc/ccs/grant_log | Access requests that didn't violate domain policy.
/proc/ccs/reject_log | Access requests that violated domain policy.
/proc/ccs/self_domain | The name of domain the current process belongs to.
/proc/ccs/.process_status | The list of domainnames and profile numbers currently running processes belongs to.
/proc/ccs/.updates_counter | Counter for policy updates.
/proc/ccs/version | Version of TOMOYO Linux.

## 3.2 Policy File's Modification

Register the name of programs or domains that can modify policy via the kernel's /proc/ccs/ interface. Only

- Processes with programs listed in /proc/ccs/manager
- Processes with domainnames listed in /proc/ccs/manager

can modify policy via the kernel's /proc/ccs/ interface. Some examples are show below.

# cat /proc/ccs/manager /usr/lib/ccs/loadpolicy /usr/lib/ccs/editpolicy /usr/lib/ccs/setlevel /usr/lib/ccs/setprofile /usr/lib/ccs/ld-watch /usr/lib/ccs/ccs-queryd <kernel> /sbin/mingetty /bin/login /bin/bash

By default, only processes with UID = 0 and EUID = 0 can modify policy via this interface. But by doing configurations described in Allowing policy modification by non root user., non root user can modify policy via this interface.

Exception is, processes that belong to domains with profiles for learning mode can append access permissions to /proc/ccs/system_policy and /proc/ccs/domain_policy by simply requesting the access.

# 4. Domain Rules

## 4.1 Domain Definition

TOMOYO Linux has two patterns of policies. One gives access permissions as a whole system. The other gives access permissions as per a domain. The former is called system policy and is managed via /proc/ccs/system_policy. The latter is called domain policy and is managed via /proc/ccs/domain_policy.

In TOMOYO Linux, every process belongs to a single domain, and all programs belong to different domain. Even the two processes are executing the same program, if their previous domains differ, they belong to different domain.

All domains are defined originating from "<kernel>" domain, which the kernel process belongs to. Since /sbin/init is invoked by the "<kernel>" domain, the domain for /sbin/init is defined as "<kernel> /sbin/init". Since /etc/rc.d/rc is invoked by /sbin/init invoked by the kernel, the domain for /etc/rc.d/rc is defined as "<kernel> /sbin/init /etc/rc.d/rc".

## 4.2 Domain Transition

There are some programs that behave differently depending on the invocation name. For example, /sbin/pidof is a symbolic link to /sbin/killall5 . Since TOMOYO Linux uses canonicalized pathname, by default, if /sbin/pidof is executed, the domain is defined as if /sbin/killall5 is executed.

When a process tries to execute a program, the steps shown below are performed.

Step | Procedure
Getting program's name | Get the name of program that the process is going to execute and keep it as "Candidate 1". This procedure solves symbolic link if the program is a symbolic link. Get the name of program that the process is going to execute and keep it as "Candidate 2". This procedure does not solve symbolic link if the program is a symbolic link.
Handling symbolic links | If "Candidate 1" and "Candidate 2" differ, search exception policy for alias "Candidate 1" "Candidate 2" and if found one, replace "Candidate 1" with "Candidate 2".
Checking argv[0] | If the basename of "Candidate 1" and the basename of argv[0] differ, search domain policy for allow_argv0 "Candidate 1" "the basename of argv[0]" and deny the execute request if not found one.
Aggregating similar programs | Search exception policy for aggregator "Candidate 1" "aggregated name" and if found one, replace "Candidate 1" with "aggregated name".
Checking permission | Search domain policy for allow_execute "Candidate 1" allow_execute @"a pathname group containing Candidate 1" and deny the execute request if not found one.
Deciding destination domain | (1) Search exception policy for no_initialize_domain "Candidate 1" from "the name of the domain the current process belongs to" no_initialize_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" no_initialize_domain "Candidate 1" and if found one, jump to (3). (2) Search exception policy for initialize_domain "Candidate 1" from "the name of the domain the current process belongs to" initialize_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" initialize_domain "Candidate 1" and if found one, concatenate "the name of the domain that the kernel belongs to (i.e. <kernel>)" and "Candidate 1" and keep the result as destination domain, then jump to (6). (3) Search exception policy for no_keep_domain "Candidate 1" from "the name of the domain the current process belongs to" no_keep_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" no_keep_domain "the name of the domain the current process belongs to" no_keep_domain "the last part of the name of the domain the current process belongs to" and if found one, jump to (5). (4) Search exception policy for keep_domain "Candidate 1" from "the name of the domain the current process belongs to" keep_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" keep_domain "the name of the domain the current process belongs to" keep_domain "the last part of the name of the domain the current process belongs to" and if found one, set "the name of the domain the current process belongs to" as destination domain, then jump to (6). (5) Concatenate "the name of the domain the current process belongs to" and "Candidate 1" and keep the result as destination domain. (6) Check whether the destination domain is defined, and deny the execute request if not.
Checking environment variable names | (1) Examine all environment variables' names are granted in the destination domain, and deny the execute request if more than one of them are not granted. (2) Perform regular steps for executing program. If successfully completed, the process transits to destination domain.

There is an exception. If either

- The execute request was denied at "Checking argv[0]" or "Checking permission" or "Deciding destination domain" but the domain the process that issued execute request belongs to has denied_execute_handler keyword.
- The domain the process that issued execute request belongs to has execute_handler keyword.

and

- The process that issued execute request is not a process executed by execute_handler or denied_execute_handler keyword.

the steps shown below is performed instead for the steps shown above. The usage of this exception is explained in "Judging execute request outside the kernel." and "Invoking alternative program for execute requests that are not permitted by policy."

Step | Procedure
Getting program's name | Keep the pathname of the program specified by denied_execute_handler or execute_handler and keep it as "Candidate 1".
Appending information | Append all environment variables to the tail of arguments, and delete all environment variables. Insert "Candidate 1" "the domainname the process that issued execute request belongs to" "the pathname of the process that issued execute request" "state of the process that issued execute request" "the pathname of the requested program" "number of arguments" "number of environment variables" to the top of arguments.
Deciding destination domain | (1) Search exception policy for no_initialize_domain "Candidate 1" from "the name of the domain the current process belongs to" no_initialize_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" no_initialize_domain "Candidate 1" and if found one, jump to (3). (2) Search exception policy for initialize_domain "Candidate 1" from "the name of the domain the current process belongs to" initialize_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" initialize_domain "Candidate 1" and if found one, concatenate "the name of the domain that the kernel belongs to (i.e. <kernel>)" and "Candidate 1" and keep the result as destination domain, then jump to (6). (3) Search exception policy for no_keep_domain "Candidate 1" from "the name of the domain the current process belongs to" no_keep_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" no_keep_domain "the name of the domain the current process belongs to" no_keep_domain "the last part of the name of the domain the current process belongs to" and if found one, jump to (5). (4) Search exception policy for keep_domain "Candidate 1" from "the name of the domain the current process belongs to" keep_domain "Candidate 1" from "the last part of the name of the domain the current process belongs to" keep_domain "the name of the domain the current process belongs to" keep_domain "the last part of the name of the domain the current process belongs to" and if found one, set "the name of the domain the current process belongs to" as destination domain, then jump to (6). (5) Concatenate "the name of the domain the current process belongs to" and "Candidate 1" and keep the result as destination domain. (6) Check whether the destination domain is defined, and deny the execute request if not.
Execute program | Perform regular steps for executing program. If successfully completed, the process transits to destination domain.

## 4.3 Access Logs

TOMOYO Linux generates two types of access logs. One contains access requests that didn't violate domain policy. The other contains access requests that violated domain policy. The former is called grant log and is readable via /proc/ccs/grant_log . The latter is called reject log and is readable via /proc/ccs/reject_log . A utility program /usr/sbin/ccs-auditd is included for reading these logs and saving the logs as files.

Some examples are shown below. The first log is generated by execute request.

#2008-04-09 12:50:15# profile=1 mode=learning pid=5054 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 state[0]=0 state[1]=0 state[2]=0 argc=2 envc=16 argv[]={ "cat" "/etc/fstab" } envp[]={ "TERM=vt100" "SHELL=/bin/bash" "SSH_CLIENT=::ffff:192.168.99.1\04048601\04022" "SSH_TTY=/dev/pts/0" "USER=root" "MAIL=/var/mail/root" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/sbin" "PWD=/root" "LANG=C" "PS1=\\h:\\w\\$\040" "SHLVL=1" "HOME=/root" "LANGUAGE=en_JP:en_US:en_GB:en" "LOGNAME=root" "SSH_CONNECTION=::ffff:192.168.99.1\04048601\040::ffff:192.168.99.152\04022" "_=/bin/cat" } <kernel> /usr/sbin/sshd /bin/bash allow_execute /bin/cat

This log shows that a process that belongs to "<kernel> /usr/sbin/sshd /bin/bash" domain attempted to execute /bin/cat , and the arguments were "cat" and "/etc/fstab", environment variables were "TERM=vt100" "SHELL=/bin/bash" "SSH_CLIENT=::ffff:192.168.99.1\04048601\04022" "SSH_TTY=/dev/pts/0" "USER=root" "MAIL=/var/mail/root" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/sbin" "PWD=/root" "LANG=C" "PS1=\\h:\\w\\$\040" "SHLVL=1" "HOME=/root" "LANGUAGE=en_JP:en_US:en_GB:en" "LOGNAME=root" "SSH_CONNECTION=::ffff:192.168.99.1\04048601\040::ffff:192.168.99.152\04022" "_=/bin/cat". Also, process information such as PID, UID are shown.

The next log is generated by opening a file for reading.

#2008-04-09 12:50:15# profile=1 mode=learning pid=5054 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 state[0]=0 state[1]=0 state[2]=0 <kernel> /usr/sbin/sshd /bin/bash /bin/cat allow_read /etc/fstab

This log shows that a process that belongs to "<kernel> /usr/sbin/sshd /bin/bash /bin/cat" domain opened /etc/fstab for reading.

The next log is generated when a new domain is created.

#2008-04-09 12:52:01# profile=1 mode=learning pid=5110 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 state[0]=0 state[1]=0 state[2]=0 <kernel> /usr/sbin/sshd /bin/bash /bin/bash /bin/audit-exec-param /bin/cat use_profile 1

This log shows that a domain named "<kernel> /usr/sbin/sshd /bin/bash /bin/bash /bin/audit-exec-param /bin/cat" was created and profile 1 was assigned. TOMOYO Linux automatically creates domains as needed. When a domain is automatically created, the profile number of the domain the process that requested program execution belongs to is inherited.

The next log is generated when a program that is different from the program being requested was executed because of Judging execute request outside the kernel.

#2008-04-09 12:52:01# profile=1 mode=learning pid=5110 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 state[0]=0 state[1]=0 state[2]=0 argc=24 envc=0 argv[]={ "/bin/audit-exec-param" "<kernel>\040/usr/sbin/sshd\040/bin/bash\040/bin/bash" "/bin/bash" "pid=5110\040uid=0\040gid=0\040euid=0\040egid=0\040suid=0\040sgid=0\040fsuid=0\040fsgid=0\040state[0]=0\040state[1]=0\040state[2]=0" "/bin/cat" "2" "18" "cat" "/etc/fstab" "SHELL=/bin/bash" "TERM=vt100" "SSH_CLIENT=::ffff:192.168.99.1\04048601\04022" "SSH_TTY=/dev/pts/0" "USER=root" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/sbin" "MAIL=/var/mail/root" "_=/bin/cat" "PWD=/root" "LANG=C" "HOME=/root" "SHLVL=2" "LANGUAGE=en_JP:en_US:en_GB:en" "LOGNAME=root" "SSH_CONNECTION=::ffff:192.168.99.1\04048601\040::ffff:192.168.99.152\04022" } envp[]={ } <kernel> /usr/sbin/sshd /bin/bash /bin/bash execute_handler /bin/audit-exec-param

This log shows that a process that belongs to a domain named "<kernel> /usr/sbin/sshd /bin/bash /bin/bash" attempted to execute a program, but since the execute_handler keyword is specified to the domain, /bin/audit-exec-param was executed, and arguments passed to /bin/audit-exec-param were "/bin/audit-exec-param" "<kernel>\040/usr/sbin/sshd\040/bin/bash\040/bin/bash" "/bin/bash" "pid=5110\040uid=0\040gid=0\040euid=0\040egid=0\040suid=0\040sgid=0\040fsuid=0\040fsgid=0\040state[0]=0\040state[1]=0\040state[2]=0" "/bin/cat" "2" "18" "cat" "/etc/fstab" "SHELL=/bin/bash" "TERM=vt100" "SSH_CLIENT=::ffff:192.168.99.1\04048601\04022" "SSH_TTY=/dev/pts/0" "USER=root" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/sbin" "MAIL=/var/mail/root" "_=/bin/cat" "PWD=/root" "LANG=C" "HOME=/root" "SHLVL=2" "LANGUAGE=en_JP:en_US:en_GB:en" "LOGNAME=root" "SSH_CONNECTION=::ffff:192.168.99.1\04048601\040::ffff:192.168.99.152\04022". To avoid /bin/audit-exec-param affected by environment variables such as LD_PRELOAD, environment variables are moved to arguments.

In this way, an access log consists of 3 lines (or 4 lines since /usr/sbin/ccs-auditd inserts an empty line), and they are in the domain policy format and appendable to the domain policy. Pick up portions you want to permit from reject log and save (for example, /var/log/tomoyo/diff.txt) and you can add to domain policy by doing

# /usr/sbin/ccs-loadpolicy -d < /var/log/tomoyo/diff.txt

Therefore, you don't need to use "learning mode" from the beginning. If you wish, you can use "permissive mode" from the beginning and let reject logs generated, then edit reject logs and append to domain policy when developing domain policy. When domain policy is generated by "learning mode", process state (the first line of an access logs) is not taken into account. But when domain policy is generated from reject logs, you can use Using conditional ACL. from the beginning. For example, generate a reject log by not using "learning mode" and append like

<kernel> /usr/sbin/sshd /bin/bash allow_execute /bin/cat if exec.argc=2 exec.argv[0]="cat" exec.argv[1]="/etc/fstab"

then, you can give more precise permission compared to the permission appended by "learning mode"'s log (shown below).

<kernel> /usr/sbin/sshd /bin/bash allow_execute /bin/cat

# 5. Syntax Details

## /proc/ccs/profile

TOMOYO Linux can perform several MACs besides MAC for files, but to reduce the load of policy managements, you can disable MACs you think unnecessary.

List up functions and their modes in "$number-$variable=$value" format. The $number is profile number between 0 and 255. To modify profile, use "ccs-setlevel" or "ccs-loadpolicy" commands.

Each domain is assigned one profile. To assign profile to domains, use "ccs-setprofile" or "ccs-editpolicy" or "ccs-loadpolicy" commands.

You can see profiles currently assigned to domains using "ccs-editpolicy" command.
You can see profiles currently assigned to processes using "ccs-ccstree" command.
If you saved current policy using "ccs-savepolicy" command, the currently assigned profile number is saved as use_profile line of domain policy.

To read or modify current profiles, operate like below.

(Example)
cat /proc/ccs/profile
ccs-savepolicy -p
ccs-setlevel 1-MAC_FOR_FILE=learning
echo 1-MAC_FOR_FILE=learning | ccs-loadpolicy -p

See also: Policy File's Modification

### MAC_FOR_FILE

Specifies access control level regarding file access requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_IOCTL

Specifies access control level regarding ioctl requests. Valid for TOMOYO Linux 1.6.7 and later.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_ARGV0

Specifies access control level regarding program invocation mame (a.k.a. argv[0]).

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_ENV

Specifies access control level regarding environment variable names (a.k.a. envp[]).

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::inet_tcp_create

Specifies access control level regarding creation of TCP sockets.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::inet_tcp_listen

Specifies access control level regarding TCP socket's listen operation.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::inet_tcp_connect

Specifies access control level regarding TCP socket's connect operation.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::use_inet_udp

Specifies access control level regarding use of UDP sockets.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::use_inet_ip

Specifies access control level regarding use of RAW sockets.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::use_route

Specifies access control level regarding use of ROUTE sockets.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::use_packet

Specifies access control level regarding use of PACKET sockets.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::use_kernel_module

Specifies access control level regarding use of create_module(2) init_module(2) delete_module(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::create_fifo

Specifies access control level regarding creation of FIFO using mknod(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::create_block_dev

Specifies access control level regarding creation of block device file using mknod(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::create_char_dev

Specifies access control level regarding creation of character device file using mknod(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::create_unix_socket

Specifies access control level regarding creation of UNIX domain socket using mknod(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_MOUNT

Specifies access control level regarding use of mount(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_UMOUNT

Specifies access control level regarding use of umount(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_REBOOT

Specifies access control level regarding use of reboot(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_CHROOT

Specifies access control level regarding use of chroot(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_KILL

Specifies access control level regarding use of kill(2) tkill(2) tgkill(2) syscall with non 0 signal.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_VHANGUP

Specifies access control level regarding use of vhangup(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_TIME

Specifies access control level regarding use of stime(2) settimeofday(2) adjtimex(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_NICE

Specifies access control level regarding use of nice(2) setpriority(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_SETHOSTNAME

Specifies access control level regarding use of sethostname(2) setdomainname(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_LINK

Specifies access control level regarding use of link(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_SYMLINK

Specifies access control level regarding use of symlink(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_RENAME

Specifies access control level regarding use of rename(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_UNLINK

Specifies access control level regarding use of unlink(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_CHMOD

Specifies access control level regarding use of chmod(2) fchmod(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_CHOWN

Specifies access control level regarding use of chown(2) fchown(2) lchown(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_IOCTL

Specifies access control level regarding use of ioctl(2) compat_sys_ioctl(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_KEXEC_LOAD

Specifies access control level regarding use of kexec_load(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_PIVOT_ROOT

Specifies access control level regarding use of pivot_root(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_CAPABILITY::SYS_PTRACE

Specifies access control level regarding use of ptrace(2) syscall.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_NETWORK

Specifies access control level regarding network access requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### MAC_FOR_SIGNAL

Specifies access control level regarding signal transmission requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### DENY_CONCEAL_MOUNT

Specifies access control level regarding mount requests that shadow existent mounts.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
permissive | Permissive mode. Prints warning messages for mount requests that will shadow existent mounts. But don't reject the request.
enforcing | Enforcing mode. Prints error messages for mount requests that will shadow existent mounts. And reject the request.

### RESTRICT_CHROOT

Specifies access control level regarding chroot requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### RESTRICT_MOUNT

Specifies access control level regarding mount request's parameters.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### RESTRICT_UNMOUNT

Specifies access control level regarding unmount request of specific directories.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
permissive | Permissive mode. Prints warning messages for unmount requests against directories that are not permitted to be unmounted. But don't reject the request.
enforcing | Enforcing mode. Prints error messages for unmount requests against directories that are not permitted to be unmounted. And reject the request.

### RESTRICT_PIVOT_ROOT

Specifies access control level regarding pivot_root requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. An access request is not rejected even if the request violates policy. Also, the permission to allow the request is automatically added to policy so that the same request no longer violates policy.
permissive | Permissive mode. An access request is not rejected even if the request violates policy. But, the permission to allow the request is not added to policy.
enforcing | Enforcing mode. An access request is rejected if the request violates policy.

### RESTRICT_AUTOBIND

Specifies access control level regarding automatic local port selection requests.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
enabled | Enabled. Forbid specified port number from being selected when automatic local port selection request happens.

### MAX_ACCEPT_ENTRY

Limits the max number of ACL entries that are automatically appended during learning mode. Default is 2048.

### MAX_GRANT_LOG

Limits the max number of grant logs that the kernel can hold. Default is 1024.

### MAX_REJECT_LOG

Limits the max number of reject logs that the kernel can hold. Default is 1024.

### TOMOYO_VERBOSE

Specifies whether to print domain policy violation messages or not.

Value | Meaning
disabled | Disabled. Don't print domain policy violation messages.
enabled | Enabled. Print domain policy violation messages.

### ALLOW_ENFORCE_GRACE

Specifies whether to permit judging access requests which violates policy in enforcing mode interactively. This item was removed in TOMOYO Linux 1.6.2 .

Value | Meaning
disabled | Reject immediately when an access request violated policy in enforcing mode.
enabled | Ask for administrator's decision when an access request violated policy in enforcing mode.

### SLEEP_PERIOD

Specifies how long should the process that violated policy in enforcing mode sleep for.

Value | Meaning
Between 0 to 3000 | Sleep duration in 0.1 seconds. Default is 0.

## /proc/ccs/system_policy

This file contains permissions that apply to the entire system.

To read or modify current system policy, operate like below.

(Example)
cat /proc/ccs/system_policy
ccs-savepolicy -s
echo 'allow_mount /proc /proc/ proc' | ccs-loadpolicy -s
echo 'delete allow_mount /proc /proc/ proc' | ccs-loadpolicy -s

See also: Policy File's Modification

### allow_mount

To grant mount permission, use allow_mount keyword followed by "$devicefile $mountpoint $filesystem $options".
The $devicefile need to be a canonicalized file if the $filesystem requires device file.
The $mountpoint must be a canonicalized file.
The $options is a hexadecimal integer expression.

To grant "mount -o remount $mountpoint" permission, use allow_mount keyword followed by "any $mountpoint --remount $options".

To grant "mount --bind $source_dir $dest_dir" and "mount --move $source_dir $dest_dir" permission, use allow_mount keyword followed by "$source_dir $dest_dir --bind $options" and "$source_dir $dest_dir --move $options" respectively.
The $source_dir and $dest_dir must be canonicalized directory.

Kernel 2.6.15 and later supports "Shared Subtree" functionality.
To grant "mount --make-unbindable $mountpoint" permission, use allow_mount keyword followed by "any $mountpoint --make-unbindable $options".
To grant "mount --make-private $mountpoint" permission, use allow_mount keyword followed by "any $mountpoint --make-private $options".
To grant "mount --make-slave $mountpoint" permission, use allow_mount keyword followed by "any $mountpoint --make-slave $options".
To grant "mount --make-shared $mountpoint" permission, use allow_mount keyword followed by "any $mountpoint --make-shared $options".

(Example)
allow_mount none /dev/pts/ devpts 0x0
allow_mount /proc /proc/ proc 0x0
allow_mount usbdevfs /proc/bus/usb/ usbdevfs 0x0
allow_mount none /data/ tmpfs 0xE
allow_mount none /dev/shm/ tmpfs 0xE
allow_mount /dev/hdc /var/www/ ext2 0xF
allow_mount any / --remount 0x0

### deny_unmount

To reject unmount request, use deny_unmount keyword followed by a canonicalized directory.
Usually, specify /dev/ directory (that contains /dev/tty? used by /sbin/mingetty) and /dev/pts/ directory (that are used to create pty device files for remote login).

If /dev/ becomes read-only or /dev/pts/ is unmounted, you can't login to the system. Therefore /dev/ and /dev/pts/ must not be unmounted for systems where / is read-only.

(Example)
deny_unmount /dev/
deny_unmount /dev/pts/
deny_unmount /proc/

### allow_chroot

To grant chroot permission, use allow_chroot keyword followed by a canonicalized directory.
Usually, grant /var/empty/sshd/ that sshd uses. In addition, if you have applications that runs in the chroot'ed environment or applications that uses chroot (for example, /usr/share/empty/ is used by vsftpd), grant such directories too.

(Example)
allow_chroot /var/empty/sshd/
allow_chroot /usr/share/empty/
allow_chroot /var/www/html/
allow_chroot /

### allow_pivot_root

To grant pivot_root permission, use allow_pivot_root keyword followed by the new root's canonicalized directory and the previous root's canonicalized directory.
Usually, you don't need this keyword.

### deny_autobind

To prevent specific local port from being selected automatically, use deny_autobind keyword followed by local port number.
This keyword is intended to prevent specific local port from being bound for temporary use. For example, some proxy server uses local port 8080, so port 8080 should not be bound by other programs for temporary use.

(Example)
deny_autobind 1-1023
deny_autobind 8080

## /proc/ccs/domain_policy

This file contains definition of all domains and permissions that are granted to each domain.

Lines from the next line to a domain definition ( any lines starting with "<kernel>") to the previous line to the next domain definitions are interpreted as access permissions for that domain.

You can specify additional conditions as needed. The syntax for specifying additional conditions are described in Using conditional ACL. Also, how to switch process's state as needed and use the process's state for conditions is described in Using stateful ACL.

To read or modify current domain policy, operate like below.

(Example) Selecting specific domain and appending ACLs. The domain will be created if nonexistent.
printf "<kernel> /sbin/init\nallow_read /etc/passwd\n" | ccs-loadpolicy -d

(Example) Selecting specific domain and appending ACLs. The domain won't be created if nonexistent.
printf "select <kernel> /sbin/init\nallow_read /etc/passwd\n" | ccs-loadpolicy -d

(Example) Selecting specific domain and removing ACLs.
printf "select <kernel> /sbin/init\ndelete allow_read /etc/passwd\ndelete allow_read /etc/shadow\n" | ccs-loadpolicy -d

(Example) Deleting specific domain.
printf "delete <kernel> /sbin/init\n" | ccs-loadpolicy -d

(Example) Reading current domain policy.
cat /proc/ccs/domain_policy

See also: Policy File's Modification

### allow_execute

This keyword grants execution of the specified pathname. No wildcards are permitted for the pathname. If you have to use wildcards, use aggregator keyword before granting execute permission using this keyword.

(Example) allow_execute /bin/ls

See also: Domain Transition aggregator

### allow_write

This keyword grants the specified pathname to be opened for writing.

(Example) allow_write /dev/null

See also: path_group

### allow_read

This keyword grants the specified pathname to be opened for reading.

(Example) allow_read /proc/meminfo

See also: path_group

### allow_read/write

This keyword grants the specified pathname to be opened for reading and writing.

(Example) allow_read/write /dev/null

See also: path_group

### allow_create

This keyword grants the specified pathname to be created.

(Example) allow_create /var/lock/subsys/crond

See also: path_group

### allow_unlink

This keyword grants the specified pathname to be deleted.

(Example) allow_unlink /var/lock/subsys/crond

See also: path_group

### allow_mkdir

This keyword grants the specified pathname to be created. The pathname must be a directory.

(Example) allow_mkdir /tmp/logwatch.\*/

See also: path_group

### allow_rmdir

This keyword grants the specified pathname to be deleted. The pathname must be a directory.

(Example) allow_rmdir /tmp/logwatch.\*/

See also: path_group

### allow_mkfifo

This keyword grants creation of FIFO by the specified pathname.

(Example) allow_mkfifo /dev/initctl

See also: path_group

### allow_mksock

This keyword grants creation of UNIX domain socket by the specified pathname.

(Example) allow_mksock /dev/log

See also: path_group

### allow_mkblock

This keyword grants creation of block device file by the specified pathname.

(Example) allow_mkblock /dev/\*

See also: path_group

### allow_mkchar

This keyword grants creation of character device file by the specified pathname.

(Example) allow_mkchar /dev/\*

See also: path_group

### allow_truncate

This keyword grants the specified pathname to be truncated or extended.

(Example) allow_truncate /etc/mtab

See also: path_group

### allow_symlink

This keyword grants creation of symbolic link by the specified pathname.

(Example) allow_symlink /dev/cdrom

See also: path_group

### allow_link

This keyword grants creation of hard link by the specified pathnames.

(Example) allow_link /etc/mtab~\$ /etc/mtab~

See also: path_group

### allow_rename

This keyword grants renaming of the specified pathnames.

(Example) allow_rename /etc/mtab.tmp /etc/mtab

See also: path_group

### allow_rewrite

This keyword grants the specified pathname to be rewritten when the pathname is specified by deny_rewrite keyword.

(Example) allow_rewrite /var/log/messages

See also: path_group deny_rewrite

### allow_ioctl

This keyword grants doing IOCTL request with the specified command numbers and the specified pathnames.

Example | Permitted access
allow_ioctl socket:[family=2:type=2:protocol=17] 35093 | Allow sockets with protocol family 2, type 2, protocol 17 to do IOCTL request with command number 35093.
allow_ioctl /dev/null 10000-20000 | Allow /dev/null to do IOCTL request with command number between 10000 and 20000.

Regarding the meaning of IOCTL request's command numbers, please refer manuals provided by each module with IOCTL functionality. For example, IOCTL request with command number 21585 means, on i386 platform, FIOCLEX command which turns on the file's close-on-exec flag. For example, IOCTL request with command number 35088 means SIOCGIFNAME command which retrieves the name of network interface.

See also: Using conditional ACL.

### allow_argv0

To restrict the contents of argv[0], use allow_argv0 keyword followed by "the pathname of program" and "the basename part of argv[0]".

The execve() system call, which is used to execute a program, accepts filename and argv[] and envp[]. Some programs (e.g. busybox) behave differently depending on the basename of argv[0]. When invoking a program via a symbolic link, the domain transition of TOMOYO Linux is done based on the Canonicalized Pathname of filename while the behavior of the program is determined based on argv[0] (usually same as filename). For example, in a system that provides /bin/ls and /bin/cat as hard links of busybox, it becomes a loophole that allows programs to behave as cat in the domain of /bin/ls by creating a symbolic link named /tmp/cat that points to /bin/ls and executing /tmp/cat .

The purpose of this keyword is to restrict the combinations of filename and argv[0] so that such loopholes won't occur.

### allow_env

To restrict the name of environment variables, use allow_env keyword followed by "the name of environment variable".

The execve() system call, which is used to execute a program, accepts filename and argv[] and envp[]. Many programs behave differently depending on envp[].

The purpose of this keyword is to restrict the environment variables passed to an executed programs.

See also: allow_env

### allow_capability

To grant capability permission, use allow_capability keyword followed by a capability. The following capabilities are applicable.

allow_capability inet_tcp_create | Permit creation of TCP sockets.
allow_capability inet_tcp_listen | Permit TCP socket's listen operation.
allow_capability inet_tcp_connect | Permit TCP socket's connect operation.
allow_capability use_inet_udp | Permit use of UDP sockets.
allow_capability use_inet_ip | Permit use of RAW sockets.
allow_capability use_route | Permit use of ROUTE sockets.
allow_capability use_packet | Permit use of PACKET sockets.
allow_capability use_kernel_module | Permit use of create_module(2) init_module(2) delete_module(2) syscall.
allow_capability create_fifo | Permit creation of FIFO using mknod(2) syscall.
allow_capability create_block_dev | Permit creation of block device using mknod(2) syscall.
allow_capability create_char_dev | Permit creation of character device using mknod(2) syscall.
allow_capability create_unix_socket | Permit creation of UNIX domain sockets using mknod(2) syscall.
allow_capability SYS_MOUNT | Permit use of mount(2) syscall.
allow_capability SYS_UMOUNT | Permit use of umount(2) syscall.
allow_capability SYS_REBOOT | Permit use of reboot(2) syscall.
allow_capability SYS_CHROOT | Permit use of chroot(2) syscall.
allow_capability SYS_KILL | Permit use of kill(2) tkill(2) tgkill(2) syscall with non 0 signal.
allow_capability SYS_VHANGUP | Permit use of vhangup(2) syscall.
allow_capability SYS_TIME | Permit use of stime(2) settimeofday(2) adjtimex(2) syscall.
allow_capability SYS_NICE | Permit use of nice(2) setpriority(2) syscall.
allow_capability SYS_SETHOSTNAME | Permit use of sethostname(2) setdomainname(2) syscall.
allow_capability SYS_LINK | Permit use of link(2) syscall.
allow_capability SYS_SYMLINK | Permit use of symlink(2) syscall.
allow_capability SYS_RENAME | Permit use of rename(2) syscall.
allow_capability SYS_UNLINK | Permit use of unlink(2) syscall.
allow_capability SYS_CHMOD | Permit use of chmod(2) fchmod(2) syscall.
allow_capability SYS_CHOWN | Permit use of chown(2) fchown(2) lchown(2) syscall.
allow_capability SYS_IOCTL | Permit use of ioctl(2) compat_sys_ioctl(2) syscall.
allow_capability SYS_KEXEC_LOAD | Permit use of kexec_load(2) syscall.
allow_capability SYS_PIVOT_ROOT | Permit use of pivot_root(2) syscall.
allow_capability SYS_PTRACE | Permit use of ptrace(2) syscall.

The purpose of allow_capability keyword is to restrict system calls that a program can call. You can restrict more strictly with other keyword and policy files for some system calls.

- You can restrict creation of block device files using allow_mkblock keyword.
- You can restrict creation of character device files using allow_mkchar keyword.
- You can restrict creation of FIFOs using allow_mkfifo keyword.
- You can restrict creation of UNIX domain sockets using allow_mksock keyword.
- You can restrict creation of symbolic links using allow_symlink keyword.
- You can restrict deletion of non-directories using allow_unlink keyword.
- You can restrict combination of pathnames that can be hard linked using allow_link keyword.
- You can restrict combination of pathnames that can be renamed using allow_rename keyword.
- You can restrict combination of IOCTL's command numbers and pathnames using allow_ioctl keyword. (Valid for TOMOYO 1.6.7 and later.)
- You can restrict IP addresses and ports using allow_network keyword.
- You can restrict signal numbers and target domain using allow_signal keyword.
- You can restrict devices and directories for mount operations using allow_mount keyword.
- You can restrict directories that you don't allow unmount using deny_unmount keyword.
- You can restrict directories that can chroot to using allow_chroot keyword.
- You can restrict directories that can exchange using allow_pivot_root keyword.

### allow_network

To grant permission for socket operations, use allow_network keyword followed by protocol(TCP or UDP or RAW) and IP address and port number (for TCP or UDP) / protocol number (for RAW). This permission is applicable to IPv4 and IPv6.

Keyword | Permitted operation | Example
allow_network TCP bind | Bind to local TCP address/port. | allow_network TCP bind 0.0.0.0 80
allow_network TCP listen | Listen to local TCP address/port. | allow_network TCP listen 0.0.0.0 80
allow_network TCP accept | Accept from and communicate with remote TCP address/port. | allow_network TCP accept 10.0.0.0-10.255.255.255 1024-65535
allow_network TCP connect | Connect to and communicate with remote TCP address/port. | allow_network TCP connect 127.0.0.1 1024-65535
allow_network UDP bind | Bind to local UDP address/port. | allow_network UDP bind 0.0.0.0 53
allow_network UDP connect | Communicate with remote UDP address/port. | allow_network UDP connect 127.0.0.1 53
allow_network RAW bind | Bind to local IP address/protocol. | allow_network RAW bind 127.0.0.1 255
allow_network RAW connect | Communicate with remote IP address/protocol. | allow_network RAW connect 10.0.0.1 1

Use of "::" for IPv6 address representation is not supported. You need to use "0:0:0:0:0:0:0:1" for "::1".

To reduce the labor of repeating same IP addresses, you can define groups like pathnames.

See also: address_group

### allow_signal

To grant permissions for signals, use allow_signal keyword followed by signal number and target domain.
There are two exceptions. If signal number is 0, it is always granted. If the target domain and the source domain are the same, it is always granted.

In other cases, signals are granted only when the signal number matches and the target domain starts with the target domain declared with this keyword.

If only <kernel> is declared as a target domain, the source domain can send signals to any domain with that signal number.

### use_profile

This keyword indicates the profile number currently assigned to this domain. The profile number is an integer between 0 and 255.

### ignore_global_allow_read

This keyword ignores pathnames specified by allow_read keyword in exception policy. You can use this keyword for domains you want to ignore globally readable files.

See also: allow_read

### ignore_global_allow_env

This keyword ignores environment variables names specified by allow_env keyword in exception policy. You can use this keyword for domains you want to ignore globally acceptable environment variable names.

See also: allow_env

### execute_handler

This domain executes only one program specified by this keyword. You can use this keyword for domains you want to validate parameters before executing the requested program.

If this keyword is specified, only one program specified by this keyword regardless of the mode specified by MAC_FOR_FILE. Thus, if the pathname specified by this program cannot be executed, no programs can be executed from this domain.

See also: denied_execute_handler MAC_FOR_FILE allow_execute allow_argv0

### denied_execute_handler

This domain executes this program only when execute request was rejected and the mode of MAC_FOR_FILE is enforcing. If this keyword is not specified and the mode of MAC_FOR_FILE is enforcing, execute request is rejected.

Exception is, if the execute_handler keyword is specified, denied_execute_handler keyword is ignored.

### quota_exceeded

This keyword indicates that this domain has failed to append entry in learning mode since the number of entries reached to the limit specified by MAX_ACCEPT_ENTRY keyword. You need to reduce the number of entries for this domain by tuning policy.

See also: MAX_ACCEPT_ENTRY

### transition_failed

This keyword indicates that this domain has failed to create a new domain since "the name of the domain to be created was too long" or "the kernel was unable to allocate memory" but processed the execute request without domain transition to avoid rejecting the execute request. You need to consider "suppressing domain transitions" or "increasing memory quota" if you are planning to assign a profile with MAC_FOR_FILE=enforcing to this domain.

See also: keep_domain Enabling quota for memory used for holding policy.

## /proc/ccs/exception_policy

To read or modify current exception policy, operate like below.

(Example)
echo 'file_pattern /proc/\$/status' | ccs-loadpolicy -e
echo 'delete file_pattern /proc/\$/status' | ccs-loadpolicy -e
cat /proc/ccs/exception_policy

See also: Policy File's Modification

### file_pattern

To declare pathname pattern, use file_pattern keyword followed by pathname pattern. The pathname pattern must be a canonicalized Pathname. This keyword is not applicable to neither granting execute permissions nor domain definitions.
For example, canonicalized pathname that contains a process ID (i.e. /proc/PID/ files) needs to be grouped in order to make access control work well.

When file access requests arise in learning mode ( profile's MAC_FOR_FILE is set to "learning" ) , the requested pathname is automatically patterned according to patterns specified using this keyword. This keyword does not affect modes other than learning mode. This keyword is used for only reducing the burden of policy tuning which is needed after the learning mode by making already known pathname patterns as templates.

### path_group

To declare pathname group, use path_group keyword followed by name of the group and pathname pattern. For example, if you want to group all files under home directory, you can define

path_group HOME-DIR-FILE /home/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\*/\* path_group HOME-DIR-FILE /home/\*/\*/\*/\*/\*/\*/\*

in the exception policy and use like

allow_read @HOME-DIR-FILE

to grant file access permission.

### address_group

To declare address group, use address_group keyword followed by name of the group and IP address pattern. For example, if you want to group all local addresses, you can define

address_group local-address 10.0.0.0-10.255.255.255 address_group local-address 172.16.0.0-172.31.255.255 address_group local-address 192.168.0.0-192.168.255.255

in the exception policy and use like

allow_network TCP accept @local-address 1024-65535

to grant network access permission.

### allow_read

To grant unconditionally readable permissions, use allow_read keyword followed by canonicalized file. This keyword is intended to reduce size of domain policy by granting read access to library files such as GLIBC and locale files. Exception is, if ignore_global_allow_read keyword is given to a domain, entries specified by this keyword are ignored.

See also: allow_read ignore_global_allow_read

### allow_env

To grant unconditionally acceptable environment variables' names, use allow_env keyword followed by the name of environment variables. This keyword is intended to reduce memory usage for commonly granted environment variables (e.g. PATH and HOME). You should not grant dangerous environment variables like LD_PRELOAD . Exception is, if ignore_global_allow_env keyword is given to a domain, entries specified by this keyword are ignored.

See also: ignore_global_allow_env allow_env

### deny_rewrite

To deny overwriting already written contents of file (such as log files) by default, use deny_rewrite keyword followed by pathname pattern. Files whose pathname match the patterns are not permitted to open for writing without append mode or truncate unless the pathnames are explicitly granted using allow_rewrite keyword in domain policy.

See also: allow_rewrite

### alias

To allow executing programs using the name of symbolic links, use alias keyword followed by dereferenced pathname and reference pathname. This keyword is intended to allow programs that behave differently depending on the name of invocation and that referenced using symbolic links instead of hard links transit domain using the symbolic link's name.

For example, /sbin/pidof is a symbolic link to /sbin/killall5 . In normal case, if /sbin/pidof is executed, the domain is defined as if /sbin/killall5 is executed. By specifying "alias /sbin/killall5 /sbin/pidof", you can run /sbin/pidof in the domain for /sbin/pidof .

See also: allow_execute

### aggregator

To deal multiple programs as a single program, use aggregator keyword followed by name of original program and aggregated program. This keyword is intended to aggregate similar programs.

For example, /usr/bin/tac and /bin/cat are similar. By specifying "aggregator /usr/bin/tac /bin/cat", you can run /usr/bin/tac in the domain for /bin/cat .

For example, /usr/sbin/logrotate for Fedora Core 3 generates programs like /tmp/logrotate.\?\?\?\?\?\? and run them, but TOMOYO Linux doesn't allow using patterns for granting execute permission and defining domains. By specifying "aggregator /tmp/logrotate.\?\?\?\?\?\? /tmp/logrotate.tmp", you can run /tmp/logrotate.\?\?\?\?\?\? as if /tmp/logrotate.tmp is running.

See also: allow_execute

### initialize_domain

To initialize domain transition when specific program is executed, use initialize_domain directive.

- initialize_domain "program" from "domain"
- initialize_domain "program" from "the last program part of domain"
- initialize_domain "program"

If the part "from" and after is not given, the entry is applied to all domain. If the "domain" doesn't start with "<kernel>", the entry is applied to all domain whose domainname ends with "the last program part of domain".

This directive is intended to aggregate domain transitions for daemon program and program that are invoked by the kernel on demand, by transiting to different domain.

See also: Domain Transition no_initialize_domain

### no_initialize_domain

To deny the effect of "initialize_domain" directive, use "no_initialize_domain" directive.

- no_initialize_domain "program" from "domain"
- no_initialize_domain "program" from "the last program part of domain"
- no_initialize_domain "program"

Use this directive when you don't want to initialize domain transition.

See also: Domain Transition initialize_domain

### keep_domain

To prevent domain transition when program is executed from specific domain, use keep_domain directive.

- keep_domain "program" from "domain"
- keep_domain "program" from "the last program part of domain"
- keep_domain "domain"
- keep_domain "the last program part of domain"

If the part "from" and before is not given, this entry is applied to all program. If the "domain" doesn't start with "<kernel>", the entry is applied to all domain whose domainname ends with "the last program part of domain".

This directive is intended to reduce total number of domains and memory usage by suppressing unneeded domain transitions.

To declare domain keepers, use keep_domain directive followed by domain definition.

Any process that belongs to any domain declared with this directive, the process stays at the same domain unless any program registered with initialize_domain directive is executed.

See also: Domain Transition no_keep_domain

### no_keep_domain

To deny the effect of "keep_domain" directive, use "no_keep_domain" directive.

- no_keep_domain "program" from "domain"
- no_keep_domain "program" from "the last program part of domain"
- no_keep_domain "domain"
- no_keep_domain "the last program part of domain"

Use this directive when you want to escape from a domain that is kept by "keep_domain" directive.

See also: Domain Transition keep_domain

## /proc/ccs/query

This file is used to manually grant or reject individual access requests when the policy violation occurs in enforcing mode. If a policy violation occur in a process whose domain is assigned a profile for enforcing mode and "ALLOW_ENFORCE_GRACE=enabled", the administrator can judge interactively using "ccs-queryd" command.

The ALLOW_ENFORCE_GRACE was removed in TOMOYO Linux 1.6.2 . If you are using TOMOYO Linux 1.6.2 and later, you just need to run "ccs-queryd" command to judge interactively.

## /proc/ccs/manager

This file is used to read or append the list of programs or domains that can write to /proc/ccs/ interface.

### manage_by_non_root

By default, only processes with both UID = 0 and EUID = 0 can modify policy via /proc/ccs/ interface. You can use this keyword to allow policy modification by non root user.

## /proc/ccs/.domain_status

This is a view (of a DBMS) that contains only profile number and domainnames of domain so that "ccs-setprofile" command can do line-oriented processing easily.

## /proc/ccs/meminfo

This file is to show the total RAM used to keep policy in the kernel by TOMOYO Linux.

(Example)
cat /proc/ccs/meminfo

## /proc/ccs/grant_log

This file holds the granted log. The reader process returns immediately if no granted logs exists. To wait until a granted log is generated, use select(2) for readability. The max number of logs that the kernel can hold is limited to MAX_GRANT_LOG, so read out timely.

(Example)
cat /proc/ccs/grant_log

## /proc/ccs/reject_log

This file holds the rejected log. The reader process returns immediately if no violation logs exists. To wait until a violation log is generated, use select(2) for readability. The max number of logs that the kernel can hold is limited to MAX_REJECT_LOG, so read out timely.

(Example)
cat /proc/ccs/reject_log

## /proc/ccs/self_domain

This file is to show the name of domain the caller process belongs to.

(Example)
cat /proc/ccs/self_domain

## /proc/ccs/.process_status

This file is used by "ccs-ccstree" command to show "list of processes currently running" and "domains which each process belongs to" and "profile number which the domain is currently assigned" like "pstree" command. This file is writable by programs that aren't registered as policy manager.

## /proc/ccs/.updates_counter

This file is a counter used by policy update monitor programs so that they can easily find that the policies may have changed since last check. The counter values are reset to 0 whenever it is referred.

## /proc/ccs/version

This file is used for getting TOMOYO Linux's version.

(Example)
cat /proc/ccs/version

# 6. Advanced Features

## 6.1 Allowing policy modification by non root user.

By default, only processes with both UID = 0 and EUID = 0 can modify policy via /proc/ccs/ interface. But if you want to permit policy modification via /proc/ccs/ interface by non root user, you can write this keyword like

# echo manage_by_non_root | /usr/sbin/ccs-loadpolicy -m

to disable UID and EUID checks. Also, you can write this keyword like

# echo delete manage_by_non_root | /usr/sbin/ccs-loadpolicy -m

to enable UID and EUID checks again. Use chown/chmod as needed since the owner of /proc/ccs/ interface is root.
To be able to do this steps, /sbin/ccs-init also executes /etc/ccs/ccs-post-init if /etc/ccs/ccs-post-init is executable. Therefore, to allow access to /proc/ccs/ interface by user demo, create /etc/ccs/ccs-post-init with

#! /bin/sh echo manage_by_non_root > /proc/ccs/manager chown -R demo /proc/ccs/

and initialize like

# chmod 755 /etc/ccs/ccs-post-init # chown -R demo /etc/ccs/ # chmod 755 /usr/lib/ccs/

Then, user demo will be able to access policy directories and policy editors.

## 6.2 Enabling quota for memory used for holding policy.

TOMOYO Linux 1.6.1 introduced memory quota for limiting maximum memory allocated for holding TOMOYO Linux's policy.

You can set memory quota by writing to /proc/ccs/meminfo like

echo Shared: 2097152 > /proc/ccs/meminfo echo Private: 2097152 > /proc/ccs/meminfo

from /etc/ccs/ccs-post-init .

## 6.3 Using conditional ACL.

You can add conditions (e.g. UID and GID) as needed. The condition clause are appended to the tail of each permission using "if" directive.

Example | Meaning
allow_read /etc/passwd | Allow opening /etc/passwd for reading.
allow_read /etc/passwd if task.uid=0 | Allow opening /etc/passwd for reading only if the process's UID is 0.
allow_read /etc/passwd if task.uid!=0 | Allow opening /etc/passwd for reading only if the process's UID is not 0.
allow_network TCP connect 10.0.0.1 80 | Allow connecting TCP socket to 10.0.0.1 port 80.
allow_network TCP connect 10.0.0.1 80 if task.uid=100 | Allow connecting TCP socket to 10.0.0.1 port 80 only if the process's UID is 100.
allow_capability SYS_KILL | Allow using kill(2) syscall.
allow_capability SYS_KILL if task.ppid=1 task.uid=0 task.euid=0 | Allow using kill(2) syscall only if the parent process is /sbin/init and the process's UID is 0 and the process's EUID is 0.

The following variables are available.

Variable | Meaning
task.uid | UID of current process
task.euid | Effective UID of current process
task.suid | Saved UID of current process
task.fsuid | File System UID of current process
task.gid | GID of current process
task.egid | Effective GID of current process
task.sgid | Saved GID of current process
task.fsgid | File System GID of current process
task.pid | PID of current process
task.ppid | PID of parent process
path1.uid | UID of object.
path1.gid | GID of object.
path1.ino | i-node number of object.
path1.parent.uid | UID of object's parent directory.
path1.parent.gid | GID of object's parent directory.
path1.parent.ino | i-node number of object's parent directory.
path2.parent.uid | UID of object's parent directory.
path2.parent.gid | GID of object's parent directory.
path2.parent.ino | i-node number of object's parent directory.

"path1" corresponds to the first pathname of operations that requires pathnames, and "path2" corresponds to the second pathname of operations that requires pathnames. For example, the case of "allow_rename file1 file2", path1 corresponds to file1 and path2 corresponds to file2.

"path1" except "path1.parent" is not available for pathnames that don't exist. Thus, you can't use when creating pathnames (such as allow_create keyword).

"path1.parent" is always available.

"path2.parent" is available only for operations that require 2 pathnames (i.e. allow_link and allow_rename keywords).

"path2" except "path2.parent" is not supported. (If "path2" already exist for "rename" operation, "unlink" or "rmdir" operation is performed implicitly.)

"path1" is not supported when accessing via "sysctl" (i.e. accessing files under /proc/sys/ directories using "sysctl" instead for "open").

### The following variables and conditions are available for allow_execute keyword.

Variable | Meaning
exec.argc | Number of argv[] passed for execute request.
exec.envc | Number of envp[] passed for execute request.

Condition | Meaning
exec.argv[index]="value" | argv[index] (where 0 <= index < exec.argc) matches "value".
exec.argv[index]!="value" | argv[index] (where 0 <= index < exec.argc) does not match "value".
exec.envp["name"]="value" | Environment variable "name" is defined and matches "value".
exec.envp["name"]!="value" | Environment variable "name" is not defined or does not match "value".
exec.envp["name"]!=NULL | Environment variable "name" is defined.
exec.envp["name"]=NULL | Environment variable "name" is not defined.

### The following conditions are also available for TOMOYO 1.6.7 and later.

#### Type of process

Condition | Meaning
task.type=execute_handler | Current process is a program specified by execute_handler keyword.
task.type!=execute_handler | Current process is not a program specified by execute_handler keyword.

#### Type of file.

Condition | Meaning
path1.type=file | path1 is a regular file.
path1.type=directory | path1 is a directory.
path1.type=fifo | path1 is a FIFO.
path1.type=socket | path1 is a socket.
path1.type=symlink | path1 is a symbolic link.
path1.type=block | path1 is a block device file.
path1.type=char | path1 is a character device file.
path1.type!=file | path1 is not a regular file.
path1.type!=directory | path1 is not a directory.
path1.type!=fifo | path1 is not a FIFO.
path1.type!=socket | path1 is not a socket.
path1.type!=symlink | path1 is not a symbolic link.
path1.type!=block | path1 is not a block device file.
path1.type!=char | path1 is not a character device file.

Since path1.parent and path2.parent are always directory, TOMOYO does not support path1.parent and path2.parent for type of file.

#### Device numbers of a device file where the file resides.

Condition | Meaning
path1.major=num1-num2 | Device major number of a device file which path1 reside is between num1 and num2.
path1.minor=num1-num2 | Device minor number of a device file which path1 reside is between num1 and num2.
path1.major!=num1-num2 | Device major number of a device file which path1 reside is not between num1 and num2.
path1.minor!=num1-num2 | Device minor number of a device file which path1 reside is not between num1 and num2.

Since a device file where path1.parent and path2.parent reside is always same as the device file where path1 resides (because cross device operation is not permitted), TOMOYO does not support path1.parent and path2.parent for device numbers.

If num1 and num2 is the same value, you can omit -num2 part.

#### Device numbers of the device file itself.

Condition | Meaning
path1.dev_major=num1-num2 | Device file's major number is between num1 and num2.
path1.dev_minor=num1-num2 | Device file's minor number is between num1 and num2.
path1.dev_major!=num1-num2 | Device file's major number is not between num1 and num2.
path1.dev_minor!=num1-num2 | Device file's minor number is not between num1 and num2.

These conditions are valid only for path1.type=block or path1.type=char cases.

If num1 and num2 is the same value, you can omit -num2 part.

#### DAC's permissions

Condition | Meaning
path1.perm=num1-num2 | path1's permission is between num1 and num2.
path1.perm!=num1-num2 | path1's permission is not between num1 and num2.
path1.perm=setuid | path1's setuid bit is on.
path1.perm!=setuid | path1's setuid bit is off.
path1.perm=setgid | path1's setgid bit is on.
path1.perm!=setgid | path1's setgid bit is off.
path1.perm=sticky | path1's sticky bit is on.
path1.perm!=sticky | path1's sticky bit is off.
path1.perm=owner_read | path1's owner read bit is on.
path1.perm!=owner_read | path1's owner read bit is off.
path1.perm=owner_write | path1's owner write bit is on.
path1.perm!=owner_write | path1's owner write bit is off.
path1.perm=owner_execute | path1's owner execute bit is on.
path1.perm!=owner_execute | path1's owner execute bit is off.
path1.perm=group_read | path1's group read bit is on.
path1.perm!=group_read | path1's group read bit is off.
path1.perm=group_write | path1's group write bit is on.
path1.perm!=group_write | path1's group write bit is off.
path1.perm=group_execute | path1's group execute bit is on.
path1.perm!=group_execute | path1's group execute bit is off.
path1.perm=others_read | path1's others read bit is on.
path1.perm!=others_read | path1's others read bit is off.
path1.perm=others_write | path1's others write bit is on.
path1.perm!=others_write | path1's others write bit is off.
path1.perm=others_execute | path1's others execute bit is on.
path1.perm!=others_execute | path1's others execute bit is off.

These conditions are applicable for path1.parent and path2.parent as well as path1 .

If num1 and num2 is the same value, you can omit -num2 part.

To specify value in octal format, start from 0 (e.g. path1.perm=0644 ).

#### Example:

- allow_read/write /dev/null if path1.type=char path1.major=1 path1.minor=3 path1.perm=0666

will allow opening /dev/null for reading and writing only if /dev/null's type is character device file and /dev/null's major number is 1 and /dev/null's minor number is 3 and /dev/null's permission is 0666.

### The following conditions for allow_symlink keyword are also available for TOMOYO 1.6.8 and later.

Condition | Meaning
symlink.target="value" | The content of a symlink to be created matches "value".
symlink.target!="value" | The content of a symlink to be created does not match "value".

## 6.4 Using stateful ACL.

Since TOMOYO Linux doesn't require modification of userland applications, it is impossible to change the range of accessible resources without domain transition. But there are cases you wish to change the range of accessible resources without domain transition. For example, you might wish to change the range of accessible resources depending on the client's IP address. To support such cases, you can assign state variables to each processes and you can use the state variables in Using conditional ACL.

Variable | Meaning
task.state[0] | Current process's state variable 0
task.state[1] | Current process's state variable 1
task.state[2] | Current process's state variable 2

Each task.state can take an integer value between 0 and 255. To change state variable, append " ; set " part after an ACL.

Example | Meaning
allow_network TCP accept @TRUSTED_HOSTS 1024-65535 ; set task.state[0]=1 | If a TCP connection is accepted from an IP address included in an address group @TRUSTED_HOSTS, set 1 to state[0].
allow_network TCP accept @UNTRUSTED_HOSTS 1024-65535 ; set task.state[0]=0 | If a TCP connection is accepted from an IP address included in an address group @UNTRUSTED_HOSTS, set 0 to state[0].
allow_execute /bin/bash if task.state[0]=1 | Allow execution of /bin/bash if state[0] is 1.
allow_execute /sbin/nologin if task.state[0]=0 | Allow execution of /sbin/nologin if state[0] is 0.
allow_execute /etc/passwd if task.state[2]=0 ; set task.state[2]=1 | If state[2] is 0, allow opening /etc/passwd for reading and then, set 1 to state[2].

When using the state variables, please be careful with the following points.

- The domain a process belongs to is automatically updated upon execution of a program, but the state variables of the process are not updated unless they are explicitly specified using " ; set " part. Thus, be careful with forgetting to reset when needed.
- The state variables are updated when the access request is permitted by the policy. Thus, situations that the access request was not processed although the state variables were updated can happen because of errors after checking the policy (e.g. out of memory).
- If an IP address is included in both @TRUSTED_HOSTS and @UNTRUSTED_HOSTS, the permission which matched first is used. So, be careful with using order dependent policy.

## 6.5 Sleep penalty for policy violation.

You can make the process which violated policy in enforcing mode sleep for specified period.

Example of /proc/ccs/profile | Meaning
3-SLEEP_PERIOD=1 | Make the process which violated policy in enforcing mode and which belongs to a domain with profile 3 sleep for 0.1 second.
4-SLEEP_PERIOD=10 | Make the process which violated policy in enforcing mode and which belongs to a domain with profile 4 sleep for 1 second.

This feature is a safeguard to avoid that the CPU usage remains 100% when policy violation occurs in an infinite loop. Usually, making processes sleep for 0.1 second is enough.

This feature is not applied against network's receive operation so that attackers cannot make services sleep for long time (in other words, delay your system's response) by intentionally sending TCP connection requests and UDP packets from unwanted sources.

## 6.6 Judging execute request outside the kernel.

Basically, TOMOYO Linux controls whether to execute a program or not according to the domain policy. You can check parameters using exec.argv and exec.envp described in Using conditional ACL. But this approach support only simple pattern matching and you need to specify what programs are permitted to be executed beforehand.

Therefore, TOMOYO Linux 1.6.0 introduced a mechanism named execute_handler. If this mechanism is used, the kernel no longer controls whether to execute a requested program or not, and the kernel merely executes the program specified by execute_handler, and the program specified by execute_handler determines whether to execute the requested program or not, and the program specified by execute_handler executes the requested program only if the program specified by execute_handler considers it is appropriate.

In Linux, the behavior "execute a program" means "overwrite the process which requested to execute a program with the requested program's image" and "the process which requested to execute a program cannot regain control if the execute request was succeeded". Therefore, the process which requested to execute a program can receive a notification only when the execute request was failed.
For example, let's consider a situation where a process running as program-A attempts to execute program-B.
When the process running as program-A requests the execution of program-B, the kernel checks the domain policy for "whether it is appropriate to execute program-B from a process running as program-A or not" and the kernel overwrites the process running as program-A with program-B if the kernel considers it is appropriate, and the kernel doesn't overwrite the process running as program-A with program-B and notifies the process running as program-A that execution of program-B is not permitted if the kernel considers it is not appropriate.

When execute_handler is specified, a different program program-C specified as execute_handler mediates this behavior.
When the process running as program-A requests the execution of program-B, the kernel overwrites the process running as program-A with program-C to let the program-C judge whether it is appropriate to execute program-B from a process running as program-A or not. The process now running as program-C determines whether it is appropriate to execute program-B from a process running as program-A or not, and the process now running as program-C requests the execution of program-B (and the kernel will overwrite the process now running as program-C with program-B) if the process now running as program-C considers it is appropriate, and the process now running as program-C terminates without executing program-B if the process now running as program-C considers it is not appropriate.

As stated above, this mechanism has a side effect that it becomes impossible to notify the process running as program-A that the requested program (i.e. program-B) was not executed since program-C abandons a mean to notify the process running as program-A that the execute request of program-B was not accepted.
But, even if execute_handler is not specified, there are various factors that cause "the execute request was accepted but the program terminated before starting the expected behavior" such as "the process was unable to read shared libraries", "the process received KILL signal", "the system became out of memory and the process was killed by OOM killer". In other words, there are uncertainties between "the execute request did not fail" and "the executed program starts the expected behavior".
Viewing in this light, there is no guarantee that "the program starts expected behavior unless the process receives a notification that the execution of the program failed" from the beginning. And, it is possible to say that it is an acceptable result that the program-C specified by execute_handler failed to notify the process previously running as program-A that the execution of program-B failed.

TOMOYO Linux's assumes that the administrator knows what programs needs to be executed from what programs beforehand and permits execution of minimal programs. Thus, assuming that unexpected execute request which are not permitted by policy won't occur as long as the system is running properly, it is OK to accept all execute requests. If an execute request that should not be accepted occurs, you can take different actions such as terminating the process instead of rejecting the request by using denied_execute_handler mechanism. So, you don't have to let the kernel judge whether to execute the program or not alone.

Thus, you can let external userland program judge whether to execute the requested program or not occurred from a domain by specifying execute_handler keyword to the domain.

If you try to judge inside the kernel, there are few library functions available and it is more likely to fail when allocating contiguous memory area. But if you try to judge outside the kernel, there are many library functions available and it is less likely to fail when allocating contiguous memory area, and you can do more detailed checking. So, you can let external userland program specified by execute_handler keyword examine parameters and let the program execute the requested program only if parameters are appropriate.

The side effect of this approach is that there is no mean to notify the process that the execute request was not accepted when it is not appropriate to execute the requested program. But since you can freely customize the program for execute_handler keyword, you can even judge using ssh to ask remotely.

To use this feature, specify like below.

Example of /proc/ccs/domain_policy | Meaning
execute_handler /usr/sbin/check-and-exec | Whenever a process which belongs to this domain requests execution of a program, execute /usr/sbin/check-and-exec instead for the requested program. /usr/sbin/check-and-exec checks parameters and executes the requested program if /usr/sbin/check-and-exec considers it is appropriate to execute.

The program specified by execute_handler keyword receives the following parameters. Compare with allow_execute log described in Access Logs.

- argv[0] contains the pathname of the program specified by execute_handler keyword.
- argv[1] contains the name of the domain which the process which issued an execute request belongs to.
- argv[2] contains the name of the program which the process which issued an execute request.
- argv[3] contains information of the process which the process which issued an execute request.
- argv[4] contains the name of the program which was requested by the process.
- argv[5] contains the number of arguments.
- argv[6] contains the number of environment variables.
- From argv[7] to argv[6 + argc] contains the arguments.
- From argv[7 + argc] to argv [6 + argc + envc] contains the environment variables.
- All environment variables are cleared for safety.
- Other resources such as standard input/output are inherited.

Be careful with the following notes when you use this feature.

- You need not to and should not give execute permission (allow_execute keyword) to the program specified by execute_handler keyword.
- This mechanism can't work if a process cannot access the program specified by execute_handler keyword because the process is running inside a chroot environment. Since it is dangerous to allow execution of programs outside the chroot environment, the program specified by execute_handler keyword is searched from the current process's / directory rather than the current process's namespace's / directory.
- This mechanism can't work if the domain for the program specified for execute_handler keyword doesn't exist. So, you need to prepare domains by (for example) creating a domain for the program specified by execute_handler keyword just under the <kernel> and mark the program specified by execute_handler keyword using initialize_domain keyword.
- The program specified by execute_handler keyword is invoked with all environment variables cleared so that the program won't be affected by some dangerous environment variables (e.g. LD_PRELOAD). This means that even environment variable PATH is not set, so please be careful when executing external programs. Also, I recommend you to assign profile for enforcing mode against the domain for the program specified by execute_handler keyword.

A source code named audit-exec-param.c is included as a sample program of how to use this mechanism in the ccs-tools source package. You can customize freely.

This mechanism is just providing a hook. How to utilize this hook is up to you.

## 6.7 Invoking alternative program for execute requests that are not permitted by policy.

TOMOYO Linux's approach is "know what programs needs to be executed from what programs beforehand and create policy that permits execution of minimal programs". Thus, you can not only reject unnecessary execution requests but also do different behavior.

By default, if an execute request of a program which is not permitted by allow_execute keyword occurs in enforcing mode, the kernel rejects the execute request. But assuming that you know what programs needs to be executed from what programs beforehand, an execute request of a program which is not permitted by allow_execute keyword will not occur as long as the process is keeping control, and you can regard that the process is not keeping control (in other words, the process already lost control) if such request occurs.

Attackers steal control of a process by attacking security holes such as buffer overflow and attempt to execute commands such as shells. If the process does not need to execute the shell (in other words, you needn't to give permission like "allow_execute /bin/bash"), it is considered that the process has already lost control at the moment of the execution request of shells.

Normally, when execution of a program which is not permitted by the policy is requested, the kernel merely reject the request. But it is unlikely that the process gets back control (in other words, the process resumes proper operations) by just rejecting the request if the request is issued by the process that has lost control.
In Linux, "execute a program" means that the current process is overwritten by the requested program and transfer control to the requested program. This means that a process gets back control by overwriting the process with different program even if the process has lost control because of buffer overflow.

The control of a process which has once lost control by the attacker and is overwritten by a program requested by the attacker depends on the program used for overwriting. If a program like shells is executed, the control remains on the attacker's side (in other words, the owner of the process) because shells accept whatever the user requested. But if a program which terminates silently (e.g. /bin/true) is executed, the control will not remains on the attacker's side because the process owned by the attacker will terminate immediately.

As described above, an event that "an execute request of an unnecessary program is issued by an attacker" depending on how you look at it. You can consider that "the attacker is giving the system a chance to get back control on the system's side".
Thus, TOMOYO Linux provides a mechanism that executes different program instead of merely rejecting the request when an execute request of a program which is not permitted by policy occurs. How to utilize this mechanism is up to you.

For example, you can replace the execute request of a program which is not permitted by the policy with /bin/true so that the process which requested the execution of a program which is not permitted by the policy will terminate immediately.

For example, you can replace the execute request of shells with a honey pot client's program and observe what requests the attacker issues.

For example, you can forcibly terminate the login session.

For example, you can show warning message like "You are not permitted to execute this program." which is similar to Ubuntu's command-not-found package (which tells the user in what package the requested command is included).

For example, you can change a firewall's configuration if you succeeded to derive the IP address of the attacker.

To use this feature, specify like below.

Example of /proc/ccs/profile | Example of /proc/ccs/domain_policy | Meaning
3-MAC_FOR_FILE=enforcing | use_profile 3 denied_execute_handler /bin/true | If a process which belongs to a domain with profile 3 requested execution of a program which is not permitted by the domain policy, execute /bin/true instead of rejecting the execute request.

Notes on this feature is the same as Judging execute request outside the kernel.

Return to index