Info: Version 1.3.1 is available.

# TOMOYO Linux ポリシー解説書

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

# 目次

## 1. はじめに

1.1 用語の定義

1.2 ドメインの定義およびドメインの遷移

## 2. ポリシーファイルの分類と構文

2.1 ポリシーマネージャ定義（manager.txt）

2.2 プロファイル定義（status.txt）

2.3 システムポリシー（system_policy.txt）

2.4 ドメイン別ポリシー（domain_policy.txt）

2.5 例外ポリシー（exception_policy.txt）

2.6 マッピング定義（mapping.txt）

## 3. /proc/ccs/ インタフェース

3.1 status

3.2 policy/system_policy

3.3 policy/domain_policy

3.4 policy/exception_policy

3.5 policy/query

3.6 policy/manager

3.7 policy/.domain_status

3.8 info/trusted_pids

3.9 info/meminfo

3.10 info/grant_log

3.11 info/reject_log

3.12 info/self_domain

3.13 info/mapping

3.14 info/.process_status

3.15 info/.updates_counter

# 1. はじめに

## 1.1 用語の定義

正規化されたパス名 | "/" で始まり、シンボリックリンクや "/./" や "//" や "/../" を含まないパス名。（ただし、現在のプロセスに関する情報にアクセスするための "/proc/self/" ディレクトリに関してはそのまま "/proc/self/" とする。） プロセスが chroot された環境下で動作する場合であっても、 chroot する前のパス名で指定される。 正規化されたパス名は、全てアスキーコードの表示可能な範囲（0x21～0x7E）で構成されている。 従って、\ 文字（0x5C）は \\ 、その他の表示不可能な文字（0x01～0x20、0x7F～0xFF）は \ooo 形式の8進数で表記する。 （例えば、空白文字（0x20）は \040 と表記する。）
正規化されたディレクトリ名 | 正規化されたパス名の内、"/"で終わるもの。
正規化されたファイル名 | 正規化されたパス名の内、"/"で終わらないもの。 正規化されたファイル名は、ディレクトリ以外の全てのファイルタイプ（通常ファイル、キャラクタ型デバイスファイル、ブロック型デバイスファイル、ＦＩＦＯ、シンボリックリンク、ソケット）を含む。
プログラム | 正規化されたファイル名の内、実行可能なもの。
ドメイン | ＭＡＣ（強制アクセス制御）を行うための属性
遷移先ドメイン | プログラムが正常に開始された場合にプロセスが遷移するドメイン
操作対象ドメイン | 操作対象となるプロセスの属しているドメイン

## 1.2 ドメインの定義およびドメインの遷移

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」と定義される。

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

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

Step | 内容
プログラム名の取得 | 実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補１」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決したパス名を取得する。 実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補２」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決する前のパス名を取得する。
シンボリックリンクの識別 | 「パス名候補１」と「パス名候補２」が一致しない場合、「パス名候補１」と「パス名候補２」の組み合わせが例外ポリシーの alias ディレクティブで指定されているパス名の組み合わせに一致するかどうかを調べる。一致する場合は「パス名候補２」を「パス名候補１」とする。
類似するプログラムの集約 | 「パス名候補１」が例外ポリシーの aggregator ディレクティブで指定されているパス名のパターンに一致するかどうかを調べる。 一致する場合は、 aggregator ディレクティブで指定されているパス名を「パス名候補１」とする。
argv[0] のチェック | 「パス名候補２」の最後の / 以降の部分と argv[0] の最後の / 以降の部分が異なっている場合、「パス名候補２」と「argv[0]の最後の / 以降の部分」の組み合わせが allow_argv0 ディレクティブにより許可されてる事を確認する。
権限のチェック | 現在のプロセスが属しているドメインが、「パス名候補１」の実行を許可している事を確認する。
遷移先の決定 | 「パス名候補１」が例外ポリシーの initializer ディレクティブで指定されているパス名に一致するかどうかを調べる。 一致する場合は「カーネルが属しているドメインのドメイン名（<kernel>）」と「パス名候補１」とを連結して「遷移先ドメイン」とし、「遷移先ドメイン」が定義されている事を確認する。 一致しない場合は、「現在のプロセスが属しているドメインのドメイン名」が例外ポリシーの trust_domain ディレクティブで指定されているドメイン名で始まっているかどうかを調べる。そうである場合は、「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とする。 そうではない場合は、「現在のプロセスが属しているドメインのドメイン名」と「パス名候補１」とを連結して「遷移先ドメイン」とし、「遷移先ドメイン」が定義されている事を確認する。
ドメイン遷移処理 | 通常のプログラム実行処理を行う。 通常のプログラム実行処理が正常に終了した場合は、「遷移先ドメイン」に遷移する。

