1

我希望能够安全地在不支持的系统上open进行O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW模拟。我可以通过以下方式实现我的要求:O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOWO_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);

但随后我介绍了一个竞争条件,可能还有一个安全问题。

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

你怎么看?

4

1 回答 1

4

您的提案仍然存在竞争条件:

  • 马洛里创建了他希望您关注的链接;
  • open()的链接O_CREAT;
  • Mallory 将链接替换为常规文件;
  • 你做你的lstat()测试,通过(不是链接);
  • Mallory 再次用链接替换了常规文件。

您可以O_TRUNC通过调用fstat()打开的文件描述符以及lstat()路径来解决此问题,并确保.st_dev.st_ino成员相同。

但是,如果您正在使用,这将不起作用O_TRUNC- 当您发现欺骗时,为时已晚 - Mallory 已经诱导您截断您的一个重要文件。

O_NOFOLLOW我相信在没有支撑的情况下消除孔的传统方法是:

  • 使用 mode 创建一个临时目录700mkdir()如果由于现有目录而失败,则错误(或重试) ;
  • 在临时目录中创建新文件;
  • 用于rename()以原子方式将临时文件移动到目标名称;
  • 删除临时目录。
于 2010-05-26T23:08:39.353 回答