2010-07-21 147 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