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

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

私はコンテナを理解しようとしており、LXC開発者が見つけたと思われるトリックに偶然遭遇しました。このランク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/..containerfsbindmountpoint

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

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

また、ドキュメントでは現在のプロセスについてのみ保証されているため、カスタム C プログラムからこの一連のシステム コールを試しましたpivot_root(そのため、すべてを同じプロセスで実行します)。動作は、上記の CLI ツールを使用したマルチプロセス手順と同じです。

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

走ると何が起きるのでしょうかpivot_root(".", ".")?

答え1

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

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

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

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

答え2

本物のバグのようです...

ディストリビューションの最新カーネルをチェックし、詳細を報告してください (テスト プログラムを添付してください)。

関連情報