Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在没有拒绝服务漏洞的情况下安全地打开常规文件?_C_Linux_Filesystems - Fatal编程技术网

C 如何在没有拒绝服务漏洞的情况下安全地打开常规文件?

C 如何在没有拒绝服务漏洞的情况下安全地打开常规文件?,c,linux,filesystems,C,Linux,Filesystems,标记O_目录可与系统调用open(2)和openat(2)一起使用,以避免在打开目录时出现拒绝服务漏洞。但是:如何避免常规文件的同类竞争条件 一些背景信息:我正在尝试开发某种备份工具。程序遍历目录树,读取所有常规文件,只读取其他文件。如果我首先为每个目录项调用fstatat(2),测试常规文件的结果,并使用openat(2)打开它们,那么系统调用之间存在竞争条件。攻击者可以用FIFO替换常规文件,我的程序将挂起FIFO 我怎样才能避免这种比赛状态?对于目录,有O_目录,对于符号链接,可以使用O_

标记
O_目录
可与系统调用
open(2)
openat(2)
一起使用,以避免在打开目录时出现拒绝服务漏洞。但是:如何避免常规文件的同类竞争条件

一些背景信息:我正在尝试开发某种备份工具。程序遍历目录树,读取所有常规文件,只读取其他文件。如果我首先为每个目录项调用
fstatat(2)
,测试常规文件的结果,并使用
openat(2)
打开它们,那么系统调用之间存在竞争条件。攻击者可以用FIFO替换常规文件,我的程序将挂起FIFO


我怎样才能避免这种比赛状态?对于目录,有
O_目录
,对于符号链接,可以使用
O_路径
。但是,我没有找到常规文件的解决方案。我只需要一个能在最新Linux版本上运行的解决方案。

使用O|RDONLY | O| NONBLOCK打开,检查结果是否为-1,然后对结果文件描述符执行fstat(),并将st_模式(可能还有st|dev和st|ino)与您期望的模式进行比较


请记住在fstat上设置AT_SYMLINK_NOFOLLOW标志。

如果您唯一关心的是fifo,
O_NONBLOCK
将防止阻塞,并允许您打开fifo,即使它没有写入程序(请参阅指定位置)。然而,还有一些其他问题:

  • 设备节点
  • Linux
    /proc
    中的假文件具有错误属性
由于非root用户通常无法在任意位置创建这些代码,因此
O_NOFOLLOW
应足以避免使用指向它们的符号链接

尽管如此,在现代Linux上还有一个更安全的解决方案:使用
O|u PATH | O_NOFOLLOW
执行初始的
open
,然后在
/proc/self/fd/%d
上执行
stat
以检查文件类型。然后,您可以打开
/proc/self/fd/%d
,并完全确定它与刚才的
stat
'd文件对应


请注意,在足够新的Linux上,您不需要使用
/proc/self/fd/%d
来访问使用
O_PATH
获得inode句柄的文件。您可以在它上面直接使用
fstat
openat
来“stat”它,并分别获得真正打开的文件描述的描述符。然而,
O_PATH
文件描述符在2.6.x后期(首次添加时)到3.8左右的范围内有很多这样的不完整/未实现的角落情况,我发现
/proc
方法最可靠。当然,您可以尝试直接方法,如果失败,则返回到
/proc

我不确定设备节点是否100%正确;行为不好的设备可能会在打开时启动不可中断的睡眠。当然,普通文件在打开时总是可以这样做的,例如,如果它们位于有连接问题的刮伤光盘或nfs挂载上:-(同意。但这些是用户空间软件不应该试图处理的问题。如果你想保护你的程序不受坏硬件的影响,你最终会问“我如何处理超出SIGPWR允许范围的断电”。我的底线是“我保证,只要操作系统按照指定的方式工作,我的程序就能正常工作。”@GuntramBlohm:不幸的是,在被刮伤的CD/DVD上表现出理智的行为是媒体播放器应用程序的一个实际的、现实的要求,也是大多数应用程序出现可怕故障的一个领域。如果整个用户界面冻结,甚至在你刮伤的时候就无法重新绘制或做任何事情,那就是糟糕的用户体验。唯一的“修复”我知道使用大量的线程来读取、取消和删除那些似乎被卡住的线程,并让它们在硬件重试5分钟或任何时间之后死去。@ GuntRAMBlom:在驱动程序级别上设置一个全局设置是非常有问题的。g从损坏的光盘上恢复尽可能多的信息。媒体播放器开发人员希望在每个打开的文件级别上有一个可配置的读取超时,但在任何情况下,这都偏离了主题…:-)是的,显然我们仍然缺少一种方法,无法将相当于
AT_EMPTY_PATH
的路径传递到
openat
。我不认为您不能忽略它,因为作为规范的一部分,这种情况似乎需要失败,至少如果
符合“相对路径”的条件。