other versions
CAPABILITIES(7) | Linux Programmer's Manual | CAPABILITIES(7) |
名前¶
capabilities - Linux のケーパビリティ (capability) の概要説明¶
権限のチェックを行う観点から見ると、伝統的な UNIX の実装では プロセスは二つのカテゴリに分類できる: 特権 プロセス (実効ユーザID が 0 のプロセス。ユーザID 0 は スーパーユーザや root と呼ばれる) と 非特権 プロセス (実効ユーザID が 0 以外のプロセス) である。 非特権プロセスでは、プロセスの資格情報 (通常は、実効UID 、実効GID と追加のグループリスト) に基づく権限チェックが行われるのに対し、 特権プロセスでは全てのカーネルの権限チェックがバイパスされる。ケーパビリティのリスト¶
以下のリストは、 Linux で実装されているケーパビリティと 各ケーパビリティが許可する操作と動作をまとめたものである。- CAP_AUDIT_CONTROL (Linux 2.6.11 以降)
- カーネル監査 (audit) の有効無効の切り替え、 監査のフィルタルールの変更、 監査の状況やフィルタルールの取得ができる。
- CAP_AUDIT_WRITE (Linux 2.6.11 以降)
- カーネル監査のログにレコードを書き込む。
- CAP_CHOWN
- ファイルの UID とGID を任意に変更する ( chown(2) 参照)。
- CAP_DAC_OVERRIDE
- ファイルの読み出し、書き込み、実行の権限チェックをバイパスする (DAC は "discretionary access control (任意のアクセス制御)" の略である)。
- CAP_DAC_READ_SEARCH
- ファイルの読み出し権限のチェックとディレクトリの読み出しと実行 の権限チェックをバイパスする。
- CAP_FOWNER
- *
- 通常、プロセスのファイルシステム UID がファイルの UID に一致することが 要求される操作 (例えば chmod(2), utime(2)) における権限チェックをバイパスする。 但し、 CAP_DAC_OVERRIDE か CAP_DAC_READ_SEARCH によりチェックが行われる操作は除く。
- *
- 任意のファイルに対して拡張ファイル属性を設定する ( chattr(1) 参照)。
- *
- 任意のファイルに対してアクセス制御リスト (ACL) を設定する。
- *
- ファイルの削除の際にディレクトリのスティッキービットを無視する。
- CAP_FSETID
- ファイルが変更されたときに set-user-ID とset-group-ID の許可ビットをクリア しない。呼び出し元プロセスのファイルシステム GID と追加の GID のいずれとも GID が一致しないファイルに対して set-group-ID ビットを設定する。
- CAP_IPC_LOCK
- メモリーのロック ( mlock(2), mlockall(2), mmap(2), shmctl(2)) を行う。
- CAP_IPC_OWNER
- System V IPC オブジェクトに対する操作に関して権限チェックをバイパスする。
- CAP_LEASE (Linux 2.4 以降)
- 任意のファイルに対して ファイルリースを設定する ( fcntl(2) 参照)。
- CAP_LINUX_IMMUTABLE
- 拡張ファイル属性 FS_APPEND_FL と FS_IMMUTABLE_FL を設定する ( chattr(1) 参照)。
- CAP_MAC_ADMIN (Linux 2.6.25 以降)
- 強制アクセス制御 (MAC) を上書きする。 Smack Linux Security Module (LSM) 用に実装されている。
- CAP_MAC_OVERRIDE (Linux 2.6.25 以降)
- MAC の設定や状態を変更する。 Smack LSM 用に実装されている。
- CAP_MKNOD (Linux 2.4 以降)
- (Linux 2.4 以降) mknod(2) を使用してスペシャルファイルを作成する。
- CAP_NET_ADMIN
- 各種のネットワーク関係の操作を実行する:
- *
- インターフェースの設定
- *
- IP のファイアウォール、マスカレード、アカウンティング
- *
- ルーティングテーブルの変更
- *
- 透過的プロキシでの任意のアドレスの割り当て (bind)
- *
- サービス種別 (type-of-service; TOS) のセット
- *
- ドライバの統計情報のクリア
- *
- promiscuous モードをセットする
- *
- マルチキャストを有効にする
- *
- setsockopt(2) を使って以下のソケットオプションを設定する: SO_DEBUG, SO_MARK, SO_PRIORITY (優先度を 0 から 6 以外に設定する場合), SO_RCVBUFFORCE, and SO_SNDBUFFORCE
- CAP_NET_BIND_SERVICE
- インターネットドメインの特権ポート (ポート番号が 1024 番未満) をバインドできる。
- CAP_NET_BROADCAST
- (未使用) ソケットのブロードキャストと、マルチキャストの待ち受けを行う。
- CAP_NET_RAW
- *
- RAW ソケットと PACKET ソケットを使用する。
- *
- 透過的プロキシでの任意のアドレスの割り当て (bind)
- CAP_SETGID
- プロセスの GID と追加の GID リストに対する任意の操作を行う。 UNIX ドメインソケット経由でソケットの資格情報 (credential) を渡す際に 偽の GID を渡すことができる。
- CAP_SETFCAP (Linux 2.6.24 以降)
- ファイルケーパビリティを設定する。
- CAP_SETPCAP
- ファイルケーパビリティがサポートされていない場合:
呼び出し元が許可されているケーパビリティセットに含まれる任意のケーパビリティを、
他のプロセスに付与したり、削除したりできる。
(カーネルがファイルケーパビリティをサポートしている場合、
CAP_SETPCAP
はこの役割を持たない。
なぜなら、ファイルケーパビリティをサポートしているカーネルでは
CAP_SETPCAP
は全く別の意味を持つからである。)
- CAP_SETUID
- プロセスの UID に対する任意の操作 ( setuid(2), setreuid(2), setresuid(2), setfsuid(2)) を行う。 UNIX ドメインソケット経由でソケットの資格情報 (credential) を渡す際に 偽の UID を渡すことができる。
- CAP_SYS_ADMIN
- *
- 以下のシステム管理用の操作を実行する: quotactl(2), mount(2), umount(2), swapon(2), swapoff(2), sethostname(2), setdomainname(2).
- *
- 特権が必要な syslog(2) の操作を実行する (Linux 2.6.37 以降では、このような操作を許可するには CAP_SYSLOG を使うべきである)
- *
- VM86_REQUEST_IRQ vm86(2) コマンドを実行する。
- *
- 任意の System V IPC オブジェクトに対する IPC_SET と IPC_RMID 操作を実行する。
- *
- 拡張属性 trusted と security に対する操作を実行する ( attr(5) 参照)。
- *
- lookup_dcookie(2) を呼び出す。
- *
- ioprio_set(2) を使って I/O スケジューリングクラス IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE を割り当てる ( IOPRIO_CLASS_IDLE は Linux 2.6.25 より前のバージョンのみ)。
- *
- ソケットの資格情報 (credential) を渡す際に偽の UID を渡す。
- *
- ファイルをオープンするシステムコール (例えば accept(2), execve(2), open(2), pipe(2)) でシステム全体でオープンできるファイル数の上限 /proc/sys/fs/file-max を超過する。
- *
- clone(2) と unshare(2) で新しい名前空間を作成する CLONE_* フラグを利用する。
- *
- perf_event_open(2) を呼び出す。
- *
- 特権が必要な perf イベントの情報にアクセスする。
- *
- setns(2) を呼び出す。
- *
- fanotify_init(2) を呼び出す。
- *
- keyctl(2) の KEYCTL_CHOWN と KEYCTL_SETPERM 操作を実行する。
- *
- madvise(2) の MADV_HWPOISON 操作を実行する。
- *
- TIOCSTI ioctl(2) を使って、 呼び出し元の制御端末以外の端末の入力キューに文字を挿入する。
- *
- 廃止予定の nfsservctl(2) システムコールを使用する。
- *
- 廃止予定の bdflush(2) システムコールを使用する。
- *
- 特権が必要なブロックデバイスに対する各種の ioctl(2) 操作を 実行する。
- *
- 特権が必要なファイルシステムに対する各種の ioctl(2) 操作を 実行する。
- *
- 多くのデバイスドライバに対する管理命令を実行する。
- CAP_SYS_BOOT
- reboot(2) と kexec_load(2) を呼び出す。
- CAP_SYS_CHROOT
- chroot(2). を呼び出す。
- CAP_SYS_MODULE
- カーネルモジュールのロード、アンロードを行う ( init_module(2) と delete_module(2) を参照のこと)。 バージョン 2.6.25 より前のカーネルで、 システム全体のケーパビリティバウンディングセット (capability bounding set) からケーパビリティを外す。
- CAP_SYS_NICE
- *
- プロセスの nice 値の引き上げ ( nice(2), setpriority(2)) や、任意のプロセスの nice 値の変更を行う。
- *
- 呼び出し元プロセスに対するリアルタイムスケジューリングポリシーと、 任意のプロセスに対するスケジューリングポリシーと優先度を設定する ( sched_setscheduler(2), sched_setparam(2))。
- *
- 任意のプロセスに対する CPU affinity を設定できる ( sched_setaffinity(2))。
- *
- 任意のプロセスに対して I/O スケジューリングクラスと優先度を設定できる ( ioprio_set(2))。
- *
- migrate_pages(2) を任意のプロセスに適用し、プロセスを任意のノードに移動する。
- *
- move_pages(2) を任意のプロセスに対して行う。
- *
- mbind(2) と move_pages(2) で MPOL_MF_MOVE_ALL フラグを使用する。
- CAP_SYS_PACCT
- acct(2) を呼び出す。
- CAP_SYS_PTRACE
- ptrace(2) を使って任意のプロセスをトレースする。 任意のプロセスに get_robust_list(2) を適用する。
- CAP_SYS_RESOURCE
- *
- ext2 ファイルシステム上の予約されている領域を使用する。
- *
- ext3 のジャーナル機能を制御する ioctl(2) を使用する。
- *
- ディスク quota の上限を上書きする。
- *
- リソース上限を増やす ( setrlimit(2))。
- *
- RLIMIT_NPROC リソース制限を上書きする。
- *
- コンソール割り当てにおいてコンソールの最大数を上書きする。
- *
- キーマップの最大数を上書きする。
- *
- リアルタイムクロックから秒間 64 回を越える回数の割り当てが許可する。
- *
- メッセージキューに関する上限 msg_qbytes を /proc/sys/kernel/msgmnb に指定されている上限よりも大きく設定する ( msgop(2) と msgctl(2) 参照)。
- *
- F_SETPIPE_SZ fcntl(2) を使ってパイプの容量を設定する際に 上限 /proc/sys/fs/pipe-size-max を上書きする。
- *
- /proc/sys/fs/pipe-max-size に指定されている上限を超えてパイプの容量 を増やすのに F_SETPIPE_SZ を使用する。
- *
- POSIX メッセージキューを作成する際に、 上限 /proc/sys/fs/mqueue/queues_max を上書きする ( mq_overview(7) 参照)。
- *
- prctl(2) の PR_SET_MM 操作を使用する。
- CAP_SYS_TIME
- システムクロックを変更する ( settimeofday(2), stime(2), adjtimex(2))。 リアルタイム (ハードウェア) クロックを変更する。
- CAP_SYS_TTY_CONFIG
- vhangup(2) を使用する。 特権が必要な仮想端末に関する各種の ioctl(2) 操作を利用できる。
- CAP_WAKE_ALARM (Linux 3.0 以降)
- システムを起こすトリガーを有効にする (タイマー CLOCK_REALTIME_ALARM や CLOCK_BOOTTIME_ALARM を設定する)。
過去と現在の実装¶
完全な形のケーパビリティを実装するには、以下の要件を満たす必要がある:- 1.
- 全ての特権操作について、カーネルはそのスレッドの実効ケーパビリティセットに 必要なケーパビリティがあるかを確認する。
- 2.
- カーネルで、あるスレッドのケーパビリティセットを変更したり、 取得したりできるシステムコールが提供される。
- 3.
- ファイルシステムが、実行可能ファイルにケーパビリティを付与でき、ファイル 実行時にそのケーパビリティをプロセスが取得できるような機能をサポートする。
スレッドケーパビリティセット¶
各スレッドは以下の 3種類のケーパビリティセットを持つ。各々のケーパビリティセットは 上記のケーパビリティの組み合わせである (全てのケーパビリティが無効でもよい)。- 許可 (permitted):
- そのスレッドが持つことになっている実効ケーパビリティの
限定的なスーパーセットである。
これは、実効ケーパビリティセットに
CAP_SETPCAP
ケーパビリティを持っていないスレッドが継承可能ケーパビリティセットに
追加可能なケーパビリティの限定的なスーパーセットでもある。
- 継承可能 (inheritable):
- execve(2) を前後で保持されるケーパビリティセットである。 この仕組みを使うことで、あるプロセスが execve(2) を行う際に新しいプログラムの許可ケーパビリティセットとして 割り当てるケーパビリティを指定することができる。
- 実効 (effective):
- カーネルがスレッドの権限 (permission) をチェックするときに 使用するケーパビリティセットである。
ファイルケーパビリティ¶
カーネル 2.6.24 以降では、 setcap(8) を使って実行ファイルにケーパビリティセットを対応付けることができる。 ファイルケーパビリティセットは security.capability という名前の拡張属性に保存される ( setxattr(2) 参照)。この拡張属性への書き込みには CAP_SETFCAP ケーパビリティが必要である。 ファイルケーパビリティセットとスレッドのケーパビリティセットの両方が 考慮され、 execve(2) 後のスレッドのケーパビリティセットが決定される。- 許可 (Permitted) (以前の 強制 (Forced)):
- スレッドの継承可能ケーパビリティに関わらず、そのスレッドに自動的に 認められるケーパビリティ。
- 継承可能 (Inheritable) (以前の 許容 (Allowed)):
- このセットと、スレッドの継承可能ケーパビリティセットとの 論理積 (AND) がとられ、 execve(2) の後にそのスレッドの許可ケーパビリティセットで有効となる 継承可能ケーパビリティが決定される。
- 実効 (effective):
- これは集合ではなく、1
ビットの情報である。
このビットがセットされていると、
execve(2)
実行中に、そのスレッドの新しい許可ケーパビリティが全て
実効ケーパビリティ集合においてもセットされる。
このビットがセットされていない場合、
execve(2)
後には新しい許可ケーパビリティのどれも新しい実効ケーパビリティ集合
にセットされない。
execve() 中のケーパビリティの変換¶
execve(2) 実行時に、カーネルはプロセスの新しいケーパビリティを次の アルゴリズムを用いて計算する:P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset) P'(effective) = F(effective) ? P'(permitted) : 0 P'(inheritable) = P(inheritable) [つまり、変更されない]
各変数の意味は以下の通り:
- P
- execve(2) 前のスレッドのケーパビリティセットの値
- P'
- execve(2) 後のスレッドのケーパビリティセットの値
- F
- ファイルケーパビリティセットの値
- cap_bset
- ケーパビリティバウンディングセットの値 (下記参照)
ケーパビリティと、ルートによるプログラムの実行¶
execve(2) 時に、ケーパビリティセットを使って、全ての権限を持った root を実現するには、以下のようにする。- 1.
- set-user-ID-root プログラムが実行される場合、 またはプロセスの実ユーザ ID が 0 (root) の場合、 ファイルの継承可能セットと許可セットを全て 1 (全てのケーパビリティが有効) に定義する。
- 2.
- set-user-ID-root プログラムが実行される場合、 ファイルの実効ケーパビリティビットを 1 (enabled) に定義する。
ケーパビリティ・バウンディングセット¶
ケーパビリティ・バウンディングセット (capability bounding set) は、 execve(2) 時に獲得できるケーパビリティを制限するために使われる セキュリティ機構である。 バウンディングセットは以下のように使用される。- *
- execve(2) 実行時に、ケーパビリティ・バウンディングセットと ファイルの許可ケーパビリティセットの論理和 (AND) を取ったものが、 そのスレッドの許可ケーパビリティセットに割り当てられる。 つまり、ケーパビリティ・バウンディングセットは、 実行ファイルが認めている許可ケーパビリティに対して 制限を課す働きをする。
- *
- (Linux 2.6.25 以降) ケーパビリティ・バウンディングセットは、スレッドが capset(2) により自身の継承可能セットに追加可能なケーパビリティの母集団を 制限する役割を持つ。 スレッドに許可されたケーパビリティであっても、バウンディングセットに 含まれていなければ、スレッドはそのケーパビリティは自身の継承可能セットに 追加できず、その結果、継承可能セットにそのケーパビリティを含むファイルを execve(2) する場合、そのケーパビリティを許可セットに持ち続けることができない、 ということである。
ユーザ ID 変更のケーパビリティへの影響¶
ユーザ ID が 0 と 0 以外の間で変化する際の振る舞いを従来と同じにするため、 スレッドの実 UID、実効 UID、保存 set-user-ID、ファイルシステム UID が ( setuid(2), setresuid(2) などを使って) 変更された際に、カーネルはそのスレッドのケーパビリティセットに 以下の変更を行う:- 1.
- UID の変更前には実 UID、実効 UID、保存 set-user-ID のうち 少なくとも一つが 0 で、変更後に実 UID、実効 UID、保存 set-user-ID が すべて 0 以外の値になった場合、許可と実効のケーパビリティセットの 全ケーパビリティをクリアする。
- 2.
- 実効 UID が 0 から 0 以外に変更された場合、 実効ケーパビリティセットの全ケーパビリティをクリアする。
- 3.
- 実効 UID が 0 以外から 0 に変更された場合、 許可ケーパビリティセットの内容を実効ケーパビリティセットにコピーする。
- 4.
- ファイルシステム UID が 0 から 0 以外に変更された場合 ( setfsuid(2) 参照)、実効ケーパビリティセットの以下のケーパビリティがクリアされる: CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, CAP_LINUX_IMMUTABLE (Linux 2.2.30 以降), CAP_MAC_OVERRIDE, CAP_MKNOD (Linux 2.2.30 以降)。 ファイルシステム UID が 0 以外から 0 に変更された場合、 上記のケーパビリティのうち許可ケーパビリティセットで有効になっているものが 実効ケーパビリティセットで有効にされる。
プログラムでケーパビリティセットを調整する¶
各スレッドは、 capget(2) や capset(2) を使って、自身のケーパビリティセットを取得したり変更したりできる。 ただし、これを行うには、 libcap パッケージで提供されている cap_get_proc(3) や cap_set_proc(3) を使うのが望ましい。 スレッドのケーパビリティセットの変更には以下のルールが適用される。- 1.
- 呼び出し側が CAP_SETPCAP ケーパビリティを持っていない場合、新しい継承可能セットは、 既存の継承可能セットと許可セットの積集合 (AND) の部分集合で なければならない。
- 2.
- (カーネル 2.6.25 以降) 新しい継承可能セットは、既存の継承可能セットとケーパビリティ・ バウンディングセットの積集合 (AND) の部分集合でなければならない。
- 3.
- 新しい許可セットは、既存の許可セットの部分集合でなければならない (つまり、そのスレッドが現在持っていない許可ケーパビリティを 獲得することはできない)。
- 4.
- 新しい実効ケーパビリティセットは新しい許可ケーパビリティセットの 部分集合になっていなければならない。
securebits フラグ: ケーパビリティだけの環境を構築する¶
カーネル 2.6.26 以降で、 ファイルケーパビリティが有効になったカーネルでは、 スレッド単位の securebits フラグが実装されており、このフラグを使うと UID 0 ( root) に対するケーパビリティの特別扱いを無効することができる。 以下のようなフラグがある。- SECBIT_KEEP_CAPS
- このフラグをセットされている場合、UID が 0 のスレッドの UID が 0 以外の値に 切り替わる際に、そのスレッドはケーパビリティを維持することができる。 このフラグがセットされていない場合には、UID が 0 から 0 以外の値に 切り替わると、そのスレッドは全てのケーパビリティを失う。 このフラグは execve(2) 時には全てクリアされる (このフラグは、以前の prctl(2) の PR_SET_KEEPCAPS 操作と同じ機能を提供するものである)。
- SECBIT_NO_SETUID_FIXUP
- このフラグをセットすると、スレッドの実効 UID とファイルシステム UID が 0 と 0 以外の間で切り替わった場合に、 カーネルはケーパビリティセットの調整を行わなくなる (「ユーザ ID 変更のケーパビリティへの影響」の節を参照)。
- SECBIT_NOROOT
- このビットがセットされている場合、 set-user-ID-root プログラムの実行時や、 実効 UID か 実 UID が 0 のプロセスが execve(2) を呼び出した時に、カーネルはケーパビリティを許可しない (「ケーパビリティと、ルートによるプログラムの実行」の節を参照)。
prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS_LOCKED | SECBIT_NO_SETUID_FIXUP | SECBIT_NO_SETUID_FIXUP_LOCKED | SECBIT_NOROOT | SECBIT_NOROOT_LOCKED);
準拠¶
ケーパビリティに関する標準はないが、 Linux のケーパビリティは廃案になった POSIX.1e 草案に基づいて実装されている。 http://wt.xpilot.org/publications/posix.1e/ を参照。注意¶
カーネル 2.5.27 以降、ケーパビリティは選択式のカーネルコンポーネント となっており、カーネル設定オプション CONFIG_SECURITY_CAPABILITIES により有効/無効を切り替えることができる。- *
- 2.6.25 より前の実装では、システム共通のケーパビリティ・バウンディングセット /proc/sys/kernel/cap-bound ではこのケーパビリティは常に無効になっており、 ソースを変更してカーネルを再コンパイルしない限り、 これを変更することはできない。
- *
- 現在の実装ではファイルケーパビリティが無効になっている場合、 プロセス毎のバウンディングセットからこのケーパビリティを抜いて init は開始され、 システム上で生成される他の全てのプロセスでこのバウンディングセットが 継承される。
関連項目¶
capget(2), prctl(2), setfsuid(2), cap_clear(3), cap_copy_ext(3), cap_from_text(3), cap_get_file(3), cap_get_proc(3), cap_init(3), capgetp(3), capsetp(3), libcap(3), credentials(7), pthreads(7), getcap(8), setcap(8) カーネルソース内の include/linux/capability.h に 各種のケーパビリティの目的についてのコメントこの文書について¶
この man ページは Linux man-pages プロジェクトのリリース 3.41 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2012-04-15 | Linux |