防止检查时间到使用时间?

Protecting against Time-of-check to time-of-use?

我正在阅读:https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use

他们证明这段代码有问题,我完全理解为什么会这样:

if (access("file", W_OK) != 0) {
    exit(1);
}
// Attacker: symlink("/etc/passwd", "file");
fd = open("file", O_WRONLY);
// Actually writing over /etc/passwd
write(fd, buffer, sizeof(buffer));

但真正的问题是如何防范此类攻击?

您可以使用 O_NOFOLLOW 标志。如果路径的 basename 是符号 link,它将导致 open 失败。这将解决所描述的攻击。

要覆盖目录路径中的 links,您可以检查 frealpath(fd, ...) 是否符合您的预期。

另一种防止进程覆盖 /etc/passwd 的方法是 运行 它作为非根用户,这样它就没有权限。或者,您可以使用 chroot - 或者更一般地说,一个容器 - 来防止主机系统的 /etc/passwd 对进程可见。

更一般地说,文件系统 TOCTOU 目前无法在 Linux 上解决。您需要在文件系统或系统调用级别上提供事务支持——这是目前所缺乏的。

没有万无一失的解决方案。

还要注意 Rice's theorem。它可能是相关的。

但是您可以采用系统范围的约定(并记录下来),即访问给定文件的每个程序都使用 flock(2).

之类的锁定工具