作爲this one的後續問題,我想到了另一種方法,它構建了@ caf的答案,用於我想要附加到文件name
的情況,並在不存在的情況下創建它。模擬O_NOFOLLOW(2):這種其他方法安全嗎?
這裏是我想出了:
- 在系統臨時目錄在同一文件系統的文件
name
創建模式0700的臨時目錄。 打開文件name
只讀和O_CREAT
。如果它是符號鏈接,則操作系統可能會遵循name
。使用mkstemp
在臨時目錄中創建一個臨時文件,並嘗試rename
由mkstemp
創建的臨時文件到name
。
打開文件name
僅供閱讀和O_CREAT | O_EXCL
。- 以臨時目錄中的臨時名稱迭代嘗試建立到
name
的硬鏈接。如果由於除「鏈接目標存在」(錯誤號碼EEXIST
)之外的錯誤導致link
呼叫失敗,請退出。 (也許有人來過並刪除了文件name
,誰知道?) - 使用
lstat
對temp_name
(硬鏈接)。如果S_ISLNK(lst.st_mode)
,則退出。 open
temp_name
寫作&附加(O_WRONLY | O_APPEND
)。- 把一切寫出來。關閉文件描述符。
unlink
硬鏈接。- 刪除臨時目錄。
(所有這一切,順便說一下,是一個open source project是我的工作。你可以查看我的實現這種方法here的來源。)
這是程序安全對符號鏈接攻擊?例如,是否有可能惡意進程確保name
的inode代表lstat
檢查期間的常規文件,然後使inode成爲指向新的符號鏈接的硬鏈接的符號鏈接?
我假設惡意進程不會影響temp_name
。
編輯:link
不會覆蓋目標,因此創建一個「佔位符」臨時文件是不是我想要做的。之後我更新了代碼並更新了上述步驟。
EDIT2:我現在使用的是備用程序步驟2中,如果不存在的話,我不認爲是易受this problem創建文件name
。
EDIT3:比重命名一個臨時的,空的,常規文件name
,其中也有取消鏈接name
,然後重命名的效果更妙的是,我可以打開該文件O_RDONLY | O_CREAT | O_EXCL
。
爲open
狀態POSIX標準:
如果
O_EXCL
和O_CREAT
設置,並path
名的符號鏈接,open()
失敗,將設置errno
到EEXIST
,不管符號鏈接的內容。
您的最終POSIX引用看起來像一個答案。如果是這樣,爲什麼不把它作爲答案並接受它,所以這個問題不再顯示爲「未答覆」? – 2010-08-08 04:59:38
@ R。抱歉。我已經接受了我的回答。 – 2010-08-08 17:50:47