Info: Version 1.7.x is available.

English Page

# TOMOYO Linux ポリシー解説書

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

# 目次

## 1. キーワード一覧

## 2. はじめに

2.1 単語の表記規則

2.2 パターンの表記規則

2.3 単語の長さに関する制約

2.4 1 行の長さに関する制約

2.5 メモリ使用量に関する制約

## 3. ポリシーファイルに関して

3.1 所在について

3.2 変更について

## 4. ドメインに関して

4.1 ドメインとは

4.2 ドメイン遷移とは

4.3 アクセスログについて

## 5. キーワード詳細

## 6. 便利な機能

6.1 root 以外のユーザによるポリシーの変更を許可

6.2 ポリシーに割り当てられるメモリ量を制限

6.3 条件付きアクセス許可の指定

6.4 ステートフルなアクセス許可の指定

6.5 ポリシー違反時のペナルティ指定

6.6 プログラムの実行可否をカーネルの外部で判断

6.7 許可されていないプログラムの実行が要求された場合の代替処理指定

# 1. キーワード一覧

/proc/ccs/profile および /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

/proc/ccs/system_policy および /etc/ccs/system_policy.conf で使われるもの

- allow_mount
- deny_unmount
- allow_chroot
- allow_pivot_root
- deny_autobind

/proc/ccs/exception_policy および /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

/proc/ccs/domain_policy および /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

/proc/ccs/manager および /etc/ccs/manager.conf で使われるもの

- manage_by_non_root

# 2. はじめに

## 2.1 単語の表記規則

TOMOYO Linux はパス名を用いたアクセス制御を行います。パス名には英数字だけでなく空白や改行などの文字、漢字のような複数バイトで構成される文字などが含まれる可能性があります。そのため、いかなる文字でも正しく処理できるようにするために、 TOMOYO Linux に於いては以下の規則に従って単語を表記します。単語とは、パス名だけでなくコメントや環境変数の名前やプログラム実行時のパラメータなど、文字列として扱う全ての情報を指します。

- NUL 文字（ 0x00 ）は文字列の終端を示すための文字であり、 \000 という表記はできません。
- \ 文字（ 0x5C ）は 8 進数表記であることを示すために使用されるため、 \\ のように 2 個続けます。
- 0x01 ～ 0x20 および 0x7F ～ 0xFF は \ooo という形式の 8 進数で表記します。
- 残りの 0x21 ～ 0x5B および 0x5D ～ 0x7E はそのままの文字で表記します。

| 下位 4 ビット
上位 4 ビット |
| 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

- 単語と単語を区切るデリミタとして空白文字（ 0x20 ）を、行と行を区切るデリミタとして改行文字（ 0x0A ）を使用します。
- 上記の規則に従って表記された単語と、デリミタとして使われる空白文字および改行文字のみが有効です。それ以外の文字は空白文字とみなされます。連続する空白文字は自動的に 1 個の空白文字に圧縮されます。行頭及び行末の空白文字は自動的に削除されます。

以下に表記例を示します。

単語 | 正しい表記 | 誤った表記
Hello world! | Hello\040world! | "Hello world!"
/home/user/Documents and Settings/ | /home/user/Documents\040and\040Settings/ | /home/user/Documents and Settings/
コメント (UTF-8 の場合) | \343\202\263\343\203\241\343\203\263\343\203\210\040(UTF-8\040\343\201\256\345\240\264\345\220\210) | コメント\040(UTF-8\040の場合)

パス名は必ず / から始まります。パス名が / で終わる場合はディレクトリ、 / 以外で終わる場合にはディレクトリ以外であると解釈されます。

パス名 | 解釈
/ | ディレクトリ
/tmp/ | ディレクトリ
/tmp | ディレクトリ以外
tmp/ | 無効なパス名

ただし、例外として、 /proc/プロセスＩＤ/fd/ ディレクトリに表示されるパイプのパス名は pipe: で、ソケットのパス名は socket: で始まります。

## 2.2 パターンの表記規則

パス名にはテンポラリファイルのように、毎回異なる文字が使われる場合があります。そのため、ワイルドカードを用いたパターン化を行うことが必要になります。 TOMOYO Linux に於いては以下のワイルドカードをサポートしています。

ワイルドカード | 意味 | 使用例
\* | / 以外の 0 文字以上 | /var/log/samba/\*
\@ | / と . 以外の 0 文字以上 | /var/www/html/\@.html
\? | / 以外の 1 文字 | /tmp/mail.\?\?\?\?\?\?
\$ | 1 桁以上の 10 進数 | /proc/\$/cmdline
\+ | 10 進数 1 桁 | /var/tmp/my_work.\+
\X | 1 桁以上の 16 進数 | /var/tmp/my-work.\X
\x | 16 進数 1 桁 | /tmp/my-work.\x
\A | 1 文字以上のアルファベット | /var/log/my-work/\$-\A-\$.log
\a | アルファベット 1 文字 | /home/users/\a/\*/public_html/\*.html
\- | パス名を除外する演算子 |
使用例 | 意味
/etc/\* | /etc/ 直下の全ファイル
/etc/\*\-\*shadow\* | /etc/\*shadow\* 以外の /etc/\*
/\*\-proc\-sys/ | /proc/ と /sys/ 以外の /\*/

## 2.3 単語の長さに関する制約

Linux に於いてはパス名の長さに関する上限は存在しませんが、パス名を用いたアクセス制御を行うために無限の長さをサポートすることはできません。そのため、 TOMOYO Linux に於いては、単語の長さは終端の NUL 文字を含めて 4000 バイトまでに制限されています。

## 2.4 1 行の長さに関する制約

TOMOYO Linux に於いては、 1 行の長さは終端の NUL 文字を含めて 8192 バイトまでに制限されています。

## 2.5 メモリ使用量に関する制約

TOMOYO Linux に於いては、アクセス許可や単語を記憶するために一度割り当てられたメモリは解放されません。システムを再起動する以外に、不要になったメモリを解放する手段は存在しません。

ただし、運用開始後にはアクセス許可の変更は生じにくいという傾向があること、および、運用開始前に適切にチューニングすることによりメモリ消費量を通常は 1 メガバイト以内に抑えられることから、心配する必要はありません。

TOMOYO Linux が現在使用中のメモリ消費量は、 /proc/ccs/meminfo から確認できます。単位はバイトです。 Shared: が単語を記憶するために使用されている量、 Private: がアクセス許可を記憶するために使用されている量で、減少することはありません。 Dynamic: がアクセス許可のチェックやアクセスログの保持などのために一時的に使用されている量で、不要になると減少します。

    # cat /proc/ccs/meminfo

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

# 3. ポリシーファイルに関して

## 3.1 所在について

ポリシーファイルとは、アクセスの可否を定義したファイルです。システムの起動時に自動的にカーネルへと読み込まれます。

システムの起動時には、 /sbin/init というプログラムが実行されます。 /sbin/init の実行が要求されたときに、 /sbin/ccs-init というプログラムが存在していた場合、 /sbin/ccs-init が実行され、 /sbin/ccs-init の処理が終了してから /sbin/init の実行が開始されます。

/sbin/ccs-init は /etc/ccs/ ディレクトリにあるポリシーファイルを /proc/ccs/ ディレクトリを通じてカーネルへと読み込みます。

カーネルとのインタフェース | ポリシーファイル | 定義されている内容
/proc/ccs/profile | /etc/ccs/profile.conf | プロファイル（制御レベルを定義したもの）
/proc/ccs/manager | /etc/ccs/manager.conf | マネージャ（ポリシーの変更ができるプログラムを定義したもの）
/proc/ccs/system_policy | /etc/ccs/system_policy.conf | システムポリシー（システム全体で適用される設定）
/proc/ccs/exception_policy | /etc/ccs/exception_policy.conf | 例外ポリシー（ドメインポリシーの例外を定義したもの）
/proc/ccs/domain_policy | /etc/ccs/domain_policy.conf | ドメインポリシー（ドメイン単位で適用される設定）

そのほかの情報を取得するためのインタフェースもあります。対応するポリシーファイルはありません。

カーネルとのインタフェース | 内容
/proc/ccs/query | 管理者の指示待ちとなっているアクセス要求
/proc/ccs/.domain_status | 定義されているドメイン名とプロファイル番号
/proc/ccs/meminfo | メモリ使用状況
/proc/ccs/grant_log | ポリシーに違反しなかったアクセス要求のログ
/proc/ccs/reject_log | ポリシーに違反したアクセス要求のログ
/proc/ccs/self_domain | 自分が属しているドメインのドメイン名
/proc/ccs/.process_status | プロセスが属しているドメイン名とプロファイル番号
/proc/ccs/.updates_counter | ポリシーの変更カウンタ
/proc/ccs/version | TOMOYO Linux のバージョン

## 3.2 変更について

カーネルとのインタフェースである /proc/ccs/ ディレクトリを経由してポリシーを変更することができるプログラム名を /proc/ccs/manager に登録します。プログラム名ではなくドメイン名で登録することもできます。

- /proc/ccs/manager に登録されているプログラム名を持つプロセス
- /proc/ccs/manager に登録されているドメイン名を持つプロセス

だけがカーネルとのインタフェースである /proc/ccs/ ディレクトリを経由してポリシーを変更できます。以下に例を示します。

# 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

デフォルトではユーザＩＤと実効ユーザＩＤの両方が 0 であるプロセスだけがポリシーを変更できますが、 root 以外のユーザによるポリシーの変更を許可の設定を行えば、非 root ユーザによるポリシーの変更も可能です。

なお、学習モード用のプロファイルが割り当てられているプロセスは、アクセスを要求するだけで /proc/ccs/system_policy または /proc/ccs/domain_policy へと自動的にアクセス許可が追加されていきます。

# 4. ドメインに関して

## 4.1 ドメインとは

TOMOYO Linux には、システム全体でアクセス許可を定義するものと、ドメイン単位でアクセス許可を定義するものの 2 種類があります。前者はシステムポリシーと呼ばれ、 /proc/ccs/system_policy を通じてアクセス許可を指定します。後者はドメインポリシーと呼ばれ、 /proc/ccs/domain_policy を通じてアクセス許可を定義します。

TOMOYO Linux においては、全てのプロセスがそれぞれ 1 つのドメインに属し、全てのプログラムがそれぞれ異なるドメインに属します。現在実行されている 2 つのプロセスが同一のプログラムであっても、それぞれのプロセスの直前のドメインが異なっていれば異なるドメインに属します。

全てのドメインはカーネルが属するドメイン「 <kernel> 」を基点として定義されます。 /sbin/init はカーネルの属するドメインから起動されますので、 /sbin/init のドメインは「 <kernel> /sbin/init 」と定義されます。 /etc/rc.d/rc はカーネルから起動された /sbin/init の属するドメインから起動されますので、 /etc/rc.d/rc のドメインは「 <kernel> /sbin/init /etc/rc.d/rc 」と定義されます。

## 4.2 ドメイン遷移とは

実行時のプログラムの名前により異なる動作をするプログラムが存在します。例えば /sbin/pidof は /sbin/killall5 へのシンボリックリンクです。 TOMOYO Linux は正規化したパス名を使用するので、 /sbin/pidof を実行すると /sbin/killall5 が実行されたものとしてドメインが定義されます。

プロセスがプログラムを実行しようとすると、以下の処理が行われます。

Step | 内容
プログラム名の取得 | 実行しようとするプログラムの絶対パス名を取得して「パス名候補 1 」とします。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決したパス名を取得します。 実行しようとするプログラムの絶対パス名を取得して「パス名候補 2 」とします。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決する前のパス名を取得します。
シンボリックリンクの識別 | 「パス名候補 1 」と「パス名候補 2 」が一致しない場合、例外ポリシーから alias 「パス名候補 1 」 「パス名候補 2 」 というエントリを探します。見つかった場合は「パス名候補 2 」を「パス名候補 1 」とします。
argv[0] のチェック | 「パス名候補 1 」の最後の / 以降の部分と argv[0] の最後の / 以降の部分が異なっている場合、ドメインポリシーから allow_argv0 「パス名候補 1 」 「 argv[0] の最後の / 以降の部分」 というエントリを探します。見つからなければプログラムの実行要求は拒否されます。
類似するプログラムの集約 | 例外ポリシーから aggregator 「パス名候補 1 」 「集約されたパス名」 というエントリを探します。見つかった場合は、「集約されたパス名」を「パス名候補 1 」とします。
権限のチェック | ドメインポリシーから allow_execute 「パス名候補 1 」 allow_execute @「パス名候補 1 」を含むグループ名 というエントリを探します。見つからなければプログラムの実行要求は拒否されます。
遷移先の決定 | (1) 例外ポリシーから no_initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 no_initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_initialize_domain 「パス名候補 1 」 というエントリを探します。見つかった場合は (3) へ進みます。 (2) 例外ポリシーから initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 initialize_domain 「パス名候補 1 」 というエントリを探します。見つかった場合は「カーネルが属しているドメインのドメイン名（ <kernel> ）」と「パス名候補 1 」とを連結して「遷移先ドメイン」として (6) へ進みます。 (3) 例外ポリシーから no_keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探します。見つかった場合は (5) へ進みます。 (4) 例外ポリシーから keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 keep_domain 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探します。見つかった場合は「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とし、 (6) へ進みます。 (5) 「現在のプロセスが属しているドメインのドメイン名」と「パス名候補 1 」とを連結して「遷移先ドメイン」とし、 (6) へ進みます。 (6) ドメインポリシーから「遷移先ドメイン」を探します。見つからなければプログラムの実行要求は拒否されます。
環境変数のチェック | (1) 全ての環境変数名が「遷移先ドメイン」で許可されているかどうかを検査します。 1 つでも許可されていないものが見つかった場合は、プログラムの実行要求は拒否されます。 (2) 通常のプログラム実行処理を行い、正常に終了した場合は「遷移先ドメイン」に遷移します。

ただし、例外として

- 上記手順の「 argv[0] のチェック」「権限のチェック」「遷移先の決定」の何れかに於いて拒否されたが、プログラムの実行を要求したプロセスの属しているドメインに denied_execute_handler キーワードが指定されている
- プログラムの実行を要求したプロセスの属しているドメインに execute_handler キーワードが指定されている

のどちらかに該当し、かつ、

- プログラムの実行を要求したプロセスが execute_handler キーワードまたは denied_execute_handler キーワードにより起動されたプロセスではない

場合には、以下の手順を実行します。この例外の使い方については「プログラムの実行可否をカーネルの外部で判断」と「許可されていないプログラムの実行が要求された場合の代替処理指定」で説明します。

Step | 内容
プログラム名の取得 | denied_execute_handler または execute_handler で指定されているプログラムのパス名を取得し、「パス名候補 1 」とします。
情報の追加 | 全ての環境変数を引数の末尾に追加し、全ての環境変数を削除します。 「パス名候補 1 」「プログラムの実行を要求したプロセスの属しているドメインのドメイン名」「プログラムの実行を要求したプロセスのパス名」「プログラムの実行を要求したプロセスの状態」「実行が要求されたプログラムのパス名」「引数の数」「環境変数の数」を引数の先頭に挿入します。
遷移先の決定 | (1) 例外ポリシーから no_initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 no_initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_initialize_domain 「パス名候補 1 」 というエントリを探します。見つかった場合は (3) へ進みます。 (2) 例外ポリシーから initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 initialize_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 initialize_domain 「パス名候補 1 」 というエントリを探します。見つかった場合は「カーネルが属しているドメインのドメイン名（ <kernel> ）」と「パス名候補 1 」とを連結して「遷移先ドメイン」として (6) へ進みます。 (3) 例外ポリシーから no_keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」 no_keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探します。見つかった場合は (5) へ進みます。 (4) 例外ポリシーから keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「パス名候補 1 」 from 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 keep_domain 「現在のプロセスが属しているドメインのドメイン名」 keep_domain 「現在のプロセスが属しているドメインのドメイン名」の最後の要素 というエントリを探します。見つかった場合は「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とし、 (6) へ進みます。 (5) 「現在のプロセスが属しているドメインのドメイン名」と「パス名候補 1 」とを連結して「遷移先ドメイン」とし、 (6) へ進みます。 (6) ドメインポリシーから「遷移先ドメイン」を探します。見つからなければプログラムの実行要求は拒否されます。
プログラムの実行 | 通常のプログラム実行処理を行い、正常に終了した場合は「遷移先ドメイン」に遷移します。

## 4.3 アクセスログについて

ドメインポリシーによって許可されたアクセス要求のログと拒否されたアクセス要求のログを生成します。前者は許可ログと呼ばれ、 /proc/ccs/grant_log から取得することができます。後者は拒否ログと呼ばれ、 /proc/ccs/reject_log から取得することができます。これらのログを取得してファイルとして保存するためのツールとして /usr/sbin/ccs-auditd というプログラムが付属しています。

以下に例を示します。最初の例はプログラムを実行しようとしたときのログです。

#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

このログは、 <kernel> /usr/sbin/sshd /bin/bash というドメインに属しているプロセスが /bin/cat というプログラムを実行しようとし、そのときの引数の内容は "cat" "/etc/fstab" 、環境変数の内容は "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" であったということを示しています。また、プロセスＩＤやユーザＩＤなど、プロセスに関する情報も一緒に出力されます。

次の例は、ファイルを読み込みモードでオープンしようとしたときのログです。

#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

このログは、 <kernel> /usr/sbin/sshd /bin/bash /bin/cat というドメインに属しているプロセスが /etc/fstab というファイルをオープンしようとしたことを示しています。

次の例は、ドメインが新規作成されたときのログです。

#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

このログは、 <kernel> /usr/sbin/sshd /bin/bash /bin/bash /bin/audit-exec-param /bin/cat というドメインが新規作成され、プロファイルとして 1 が割り当てられたことを示しています。 TOMOYO Linux では、ドメインが自動的に新規作成されていきます。自動的に新規作成された場合には、ドメインを新規作成することになったプロセスの属しているドメインに割り当てられていたプロファイル番号が引き継がれます。

次の例は、プログラムの実行可否をカーネルの外部で判断するために要求されたのとは異なるプログラムが実行されたときのログです。

#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

このログは、 <kernel> /usr/sbin/sshd /bin/bash /bin/bash というドメインに属しているプロセスがプログラムを実行しようとしたが、 execute_handler が指定されていたので代わりに /bin/audit-exec-param というプログラムが実行されたこと、 /bin/audit-exec-param に渡された引数の内容は "/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" であったということを示しています。 LD_PRELOAD などの環境変数によって /bin/audit-exec-param の動作が左右されるのを防ぐため、環境変数を引数に移動しています。

このように、アクセスログは 3 行で 1 件（ /usr/sbin/ccs-auditd によってファイルに保存されるときに空行が入るので 4 行で 1 件）となっており、これらのログはそのままドメインポリシーとして追加可能な形式になっています。アクセス拒否ログから許可したい部分を抽出して、例えば /var/log/tomoyo/diff.txt という名前で保存した後、

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

という操作を行うことで、ドメインポリシーに追加することができます。そのため、「学習モード」を使わなくても、最初から「確認モード」を使って拒否ログを出力させ、拒否ログの内容を編集するというアプローチでもドメインポリシーを定義していくことができます。「学習モード」でドメインポリシーを作成する場合にはプロセスの状態（アクセスログの先頭行の内容）は加味されませんが、アクセス拒否ログからドメインポリシーを生成すると、最初から条件付きアクセス許可の指定を行うことができます。例えば、「学習モード」を使わずにログを生成し、

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

としてドメインポリシーを追加した場合、「学習モード」で追加される

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

よりも細かい指定を行うことができるようになります。

# 5. キーワード詳細

## /proc/ccs/profile

TOMOYO Linux では、ファイル以外にもいくつかの項目について強制アクセス制御を行うことができますが、ポリシー管理の負担を減らすために、必要の無い機能を無効化できるようになっています。

有効にしたい機能とそのモードを「 プロファイル番号-項目=値 」という形式で定義します。プロファイル番号は 0 ～ 255 が指定可能です。プロファイルの内容を変更するには ccs-setlevel コマンドまたは ccs-loadpolicy コマンドを使用します。

各ドメインには 1 個のプロファイルが割り当てられます。ドメインにプロファイルを割り当てるには ccs-setprofile コマンドまたは ccs-editpolicy コマンドまたは ccs-loadpolicy コマンドを使用します。

現在ドメインに割り当てられているプロファイル番号は ccs-editpolicy コマンドで確認できます。
現在動作中のプロセスに割り当てられているプロファイル番号は ccs-ccstree コマンドで確認できます。
現在のポリシーを ccs-savepolicy コマンドで保存した場合、 use_profile というキーワードに保持されます。

