安装命名空间中 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

看起来像一个真正的错误......

检查您的发行版中的最新内核,并报告其完整详细信息(附上您的测试程序!)。

相关内容