我希望能够安全地在不支持open
的系统上使用O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW
和O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW
模拟O_NOFOLLOW
。我可以在某种程度上实现我的要求:
struct stat lst;
if (lstat(filename, &lst) != -1 && S_ISLNK(lst.st_mode)) {
errno = ELOOP;
return -1;
}
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, mode);
然后我介绍了竞争条件,可能还有安全问题。
我想过可能只创建一个只有用户能够编写的虚拟文件,有点像touch
ing filename
,进行lstat
检查,然后使用{{1我写完之后(纠正文件模式位),但我可能会忽略一些主要的东西(例如,如果chmod
处的文件存在,不是常规文件,或者已经是符号链接)。< / p>
您怎么看?
答案 0 :(得分:4)
您的提案仍有竞争条件:
open()
与O_CREAT
; lstat()
测试,该测试通过(不是链接); 您可以通过在打开的文件描述符上调用O_TRUNC
以及路径上的fstat()
来解决非lstat()
案例的问题,并确保.st_dev
和.st_ino
成员是一样的。
然而,如果您使用O_TRUNC
,这不起作用 - 当您发现欺骗时,为时已晚--Mallory已经诱使您截断您的一个重要文件。
我认为在没有O_NOFOLLOW
支持的情况下消除漏洞的传统方法是:
700
创建临时目录。如果mkdir()
由于现有目录而失败,则出错(或重试); rename()
以原子方式将临时文件移动到目标名称;