現在のプロファイルを読み出しまたは追加するには以下のように操作します。

（例）
cat /proc/ccs/profile
ccs-savepolicy -p
ccs-setlevel 1-MAC_FOR_FILE=learning
echo 1-MAC_FOR_FILE=learning | ccs-loadpolicy -p

関連項目：変更について

### MAC_FOR_FILE

ファイルに対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_IOCTL

ファイルに対する強制アクセス制御のレベルを指定します。 TOMOYO 1.6.7 以降で利用可能です。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_ARGV0

プログラム実行時の argv[0] に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_ENV

プログラム実行時の環境変数名に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::inet_tcp_create

TCP ソケットの使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::inet_tcp_listen

TCP ソケットの listen に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::inet_tcp_connect

TCP ソケットの connect に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::use_inet_udp

UDP ソケットの使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::use_inet_ip

RAW ソケットの使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::use_route

ROUTE ソケットの使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::use_packet

PACKET ソケットの使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::use_kernel_module

create_module(2) init_module(2) delete_module(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::create_fifo

mknod(2) で FIFO の作成に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::create_block_dev

mknod(2) でブロック型デバイスの作成に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::create_char_dev

mknod(2) でキャラクタ型デバイスの作成に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::create_unix_socket

mknod(2) で UNIX ドメインソケットの作成に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_MOUNT

mount(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_UMOUNT

umount(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_REBOOT

reboot(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_CHROOT

chroot(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_KILL

0 以外のシグナルで kill(2) tkill(2) tgkill(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_VHANGUP

vhangup(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_TIME

stime(2) settimeofday(2) adjtimex(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_NICE

nice(2) setpriority(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_SETHOSTNAME

sethostname(2) setdomainname(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_LINK

link(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_SYMLINK

symlink(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_RENAME

rename(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_UNLINK

unlink(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_CHMOD

chmod(2) fchmod(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_CHOWN

chown(2) fchown(2) lchown(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_IOCTL

ioctl(2) compat_sys_ioctl(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_KEXEC_LOAD

kexec_load(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_PIVOT_ROOT

pivot_root(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_CAPABILITY::SYS_PTRACE

ptrace(2) の使用に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_NETWORK

ネットワークに対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### MAC_FOR_SIGNAL

シグナルの送信に対する強制アクセス制御のレベルを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### DENY_CONCEAL_MOUNT

既存のマウントを隠蔽するようなマウントを禁止します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
permissive | 確認モード。既存のマウントを隠蔽するようなマウント要求に対して警告メッセージを表示しますが、拒否はしません。
enforcing | 強制モード。既存のマウントを隠蔽するようなマウント要求に対してエラーメッセージを表示し、拒否します。

### RESTRICT_CHROOT

chroot で移動可能なディレクトリの制限を有効にします。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### RESTRICT_MOUNT

mount で指定可能なパラメータの制限を有効にします。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### RESTRICT_UNMOUNT

指定されたディレクトリのアンマウントを禁止します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
permissive | 確認モード。指定されたディレクトリのアンマウント要求に対して警告メッセージを表示しますが、拒否はしません。
enforcing | 強制モード。指定されたディレクトリのアンマウント要求に対してエラーメッセージを表示し、拒否します。

### RESTRICT_PIVOT_ROOT

pivot_root で交換可能なディレクトリの制限を有効にします。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
learning | 学習モード。ポリシーに違反してもアクセス要求を拒否することはせず、再度同じアクセス要求が発生した場合にポリシー違反とならないようにするために、ポリシーへの自動追加を行います。
permissive | 確認モード。ポリシーに違反してもアクセス要求を拒否することはしませんが、ポリシーへの自動追加も行いません。
enforcing | 強制モード。ポリシーに違反するアクセス要求を拒否します。

### RESTRICT_AUTOBIND

ローカルのポート番号を自動選択させる際に特定のポート番号を選択させないようにするかどうかを指定します。

値 | 内容
disabled | 無効。通常のカーネルと同様に動作します。
enabled | 有効。ローカルのポート番号を自動選択させる際に、特定のポート番号を選択させないようにします。

### MAX_ACCEPT_ENTRY

学習モードに於いて自動的に追加されるアクセス許可の上限を指定します。デフォルトは 2048 件です。

### MAX_GRANT_LOG

カーネル内に保持する、ポリシーによって許可されたアクセス要求のログの件数を指定します。デフォルトは 1024 件です。

### MAX_REJECT_LOG

カーネル内に保持する、ポリシーによって許可されなかったアクセス要求のログの件数を指定します。デフォルトは 1024 件です。

### TOMOYO_VERBOSE

ドメインポリシーに対する違反を表示するかどうかを指定します。

値 | 内容
disabled | ドメインポリシーに対する違反を表示しません。
enabled | ドメインポリシーに対する違反を表示します。

### ALLOW_ENFORCE_GRACE

強制モードに於いてポリシーに違反したアクセス要求を対話的に許可できるようにするかどうかを指定します。この項目は TOMOYO Linux 1.6.2 で廃止されました。

値 | 内容
disabled | 強制モードでポリシーに違反したら直ちに拒否します。
enabled | 強制モードでポリシーに違反しても、対話的な操作により許可することを可能にします。

### SLEEP_PERIOD

強制モードに於いてポリシー違反が発生した場合にスリープさせるかどうかを指定します。

値 | 内容
0 ～ 3000 | スリープさせる時間を 0.1 秒単位で指定します。デフォルトは 0 秒です。

## /proc/ccs/system_policy

このファイルでは、システム全体として与えるアクセス許可を定義します。

現在のシステムポリシーを読み出しまたは追加または削除するには以下のように操作します。

（例）
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

関連項目：変更について

### allow_mount

マウント許可を指定するには、 allow_mount というキーワードに続けて、「デバイスファイル マウントポイント ファイルシステム オプション」を指定します。 デバイスファイルを必要とするファイルシステムを指定する場合は、デバイスファイルは正規化されたファイル名でなければいけません。マウントポイントは正規化されたファイル名でなければいけません。オプションは 16 進数の数値で指定します。

「 any マウントポイント --remount オプション」と指定すると、「 mount -o remount マウントポイント」が許可されます。

「複製元 複製先 --bind オプション」と指定すると、「 mount --bind 複製元 複製先」が許可されます。
「移動元 移動先 --move オプション」と指定すると、「 mount --move 移動元 移動先」が許可されます。
複製元／複製先／移動元／移動先は正規化されたディレクトリ名でなければなりません。

カーネル 2.6.15 以降では、 Shared Subtree という機能が利用できます。
「 any マウントポイント --make-unbindable オプション」と指定すると、「 mount --make-unbindable マウントポイント」が許可されます。
「 any マウントポイント --make-private オプション」と指定すると、「 mount --make-private マウントポイント」が許可されます。
「 any マウントポイント --make-slave オプション」と指定すると、「 mount --make-slave マウントポイント」が許可されます。
「 any マウントポイント --make-shared オプション」と指定すると、「 mount --make-shared マウントポイント」が許可されます。

（例）
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

アンマウント禁止を指定するには、 deny_unmount というキーワードに続けて、アンマウントを許可しない正規化されたディレクトリ名を指定します。
通常、 /sbin/mingetty が使用する /dev/tty? を含む /dev/ ディレクトリと、リモートログインする場合に pty デバイスファイルが作成される /dev/pts/ ディレクトリを指定します。

/dev が読み込み専用になってしまったり、 /dev/pts がアンマウントされてしまうと、ログインができなくなってしまいます。そのため、 / が読み込み専用のシステムでは、 /dev/ や /dev/pts/ がアンマウントされないようにしなければなりません。

（例）
deny_unmount /dev/
deny_unmount /dev/pts/
deny_unmount /proc/

### allow_chroot

chroot 許可を指定するには、 allow_chroot というキーワードに続けて、 chroot で移動することを許可したい正規化されたディレクトリ名を指定します。
通常、 sshd が使用する /var/empty/sshd/ を指定します。 その他に chroot 環境で動かしたいアプリケーションや、 chroot を行うアプリケーション（ vsftpd の場合 /usr/share/empty/ ）が存在する場合は、それらも指定します。

（例）
allow_chroot /var/empty/sshd/
allow_chroot /usr/share/empty/
allow_chroot /var/www/html/
allow_chroot /

### allow_pivot_root

pivot_root 許可を指定するには、 allow_pivot_root というキーワードに続けて、新しいルートとなる正規化されたディレクトリ名と古いルートディレクトリとなる正規化されたディレクトリ名を指定します。
通常、このキーワードを使う必要はありません。

### deny_autobind

ローカルポートの自動選択で特定のポート番号が選択させるのを禁止するには、 deny_autobind というキーワードに続けて、ローカルポート番号を指定します。 このキーワードは、特定のポート番号が一時的な用途で割り当てられるのを防ぐのが狙いです。例えば、一部のプロキシサーバはポート 8080 を使用するので、ポート 8080 が一時的な用途のために割り当てられるべきではありません。

（例）
deny_autobind 1-1023
deny_autobind 8080

## /proc/ccs/domain_policy

このファイルでは、全てのドメインを定義し、各ドメインに対して与えるアクセス許可を定義します。

ドメインを定義している行（ <kernel> で始まる行）の次行から次のドメインを定義している行の前行までが、そのドメインに対するアクセス許可です。

それぞれのアクセス許可について、必要に応じて追加の条件を指定することができます。そのための構文は条件付きアクセス許可の指定で説明します。さらに、必要に応じてプロセスの状態を切り替え、プロセスの状態も条件として使うための方法をステートフルなアクセス許可の指定で説明します。

現在のドメインポリシーを読み出しまたは追加または削除するには、以下のように操作します。

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成されます）
printf "<kernel> /sbin/init\nallow_read /etc/passwd\n" | ccs-loadpolicy -d

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成されません）
printf "select <kernel> /sbin/init\nallow_read /etc/passwd\n" | ccs-loadpolicy -d

（例）ドメインを選択してアクセス許可を削除
printf "select <kernel> /sbin/init\ndelete allow_read /etc/passwd\ndelete allow_read /etc/shadow\n" | ccs-loadpolicy -d

（例）特定のドメインを削除
printf "delete <kernel> /sbin/init\n" | ccs-loadpolicy -d

（例）ドメインポリシーの読み出し
cat /proc/ccs/domain_policy

関連項目：変更について

### allow_execute

指定されたパス名を実行することを許可します。パス名にワイルドカードを使用することは認められていません。ワイルドカードで指定しなければ対応できない場合には、プログラム名をグループ化してからアクセス許可を与えてください。

（例） allow_execute /bin/ls

関連項目：ドメイン遷移 aggregator

### allow_write

指定されたパス名を書き込みモードでオープンすることを許可します。

（例） allow_write /dev/null

関連項目： path_group

### allow_read

指定されたパス名を読み込みモードでオープンすることを許可します。

（例） allow_read /proc/meminfo

関連項目： path_group

### allow_read/write

指定されたパス名を読み書きモードでオープンすることを許可します。

（例） allow_read/write /dev/null

関連項目： path_group

### allow_create

指定されたパス名のファイルを新規作成することを許可します。

（例） allow_create /var/lock/subsys/crond

関連項目： path_group

### allow_unlink

指定されたパス名を削除することを許可します。

（例） allow_unlink /var/lock/subsys/crond

関連項目： path_group

### allow_mkdir

パス名で指定されたディレクトリを作成することを許可します。

（例） allow_mkdir /tmp/logwatch.\*/

関連項目： path_group

### allow_rmdir

ディレクトリの削除を許可します。

（例） allow_rmdir /tmp/logwatch.\*/

関連項目： path_group

### allow_mkfifo

FIFO の作成を許可します。

（例） allow_mkfifo /dev/initctl

関連項目： path_group

### allow_mksock

UNIX ドメインソケットの作成を許可します。

（例） allow_mksock /dev/log

関連項目： path_group

### allow_mkblock

ブロック型デバイスファイルの作成を許可します。

（例） allow_mkblock /dev/\*

関連項目： path_group

### allow_mkchar

キャラクタ型デバイスファイルの作成を許可します。

（例） allow_mkchar /dev/\*

関連項目： path_group

### allow_truncate

ファイルの切り詰めと伸長を許可します。

（例） allow_truncate /etc/mtab

関連項目： path_group

### allow_symlink

シンボリックリンクの作成を許可します。

（例） allow_symlink /dev/cdrom

関連項目： path_group

### allow_link

ハードリンクの作成を許可します。

（例） allow_link /etc/mtab~\$ /etc/mtab~

関連項目： path_group

### allow_rename

ファイル名の変更を許可します。

（例） allow_rename /etc/mtab.tmp /etc/mtab

関連項目： path_group

### allow_rewrite

deny_rewrite によりファイルの内容の上書きが禁止されているパス名が指すファイル内容の上書きを許可します。

（例） allow_rewrite /var/log/messages

関連項目： path_group deny_rewrite

### allow_ioctl

IOCTL 要求で指定可能なコマンド番号を指定するには、 allow_ioctl というキーワードに続けて、パス名とコマンド番号を指定します。パス名にはパターンおよびパス名のグループも使用できます。

指定例 | 許可されるアクセス
allow_ioctl socket:[family=2:type=2:protocol=17] 35093 | アドレスファミリーが 2 、種別が 2 、プロトコルが 17 のソケットに対して 35093 番の IOCTL 要求を許可
allow_ioctl /dev/null 10000-20000 | /dev/null に対して 10000 ～ 20000 番の IOCTL 要求を許可

IOCTL 要求のコマンド番号の意味については、 IOCTL 機能を提供しているモジュールの説明を参照してください。例えば、 i386 環境において 21585 番の IOCTL 要求は close-on-exec フラグをセットするための FIOCLEX コマンドを指します。例えば、ソケットに対する 35088 番の IOCTL 要求は、ネットワークインターフェースの名前を取得する SIOCGIFNAME コマンドを指します。

関連項目： 条件付きアクセス許可の指定

### allow_argv0

argv[0] の組み合わせを制限するには、 allow_argv0 というキーワードに続けて、絶対パス名と「 argv[0] の最後の / より後ろの部分」を指定します。

プログラムを実行する関数である execve() には filename と argv[] と envp[] を渡すことができます。いくつかのプログラム（例えば busybox ）は argv[0] の内容によって振る舞いを変化させます。 プログラムへのシンボリックリンクを経由してプログラムを実行する場合、 TOMOYO Linux のドメイン遷移は filename が指すパス名を正規化した内容に基づいて行われるのに対し、振る舞いは argv[0] （通常は filename が指すパス名と同じ内容）に基づいて行われてしまいます。例えば、 /bin/ls と /bin/cat が busybox へのハードリンクとして提供されている環境において、 /tmp/cat という /bin/ls へのシンボリックリンクを作成して /tmp/cat を実行することにより、 /bin/ls のためのドメインで cat として振舞うことができてしまうという抜け穴になります。

このキーワードの目的は、 filename と argv[0] の内容の組み合わせを制限することでそのような抜け穴を塞ぐことです。

### allow_env

環境変数名を制限するには、 allow_env というキーワードに続けて、「環境変数名」を指定します。

プログラムを実行する関数である execve() には filename と argv[] と envp[] を渡すことができます。多くのプログラムは envp[] の内容によって振る舞いを変化させます。

このキーワードの目的は、実行されるプログラムに渡される環境変数を制限することです。

関連項目： allow_env

### allow_capability

ケイパビリティのアクセス許可を指定するには、 allow_capability というキーワードに続けて、ケイパビリティを指定します。以下のケイパビリティが指定できます。

allow_capability inet_tcp_create | TCP ソケットの使用を許可
allow_capability inet_tcp_listen | TCP ソケットの listen を許可
allow_capability inet_tcp_connect | TCP ソケットの connect を許可
allow_capability use_inet_udp | UDP ソケットの使用を許可
allow_capability use_inet_ip | RAW ソケットの使用を許可
allow_capability use_route | ROUTE ソケットの使用を許可
allow_capability use_packet | PACKET ソケットの使用を許可
allow_capability use_kernel_module | create_module(2) init_module(2) delete_module(2) の使用を許可
allow_capability create_fifo | mknod(2) で FIFO の作成を許可
allow_capability create_block_dev | mknod(2) でブロック型デバイスの作成を許可
allow_capability create_char_dev | mknod(2) でキャラクタ型デバイスの作成を許可
allow_capability create_unix_socket | mknod(2) で UNIX ドメインソケットの作成を許可
allow_capability SYS_MOUNT | mount(2) の使用を許可
allow_capability SYS_UMOUNT | umount(2) の使用を許可
allow_capability SYS_REBOOT | reboot(2) の使用を許可
allow_capability SYS_CHROOT | chroot(2) の使用を許可
allow_capability SYS_KILL | 0 以外のシグナルで kill(2) tkill(2) tgkill(2) の使用を許可
allow_capability SYS_VHANGUP | vhangup(2) の使用を許可
allow_capability SYS_TIME | stime(2) settimeofday(2) adjtimex(2) の使用を許可
allow_capability SYS_NICE | nice(2) setpriority(2) の使用を許可
allow_capability SYS_SETHOSTNAME | sethostname(2) setdomainname(2) の使用を許可
allow_capability SYS_LINK | link(2) の使用を許可
allow_capability SYS_SYMLINK | symlink(2) の使用を許可
allow_capability SYS_RENAME | rename(2) の使用を許可
allow_capability SYS_UNLINK | unlink(2) の使用を許可
allow_capability SYS_CHMOD | chmod(2) fchmod(2) の使用を許可
allow_capability SYS_CHOWN | chown(2) fchown(2) lchown(2) の使用を許可
allow_capability SYS_IOCTL | ioctl(2) compat_sys_ioctl(2) の使用を許可
allow_capability SYS_KEXEC_LOAD | kexec_load(2) の使用を許可
allow_capability SYS_PIVOT_ROOT | pivot_root(2) の使用を許可
allow_capability SYS_PTRACE | ptrace(2) の使用を許可

allow_capability キーワードの目的は、プログラムが呼び出すことができるシステムコールを制限することです。幾つかのシステムコールに対しては他のキーワードやポリシーファイルを使用してより詳細な制限が可能になっています。

- 作成を許可するキャラクタ型デバイスファイルのパス名を allow_mkblock キーワードを使用して制限することができます。
- 作成を許可するブロック型デバイスファイルのパス名を allow_mkchar キーワードを使用して制限することができます。
- 作成を許可する FIFO のパス名を allow_mkfifo キーワードを使用して制限することができます。
- 作成を許可する UNIX ドメインソケットのパス名を allow_mksock キーワードを使用して制限することができます。
- 作成を許可するシンボリックリンクのパス名を allow_symlink キーワードを使用して制限することができます。
- 削除を許可するパス名を allow_unlink キーワードを使用して制限することができます。
- ハードリンクを許可する組み合わせを allow_link キーワードを使用して制限することができます。
- パス名の変更を許可する組み合わせを allow_rename キーワードを使用して制限することができます。
- 利用を許可する IOCTL のパス名とコマンド番号の組み合わせを allow_ioctl キーワードを使用して制限することができます。（ TOMOYO 1.6.7 以降のみ）
- 使用を許可する IP アドレスの範囲ととポート番号の範囲を allow_network キーワードを使用して制限することができます。
- 送信可能なシグナルの番号と送信先のドメインを allow_signal キーワードを使用して制限することができます。
- マウントを許可するデバイスおよびマウントポイントを allow_mount キーワードを使用して制限することができます。
- アンマウントを許可しないマウントポイントを deny_unmount キーワードを使用して指定することができます。
- chroot で移動できるディレクトリを allow_chroot キーワードを使用して制限することができます。
- pivot_root で交換できるディレクトリを allow_pivot_root キーワードを使用して制限することができます。

### allow_network

ネットワークのアクセス許可を指定するには、 allow_network というキーワードに続けて、プロトコル（ TCP UDP RAW の何れか）、 IP アドレス、ポート番号（ TCP UDP の場合）またはプロトコル番号（ RAW の場合）を指定します。 IPv4 プロトコルおよび IPv6 プロトコルで使用するローカルポート番号が対象です。

キーワード | 許可されるアクセス | 指定例
allow_network TCP bind | ローカルの TCP アドレス／ポートの割り当て | allow_network TCP bind 0.0.0.0 80
allow_network TCP listen | ローカルの TCP アドレス／ポートでの待機 | allow_network TCP listen 0.0.0.0 80
allow_network TCP accept | リモートの TCP アドレス／ポートからの接続受付および通信 | allow_network TCP accept 10.0.0.0-10.255.255.255 1024-65535
allow_network TCP connect | リモートの TCP アドレス／ポートへの接続および通信 | allow_network TCP connect 127.0.0.1 1024-65535
allow_network UDP bind | ローカルの UDP アドレス／ポートの割り当て | allow_network UDP bind 0.0.0.0 53
allow_network UDP connect | リモートの UDP アドレス／ポートとの通信 | allow_network UDP connect 127.0.0.1 53
allow_network RAW bind | ローカルの IP アドレス／プロトコルの割り当て | allow_network RAW bind 127.0.0.1 255
allow_network RAW connect | リモートの IP アドレス／プロトコルとの通信 | allow_network RAW connect 10.0.0.1 1

IPv6 で使われる "::" という表記はサポートされていません。 "::1" ではなく "0:0:0:0:0:0:0:1" のように表記する必要があります。

同じＩＰアドレスを繰り返し指定する手間を避けるために、パス名と同様にグループ化を行うことができます。

関連項目： address_group

### allow_signal

シグナルのアクセス許可を指定するには、 allow_signal というキーワードに続けて、シグナルの番号および操作対象ドメインを指定します。
例外が 2 つ存在します。シグナル番号が 0 の場合は常に許可されます。また、自分の属するドメインへのシグナルの場合には常に許可されます。
その他の場合、このファイルに指定されたシグナル番号とドメイン名で始まる場合のみそのシグナルを送信できます。
操作対象ドメインとして <kernel> を指定すると、全てのドメインに指定された番号のシグナルを送信できます。

### use_profile

これは、このドメインに対して割り当てられているプロファイル番号を示しています。プロファイル番号は 0 ～ 255 の値をとります。

### ignore_global_allow_read

これは、このドメインに対しては例外ポリシーで指定されている allow_read を無視することを示しています。特定のドメインに対して特に読み込みモードでオープンできるファイルを制限したい場合に使います。

関連項目： allow_read

### ignore_global_allow_env

これは、このドメインに対しては例外ポリシーで指定されている allow_env を無視することを示しています。特定のドメインに対して特に環境変数の受け渡しを制限したい場合に使います。

関連項目： allow_env

### execute_handler

これは、このドメインに対しては常にこのキーワードで指定されたプログラムだけを実行することを示しています。特定のドメインで実行されるプログラムの実行要求を全て特定のプログラムを経由して起動させたい場合に使います。

このキーワードが指定されている場合、 MAC_FOR_FILE の値に関わらず常にこのキーワードで指定されたプログラムが実行されます。そのため、このキーワードに適切なプログラムへのパス名が指定されていなかった場合、このキーワードが指定されているドメインからは一切のプログラムを実行できなくなります。

関連項目： denied_execute_handler MAC_FOR_FILE allow_execute allow_argv0

### denied_execute_handler

これは、 MAC_FOR_FILE が enforcing の状態に於いて許可されていないプログラムの実行が要求された場合には、常にこのキーワードで指定されたプログラムを実行することを示しています。このキーワードが指定されていない場合、 MAC_FOR_FILE が enforcing の状態に於いて許可されていないプログラムの実行が要求された場合にはプログラムの実行を拒否します。

ただし、ドメインに対して execute_handler キーワードが指定されている場合、このキーワードは無視されます。

### quota_exceeded

これは、学習モードで動作中にアクセス許可の数が MAX_ACCEPT_ENTRY で指定された値に到達したため、このドメインに対してはアクセス許可を学習しきれなかったことを示しています。チューニングを行うなどしてアクセス許可の数を減らすようにしてください。

関連項目： MAX_ACCEPT_ENTRY

### transition_failed

これは、プログラムの実行時にドメインを新規作成しようと試みたが、「新規作成されるドメインのドメイン名が長すぎる」または「カーネルがメモリを割り当てることができなかった」という理由により、ドメイン遷移を行わないままプログラムの実行を許可したことを示しています。このドメインに対して MAC_FOR_FILE=enforcing のプロファイルを割り当てる予定がある場合には、「ドメイン遷移を抑制する」または「メモリ割り当て量を増やす」ようにしてください。

関連項目： keep_domain ポリシーに割り当てられるメモリ量を制限

## /proc/ccs/exception_policy

現在の例外ポリシーを読み出しまたは追加または削除するには以下のように操作します。

（例）
echo 'file_pattern /proc/\$/status' | ccs-loadpolicy -e
echo 'delete file_pattern /proc/\$/status' | ccs-loadpolicy -e
cat /proc/ccs/exception_policy

関連項目： 変更について

### file_pattern

パス名のパターン化を指示するには、 file_pattern というキーワードに続けて、パス名のパターンを指定します。パス名は正規化されたパス名でなければなりません。このキーワードは実行許可を与える場合とドメイン定義には適用されません。
例えば、プロセスＩＤを含む正規化されたパス名（ /proc/PID/ ）は、アクセス制御が正しく行われるようにグループ化されなければなりません。

学習モード（ MAC_FOR_FILE が learning に設定されている状態）でパス名に対するアクセスを行うと、自動的にパターン化された状態で学習されます。学習モード以外には影響しません。この構文は、既知のパターンをテンプレート化することによって、後でチューニングを行うときの手間を軽減するためだけに使われます。

### path_group

パス名のグループを定義するには、 path_group というキーワードに続けて、グループ名とパス名のパターンを指定します。
例えば、ホームディレクトリ以下の全ファイルをまとめたい場合、

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/\*/\*/\*/\*/\*/\*/\*

のように定義しておくことで、ドメインポリシーのファイルに対するアクセス許可を指定する際に

allow_read @HOME-DIR-FILE

のように指定できます。

### address_group

アドレスのグループを定義するには、 address_group というキーワードに続けて、グループ名と IP アドレスのパターンを指定します。
例えば、ローカルアドレスをまとめたい場合、

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

のように定義しておくことで、ドメインポリシーのネットワークに対するアクセス許可を指定する際に

allow_network TCP accept @local-address 1024-65535

のように指定できます。

### allow_read

無条件に読み込みを許可するファイルを指定するには、 allow_read というキーワードに続けて、正規化されたファイル名を指定します。このキーワードの目的は、 GLIBC がプログラム実行時に参照するファイルやエラーメッセージを表示する際に参照するファイルのように、どのようなプログラムから参照されても構わないというファイルを指定することで、各ドメインで記述しないで済むようにすることです。なお、各ドメインで ignore_global_allow_read という指定をすると、ここで指定された allow_read は無視されます。

関連項目： allow_read ignore_global_allow_read

### allow_env

無条件に受け取ってよい環境変数名を指定するには、 allow_env というキーワードに続けて、環境変数名を指定します。このキーワードの目的は、 PATH や HOME のように、どのようなプログラムに渡されても構わないような環境変数名を指定することで、各ドメインで記述しないで済むようにすることです。くれぐれも LD_PRELOAD のような危険な環境変数を指定しないでください。なお、各ドメインで ignore_global_allow_env という指定をすると、ここで指定された allow_env は無視されます。

関連項目： ignore_global_allow_env allow_env

### deny_rewrite

deny_rewrite というキーワードを使用して、既に記録されている部分の書き換えを禁止したいファイル（ログファイル等）のパス名を登録します。パターンが使用できます。 deny_rewrite というキーワードを使用して登録されたファイルは、ドメイン用ポリシーの中で明示的に allow_rewrite というキーワードを用いて許可が与えられない限り、追記ではない書き込みモードでのオープンとファイルの切り詰めが禁止されます。

関連項目： allow_rewrite

### alias

シンボリックリンクを解決した名前ではなくシンボリックリンクの名前のまま実行させるプログラムを指定するには、 alias というキーワードに続けてシンボリックリンクを解決したパス名とシンボリックリンクを解決する前のパス名を指定します。このキーワードの目的は、実行時の名前によって異なる振る舞いをするプログラムが、ハードリンクではなくシンボリックリンクで参照される場合に、シンボリックリンクの名前でドメインを遷移できるようにすることです。

例えば /sbin/pidof は /sbin/killall5 へのシンボリックリンクであるため、通常は /sbin/pidof を実行すると /sbin/killall5 が実行されたものとしてドメインが定義されます。しかし、 alias /sbin/killall5 /sbin/pidof という指定をすることで、 /sbin/pidof を実行すると /sbin/pidof が実行されたものとしてドメインが定義されるようにできます。

関連項目： allow_execute

### aggregator

複数のプログラムを単一のプログラム名で扱うには、 aggregator というキーワードに続けて集約前のプログラム名と集約後のプログラム名を指定します。このキーワードの目的は、同様のプログラムを集約することです。

例えば、 /usr/bin/tac と /bin/cat は似ているので、 aggregator /usr/bin/tac /bin/cat という指定をすることで /usr/bin/tac を /bin/cat のドメインで実行することができるようになります。

例えば、 Fedora Core 3 の /usr/sbin/logrotate は /tmp/logrotate.\?\?\?\?\?\? というパターンのプログラムを作成して実行するが、 TOMOYO Linux では安全上の理由からプログラムの実行許可を与える場合とドメインを定義する場合にパターンを使用することを認めていません。しかし、 aggregator /tmp/logrotate.\?\?\?\?\?\? /tmp/logrotate.tmp という指定をすることで /tmp/logrotate.\?\?\?\?\?\? を /tmp/logrotate.tmp のドメインで実行することができるようになります。

関連項目： allow_execute

### initialize_domain

特定のプログラムが実行された場合にドメイン遷移を初期化させるには、 initialize_domain というキーワードを使用します。

- initialize_domain プログラム名 from ドメイン名
- initialize_domain プログラム名 from ドメイン名の最後のプログラム名
- initialize_domain プログラム名

from 以降が指定されていない場合は任意のドメインから実行された場合に適用されます。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用されます。

このキーワードの目的は、常駐型プログラムや必要に応じてカーネルから起動されるプログラムを、通常とは異なるドメインに遷移させることで、ドメイン遷移を集約することです。

関連項目：ドメイン遷移 no_initialize_domain

### no_initialize_domain

initialize_domain の効力を打ち消すには、 no_initialize_domain というキーワードを指定します。

- no_initialize_domain プログラム名 from ドメイン名
- no_initialize_domain プログラム名 from ドメイン名の最後のプログラム名
- no_initialize_domain プログラム名

このキーワードはドメイン遷移を初期化させたくない場合に使用します。

関連項目：ドメイン遷移 initialize_domain

### keep_domain

特定のドメインからプログラムが実行されてもドメイン遷移を行わないようにするには、 keep_domain というキーワードを使用します。

- keep_domain プログラム名 from ドメイン名
- keep_domain プログラム名 from ドメイン名の最後のプログラム名
- keep_domain ドメイン名
- keep_domain ドメイン名の最後のプログラム名

from 以前が指定されていない場合は任意のプログラムが実行された場合に適用されます。ドメイン名が <kernel> で始まらない場合は、ドメイン名の最後のプログラム名が一致する全てのドメインに適用されます。

このキーワードの目的は、不要なドメイン遷移の発生を抑制することでドメイン数とメモリ消費を抑えることです。

関連項目：ドメイン遷移 no_keep_domain

### no_keep_domain

keep_domain の効力を打ち消すには、 no_keep_domain というキーワードを指定します。

- no_keep_domain プログラム名 from ドメイン名
- no_keep_domain プログラム名 from ドメイン名の最後のプログラム名
- no_keep_domain ドメイン名
- no_keep_domain ドメイン名の最後のプログラム名

このキーワードはドメイン遷移を行わせたい場合に使用します。

関連項目：ドメイン遷移 keep_domain

## /proc/ccs/query

強制モードで動作中にポリシー違反が発生した場合に、そのアクセス要求を個別に許可するかどうかの指定を行うために使用します。 ALLOW_ENFORCE_GRACE=enabled に設定されているプロファイルが割り当てられているドメインに対して強制モードでポリシー違反が発生した場合、 ccs-queryd を用いて対話的に諾否を指定できます。

TOMOYO Linux 1.6.2 では ALLOW_ENFORCE_GRACE が廃止されました。よって、 TOMOYO Linux 1.6.2 以降をお使いの場合、 ccs-queryd を実行するだけで対話的に諾否を指定できます。

## /proc/ccs/manager

ポリシーの読み書きを行えるプログラムまたはドメインの一覧を取得または追加します。

### manage_by_non_root

デフォルトではユーザＩＤと実効ユーザＩＤの両方が 0 であるプロセスだけがポリシーを変更できますが、非 root ユーザによる変更を認めたい場合に使用します。

## /proc/ccs/.domain_status

ccs-setprofile コマンドが行単位での処理を行いやすくするために domain_policy の内容からプロファイル番号とドメイン名の部分だけを抽出したもの。ＤＢＭＳのビューに相当する機能を提供します。

## /proc/ccs/meminfo

TOMOYO Linux がポリシーを保持するために使用しているカーネルのメモリ情報を取得します。

（例）
cat /proc/ccs/meminfo

## /proc/ccs/grant_log

ドメインポリシーに対するアクセス許可ログを取得します。取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使ってください。記憶できる件数は MAX_GRANT_LOG 件までです。それ以上は記録されないので、随時読み出すようにする必要があります。

（例）
cat /proc/ccs/grant_log

## /proc/ccs/reject_log

ドメインポリシーに対するアクセス拒否ログを取得します。取得すべきログが無い場合はすぐに戻ってくるので、ログが発生するまで待機させるには select(2) を使ってください。記憶できる件数は MAX_REJECT_LOG 件までです。それ以上は記録されないので、随時読み出すようにする必要があります。

（例）
cat /proc/ccs/reject_log

## /proc/ccs/self_domain

呼び出し元プロセスが属しているドメインの名前を取得します。

（例）
cat /proc/ccs/self_domain

## /proc/ccs/.process_status

ccs-ccstree コマンド（「現在動作中のプロセス」と「そのプロセスが属しているドメイン」と「そのドメインに割り当てられているプロファイル番号」を pstree のように一覧表示する）のためのインタフェース。例外的にポリシーマネージャとして登録されていないプログラムでも書き込みを行える。

## /proc/ccs/.updates_counter

ポリシーの変更を検出するためのカウンタです。参照されるたびに 0 にリセットされます。ポリシーの更新を監視するプログラムのためのインタフェースです。

## /proc/ccs/version

TOMOYO Linux のバージョン番号を取得するためのインタフェースです。

（例）
cat /proc/ccs/version

# 6. 便利な機能

## 6.1 root 以外のユーザによるポリシーの変更を許可

デフォルトではユーザＩＤと実効ユーザＩＤの両方が 0 であるプロセスだけがポリシーを変更できますが、非 root ユーザによる変更を認めたい場合には

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

のように manage_by_non_root というキーワードを書き込むことで、ユーザＩＤと実効ユーザＩＤのチェックを無効にすることができます。また、再びユーザＩＤと実効ユーザＩＤのチェックを有効にするには、

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

のように delete manage_by_non_root というキーワードを書き込んでください。 /proc/ccs/ 以下のエントリの所有者は root なので、非 root ユーザによるアクセスを認めるためには必要に応じて chown/chmod を実行してください。
起動時に自動的にこの処理が行われるようにするために、 /sbin/ccs-init は /etc/ccs/ccs-post-init というプログラムが存在する場合には /etc/ccs/ccs-post-init も実行するようになっています。よって、例えば demo ユーザが /proc/ccs/ インタフェースへの読み書きができるように設定したい場合は、

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

という内容で /etc/ccs/ccs-post-init を作成し、

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

を実行することで demo ユーザがポリシーのあるディレクトリへのアクセスとポリシーを編集するためのプログラムを実行できるようになります。

## 6.2 ポリシーに割り当てられるメモリ量を制限

TOMOYO Linux 1.6.1 ではポリシーを保持しておくために割り当てられるメモリの量を制限できるようにするためにメモリクォータが導入されました。

/etc/ccs/ccs-post-init から以下のように /proc/ccs/meminfo に書き込みを行うことで設定できます。

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

## 6.3 条件付きアクセス許可の指定

アクセス許可にユーザＩＤ等に基づいた条件を付加することができます。条件は個々のアクセス許可の末尾に " if " 句を追加する形で指定します。

指定例 | 意味
allow_read /etc/passwd | /etc/passwd の参照を許可
allow_read /etc/passwd if task.uid=0 | プロセスのユーザＩＤが 0 の場合に限り、 /etc/passwd の参照を許可
allow_read /etc/passwd if task.uid!=0 | プロセスのユーザＩＤが 0 ではない場合に限り、 /etc/passwd の参照を許可
allow_network TCP connect 10.0.0.1 80 | TCP プロトコルで 10.0.0.1 ポート 80 への接続を許可
allow_network TCP connect 10.0.0.1 80 if task.uid=100 | プロセスのユーザＩＤが 100 の場合に限り、 TCP プロトコルで 10.0.0.1 ポート 80 への接続を許可
allow_capability SYS_KILL | kill(2) の使用を許可
allow_capability SYS_KILL if task.ppid=1 task.uid=0 task.euid=0 | 親プロセスが /sbin/init であり、かつ、プロセスのユーザＩＤと実効ユーザＩＤが 0 の場合に限り、 kill(2) の使用を許可

以下の変数を指定できます。

変数 | 意味
task.uid | 呼び出したプロセスのユーザＩＤ
task.euid | 呼び出したプロセスの実効ユーザＩＤ
task.suid | 呼び出したプロセスの保存ユーザＩＤ
task.fsuid | 呼び出したプロセスのファイルシステムユーザＩＤ
task.gid | 呼び出したプロセスのグループＩＤ
task.egid | 呼び出したプロセスの実効グループＩＤ
task.sgid | 呼び出したプロセスの保存グループＩＤ
task.fsgid | 呼び出したプロセスのファイルシステムグループＩＤ
task.pid | 呼び出したプロセスのプロセスＩＤ
task.ppid | 呼び出したプロセスの親プロセスのプロセスＩＤ
path1.uid | 許可されるパス名の所有者ＩＤ
path1.gid | 許可されるパス名のグループＩＤ
path1.ino | 許可されるパス名のｉノード番号
path1.parent.uid | 許可されるパス名の親ディレクトリの所有者ＩＤ
path1.parent.gid | 許可されるパス名の親ディレクトリのグループＩＤ
path1.parent.ino | 許可されるパス名の親ディレクトリのｉノード番号
path2.parent.uid | 作成されるパス名の親ディレクトリの所有者ＩＤ
path2.parent.gid | 作成されるパス名の親ディレクトリのグループＩＤ
path2.parent.ino | 作成されるパス名の親ディレクトリのｉノード番号

path1 はパス名を必要とする操作の 1 個目のパス名に対応し、 path2 はパス名を必要とする操作の 2 個目のパス名に対応します。 例えば、「 allow_rename file1 file2 」というアクセス許可の場合、 path1 が file1 に、 path2 が file2 に対応します。

path1.uid および path1.gid は存在しないパス名に対しては指定できません。つまり、ファイル等の作成時（ allow_create 等）には使用できません。

path1.parent.uid および path1.parent.gid は常に指定可能です。

path2.parent.uid および path2.parent.gid はパス名を 2 つ必要とする操作（つまり allow_link および allow_rename ）に限り指定できます。

path2.uid および path2.gid はサポートしていません。（ rename 操作に於いて、 path2 が存在する場合には暗黙のうちに unlink または rmdir が実行されます。）

sysctl による読み書き（ /proc/sys/ ディレクトリ以下のファイルを open ではなく sysctl を用いてアクセス）を行う場合については、 path1 path2 ともにサポートしていません。

### プログラムの実行許可（allow_execute）に対しては以下の変数と条件も指定できます。

変数 | 意味
exec.argc | プログラム実行時の引数の数
exec.envc | プログラム実行時の環境変数の数

条件 | 意味
exec.argv[index]="value" | index （ 0 <= index < exec.argc ）番目の引数の値が value である
exec.argv[index]!="value" | index （ 0 <= index < exec.argc ）番目の引数の値が value ではない
exec.envp["name"]="value" | 環境変数 name が定義されており、値が value である
exec.envp["name"]!="value" | 環境変数 name が定義されていないか、あるいは値が value ではない
exec.envp["name"]!=NULL | 環境変数 name が定義されている
exec.envp["name"]=NULL | 環境変数 name が定義されていない

### TOMOYO 1.6.7 以降では以下の条件も指定できます。

#### プロセス種別の指定

条件 | 意味
task.type=execute_handler | プロセスは execute_handler として動作している
task.type!=execute_handler | プロセスは普通のプロセスとして動作している

#### ファイル種別の指定

条件 | 意味
path1.type=file | path1 は通常のファイルである
path1.type=directory | path1 はディレクトリである
path1.type=fifo | path1 is a は FIFO である
path1.type=socket | path1 はソケットである
path1.type=symlink | path1 はシンボリックリンクである
path1.type=block | path1 はブロックデバイスファイルである
path1.type=char | path1 はキャラクタデバイスファイルである
path1.type!=file | path1 は通常のファイルではない
path1.type!=directory | path1 はディレクトリではない
path1.type!=fifo | path1 は FIFO ではない
path1.type!=socket | path1 はソケットではない
path1.type!=symlink | path1 はシンボリックリンクではない
path1.type!=block | path1 はブロックデバイスファイルではない
path1.type!=char | path1 はキャラクタデバイスファイルではない

path1.parent や path2.parent は常にディレクトリなので、 path1.parent.type や path2.parent.type という指定はサポートしません。

#### ファイルの保存されているデバイス番号の指定

条件 | 意味
path1.major=数値1-数値2 | path1 のメジャー番号部分が「数値1～数値2」である
path1.minor=数値1-数値2 | path1 のマイナー番号部分が「数値1～数値2」である
path1.major!=数値1-数値2 | path1 のメジャー番号部分が「数値1～数値2」ではない
path1.minor!=数値1-数値2 | path1 のマイナー番号部分が「数値1～数値2」ではない

path1.parent や path2.parent のデバイスは（デバイスを跨ぐ操作は認められていないため）常に path1 と同一なので、 path1.parent や path2.parent という指定はサポートしません。

「数値1」と「数値2」が同じ値の場合、「-数値2」の部分は省略可能です。

#### デバイスファイル属性の指定

条件 | 意味
path1.dev_major=数値1-数値2 | path1 のデバイスメジャー番号部分が「数値1～数値2」である
path1.dev_minor=数値1-数値2 | path1 のデバイスマイナー番号部分が「数値1～数値2」である
path1.dev_major!=数値1-数値2 | path1 のデバイスメジャー番号部分が「数値1～数値2」ではない
path1.dev_minor!=数値1-数値2 | path1 のデバイスマイナー番号部分が「数値1～数値2」ではない

path1.type=block または path1.type=char に対してのみ有効です。

「数値1」と「数値2」が同じ値の場合、「-数値2」の部分は省略可能です。

#### DAC のパーミッション指定

条件 | 意味
path1.perm=数値1-数値2 | path1 のパーミッションが「数値1～数値2」である
path1.perm!=数値1-数値2 | path1 のパーミッションが「数値1～数値2」ではない
path1.perm=setuid | path1 に関して setuid ビットが on である
path1.perm!=setuid | path1 に関して setuid ビットが off である
path1.perm=setgid | path1 に関して setgid ビットが on である
path1.perm!=setgid | path1 に関して setgid ビットが off である
path1.perm=sticky | path1 に関して sticky ビットが on である
path1.perm!=sticky | path1 に関して sticky ビットが off である
path1.perm=owner_read | path1 に関して owner に対する read ビットが on である
path1.perm!=owner_read | path1 に関して owner に対する read ビットが off である
path1.perm=owner_write | path1 に関して owner に対する write ビットが on である
path1.perm!=owner_write | path1 に関して owner に対する write ビットが off である
path1.perm=owner_execute | path1 に関して owner に対する execute ビットが on である
path1.perm!=owner_execute | path1 に関して owner に対する execute ビットが off である
path1.perm=group_read | path1 に関して group に対する read ビットが on である
path1.perm!=group_read | path1 に関して group に対する read ビットが off である
path1.perm=group_write | path1 に関して group に対する write ビットが on である
path1.perm!=group_write | path1 に関して group に対する write ビットが off である
path1.perm=group_execute | path1 に関して group に対する execute ビットが on である
path1.perm!=group_execute | path1 に関して group に対する execute ビットが off である
path1.perm=others_read | path1 に関して others に対する read ビットが on である
path1.perm!=others_read | path1 に関して others に対する read ビットが off である
path1.perm=others_write | path1 に関して others に対する write ビットが on である
path1.perm!=others_write | path1 に関して others に対する write ビットが off である
path1.perm=others_execute | path1 に関して others に対する execute ビットが on である
path1.perm!=others_execute | path1 に関して others に対する execute ビットが off である

path1 だけでなく path1.parent や path2.parent も指定可能です。

「数値1」と「数値2」が同じ値の場合、「-数値2」の部分は省略可能です。

数値を 8 進数で指定する場合には 0 から始まるようにしてください。（例： path1.perm=0644 ）

#### 例

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

「パス名が /dev/null 」「ファイル種別がキャラクタデバイスファイル」「デバイスメジャー番号が 1 」「デバイスマイナー番号が 3 」「パーミッションが 0666 」の場合のみ「読み書きモードでのオープンを許可する」という意味になります。

### TOMOYO 1.6.8 以降では、シンボリックリンクの作成許可（allow_symlink）に対して以下の条件も指定できます。

条件 | 意味
symlink.target="value" | 作成されるシンボリックリンクの内容が value である
symlink.target!="value" | 作成されるシンボリックリンクの内容が value ではない

## 6.4 ステートフルなアクセス許可の指定

TOMOYO Linux はユーザランドアプリケーションの修正を行わないため、プログラムの実行を伴わずにアクセス可能な資源の範囲を変更することはできません。しかし、例えば接続元クライアントのＩＰアドレスによってアクセスの可否を切り替えたいという場合があります。そのような場合に対応するため、プロセス毎に状態変数を割り当てることができ、条件付きアクセス許可の指定で使えるようになっています。

変数 | 意味
task.state[0] | 呼び出したプロセスの状態変数 0
task.state[1] | 呼び出したプロセスの状態変数 1
task.state[2] | 呼び出したプロセスの状態変数 2

task.state[0] ～ task.state[2] は 0 ～ 255 までの値を指定できます。この値を設定するには、以下のようにアクセス許可の指定に続けて " ; set " という句を指定します。

使用例 | 意味
allow_network TCP accept @TRUSTED_HOSTS 1024-65535 ; set task.state[0]=1 | クライアントが @TRUSTED_HOSTS である場合には、 state[0] に 1 を設定します。
allow_network TCP accept @UNTRUSTED_HOSTS 1024-65535 ; set task.state[0]=0 | クライアントが @UNTRUSTED_HOSTS である場合には、 state[0] に 0 を設定します。
allow_execute /bin/bash if task.state[0]=1 | state[0] が 1 の場合は、 /bin/bash の実行を許可します。
allow_execute /sbin/nologin if task.state[0]=0 | state[0] が 0 の場合は、 /sbin/nologin の実行を許可します。
allow_execute /etc/passwd if task.state[2]=0 ; set task.state[2]=1 | state[2] が 0 の場合は /etc/passwd の読み込みモードでのオープンを許可し、その後 state[2] に 1 を設定します。

状態変数を使用する際には、以下の点に注意してください。

- プロセスのドメインはプログラムの実行によって自動的に変更されるのに対して、プロセスの状態変数は明示的に " ; set " という句で指定されない限り変更されません。そのため、状態変数の戻し忘れに注意してください。
- 状態変数の設定はポリシーのチェックにより許可された時点で行われます。そのため、メモリ不足などポリシーのチェック以降のエラーによって、状態変数が変更されたけれどもアクセス要求は処理されなかったという状況が発生しえます。
- 上記の @TRUSTED_HOSTS と @UNTRUSTED_HOSTS の両方に含まれていた場合、先に一致したほうの状態変数が使われてしまいます。そのため、順番に依存するアクセス許可を定義しないように注意してください。

## 6.5 ポリシー違反時のペナルティ指定

強制モードでポリシー違反が発生した場合に、ポリシー違反の原因となったプロセスを一定時間スリープ状態にさせることができます。

/proc/ccs/profile での指定例 | 意味
3-SLEEP_PERIOD=1 | プロファイル 3 が割り当てられているプロセスが強制モードに於いてポリシー違反を発生させた場合、 0.1 秒間スリープさせます。
4-SLEEP_PERIOD=10 | プロファイル 4 が割り当てられているプロセスが強制モードに於いてポリシー違反を発生させた場合、 1 秒間スリープさせます。

この機能は、無限ループの中でポリシー違反が発生した場合に、ＣＰＵ使用率が 100% になってしまうのを回避するための安全装置です。通常は 0.1 秒間スリープさせるだけで充分です。

この機能は、許可されていないホストからの TCP 接続要求や UDP パケットを攻撃者が故意に送りつけることでポリシー違反を発生させることでサービスを長時間スリープ状態にさせることにより、許可されているホストからの TCP 接続要求や UDP パケットの処理を大幅に遅延させるという攻撃が成立してしまうのを回避するために、ネットワークの受信系の操作に対しては機能しないようになっています。

## 6.6 プログラムの実行可否をカーネルの外部で判断

TOMOYO Linux では、原則としてポリシーに従ってプログラムの実行可否を制御します。プログラム実行時のパラメータをチェックしたい場合には、条件付きアクセス許可の指定で説明したように exec.argv や exec.envp を使ってチェックを行うことができます。しかし、条件付きアクセス許可の指定では、単純なパターンマッチしかサポートされておらず、また、どのようなプログラムの実行を許可するかを予め指定しておく必要があります。

そこで、 TOMOYO Linux 1.6.0 では execute_handler という仕組みが導入されました。この仕組みは、プログラムの実行可否をカーネルが判断するのではなく、 execute_handler により指定されたプログラムが判断し、プログラムの実行を許可すべきと判断した場合には実際にプログラムを実行するという動作をします。

Linux に於いては、プログラムを実行するという動作は、プログラムの実行を要求したプロセスを上書きするという動作であり、プログラムの実行に成功した場合にはプログラムの実行を要求したプロセスに制御が戻ることはありません。つまり、要求されたプログラムの実行に失敗した場合にしか、プログラムの実行を要求したプロセスに対して、要求されたプログラムが実行されなかったことが通知されません。
例えば、プログラムＡとして動作しているプロセスがプログラムＢの実行を要求する場合を考えてみます。
プログラムＡとして動作しているプロセスがプログラムＢの実行を要求すると、カーネルが「プログラムＡとして動作しているプロセスからプログラムＢを実行することは適切であるかどうか」をポリシーを照合することで判断し、適切であると判断された場合には「プログラムＡとして動作しているプロセスをプログラムＢで上書き」し、適切では無いと判断された場合には「プログラムＡとして動作しているプロセスにプログラムＢの実行が認められていないことを通知」します。

execute_handler を指定した場合、 execute_handler として指定されたプログラムＣがこの動作に介在します。
プログラムＡとして動作しているプロセスがプログラムＢの実行を要求すると、プログラムＣに「プログラムＡとして動作しているプロセスからプログラムＢを実行することは適切であるかどうか」を判断してもらうために「プログラムＡとして動作しているプロセスをプログラムＣで上書き」します。プログラムＣとして動作するようになったプロセスが「プログラムＡとして動作していたプロセスからプログラムＢを実行することは適切であるかどうか」を判断し、適切であると判断した場合には「プログラムＣとして動作しているプロセスをプログラムＢで上書き」し、適切では無いと判断された場合には「プログラムＣとして動作しているプロセスをプログラムＢで上書きせずに終了」します。

このように、プログラムＢの実行を要求したプログラムＡとして動作していたプロセスがに対して、プログラムＢの実行に失敗したことを通知する手段を放棄することになるため、プログラムＢの実行を要求したプログラムＡとして動作していたプロセスが、プログラムＢが実行されなかったという通知を受けることができなくなるという副作用が発生します。
しかし、たとえ execute_handler を指定していない場合であっても、「共有ライブラリの読み込みができなかった」「 KILL シグナルを受信した」「メモリ不足になり OOM killer によって強制終了させられた」など、様々な要因によって「実行には成功したが期待された動作を始める前に終了してしまった」という状況が起こりえます。つまり、「プログラムの実行が失敗しなかった」ということと「要求されたプログラムが期待した動作を始めた」ということの間には、不確定要素が存在します。
そう考えると、「プログラムの実行に失敗したという通知が無い限りプログラムは期待された動作を始める」という保証は最初から存在しないわけなので、 execute_handler により指定されたプログラムＣが、プログラムＢの実行に失敗したことをプログラムＢの実行を要求したプログラムＡとして動作していたプロセスに通知できなかったという結果になったとしても、容認できる範囲であると言えると思います。

TOMOYO Linux は、どのプログラムからどのプログラムを実行する必要があるかを事前に把握して、必要最小限のプログラムの実行のみを認めるというアプローチを採用しています。そのため、正常な動作をしている限り、ポリシーで許可されていないプログラムの実行要求は起こらないはずだと仮定すると、全てのプログラムの実行要求をとりあえず受理して構わないと考えることができます。もしも受理すべきではないプログラムの実行要求が発生した場合、 denied_execute_handler の機能を使うことで要求を拒否する代わりにそのプロセスを強制終了させるなどの行動を起こすことができます。つまり、カーネルの内部でプログラムの実行可否の判断を行わなくても構わないということです。

そこで、ドメインに対して execute_handler キーワードを指定しておくことで、そのドメインから発生する全てのプログラムの実行可否の判断をカーネル外部のプログラムに委ねることができるようになります。

カーネルの内部では利用可能なライブラリが少ない上に連続したメモリ領域の割り当てが失敗する可能性が高くなりますが、 カーネルの外部であれば豊富なライブラリを使ってメモリ割り当ての限界を心配せずに詳細なチェックが可能になります。そこで、 execute_handler で指定したプログラムにプログラム実行時のパラメータをチェックしてもらい、適切であればプログラムを実行してもらうようにすることができます。

この方式の副作用は、プログラムの実行を拒否すべきと判断した場合に、プログラムの実行を要求したプロセスに通知する方法が無い点です。しかし、自由にカスタマイズできるので、 ssh 等を用いて遠隔地のマシンに問い合わせをしながらしながら判断することも可能です。

この機能を使うには、以下のように指定します。

/proc/ccs/domain_policy の例 | 意味
execute_handler /usr/sbin/check-and-exec | このドメインに属しているプロセスがプログラムの実行を要求した場合、要求されたプログラムを実行する代わりに /usr/sbin/check-and-exec を実行します。 /usr/sbin/check-and-exec はパラメータをチェックし、妥当と判断した場合には要求されたプログラムを実行します。

execute_handler で指定されたプログラムは、以下のパラメータを受け取ります。アクセスログについてで説明した、 allow_execute のログと比較してみてください。

- argv[0] には、 execute_handler で指定されたプログラムのパス名が入っています。
- argv[1] には、プログラムの実行を要求したプロセスのドメイン名が入っています。
- argv[2] には、プログラムの実行を要求したプロセスのパス名が入っています。
- argv[3] には、プログラムの実行を要求したプロセスの情報が入っています。
- argv[4] には、実行が要求されたプログラムのパス名が入っています。
- argv[5] には、プログラム実行要求時の引数の数が入っています。
- argv[6] には、プログラム実行要求時の環境変数の数が入っています。
- argv[7] から argv[6 + argc] には、呼び出し元プロセスが渡した argv[] の内容が入っています。
- argv[7 + argc] から argv [6 + argc + envc] には、呼び出し元プロセスが渡した envp[] の内容が入っています。
- 環境変数 envp[] は全てクリアされます。
- 標準入出力などは呼び出し元プロセスのものを引き継ぎます。

この機能を使用する際には、以下の点に注意してください。

- execute_handler で指定されたプログラムに対して実行許可（ allow_execute ）を与える必要はありませんし、与えるべきではありません。
- プロセスが chroot 内部の環境で動作している場合、 execute_handler で指定されたプログラムが見つからないために実行されない場合があります。これは、プロセスが chroot 内部の環境で動作している場合に、 chroot 外部の環境にあるプログラムを実行できてしまうと危険なので、 execute_handler で指定されたプログラムは、プロセスの名前空間のルートディレクトリではなく、プロセスのルートディレクトリから検索するようになっているためです。
- execute_handler で指定されたプログラムが動作するためのドメインが存在しない場合、実行されません。そのため、例えば <kernel> 直下に execute_handler で指定されたプログラム用のドメインを作成して、そのプログラムを initialize_domain キーワードで指定するなどの準備をしてください。
- execute_handler で指定されたプログラムは環境変数の影響を受けるのを避けるため、全ての環境変数の内容をクリアした状態で起動されます。そのため、環境変数 PATH 等が設定されていないので、外部コマンドを呼び出す場合には注意してください。また、 execute_handler で指定されたプログラムが動作するドメインにも強制モード用のプロファイルを割り当てておくことを推奨します。

ccs-tools のソースパッケージには、 audit-exec-param.c というサンプルプログラムが入っています。ご自由に改造してお使いください。

この機能は、機構を提供しているだけです。この機構を活用できるかどうかはあなた次第です。

## 6.7 許可されていないプログラムの実行が要求された場合の代替処理指定

TOMOYO Linux では、どのプログラムからどのプログラムを実行する必要があるかを事前に把握して、必要最小限のプログラムの実行のみを認めるというアプローチを採用しています。そのため、不要なプログラムの実行を拒否するという振る舞いだけでなく、それ以外の振る舞いを行うこともできます。

強制モードに於いて allow_execute 構文により許可されていないプログラムの実行が要求された場合、デフォルトではプログラムの実行を拒否します。しかし、あるプログラムからどのプログラムの実行を許可する必要があるかを把握済みであるという前提があれば、プロセスが正常な動作をしている限りに於いて許可されていないプログラムの実行が要求されることは無いので、許可されていないプログラムの実行が要求されたということはプロセスが正常な動作をしていない（つまり、プロセスにとっては制御を失った状態である）とみなすことができます。

攻撃者はバッファオーバーフローなどのセキュリティホールを攻撃することでプロセスの制御を奪い、シェルなどのコマンドの実行を要求してきます。もし、そのプロセスからシェルの実行を許可する必要が無い（すなわち allow_execute /bin/bash のようなアクセス許可を与える必要が無い）のであれば、シェルの実行が要求された時点で既にプロセスにとっては制御を失っていると考えることができます。

通常、許可されていないプログラムの実行が要求された場合は、その要求を拒否するだけです。しかし、制御を失っているプロセスから要求されたプログラムの実行要求を拒否したところで、そのプロセスの制御が取り戻される（つまり、正常な動作をするようになる）とは考えられません。しかし、プログラムを実行するということは、現在動作中のプロセスを新しいプログラムに置き換えることで、制御を新しいプログラムに譲渡することを意味します。つまり、あるプロセスがバッファオーバーフローなどにより制御を失っていたとしても、プログラムを実行することにより、そのプロセスの制御が取り戻されるわけです。

攻撃者の手によって制御を失ったプロセスからプログラムが実行された後の制御は、どのプログラムが実行されたかによって決まります。シェルが実行された場合には、シェルはユーザが要求したとおりに処理を実行してしまうため、プログラムの実行を要求したプロセスの所有者である攻撃者の手に委ねられてしまうわけです。しかし、何もせずに終了するようなプログラム（例えば /bin/true ）が実行された場合には、プロセスの制御が攻撃者の手に委ねられてしまうことはありません。

このように、攻撃者の手によって本来許可する必要の無いプログラムの実行が要求されるという出来事は、見方を変えると、攻撃者自身が制御を取り戻すためのチャンスを与えてくれていると考えることができます。そこで、 TOMOYO Linux では、許可されていないプログラムの実行が要求された場合、その要求を拒否する代わりに他のプログラムを実行するための機構を提供しています。この機構を用いて何をするかはシステム管理者の自由です。

例えば、シェルの実行要求を /bin/true の実行要求に差し替えてしまうことで、そのプロセスを直ちに強制終了させることができます。

例えば、シェルの実行要求をハニーポットクライアントプログラムの実行要求に差し替えてしまうことで、攻撃者がどのようなリクエストを行うかを観察することができます。

例えば、そのログインセッションを強制終了させることができます。

例えば、要求されたコマンドがどのパッケージに含まれているかを教えてくれる Ubuntu の command-not-found パッケージのように、「 You are not permitted to execute this program. 」のような警告を表示することができます。

例えば、攻撃者の接続元ＩＰアドレスを割り出して、ファイアウォールの設定を変更することができます。

この機能を使うには、以下のように指定します。

/proc/ccs/profile の例 | /proc/ccs/domain_policy の例 | 意味
3-MAC_FOR_FILE=enforcing | use_profile 3 denied_execute_handler /bin/true | プロファイル 3 が割り当てられているドメインに属しているプロセスが、許可されていないプログラムの実行を要求した場合、代わりに /bin/true を実行します。

この機能を使用する際の注意事項はプログラムの実行可否をカーネルの外部で判断と同じです。

目次へ戻る