web-dev-qa-db-ja.com

マウント名前空間でのpivot_root( "。"、 "。")の奇妙な動作

私はコンテナを理解しようとしていますが、LXC開発者が明らかに見つけたトリックに出くわしました。 this runc PR を参照してください:pivot_root(".", ".")を呼び出すと、ディレクトリを配置する必要がなくなります。古いルートをに。ただし、これにより、マウント名前空間の動作がおかしくなります。

_unshare --user --map-root-user --mount bash -c "
mount --bind containerfs bindmountpoint
cd bindmountpoint
pivot_root . .
# this is fine:
ls -l /
# this is not fine:
ls -l /..
"
_

_._または_./.._または_/.._を介してアクセスされる_/proc/<any>/cwd/.._の親は、ルートマウント名前空間のルートを指します(まだネストを試していません)。 containerfsまたはbindmountpointの親を指すのではなく、実際にはルート/外部マウント名前空間のルートを指します。

同様に、_nsenter --user --preserve-credentials --mount --target=<pid>_を試すと、この新しいプロセスのCWDはルートマウント名前空間のルートに配置されます。

pivot_root(".", "oldroot")の場合、これは発生しません。ファイル記述子_umount -l /_または_umount -l /proc/1/cwd_を介して古いルートをアンマウントすると、この動作も消えます。

_pivot_root_のドキュメントは現在のプロセスに関する保証しか提供していないため、カスタムCプログラムからのこの一連のシステムコールも試しました(したがって、すべてを同じプロセスで実行します)。動作は、上記のCLIツールを使用したマルチプロセスステップと同じです。

5.3カーネルでテスト済み。

pivot_root(".", ".")を実行するとどうなりますか?

2
dyp

pivot_root(new_root, put_old)は、呼び出し元プロセスの古いルートディレクトリ(マウントのルートである必要があります)を_put_old_に移動し、その場所に_new_root_を配置します。次に、古いルートディレクトリに設定されていたすべてのプロセスの現在のディレクトリとルートを_new_root_に設定します。

したがって、pivot_root(".", ".")の後、新しいルートディレクトリには古いルートディレクトリがマウントされます。

_.._が別のディレクトリがマウントされているディレクトリに解決される場合は常に、実際には一番上にマウントされているディレクトリに解決されます。これは、ファイルシステムのルートディレクトリを除いて、_.._がパストラバーサルで特別な処理を行わず、ディスクに格納されたディレクトリエントリによって実装された、歴史的なUnixおよびLinuxの動作と一致します。

これは、マウント名前空間エスケープではありません。

3
Timothy Baldwin