避免在统计数据和重命名之间进行TOCTOU(检查时间,使用时间)
Avoid TOCTOU (time-of-check, time-of-use) race condition between stat and rename
如何避免toctou(检查时间,使用时间(的比赛条件的统计条件和重命名的logfile的竞赛条件?
在日志文件的尺寸值超过最大大小后,需要移动日志文件。
result = stat(LOGFILE, & data);
if (result != 0) {
// stat failed
// file probably does not exist
} else if (data.st_size > MAX_LOGSIZE) {
unlink(PREV_LOGFILE);
(void) rename(LOGFILE, PREV_LOGFILE);
}
避免使用文件操作的标准方法是 open
a file 一次,然后通过文件描述符而不是文件名来完成所需的一切。
但是,重命名和未链接文件都需要其路径(因为他们需要知道要重命名或删除的链接(,因此您无法在此处使用该方法。一种替代方法可能是将文件的内容在其他地方复制,然后将其截断为零字节,尽管您使用日志文件的场景可能要求操作是原子,这可能很难实现。另一种方法是需要在目录上进行紧密的访问控件:如果攻击者无法写入目录,那么它就无法使用您的流程玩Tocttou游戏。您可以使用unlinkat
和renameat
将路径限制到特定目录的文件描述符,因此您不必担心目录本身会更改。
假设一个类似于Posix的平台的未经测试的代码可能会完成工作:
dirfd = open(LOGDIR, O_DIRECTORY);
// check for failure
res = fstatat(dirfd, LOGFILE, statbuf, AT_SYMLINK_NOFOLLOW);
if ((0 == res) && (S_ISREG(statbuf) && (data.st_size > MAX_LOGSIZE)) {
unlinkat(dirfd, PREV_LOGFILE, 0);
renameat(dirfd, LOGFILE, dirfd, PREV_LOGFILE);
}
close(dirfd);
相关文章:
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 在做一段时间内检查字符的无限循环
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- c++中的执行时间和检查流状态
- 如何检查 2 个 c++ 数组在 O(1) 或 O(log n) 时间复杂度中是否相同(所有元素都相同,顺序很重要)?
- 替换枚举以最大化编译时间检查的最佳方法
- 如何在 Zedboard 上的C++程序中检查时间性能
- 避免在统计数据和重命名之间进行TOCTOU(检查时间,使用时间)
- 特征:返回对具有编译时间尺寸检查的矩阵块的引用
- 运行时间检查:变量周围的堆栈已损坏
- 如何检查 O(N) 时间复杂度的多重集中是否有 2 个或更多元素具有相同的值
- C 编译时间检查模板类型中是否存在方法
- 在编译时间检查模板参数类型是否设置或多键,并且容器的元素类型是算术的
- C - 用STD :: difftime编写调度程序 - 如何在白天检查时间(HH:MM:SS)
- c++线程的安全性和时间效率:为什么有互斥检查的线程有时比没有它的线程工作得更快
- 如何检查用户登录到Windows的时间
- 如何在编译时间检查查找表的大小正确
- 如何在编译时间检查课程,是否是抽象的
- 编译具有相同签名的时间检查构造函数
- 运行时间检查失败#2: