TOMOYO Linux ポリシー解説書

Last modified: $Date: 2006-11-25 10:18:46 +0900 (Sat, 25 Nov 2006) $

目次

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 と表記する。)
正規化されたディレクトリ名 正規化されたパス名の内、"/"で終わるもの。
正規化されたファイル名 正規化されたパス名の内、"/"で終わらないもの。
正規化されたファイル名は、ディレクトリ以外の全てのファイルタイプ(通常ファイル、キャラクタ型デバイスファイル、ブロック型デバイスファイル、FIFO、シンボリックリンク、ソケット)を含む。
プログラム 正規化されたファイル名の内、実行可能なもの。
ドメイン MAC(強制アクセス制御)を行うための属性
遷移先ドメイン プログラムが正常に開始された場合にプロセスが遷移するドメイン
操作対象ドメイン 操作対象となるプロセスの属しているドメイン

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内容
プログラム名の取得

実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補1」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決したパス名を取得する。

実行しようとするプログラムの「正規化されたファイル名」を取得して「パス名候補2」とする。ただし、実行しようとするプログラムがシンボリックリンクの場合は、シンボリックリンクを解決する前のパス名を取得する。

シンボリックリンクの識別

「パス名候補1」と「パス名候補2」が一致しない場合、「パス名候補1」と「パス名候補2」の組み合わせが例外ポリシーの alias ディレクティブで指定されているパス名の組み合わせに一致するかどうかを調べる。一致する場合は「パス名候補2」を「パス名候補1」とする。

類似するプログラムの集約

「パス名候補1」が例外ポリシーの aggregator ディレクティブで指定されているパス名のパターンに一致するかどうかを調べる。 一致する場合は、 aggregator ディレクティブで指定されているパス名を「パス名候補1」とする。

argv[0] のチェック

「パス名候補2」の最後の / 以降の部分と argv[0] の最後の / 以降の部分が異なっている場合、「パス名候補2」と「argv[0]の最後の / 以降の部分」の組み合わせが allow_argv0 ディレクティブにより許可されてる事を確認する。

権限のチェック

現在のプロセスが属しているドメインが、「パス名候補1」の実行を許可している事を確認する。

遷移先の決定

「パス名候補1」が例外ポリシーの initializer ディレクティブで指定されているパス名に一致するかどうかを調べる。 一致する場合は「カーネルが属しているドメインのドメイン名(<kernel>)」と「パス名候補1」とを連結して「遷移先ドメイン」とし、「遷移先ドメイン」が定義されている事を確認する。

一致しない場合は、「現在のプロセスが属しているドメインのドメイン名」が例外ポリシーの trust_domain ディレクティブで指定されているドメイン名で始まっているかどうかを調べる。そうである場合は、「現在のプロセスが属しているドメインのドメイン名」を「遷移先ドメイン」とする。

そうではない場合は、「現在のプロセスが属しているドメインのドメイン名」と「パス名候補1」とを連結して「遷移先ドメイン」とし、「遷移先ドメイン」が定義されている事を確認する。

ドメイン遷移処理

通常のプログラム実行処理を行う。

通常のプログラム実行処理が正常に終了した場合は、「遷移先ドメイン」に遷移する。


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 種類のアクセス許可を指定できる。

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

マウント許可を指定するには、 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 種類のアクセス許可を指定できる。

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

ドメインを定義している行(<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_mkfifoFIFO の作成allow_mkfifo /dev/initctl
allow_mksockUNIX ドメインソケットの作成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_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" のように表記する必要がある。

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

ローカルポート番号のアクセス許可を指定するには、 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> を指定すると、全てのドメインに指定された番号のシグナルを送信できる。

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

アクセス許可にユーザID等に基づいた条件を付加することができる。条件は個々のアクセス許可の末尾に 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.1TCP プロトコルで 10.0.0.1 への接続を許可
allow_network TCP connect 10.0.0.1 if task.uid=100プロセスのユーザIDが100の場合に限り、TCP プロトコルで 10.0.0.1 への接続を許可
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 ファイル1 ファイル2」というアクセス許可の場合、 path1 がファイル1に、 path2 がファイル2に対応する。

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 ともにサポートしていない。

2.5 例外ポリシー(exception_policy.txt)

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

パス名のパターン

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

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

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

無条件に読み込みを許可するファイルを指定するには、 allow_read というディレクティブに続けて、正規化されたファイル名を指定する。このディレクティブの目的は、 GLIBC がプログラム実行時に参照するファイルやエラーメッセージを表示する際に参照するファイルを指定することで、ドメイン別ポリシーの記述量を減らすことである。DACで許可されれば全てのプロセスが読み込めるので、くれぐれも /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 を指定した場合、そのチェック項目はチェックされなくなる。 チェック方法としてチェック項目と同じ値を指定した場合、そのチェック項目はそのディレクティブで与えられているアクセス許可でチェックされる。

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


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 の内容からプロファイル番号とドメイン名の部分だけを抽出したもの。DBMSのビューに相当する機能を提供する。

3.8 info/trusted_pids

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

(例)
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 にリセットされる。ポリシーの更新を監視するプログラムのためのインタフェース。


目次へ戻る