单个fopen会引入TOCTOU漏洞吗?

信息安全 linux 脆弱性 C 文件访问
2021-08-20 09:33:11

我实际上是在 Linux 下修复驱动程序。Klokwork 说代码如下:

file = fopen(fileName, "w+"); // w+,r,a and any mix of those is used here
if (file != NULL) { /* do things*/ }
else { /* throw error */ }
fclose(file);

可以作为 Time-of-check to time-of-use 漏洞结束。

然而,据我所知,它需要像 if(access())以前一样做一些事情fopen来实现它。

还有一个问题:我展示的那个代码示例有什么弱点吗?或者我不需要关心?

1个回答

调用fopen本身并不是 TOCTOU 漏洞。根据定义,TOCTOU 涉及两个操作:“检查”和“使用”。

TOCTOU 漏洞的一个常见示例是access在打开文件之前检查访问权限。这是一个错误(竞争条件),因为权限可能会在检查和打开之间发生变化,并且通常是一个漏洞,因为文件权限对于安全性很重要。

系统access调用非常可疑,因为没有多少使用它的方法不引入 TOCTOU。调用本身并不是特别可疑,fopen因为有许多安全的使用方法。然而,这并不意味着这access是制作 TOCTOU 的唯一方法fopen

打开文件时可能发生的竞争条件的一个示例是,如果您从某个外部来源获取文件名,并且您对该名称做出假设。例如,如果您fopen通过连接目录名和文件名来构建参数,并且您已经对目录进行了一些检查,那么这也是一个 TOCTOU 漏洞。当您使用目录打开文件时,对目录的检查可能不再有效。这就是 Linux 具有openat系统调用的原因:因此您可以调用opendir一个目录,对目录执行检查,然后调用openat以打开该目录中的文件(而open使用串联名称将在现在具有该名称的目录中打开一个文件,但是可能不是您检查的那个)。

所以,是的,你确实需要关心。您的代码可能有也可能没有漏洞。在我非常有限的经验中,Klocwork 确实有很多误报,但并非所有事情都是误报。首先仔细阅读完整的消息。仔细检查您的代码,并记录下安全目标,并跟踪这些安全目标是如何实现(或未实现)的。没有奇迹:编写正确和安全的代码比应用检查表更难。