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 で使われるもの

/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/manager および /etc/ccs/manager.conf で使われるもの

2. はじめに

2.1 単語の表記規則

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

下位 4 ビット
上位 4 ビット
0x00x10x20x30x40x50x60x70x80x90xA0xB0xC0xD0xE0xF
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!"#$%&'()*+,-./
0x30123456789:;<=>?
0x4@ABCDEFGHIJKLMNO
0x5PQRSTUVWXYZ[\\]^_
0x6`abcdefghijklmno
0x7pqrstuvwxyz{|}~\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

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

単語正しい表記誤った表記
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/プロセスID/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.\+
\X1 桁以上の 16 進数/var/tmp/my-work.\X
\x16 進数 1 桁/tmp/my-work.\x
\A1 文字以上のアルファベット/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/versionTOMOYO Linux のバージョン

3.2 変更について

カーネルとのインタフェースである /proc/ccs/ ディレクトリを経由してポリシーを変更することができるプログラム名を /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

デフォルトではユーザIDと実効ユーザIDの両方が 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) 通常のプログラム実行処理を行い、正常に終了した場合は「遷移先ドメイン」に遷移します。

ただし、例外として

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

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

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" であったということを示しています。また、プロセスIDやユーザIDなど、プロセスに関する情報も一緒に出力されます。

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

#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_createTCP ソケットの使用を許可
allow_capability inet_tcp_listenTCP ソケットの listen を許可
allow_capability inet_tcp_connectTCP ソケットの connect を許可
allow_capability use_inet_udpUDP ソケットの使用を許可
allow_capability use_inet_ipRAW ソケットの使用を許可
allow_capability use_routeROUTE ソケットの使用を許可
allow_capability use_packetPACKET ソケットの使用を許可
allow_capability use_kernel_modulecreate_module(2) init_module(2) delete_module(2) の使用を許可
allow_capability create_fifomknod(2) で FIFO の作成を許可
allow_capability create_block_devmknod(2) でブロック型デバイスの作成を許可
allow_capability create_char_devmknod(2) でキャラクタ型デバイスの作成を許可
allow_capability create_unix_socketmknod(2) で UNIX ドメインソケットの作成を許可
allow_capability SYS_MOUNTmount(2) の使用を許可
allow_capability SYS_UMOUNTumount(2) の使用を許可
allow_capability SYS_REBOOTreboot(2) の使用を許可
allow_capability SYS_CHROOTchroot(2) の使用を許可
allow_capability SYS_KILL0 以外のシグナルで kill(2) tkill(2) tgkill(2) の使用を許可
allow_capability SYS_VHANGUPvhangup(2) の使用を許可
allow_capability SYS_TIMEstime(2) settimeofday(2) adjtimex(2) の使用を許可
allow_capability SYS_NICEnice(2) setpriority(2) の使用を許可
allow_capability SYS_SETHOSTNAMEsethostname(2) setdomainname(2) の使用を許可
allow_capability SYS_LINKlink(2) の使用を許可
allow_capability SYS_SYMLINKsymlink(2) の使用を許可
allow_capability SYS_RENAMErename(2) の使用を許可
allow_capability SYS_UNLINKunlink(2) の使用を許可
allow_capability SYS_CHMODchmod(2) fchmod(2) の使用を許可
allow_capability SYS_CHOWNchown(2) fchown(2) lchown(2) の使用を許可
allow_capability SYS_IOCTLioctl(2) compat_sys_ioctl(2) の使用を許可
allow_capability SYS_KEXEC_LOADkexec_load(2) の使用を許可
allow_capability SYS_PIVOT_ROOTpivot_root(2) の使用を許可
allow_capability SYS_PTRACEptrace(2) の使用を許可

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

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" のように表記する必要があります。

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

関連項目: 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 というキーワードに続けて、パス名のパターンを指定します。パス名は正規化されたパス名でなければなりません。このキーワードは実行許可を与える場合とドメイン定義には適用されません。
例えば、プロセスIDを含む正規化されたパス名( /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 というキーワードを使用します。

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

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

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

no_initialize_domain

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

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

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

keep_domain

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

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

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

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

no_keep_domain

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

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

/proc/ccs/.domain_status

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

/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 以外のユーザによるポリシーの変更を許可

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

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

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

# 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 条件付きアクセス許可の指定

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

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

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

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

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=filepath1 は通常のファイルである
path1.type=directorypath1 はディレクトリである
path1.type=fifopath1 is a は FIFO である
path1.type=socketpath1 はソケットである
path1.type=symlinkpath1 はシンボリックリンクである
path1.type=blockpath1 はブロックデバイスファイルである
path1.type=charpath1 はキャラクタデバイスファイルである
path1.type!=filepath1 は通常のファイルではない
path1.type!=directorypath1 はディレクトリではない
path1.type!=fifopath1 は FIFO ではない
path1.type!=socketpath1 はソケットではない
path1.type!=symlinkpath1 はシンボリックリンクではない
path1.type!=blockpath1 はブロックデバイスファイルではない
path1.type!=charpath1 はキャラクタデバイスファイルではない

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

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

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

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

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

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

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

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

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

DAC のパーミッション指定

条件意味
path1.perm=数値1-数値2path1 のパーミッションが「数値1~数値2」である
path1.perm!=数値1-数値2path1 のパーミッションが「数値1~数値2」ではない
path1.perm=setuidpath1 に関して setuid ビットが on である
path1.perm!=setuidpath1 に関して setuid ビットが off である
path1.perm=setgidpath1 に関して setgid ビットが on である
path1.perm!=setgidpath1 に関して setgid ビットが off である
path1.perm=stickypath1 に関して sticky ビットが on である
path1.perm!=stickypath1 に関して sticky ビットが off である
path1.perm=owner_readpath1 に関して owner に対する read ビットが on である
path1.perm!=owner_readpath1 に関して owner に対する read ビットが off である
path1.perm=owner_writepath1 に関して owner に対する write ビットが on である
path1.perm!=owner_writepath1 に関して owner に対する write ビットが off である
path1.perm=owner_executepath1 に関して owner に対する execute ビットが on である
path1.perm!=owner_executepath1 に関して owner に対する execute ビットが off である
path1.perm=group_readpath1 に関して group に対する read ビットが on である
path1.perm!=group_readpath1 に関して group に対する read ビットが off である
path1.perm=group_writepath1 に関して group に対する write ビットが on である
path1.perm!=group_writepath1 に関して group に対する write ビットが off である
path1.perm=group_executepath1 に関して group に対する execute ビットが on である
path1.perm!=group_executepath1 に関して group に対する execute ビットが off である
path1.perm=others_readpath1 に関して others に対する read ビットが on である
path1.perm!=others_readpath1 に関して others に対する read ビットが off である
path1.perm=others_writepath1 に関して others に対する write ビットが on である
path1.perm!=others_writepath1 に関して others に対する write ビットが off である
path1.perm=others_executepath1 に関して others に対する execute ビットが on である
path1.perm!=others_executepath1 に関して others に対する execute ビットが off である

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

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

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

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

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

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

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

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

変数意味
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]=1state[0] が 1 の場合は、 /bin/bash の実行を許可します。
allow_execute /sbin/nologin if task.state[0]=0state[0] が 0 の場合は、 /sbin/nologin の実行を許可します。
allow_execute /etc/passwd if task.state[2]=0 ; set task.state[2]=1state[2] が 0 の場合は /etc/passwd の読み込みモードでのオープンを許可し、その後 state[2] に 1 を設定します。

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

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

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

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

この機能は、無限ループの中でポリシー違反が発生した場合に、CPU使用率が 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 に於いては、プログラムを実行するという動作は、プログラムの実行を要求したプロセスを上書きするという動作であり、プログラムの実行に成功した場合にはプログラムの実行を要求したプロセスに制御が戻ることはありません。つまり、要求されたプログラムの実行に失敗した場合にしか、プログラムの実行を要求したプロセスに対して、要求されたプログラムが実行されなかったことが通知されません。
例えば、プログラムAとして動作しているプロセスがプログラムBの実行を要求する場合を考えてみます。
プログラムAとして動作しているプロセスがプログラムBの実行を要求すると、カーネルが「プログラムAとして動作しているプロセスからプログラムBを実行することは適切であるかどうか」をポリシーを照合することで判断し、適切であると判断された場合には「プログラムAとして動作しているプロセスをプログラムBで上書き」し、適切では無いと判断された場合には「プログラムAとして動作しているプロセスにプログラムBの実行が認められていないことを通知」します。

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

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

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 のログと比較してみてください。

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

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. 」のような警告を表示することができます。

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

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

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

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


目次へ戻る

sflogo.php