在没有此标志的系统上模拟 O_NOFOLLOW 的好方法是什么? [英] What is a good way to simulate O_NOFOLLOW on systems without this flag?
问题描述
我希望能够安全地模拟 open
与 O_CREAT |O_WRONLY |O_TRUNC |O_NOFOLLOW
和 O_CREAT |O_WRONLY |O_APPEND |O_NOFOLLOW
在不支持 O_NOFOLLOW
的系统上.我可以在某种程度上实现我的要求:
I would like to safely be able to simulate open
with O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW
and O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW
on systems that do not support O_NOFOLLOW
. I can somewhat achieve what I am asking for with:
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);
但随后我引入了竞争条件和可能的安全问题.
but then I introduce a race condition and possibly a security problem.
我想过创建一个只有用户可以写的虚拟文件,有点像touch
ing filename
,做lstat
检查,然后在我写完之后使用 chmod
(以更正文件模式位),但我可能会忽略一些主要的东西(例如,如果 filename
中的文件存在,不是普通文件,或者已经是符号链接).
I thought about maybe creating a dummy file with only the user being able to write, kind of like touch
ing filename
, doing the lstat
check, and then using chmod
after I finish writing (to correct the file mode bits), but I could be overlooking something major (e.g. if the file at filename
exists, is not a regular file, or is already a symbolic link).
你怎么看?
推荐答案
您的提案仍然存在竞争条件:
Your proposal still has a race condition:
- Mallory 创建了他希望您关注的链接;
- 你
open()
链接O_CREAT
; - Mallory 将链接替换为常规文件;
- 您进行了
lstat()
测试,它通过了(不是链接); - Mallory 再次用链接替换了常规文件.
- Mallory creates the link he wants you to follow;
- You
open()
the link withO_CREAT
; - Mallory replaces the link with a regular file;
- You do your
lstat()
test, which passes (not a link); - Mallory replaces the regular file with the link again.
您可以通过在打开的文件描述符上调用 fstat()
以及 lstat()
来针对非 O_TRUNC
情况解决此问题在路径上,并确保 .st_dev
和 .st_ino
成员相同.
You can fix this for the non-O_TRUNC
case by calling fstat()
on your open file descriptor as well as lstat()
on the path, and ensuring that the .st_dev
and .st_ino
members are the same.
但是,如果您使用的是 O_TRUNC
,这将不起作用 - 当您发现欺骗时,为时已晚 - Mallory 已经诱使您截断您的一个重要文件.
However, this doesn't work if you're using O_TRUNC
- by the time you've discovered the deception, it's too late - Mallory has already induced you to truncate one of your important files.
我认为在没有O_NOFOLLOW
支持的情况下消除孔洞的传统方法是:
I believe the traditional way to eliminate the hole without O_NOFOLLOW
support is:
- 创建一个模式为
700
的临时目录.如果mkdir()
由于现有目录而失败,则出错(或重试); - 在临时目录中创建新文件;
- 使用
rename()
将临时文件原子移动到目标名称; - 删除临时目录.
- Create a temporary directory with mode
700
. Error (or retry) ifmkdir()
fails due to existing directory; - Create your new file within the temporary directory;
- Use
rename()
to atomically move the temporary file to the target name; - Remove the temporary directory.
这篇关于在没有此标志的系统上模拟 O_NOFOLLOW 的好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!