圆点认为有害

Fuchsia 上的子进程只能访问提供给它们的资源 - 这是涉及“基于功能”的系统的基本理念。如果为服务提供了句柄,则访问该句柄意味着客户端可以使用该句柄。

直观地说,这一概念也适用于文件系统:如果为某个目录提供句柄,则句柄应暗示访问该目录(以及其子目录)内的资源。不过,不幸的是,POSIX 的暂留机制会阻止目录句柄与功能系统中的这些概念完全集成:“..”。如果向目录提供一个句柄,客户端只需请求“..”,该句柄将被“升级”,以便访问范围更广的父目录。因此,这意味着可以任意升级目录的句柄来访问整个文件系统。

一直以来,文件系统都尝试使用“chroot”来解决这个问题,这改变了文件系统根目录的概念,在路径遍历这种微不足道的情况下阻止了“..”以外的访问。不过,这种方法存在一些问题:

  • Chroot 会粗略地“按程序”(而不是按描述符)更改 root 的概念
  • Chroot 经常遭到滥用(例如,将 fchdir 转换为位于 chroot 之外的其他开放句柄)
  • Chroot 并非“默认开启”,因此可能会让程序直接不使用它们。

为了克服这些不足,Fuchsia 未在文件系统服务器上实现传统的 dot 语义,这会允许开放目录向上遍历。更具体地说,它禁止访问“..”,从而阻止客户端轻松访问父目录。这为进程创建提供了一些强有力的属性:如果应用管理器只想为进程提供对“/data/my_private_data”的访问权限,那么它只需为子进程提供该开放目录的句柄,系统就会“自动”将其沙盒化。

对于无需文件系统服务器即可解析的路径呢?

在没有符号链接的情况下,无需访问文件系统服务器即可确定某些路径(例如可转换为“bar”的“foo/../bar”),并且在撰写本文时,Fuchsia 上不存在符号链接。在将基于路径的请求发送到文件系统服务器之前,可以在客户端对这些路径进行规范化或清理:libfdio 库已经对最终通过名为 __fdio_cleanpath 的函数传输到文件系统服务器的任何 fdio 操作执行此操作。

shell 遍历怎么样?

举例来说,如果用户通过“cd”命令进入某个目录,他们该如何离开?在内部,“CWD”的概念不仅仅是某个开放目录的文件描述符,而是“文件描述符”和“解释为 CWD 的绝对路径”的组合。如果所有对 cd 的操作都在此绝对路径上执行,那么“..”始终可在客户端本地解析,而不是传输到文件系统。例如,如果 CWD 为“/foo/bar”,并且用户调用“cd ..”,则底层调用可能会转换为“chdir /foo/bar/..”,而“chdir /foo/bar/..”可规范化为“/foo”。

克服这些障碍后,移除“..”的好处是巨大的:对文件系统资源的访问可以自然地在功能系统中,沙盒新进程可以大大简化,资源访问可以通过文件系统命名空间更自然地组合起来。