PATH_RESOLUTION - Linux手册页
Linux程序员手册 第7部分
更新日期: 2020-04-11
名称
path_resolution-如何将路径名解析为文件
说明
某些UNIX / Linux系统调用将一个或多个文件名作为参数。的文件名(或路径名)如下得到解决。
Step 1: start of the resolution process
如果路径名以aq / aq字符开头,则起始查找目录是调用进程的根目录。进程从其父级继承其根目录。通常,这将是文件层次结构的根目录。进程可以通过使用chroot(2)系统调用获得不同的根目录,或者可以通过将openat2(2)设置为RESOLVE_IN_ROOT标志来临时使用其他根目录。
如果进程(或其祖先之一)是通过调用设置了CLONE_NEWNS标志的clone(2)系统调用启动的,则该进程可能会获得完全私有的安装命名空间。这处理路径名的aq / aq部分。
如果路径名不是以aq / aq字符开头,则解析进程的开始查找目录是该进程的当前工作目录-或对于openat(2)风格的系统调用,使用dfd参数(或者,如果AT_FDCWD当前工作目录的DFD参数传递)。当前工作目录是从父目录继承的,可以通过使用chdir(2)系统调用来更改。)
以aq / aq字符开头的路径名称为绝对路径名。不以aq / aq开头的路径名称为相对路径名。
Step 2: walk along the path
将当前查找目录设置为起始查找目录。现在,对于路径名的每个非最终组成部分,其中一个组成部分是由aq / aq字符分隔的子字符串,将在当前查找目录中查找该组件。
如果过程不会对当前查找目录搜索权限,将返回EACCES错误("权限被拒绝")。
如果找不到该组件,则返回ENOENT错误("无此文件或目录")。
如果找到该组件,但既不是目录也不是符号链接,则返回ENOTDIR错误("非目录")。
如果找到该组件并且是目录,我们将当前查找目录设置为该目录,然后转到下一个组件。
如果找到了该组件并且它是一个符号链接(symlink),则我们首先解析该符号链接(以当前的查找目录作为起始查找目录)。一旦错误,则返回错误。如果结果不是目录,则返回ENOTDIR错误。如果符号链接的解析成功并返回目录,则将当前查找目录设置为该目录,然后转到下一个组件。请注意,如果路径名的前缀('dirname')组件包含一个文件名,该文件名是解析为目录的符号链接(其中该目录的前缀组件可能包含一个符号链接,那么这里的解析过程可能涉及递归)上)。为了保护内核免受堆栈溢出的侵害,并防止拒绝服务,对最大递归深度和跟随的最大符号链接数进行了限制。超过最大值时,将返回ELOOP错误("符号链接级别太多")。
正如当前在Linux上实现的那样,解析路径名时将遵循的最大符号链接数为40。在2.6.18之前的内核中,递归深度的限制为5。从Linux 2.6.18开始,此限制有所提高。到8。在Linux 4.2中,对内核的路径名解析代码进行了重新设计,以消除对递归的使用,因此,剩下的唯一限制是整个路径名最多只能有40种解析度。
可以使用openat2(2)并设置RESOLVE_NO_SYMLINKS标志来阻止此阶段符号链接的解析。
Step 3: find the final entry
如上一步中所述,对路径名的最终组件的查找与所有其他组件的查找一样,有两个区别:(i)最终组件不必是目录(至少在路径解析过程中是如此)有关-由于特定系统调用的要求,它可能必须是目录或非目录),并且(ii)如果找不到该组件,则不一定是错误--也许我们只是创建它。在最后一项的处理细节在具体的系统调用的手册页描述。
. and ..
按照约定,每个目录都有条目"。"。和" ..",分别指目录本身及其父目录。
路径解析过程将假定这些条目具有其常规含义,而不管它们是否实际存在于物理文件系统中。
一个人不能越过根:" / .."与" /"相同。
Mount points
在执行" mount dev path"命令后,路径名" path"是指设备" dev"上文件系统层次结构的根目录,而不再是之前引用的内容。
可以走出已安装的文件系统:" path / .."是指" path"的父目录,位于" dev"上文件系统层次结构之外。
可以通过使用openat2(2)并设置RESOLVE_NO_XDEV标志来阻止对安装点的遍历(尽管请注意,这也限制了绑定安装的遍历)。
Trailing slashes
如果路径名以aq / aq结尾,则必须像步骤2中那样强制解析前面的组件:它必须存在并解析为目录。否则,将忽略结尾的aq / aq。 (或者,等价地,具有路径名尾随水溶液/水溶液相当于通过附加aq.aq到它获得的路径名。)
Final symlink
如果路径名的最后一个部分是符号链接,则取决于系统调用是引用的文件是符号链接还是其内容的路径解析结果。例如,系统调用lstat(2)将在符号链接上运行,而stat(2)在符号链接所指向的文件上运行。
Length limit
路径名的最大长度。如果路径名(或解析符号链接时获得的某些中间路径名)太长,则返回ENAMETOOLONG错误("文件名太长")。
Empty pathname
在原始UNIX中,空路径名引用当前目录。如今,POSIX裁定不能成功解析空路径名。在这种情况下,Linux返回ENOENT。
Permissions
文件的许可位由三组组成,每组三位;参见chmod(1)和stat(2)。当调用过程的有效用户ID等于文件的所有者ID时,使用第一组(三个)。当文件的组ID等于调用进程的有效组ID,或者是调用进程的补充组ID之一(由setgroups(2)设置)时,使用第二个三组。如果两个都不成立,则使用第三组。
在使用的三位中,第一位确定读取权限,第二个写入权限和最后执行权限(对于普通文件而言)或对于目录的搜索权限。
Linux在权限检查中使用fsuid而不是有效的用户ID。通常,fsuid将等于有效的用户ID,但是可以通过系统调用setfsuid(2)来更改fsuid。
(这里的" fsuid"代表"文件系统用户ID"之类的东西。当进程可以向具有相同有效用户ID的进程发送信号时,实现用户空间NFS服务器是必需的。现在。没有人应该使用setfsuid(2)。)
同样,Linux使用fsgid("文件系统组ID")代替有效的组ID。请参见setfsgid(2)。
Bypassing permission checks: superuser and capabilities
在传统的UNIX系统上,超级用户(root,用户ID 0)具有强大的功能,并且在访问文件时会绕过所有权限限制。
在Linux上,超级用户特权分为功能(请参阅功能(7))。有两种功能与文件权限检查相关:CAP_DAC_OVERRIDE和CAP_DAC_READ_SEARCH。 (如果进程的fsuid为0,则它们具有这些功能。)
CAP_DAC_OVERRIDE功能会覆盖所有权限检查,但仅在设置了文件的三个执行权限位中的至少一个时,才授予执行权限。
CAP_DAC_READ_SEARCH功能授予目录的读取和搜索权限,以及普通文件的读取权限。
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。