web-dev-qa-db-ja.com

機能を追加して権限を失いますか?

説明できない以下の現象を観察しました。 CAP_SYS_ADMIN機能を追加すると、unshare/proc/self/setgroupsに書き込むことができなくなります。

実際、このファイルへの書き込みrequires機能ですが、これはユーザーの名前空間を変更することで実現されます。では、なぜadding親プロセスの機能がこのファイルへの書き込みを妨げているのでしょうか。

me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ Sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ Sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#

ちなみに:カーネルバージョン4.4でUbuntu 16.04.4 LTSを実行していて、util-linuxのバージョン(unshareを含む)は2.27.1です。

7
koalo

ここで起こっていることは、「共有解除」プロセスが上のsetgroups(および_uid_maps_、_gid_maps_)ファイルへの書き込みアクセス権を持っていないことですexternalユーザー名前空間。

その名前空間では、_/proc/<PID>_の疑似ファイルがルート所有され、有効なuidがまだ自分のユーザーのものであるかのように、それらのファイルに書き込むためのアクセス権がありません。

バックグラウンドでプロセス(sleepなど)を実行し、実行中にsetgroupsファイルの権限を検査することで、それを簡単に視覚化できます(_uid_maps_および_gid_maps_動作するまったく同じ。)

最初に、追加機能のないバイナリを使用します。

_$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+  Done                    ./sleep 10
$
_

次に、ファイル機能をいくつか追加して、所有権の変更を確認します。

_$ Sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups 
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+  Done                    ./sleep 10
$
_

_/proc/<PID>_内のファイルの所有権は、Linuxカーネル内の「ダンプ可能」フラグによって制御されます。これは、特権プロセスから非特権ユーザーへの情報漏洩を防ぐために使用されます。

また、unshareを追加機能で実行しているが、ルート以外の有効なuidを使用している場合は、これらの疑似ファイルへのアクセスを書き込みます。 rootが所有するものは、オペレーティングシステムの通常のアクセス制御によって防止されます。


prctl(2) syscallの_PR_GET_DUMPABLE_コマンドを使用して、「ダンプ可能」フラグの値を検査できます。

_PR_SET_DUMPABLE_の説明には、次の情報も含まれています。

通常、このフラグは1に設定されます。ただし、次の状況では、ファイル_/proc/sys/fs/suid_dumpable_(デフォルトでは値0)に含まれている現在の値にリセットされます。

[...]

  • プロセスは、ファイル機能を備えたプログラムを実行します(execve(2))( capabilities(7) を参照)。ただし、取得された許可された機能が、プロセスですでに許可されている機能を超えている場合に限ります。 。

これはまさにあなたのケースであり、ファイル機能を持​​つunshareバイナリがあります。

興味深いことに、unshareにルート所有のsetuidバイナリを使用しても、この正確な問題は発生しません。はい、「ダンプ可能」フラグがクリアされ、_/proc/<PID>_内のファイルはrootによって所有されます。しかし、setuidバイナリを実行しているとき、有効なuidがalsorootであると考えると、アクセスは許可されます。

その場合、別の問題が発生します。これは、unshareのロジックがその特定のセットアップを処理できないことに関係しています(おそらく、有効なuidと実際のuidが一致しないことに関係しています)。

_$ cp /usr/bin/unshare .
$ Sudo setcap -r unshare
$ Sudo chown root:root unshare
$ Sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$ 
_

また、「ダンプ可能」フラグのクリアは、ファイル機能が設定されたバイナリを実行することによってトリガーされたことにも注意してください。別の方法で追加機能を取得すると、この問題に遭遇しない可能性があります。たとえば、「アンビエント」機能を使用すると、名前空間の外で追加機能を取得できますが、新しいユーザー名前空間との共有を解除するときに問題が発生することはありません。

(残念ながら、アンビエント機能に関するツールはまだ多くありません。libcapは、現在ほとんどのディストリビューションで出荷されているバージョン2.25を過ぎた最新のgitでのみサポートを出荷します。capshはかなりです低レベルなので、正しく理解するのも簡単ではありません。最新のcapshを使用してアンビエント機能を追加する方法の詳細については、 ここ を参照してください。_systemd-run_も試しましたが、できませんでした。そこにアンビエント機能を設定することもできません。とにかく、機能が必要な場合は、root以外のユーザーとユーザーの名前名を一緒に調べてください!)

10
filbranden