2010-07-21 141 views
23

我得到这个警告,说tmpnam是危险的,但我宁愿使用它,因为它可以在Windows和Linux中一样使用。我想知道为什么它会被认为是危险的(我猜这是因为可能存在滥用而非实际工作不正常)。tmpnam警告说这是危险的

+0

你可以添加一些上下文吗?谁声称这是危险的? – nmichaels 2010-07-21 13:46:42

+0

tmpname是变量名称,文件名称,源文件名称还是其他名称?并不是所有人都有心理能力。 – sbi 2010-07-21 13:50:06

+6

@sbi:'tmpnam'是标准C库函数。 – 2010-07-21 14:13:25

回答

25

从使用tmpnam手册页:

的使用tmpnam()函数生成在每次调用,高达TMP_MAX倍时间不同的字符串。如果它被调用的时间超过TMP_MAX,则行为是实现定义的。

虽然tmpnam()会生成很难猜测的名称,但tmpnam()返回路径名的时间与程序打开它的时间之间可能存在差异,但另一个程序可能使用open() 2),或将其创建为符号链接。这可能会导致安全漏洞。为了避免这种可能性,使用open(2)O_EXCL标志打开路径名。或者更好的是,使用mkstemp(3)或tmpfile(3)。

Mktemp确实创建了文件,因此您可以放心使用,而tmpnam会返回一个可能已经存在的名称。

+2

使用'mktemp'是Unix专用的Windows,您需要'tmpnam_s'和'_wtmpnam_s'。因此,独立于平台的版本并不那么容易。 – usr1234567 2015-04-23 07:56:57

1

从使用tmpnam(3)手册页:

虽然使用tmpnam()生成了难以猜测的名字,但它仍然是可能的是使用tmpnam(时间之间 )返回一个路径名,和时间程序打开它,另一个程序可能使用open(2)创建该路径,或者将其创建为符号链接。这可能会导致安全漏洞。为了避免这种可能性,使用open(2)O_EXCL标志打开路径名。或者更好的是,使用mkstemp(3)或tmpfile(3)。

1

,如果你谈论MSVC的编译器警告:

These functions are deprecated because more secure versions are available; 
see tmpnam_s, _wtmpnam_s. 

http://msdn.microsoft.com/de-de/library/hs3e7355(VS.80).aspx

否则刚刚看了一下联机手册说这个功能的缺点。它主要是关于第二个进程创建与您的进程完全相同的文件名。

3

如果您想在多个平台上使用相同的符号,请使用宏定义TMPNAM。只要你用相同的接口选择更安全的功能,你就可以在两者上使用它。无论如何,你的代码中都有条件编译,对吧?

0

该函数是危险的,因为您负责分配缓冲区,该缓冲区的大小足以处理tmpnam()要写入该缓冲区的字符串。如果分配的缓冲区太小,tmpnam()无法知道,并且会超出缓冲区(造成严重破坏)。 tmpnam_s()(MS的安全版本)要求你传递缓冲区的长度,所以tmpnam_s知道何时停止。

+3

有一个预处理器常量L_tmpnam指定实现将写入的最大长度(或者在单线程程序中,可以使用NULL指针,在这种情况下它将使用静态缓冲区)。因此这是一个容易避免的问题。危险的部分来自创建文件名称和随后创建文件本身之间的可能竞争条件。 – janneb 2010-07-21 17:08:00

+0

大多数安全漏洞很容易避免。 (你的答案引用了一种简单的方法来避免你描述的问题)。如果你不遵守规则,我描述的问题更可能发生。 (这也是tmpnam_s()修复的问题,所以这显然是他们所考虑的问题) – 2010-07-21 17:27:51