# 2. ポリシーファイルの分類と構文

ポリシーファイルは全て /etc/ccs/ ディレクトリに作成しておく。このディレクトリに存在するファイルが /sbin/init の開始時に /.init によって読み込まれるようになっている。

## 2.1 ポリシーマネージャ定義（manager.txt）

全てのプログラムがポリシーの変更を行えるのは危険であるため、このファイルには /proc/ccs/ インタフェースへの書き込みアクセスを許可するプログラムを定義しておく。

このファイルに定義されていないプログラムからは /proc/ccs/ インタフェースへの書き込みアクセスができない。システム運用時にポリシーの変更を許可しない場合はこのファイルを削除しておく。

（例）
/root/ccstools/loadpolicy
/root/ccstools/editpolicy
/root/ccstools/setlevel
/root/ccstools/setprofile
/root/ccstools/ld-watch
/root/ccstools/ccs-queryd

## 2.2 プロファイル定義（status.txt）

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

項目 | 内容 | 自動学習対応
MAC_FOR_FILE | ファイルに対する強制アクセス制御を有効にする。 | ○
MAC_FOR_ARGV0 | プログラム実行時の argv[0] のチェックを有効にする。 | ○
MAC_FOR_CAPABILITY::*** | ケイパビリティに対する強制アクセス制御を有効にする。 *** の部分にはドメイン別ポリシーの allow_capability キーワードで指定可能な値が入る。 | ○
MAC_FOR_NETWORK | ネットワークに対する強制アクセス制御を有効にする。 | ○
MAC_FOR_BINDPORT | ローカルのポート番号に対する強制アクセス制御を有効にする。これは MAC_FOR_NETWORK の機能限定版である。 | ○
MAC_FOR_CONNECTPORT | リモートのポート番号に対する強制アクセス制御を有効にする。これは MAC_FOR_NETWORK の機能限定版である。 | ○
MAC_FOR_SIGNAL | シグナルの送信に対する強制アクセス制御を有効にする。 | ○
DENY_CONCEAL_MOUNT | 既存のマウントを隠蔽するようなマウントを禁止する。 | ×
RESTRICT_CHROOT | chroot で移動可能なディレクトリの制限を有効にする。 | ○
RESTRICT_MOUNT | mount で指定可能なパラメータの制限を有効にする。 | ○
RESTRICT_UNMOUNT | 指定されたディレクトリのアンマウントを禁止する。 | ×
DENY_PIVOT_ROOT | pivot_root の呼び出しを禁止する。 | ×
RESTRICT_AUTOBIND | ローカルのポート番号を自動選択させる際に、特定のポート番号を選択させないようにする。 | ×
TRACE_READONLY | ファイルシステムが読み込み専用であることで失敗したファイル名を表示する。 | －
MAX_ACCEPT_FILES | 学習モードで自動的に追加されるアクセス許可の上限を指定する。 | －
MAX_GRANT_LOG | アクセスが許可されたログの上限を指定する。 | －
MAX_REJECT_LOG | アクセスが拒否されたログの上限を指定する。 | －
TOMOYO_VERBOSE | ドメイン別ポリシーに対する違反を syslog に表示する。 | －
ALLOW_ENFORCE_GRACE | ポリシーに違反するアクセス要求を対話的に許可する。 | －

TRACE_READONLY および RESTRICT_AUTOBIND については以下の値を指定できる。

値 | 内容
0 | 無効。通常のカーネルと同様に動作する。
1 | 有効。

MAX_ACCEPT_FILES については以下の値を指定できる。

値 | 内容
任意の整数 | 学習モードで自動的に追加されるアクセス許可の上限。デフォルトはデフォルトはカーネルのコンパイル時に指定。

MAX_GRANT_LOG および MAX_REJECT_LOG については以下の値を指定できる。

値 | 内容
任意の整数 | カーネル内に保持するアクセスログの上限。デフォルトはカーネルのコンパイル時に指定。

TOMOYO_VERBOSE については以下の値を指定できる。

値 | 内容
0 | ドメイン別ポリシーに対する違反を表示しない。
1 | ドメイン別ポリシーに対する違反を表示する。

ALLOW_ENFORCE_GRACE については以下の値を指定できる。

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

上記以外については以下の値を指定できる。

