掛載命名空間中的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 /..
"

的父級,透過or.訪問或指向根掛載命名空間的根(我還沒有嘗試嵌套)!它並不指向nor的父級,而是指向根/外部掛載命名空間的根。./../../proc/<any>/cwd/..containerfsbindmountpoint

同樣,當我嘗試時nsenter --user --preserve-credentials --mount --target=<pid>,這個新進程將其 CWD 放置在根安裝命名空間的根目錄下。

當我 時,這一切都不會發生pivot_root(".", "oldroot")。透過檔案描述子或umount -l /.unmount卸載舊根時,該行為也會消失umount -l /proc/1/cwd

我還嘗試了來自自訂 C 程式的系統呼叫序列,因為pivot_root僅提供了有關當前進程的保證(因此我在同一進程中執行所有操作)。該行為與上面顯示的使用 CLI 工具的多進程步驟相同。

在 5.3 核心上測試。

當我跑步時發生了什麼事pivot_root(".", ".")

答案1

pivot_root(new_root, put_old)將呼叫程序的舊根目錄(必須是掛載的根目錄)移到put_old,並放置new_root在它的位置。然後,它將當前目錄和設定為舊根目錄的每個進程的根設定為new_root

因此,在pivot_root(".", ".")新的根目錄之後,舊的根目錄將安裝在其之上。

每當..解析為安裝有另一個目錄的目錄時,它實際上解析為安裝在頂部的目錄。這與歷史上的 Unix 和 Linux 行為相匹配,其中..,除了檔案系統的根目錄之外,在路徑遍歷中沒有特殊處理,並且由儲存在磁碟上的目錄條目實現。

這不是掛載命名空間轉義。

答案2

看起來像一個真正的錯誤...

檢查您的發行版中的最新內核,並報告其完整詳細資訊(附上您的測試程式!)。

相關內容