在没有此标志的系统上模拟 O_NOFOLLOW 的好方法是什么? [英] What is a good way to simulate O_NOFOLLOW on systems without this flag?

查看:75
本文介绍了在没有此标志的系统上模拟 O_NOFOLLOW 的好方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够安全地模拟 openO_CREAT |O_WRONLY |O_TRUNC |O_NOFOLLOWO_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.

我想过创建一个只有用户可以写的虚拟文件,有点像touching filename,做lstat 检查,然后在我写完之后使用 chmod(以更正文件模式位),但我可能会忽略一些主要的东西(例如,如果 filename 中的文件存在,不是普通文件,或者已经是符号链接).

I thought about maybe creating a dummy file with only the user being able to write, kind of like touching 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 with O_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) if mkdir() 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