値 | 内容
0 | 無効。通常のカーネルと同様に動作する。
1 | 学習モード。ポリシーに違反してもエラーにせず、ポリシーへの自動追加を行う。
2 | 確認モード。ポリシーに違反してもエラーにせず、ポリシーへの自動追加も行わない。
3 | 強制モード。ポリシーに違反したらエラーとする。

有効にしたい機能とそのモードを「プロファイル番号-項目=値」という形式で定義する。 プロファイル番号は 0 ～ 255 が指定可能である。プロファイルを切り替えるには setprofile コマンドを使用する。また、現在割り当てられているプロファイル番号は ドメイン別ポリシー（domain_policy.txt） の中に use_profile というキーワードで保持される。

## 2.3 システムポリシー（system_policy.txt）

このファイルでは、システム全体に対して適用されるアクセス許可を定義する。以下の 4 種類のアクセス許可を指定できる。

- マウントを許可するデバイスおよびマウントポイント
- アンマウントを許可しないマウントポイント
- chroot で移動できるディレクトリ
- ローカルポート番号の自動選択時に選択させないポート

### マウントを許可するデバイスおよびマウントポイント

マウント許可を指定するには、 allow_mount というディレクティブに続けて、「デバイスファイル マウントポイント ファイルシステム オプション」を指定する。 デバイスファイルを必要とするファイルシステムを指定する場合は、デバイスファイルは正規化されたファイル名でなければいけない。マウントポイントは正規化されたディレクトリ名でなければいけない。オプションは dev,nodev,exec,noexec,suid,nosuid,rw,ro,atime,noatime,diratime,nodiratime,recurse,norecurse の組み合わせである。指定されたオプションはマウント時の指定に優先する。 例えば、 rw が指定されていた場合、ユーザが ro を指定したとしても、カーネルは rw が指定されたものとしてマウントする。オプションは省略可能である。

「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 マウントポイント」が許可される。
オプションは recurse または norecurse のどちらかである。指定されたオプションはマウント時の指定に優先する。 例えば、 recurse が指定されていた場合、ユーザが norecurse を指定したとしても、カーネルは recurse が指定されたものとしてマウントする。オプションは省略可能である。

### アンマウントを許可しないマウントポイント

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

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

### chroot で移動できるディレクトリ

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

### ローカルポート番号の自動選択時に選択させないポート

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

### ポリシー例

allow_mount | none | /dev/pts/ | devpts
allow_mount | /proc | /proc/ | proc
allow_mount | usbdevfs | /proc/bus/usb/ | usbdevfs
allow_mount | none | /data/ | tmpfs nosuid,nodev,noexec
allow_mount | none | /dev/shm/ | tmpfs nosuid,nodev,noexec
allow_mount | /dev/hdc | /var/www/ | ext2 ro,nosuid,nodev,noexec
allow_mount | any | / | --remount
deny_unmount | /dev/
deny_unmount | /dev/pts/
deny_unmount | /proc/
allow_chroot | /var/empty/sshd/
allow_chroot | /usr/share/empty/
allow_chroot | /var/www/html/
allow_chroot | /
deny_autobind | 1-1023
deny_autobind | 8080

## 2.4 ドメイン別ポリシー（domain_policy.txt）

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

- ファイルに対するアクセス許可
- 指定可能な argv[0] の組み合わせ
- 使用可能なケイパビリティ
- 使用可能なネットワークアドレスとポート
- 使用可能なローカルポート番号
- 使用可能なリモートポート番号
- 使用可能なシグナル

それぞれのアクセス許可について、必要に応じて追加の条件を指定することができる。そのための構文は後述する。

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

### ファイルに対するアクセス許可

ファイルに対するアクセス許可としては、以下のディレクティブが存在する。

