ping コマンドの file capability(2)
(理解が不十分なので間違っている所があれば優しく教えてください)
さて、ping コマンドの file capability(1) - TenForward で紹介したように ping コマンドの File capability は Permitted
のみが有効になっていて、Effective
ビットはオン(+e
)になっていません。これで ping が実行できる理由は説明したとおりですが、+e
が設定されていない理由は「不要だから」というだけの理由ではありません。
「なんで +e
ないんだろう?」とつぶやいていると WhiteAnthrax さんが調べて教えてくれました!ありがとうございます!
これは
に書かれている通りです。Docker コマンド内の ping コマンドの実行で問題が起こるからということです。
まず Docker コンテナでは、普通に docker run
すると cap_net_admin
が許可されません。cap_net_admin
は ping -m
のように実行する際に必要です(man ping
すると -m
は "use mark to tag the packets going out." とのことです)。一方で ping
を普通に実行する際に必要な cap_net_raw
は許可されています。つまり Docker コンテナ内では ping コマンドで -m
をつけても目的は達成できません。
ここで(これは明確に man capabilities
には書いてない気がするけど…)
- File capability で
+e
すると、指定したすべての capability が取得できない場合、コマンドを実行した瞬間に実行は失敗する
ということのようです。
特権が必要なシステムコールの実行が行われる、行われないに関わらず、すべての capability の取得に失敗すると、コマンド自体が実行できないということです。ping --help
のような特権が不要な実行であってもです。
ということは、
- Docker コンテナ内で
cap_net_admin,cap_net_raw+ep
と設定してしまうと、cap_net_admin
が取得できないので、cap_net_raw
のみが必要な実行であってもping
コマンドを実行した瞬間にコマンド実行が失敗する
ということです。
今回の ping
コマンドはプログラム中で自身で capability をチェックして Permitted
がオンであれば capset()
を使って Effective
を有効にしていますので、+p
とだけしておくと、たとえ cap_net_admin
が取得できなくてもコマンド実行は成功します。
つまりプログラム中で権限のチェックを行って capability をセットしていますので、
- capability のセットに失敗したシステムコールだけが失敗する
となります。それ以外のシステムコールは問題なく実行されるわけです。
ping -m
と実行すると、プログラム中で cap_net_admin
のチェックをしているところのみ失敗します。つまり "mark" だけが失敗して、cap_net_raw
が必要な処理は行われます。
https://bugzilla.redhat.com/show_bug.cgi?id=1142311#c24 によると
[root@29b49db23971 /]# /opt/ping/ping -m 123 -c1 10.3.1.1 PING 10.3.1.1 (10.3.1.1) 56(84) bytes of data. Warning: Failed to set mark 123 64 bytes from 10.3.1.1: icmp_seq=1 ttl=62 time=0.327 ms
のように mark 処理の部分だけ失敗して、それ以外の処理は行われるようです(試してませんw)。
というわけで +e
してしまうと、ping コマンドはヘルプすら表示できず、本来の実行できる処理も実行できなくなるので、+p
のみが設定されているということです。
(2019-09-30 追記)
『これは明確に man capabilities
には書いてない気がするけど…』と書きましたが、id:udzura さんから man 2 execve
に
EPERM A "capability-dumb" applications would not obtain the full set of permitted capabilities granted by the executable file. See capabilities(7).
という説明があると教えてもらいました!(これでも曖昧ではあるけど "the full set" とあるのできっと…)