2010-05-26 67 views
1

我想安全地在不支持O_NOFOLLOW的系統上使用O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOWO_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW來模擬open。我可以在某種程度上實現什麼,我要求有:在沒有此標誌的系統上模擬O_NOFOLLOW的好方法是什麼?

struct stat lst; 
if (lstat(filename, &lst) != -1 && S_ISLNK(lst.st_mode)) { 
    errno = ELOOP; 
    return -1; 
} 

mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 
int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, mode); 

但後來我介紹了一個競爭條件和可能的安全問題。

我想到,也許只有用戶能夠編寫,有點像touch荷蘭國際集團filename,做lstat檢查,然後使用chmod我寫完(更正文件模式位)之後創建一個虛擬文件,但我可以忽略一些重要的東西(例如,如果filename的文件存在,不是常規文件,或者已經是符號鏈接)。

您認爲如何?

回答

4

你的建議仍然具有競爭條件:

  • 馬洛裏創建他要你跟隨鏈接;
  • open()O_CREAT的鏈接;
  • Mallory用普通文件替換鏈接;
  • 你做你的lstat()測試,通過(不是鏈接);
  • Mallory將該鏈接再次替換爲常規文件。

您可以通過打開的文件描述符調用fstat()以及lstat()的道路上,並確保.st_dev.st_ino成員是一樣的解決這個問題的非O_TRUNC情況。

但是,如果您使用的是O_TRUNC,則無法使用 - 在您發現欺騙的時候,已經太晚了 - 馬洛裏已經誘使您截斷其中一個重要文件。

我相信,以消除無孔支持O_NOFOLLOW傳統的方式是:

  • 創建模式700一個臨時目錄。如果mkdir()由於現有目錄而失敗,則錯誤(或重試);
  • 在臨時目錄中創建新文件;
  • 使用rename()自動將臨時文件移動到目標名稱;
  • 刪除臨時目錄。
相關問題