ディレクティブ | 許可されるアクセス | 指定例
1 | プログラムの実行 | 1 /bin/ls
2 | ファイルの書き込み | 2 /dev/null
3 | ファイルの書き込みと実行 |
4 | ファイルの読み込み | 4 /proc/meminfo
5 | ファイルの読み込みと実行 |
6 | ファイルの読み書き | 6 /dev/null
7 | ファイルの読み書きと実行 |
allow_create | ファイルの新規作成 | allow_create /var/lock/subsys/crond
allow_unlink | ファイルの削除 | allow_unlink /var/lock/subsys/crond
allow_mkdir | ディレクトリの作成 | allow_mkdir /tmp/logwatch.\*/
allow_rmdir | ディレクトリの削除 | allow_rmdir /tmp/logwatch.\*/
allow_mkfifo | FIFO の作成 | allow_mkfifo /dev/initctl
allow_mksock | UNIX ドメインソケットの作成 | allow_mksock /dev/log
allow_mkblock | ブロック型デバイスファイルの作成 | allow_mkblock /dev/\*
allow_mkchar | キャラクタ型デバイスファイルの作成 | allow_mkchar /dev/\*
allow_truncate | ファイルの切り詰めと伸長 | allow_truncate /etc/mtab
allow_symlink | シンボリックリンクの作成 | allow_symlink /dev/cdrom
allow_link | ハードリンクの作成 | allow_link /etc/mtab~\$ /etc/mtab~
allow_rename | ファイル名の変更 | allow_rename /etc/mtab.tmp /etc/mtab
allow_rewrite | ファイル内容の上書き | allow_rewrite /var/log/messages

1 3 5 7 以外のディレクティブではワイルドカードを使用できる。なお、ディレクティブ 3 5 7 の指定は極力避けるべきである。

なお、マッピング定義を使って、 allow_ で始まるディレクティブを 2 3 6 7 のいずれかに対するアクセス許可で代用することも可能である。

### 指定可能な argv[0] の組み合わせ

argv[0] の組み合わせを制限するには、 allow_argv0 というディレクティブに続けて、「シンボリックリンクを解決する前の / から始まるパス名」と「argv[0] の最後の / より後ろの部分」を指定する。

プログラムを実行する関数である execve() には filename と argv[] と envp[] を渡せるが、たまに argv[0] の内容によって振る舞いを変化させるプログラムが存在する。 busybox はその一例である。 TOMOYO Linux のドメイン遷移は filename の内容に基づいて行われている。たいていの場合、 filename と argv[0] は同じ内容なので問題無いが、バイナリラッパのように意図的に filename と argv[0] で異なる内容を指定する場合がある。例えば、 filename に /sbin/busybox へのシンボリックリンクである /bin/ls を、 argv[0] に /sbin/busybox へのシンボリックリンクである /bin/cat を指定した場合、 /bin/ls のドメインで /bin/cat として振る舞うというちぐはぐな状況が発生する。攻撃者が意図的に filename と argv[0] で異なる内容を指定できれば、穴になってしまうわけである。このディレクティブの目的は、 filename と argv[0] の内容の組み合わせを制限することでそのような状況が発生しないようにすることである。

### 使用可能なケイパビリティ

ケイパビリティのアクセス許可を指定するには、 allow_capability というディレクティブに続けて、ケイパビリティを指定する。以下のケイパビリティが指定できる。

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

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

- 作成を許可するキャラクタ型デバイスファイルのパス名を allow_mkblock ディレクティブを使用して制限することができる。
- 作成を許可するブロック型デバイスファイルのパス名を allow_mkchar ディレクティブを使用して制限することができる。
- 作成を許可する FIFO のパス名を allow_mkfifo ディレクティブを使用して制限することができる。
- 作成を許可する UNIX ドメインソケットのパス名を allow_mksock ディレクティブを使用して制限することができる。
- 作成を許可するシンボリックリンクのパス名を allow_symlink ディレクティブを使用して制限することができる。
- 削除を許可するパス名を allow_unlink ディレクティブを使用して制限することができる。
- ハードリンクを許可する組み合わせを allow_link ディレクティブを使用して制限することができる。
- パス名の変更を許可する組み合わせを allow_rename ディレクティブを使用して制限することができる。
- 使用を許可する IP アドレスの範囲ととポート番号の範囲を allow_network ディレクティブを使用して制限することができる。
- TCP または UDP でバインド可能なローカルポートの範囲を allow_bind ディレクティブを使用して制限することができる。
- TCP または UDP で接続可能なリモートポートの範囲を allow_connect ディレクティブを使用して制限することができる。
- 送信可能なシグナルの番号と送信先のドメインを allow_signal ディレクティブを使用して制限することができる。
- マウントを許可するデバイスおよびマウントポイントを allow_mount ディレクティブを使用して制限することができる。
- アンマウントを許可しないマウントポイントを deny_unmount ディレクティブを使用して指定することができる。
- chroot で移動できるディレクトリを allow_chroot ディレクティブを使用して制限することができる。

### 使用可能なネットワークアドレスとポート

ネットワークのアクセス許可を指定するには、 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" のように表記する必要がある。

msg_name == NULL での recvmsg() および read() の場合はパーミッションのチェックは行われない。

