是否可以打开一个知道其索引节点的文件?
ls -i /tmp/test/test.txt
529965 /tmp/test/test.txt
我可以提供路径,索引节点(上529965),我希望得到一个文件描述符。
这是不可能的,因为它会在访问控制规则中打开漏洞。 是否可以打开文件不仅取决于它自己的访问权限位,还取决于每个包含目录的权限位。 (例如,在您的示例中,如果test.txt
是模式 644,但包含目录test
是模式 700,则只有 root
和test
的所有者可以打开test.txt
。 索引节点号仅标识文件,而不标识包含目录(一个文件可能位于多个目录中;在"硬链接"上读取),因此内核无法仅使用索引节点编号执行一组完整的访问控制检查。
(一些Unix实现提供了非标准的仅根API来通过inode号打开文件,绕过了一些访问控制规则,但如果当前的Linux有这样的API,我不知道。
不完全是你要问的,但是(正如zwol所暗示的)Linux和NetBSD/FreeBSD都提供了使用以前创建的"句柄"打开文件的能力: 这些是类似 inode 的持久名称,用于标识文件系统上的文件。
在 *BSD(getfh
和 fhopen
)上,使用它非常简单:
#include <sys/param.h>
#include <sys/mount.h>
fhandle_t file_handle;
getfh("<file_path>", &file_handle); // Or `getfhat` for the *at-style API
// … possibly save handle as bytes somewhere and recreate it some time later …
int fd = fhopen(&file_handle, O_RDWR);
但是,要求调用方为根用户的最后一个调用。
Linux name_to_handle_at
和 open_by_handle_at
系统调用类似,但更明确,并且要求调用方跟踪相关的文件系统挂载 ID/UUID 本身,因此我将谦虚地链接到手册页中的详细示例。请注意,如果您希望在重新启动后保留句柄,则该示例不完整;必须将接收到的挂载 ID 转换为持久性文件系统标识符,例如文件系统 UUID,并在以后将其转换回挂载 ID。然而,从本质上讲,他们做同样的事情。就像在 *BSD 上使用后面的系统调用需要提升的权限(确切地说是CAP_DAC_READ_SEARCH)。