在没有此标志的情况下,在系统上模拟O_Nofollow的好方法是什么?
-
04-10-2019 - |
题
我想安全地模拟 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
检查,然后使用 chmod
完成写作后(纠正文件模式位),但是我可以忽略一些主要的东西(例如,如果文件处于 filename
存在,不是常规文件,也不是符号链接)。
你怎么看?
解决方案
您的建议仍然有种族条件:
- 马洛里(Mallory)创建了他希望您遵循的链接;
- 你
open()
链接与O_CREAT
; - Mallory用常规文件代替链接;
- 你做你的
lstat()
测试,通过(不是链接); - Mallory再次用链接替换了常规文件。
您可以为非 -O_TRUNC
通过打电话 fstat()
在您的打开文件描述符上以及 lstat()
在道路上,并确保 .st_dev
和 .st_ino
成员是一样的。
但是,如果您使用的话,这无效 O_TRUNC
- 当您发现欺骗时,为时已晚 - 马洛里已经诱使您截断了一个重要的文件之一。
我相信消除没有漏洞的传统方式 O_NOFOLLOW
支持是:
- 使用模式创建一个临时目录
700
. 。错误(或重试)如果mkdir()
由于现有目录而失败; - 在临时目录中创建新文件;
- 采用
rename()
原子上将临时文件移至目标名称; - 删除临时目录。
不隶属于 StackOverflow