### 使用可能なローカルポート番号

ローカルポート番号のアクセス許可を指定するには、 allow_bind というディレクティブに続けて、プロトコル（TCP または UDP）とポート番号を指定する。 IPv4 プロトコルおよび IPv6 プロトコルで使用するローカルポート番号が対象である。
ポートの自動選択を指定するには、 allow_bind TCP/0 または allow_bind UDP/0 と指定する。ただし、bind() をせずに connect() 等を行った場合はこの制限を受けない。
全てのポート番号（1 ～ 65535）を指定するには、 allow_bind TCP/1-65535 または allow_bind UDP/1-65535 と指定する。

### 使用可能なリモートポート番号

リモートポート番号のアクセス許可を指定するには、 allow_connect というディレクティブに続けて、プロトコル（TCP または UDP）とポート番号を指定する。 IPv4 プロトコルおよび IPv6 プロトコルで使用するリモートポート番号が対象である。
全てのポート番号（1 ～ 65535）を指定するには、 allow_connect TCP/1-65535 または allow_connect UDP/1-65535 と指定する。

### 使用可能なシグナル

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

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

アクセス許可にユーザＩＤ等に基づいた条件を付加することができる。条件は個々のアクセス許可の末尾に if というディレクティブを用いて指定する。

指定例 | 意味
4 /etc/passwd | /etc/passwd の参照を許可
4 /etc/passwd if task.uid=0 | プロセスのユーザIDが0の場合に限り、/etc/passwd の参照を許可
4 /etc/passwd if task.uid!=0 | プロセスのユーザIDが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 | プロセスのユーザIDが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 の子であり、かつ、プロセスのユーザIDと実効ユーザIDが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 はパス名を必要とする操作の１個目のパス名に対応し、 path2 はパス名を必要とする操作の２個目のパス名に対応する。 例えば、「allow_rename ファイル１ ファイル２」というアクセス許可の場合、 path1 がファイル１に、 path2 がファイル２に対応する。

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

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

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

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

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

## 2.5 例外ポリシー（exception_policy.txt）

このファイルでは、ドメイン単位でのアクセス制御の例外を定義する。以下の 7 種類のアクセス例外を指定できる。

- パス名のパターン
- 無条件に読み込みを許可するファイル
- 書き換えを禁止するファイル
- ドメイン遷移を初期化するプログラム
- シンボリックリンクの名前で実行するプログラム
- 集約するプログラム
- 信頼済みドメイン

### パス名のパターン

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

値 | 意味
\\ | \ 自身
\* | / 以外の0文字以上
\@ | / と . 以外の0文字以上
\? | / 以外の1文字
\$ | 1桁以上の10進数
\+ | 10進数1桁
\X | 1桁以上の16進数
\x | 16進数1桁
\A | 1文字以上のアルファベット
\a | アルファベット1文字

### 無条件に読み込みを許可するファイル

無条件に読み込みを許可するファイルを指定するには、 allow_read というディレクティブに続けて、正規化されたファイル名を指定する。このディレクティブの目的は、 GLIBC がプログラム実行時に参照するファイルやエラーメッセージを表示する際に参照するファイルを指定することで、ドメイン別ポリシーの記述量を減らすことである。ＤＡＣで許可されれば全てのプロセスが読み込めるので、くれぐれも /etc/passwd のようなファイルを指定しないこと。

### 書き換えを禁止するファイル

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

### ドメイン遷移を初期化するプログラム

ドメイン遷移を初期化するプログラムを指定するには、 initializer というディレクティブに続けて、プログラム名を指定する。このディレクティブの目的は、常駐型プログラムや必要に応じてカーネルから起動されるプログラムを、通常とは異なるドメインに遷移させることで、ドメイン遷移を集約することである。

### シンボリックリンクの名前で実行するプログラム

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

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

### 集約するプログラム

複数のプログラムを単一のプログラム名で扱うには、 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 のドメインで実行することができるようになる。

### 信頼済みドメイン

信頼済みドメインを指定するには、 trust_domain というディレクティブに続けて、ドメイン名を指定する。このディレクティブの目的は、強制アクセス制御を受けないドメインの範囲を定義することで、ソフトウェアの更新のように事前に必要なポリシーを知ることができない操作を行えるようにすることである。
ドメイン名がこのディレクティブで指定されたドメイン名で始まる場合には、このドメインは”信頼済み”であるとマークされる。”信頼済み”であるとマークされたドメインに属するプロセスに対しては、ドメイン単位のアクセス制限が適用されない。
例えば、 <kernel> /usr/sbin/sshd /bin/tcsh という行が含まれている場合、 <kernel> /usr/sbin/sshd /bin/tcsh というドメインと、その子孫ドメイン（ <kernel> /usr/sbin/sshd /bin/tcsh /bin/cat 等）は”信頼済み”であるとマークされる。
なお、 <kernel> とだけ書かれた行が含まれていた場合、全てのドメインが”信頼済み”であるとマークされてしまう。

## 2.6 マッピング定義（mapping.txt）

このファイルでは、ファイルに対する書き込みアクセス許可のチェック方法を定義する。 どれくらい厳密にファイルに対する書き込みアクセス許可を制御したいかに応じて、書き込みアクセス許可の粒度をこのファイルを使用して切り替えられるようになっている。

このファイルの書式は、「チェック項目=チェック方法」を列挙した形式である。以下に例を示す。

create=generic-write unlink=generic-write mkdir=mkdir rmdir=rmdir mkfifo=mkfifo mksock=mksock mkblock=mkblock mkchar=mkchar truncate=generic-write symlink=symlink link=link rename=rename rewrite=rewrite

チェック方法として generic-write を指定した場合、そのチェック項目は、ディレクティブ 2 3 6 7 で与えられているアクセス許可でチェックされる。 チェック方法として no-check を指定した場合、そのチェック項目はチェックされなくなる。 チェック方法としてチェック項目と同じ値を指定した場合、そのチェック項目はそのディレクティブで与えられているアクセス許可でチェックされる。

このファイルは起動時に１度だけ読み込まれ、起動後に変更することはできない。

# 3. /proc/ccs/ インタフェース

これは、起動後にポリシーを読み出し／追加／削除を行うためのインタフェースである。ポリシーマネージャ定義で定義されたプログラムのみがポリシーの追加と削除を行える。

## 3.1 status

現在の制御レベルを取得または変更する。

（例）
cat /proc/ccs/status
echo 'MAC_FOR_FILE=1' > /proc/ccs/status

## 3.2 policy/system_policy

現在のシステムポリシーを読み出しまたは追加または削除する。

（例）
echo 'allow_mount /proc /proc/ proc' > /proc/ccs/policy/system_policy
echo 'delete allow_mount /proc /proc/ proc' > /proc/ccs/policy/system_policy
cat /proc/ccs/policy/system_policy

## 3.3 policy/domain_policy

現在のドメイン別ポリシーを読み出しまたは追加または削除する。

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成される）
printf "<kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/policy/domain_policy

（例）ドメインを選択してアクセス許可を追加（ドメインが存在しない場合は作成されない）
printf "select <kernel> /sbin/init\n4 /etc/passwd\n" > /proc/ccs/policy/domain_policy

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

（例）特定のドメインを削除
printf "delete <kernel> /sbin/init\n" > /proc/ccs/policy/domain_policy

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

## 3.4 policy/exception_policy

現在の例外ポリシーを読み出しまたは追加または削除する。

（例）
echo 'file_pattern /proc/\$/status' > /proc/ccs/policy/exception_policy
echo 'delete file_pattern /proc/\$/status' > /proc/ccs/policy/exception_policy
cat /proc/ccs/policy/exception_policy

## 3.5 policy/query

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

## 3.6 policy/manager

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

## 3.7 policy/.domain_status

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

## 3.8 info/trusted_pids

”信頼済み”であるとマークされたドメインに属しているプロセスのＰＩＤを一覧表示する。 メンテナンスの終了時などに、”信頼済み”であるとマークされたドメインに属しているプロセスが残っていないかどうかを確認するために使用する。 なお、”信頼済み”であるとマークされたドメインに属しているプロセスが多すぎる場合、一部のプロセスのＰＩＤは表示されない。

（例）
cat /proc/ccs/info/trusted_pids

## 3.9 info/meminfo

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

（例）
cat /proc/ccs/info/meminfo

## 3.10 info/grant_log

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

（例）
cat /proc/ccs/info/grant_log

## 3.11 info/reject_log

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

（例）
cat /proc/ccs/info/reject_log

## 3.12 info/self_domain

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

（例）
cat /proc/ccs/info/self_domain

## 3.13 info/mapping

MAC_FOR_FILE における書き込みアクセス許可のチェック方法を取得する。

（例）
cat /proc/ccs/info/mapping

## 3.14 info/.process_status

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

## 3.15 info/.updates_counter

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

目次へ戻る