乙個Bug 差點讓伺服器的檔案系統崩潰

2021-09-20 16:07:33 字數 1439 閱讀 8064

昨天,公司的美國客戶發郵件給我,說我的軟體出問題了,我查來查去,發現居然是伺服器上乙個目錄無法刪除,一刪除就報 cannot read from the source file or disk. 如果用命令列方式刪除,則報 cannot find the specified path。一開始以為是檔案系統遭破壞了,用 chkdsk 命令檢查,沒有發現問題,後來仔細一看,那個不能刪除的目錄名居然以乙個空格字元結尾,而我嘗試在資源管理器中建立乙個目錄以空格結尾結果資源管理器會自動將末尾的字元刪除,用程式建立,結果也一樣,這個美國佬是怎麼建立這個古怪的目錄的?出現這種情況後不但是無法刪除這麼簡單,列目錄什麼的也會有問題,這樣一來,系統的執行都會有問題,我想到的最壞結果就是可能不得不格式化伺服器的硬碟,想到這裡我幾乎不敢再想下去了!research了一天,後來終於找到了解決方案,並且由此還發現問題的起因是我程式上的乙個bug造成,可怕的bug!

windows 的檔案系統可以支援特殊字元的檔名,比如以空格結尾,以點號結尾等,有一篇英文的文章說ntfs 支援這些檔名,但fat不支援,我試了一下,fat也支援。但windows api 卻對這些特殊檔名進行了限制,也就是說,我們通過程式是無法建立乙個以空格或點號結尾的檔名或路徑名的。但copy 和 move的api 卻不做這方面的限制,這導致我們可以從其他的檔案系統拷貝或移動乙個特殊檔名的檔案到windows 的檔案系統,但一旦在windows的檔案系統上建立成功,就無法通過正常途徑刪除或改名。因為呼叫api 刪除或改名時,api 會首先進行規則檢查,如果發現不符合規則,則直接忽略。這兩組api 在處理上的不一致,帶來乙個非常嚴重的安全問題,可惜微軟到了windows7 還沒有去彌補這個問題。

下面讓我們用**復現這個問題

try

catch (exception ex)

在執行這段**前,你一定要有一點思想準備,因為一旦執行成功,你的 c:temp 目錄下就有了乙個 「bcd 」這樣的古怪的目錄,而且你用正常的方法根本無法刪除它。如果我在此打住,你一定會為之抓狂。不過沒關係,我已經找到了刪除它的方法,下面就和大家共享:

windows 的命令列工具 del 和 rd 支援一種方式可以不對輸入檔名的合法性進行檢查,這種方式是在完整目錄名前加乙個 \?\

比如del 「\?c:temp***.」 刪除***. 這個檔案

刪除目錄的話

rd /s 「\?c:temp***.」 刪除 ***. 這個目錄

執行這個命令後,就可以刪除這些古怪的檔案了。注意,這裡一定要輸入完整的目錄才可以,相對路徑不行。

講到這裡,我們知道了原因和解決方案,那麼在這裡我需要提醒大家我們以後在程式中呼叫 system.io.directory.move 或者 system.io.file.copy , system.io.file.move 這些函式前,一定要注意先判斷一下輸入的目標檔名或目錄名的結尾是不是空格或點號,可能還要判斷其他情況,但目前我只知道這兩種情況,而且結尾是空格非常有隱蔽性。

編了乙個伺服器

伺服器 include 包含socket 2版本的標頭檔案 include include pragma comment lib,ws2 32.lib 呼叫網路動態庫!int tmain int argc,tchar argv word sockversion 0x0002 定義版本號 sockve...

乙個簡單的Squid伺服器

本文參考http blog.s135.com book squid chap07.html a13,基本上是一步步照做 一 伺服器主機 centos5.3 159.226.3.209 區域網環境 網路設定 172.16.2.24 閘道器 172.16.2.254 說明 由於區域網所用閘道器已另行設定...

乙個簡單的Http伺服器

計算機網路的課程設計 使用基本的socket編寫的,採用多執行緒處理訪問 寫了 一下午,本來想把php鏈進來,結果之後就不想碰了 環境是 vs2010 主要是兩個類 httpserver 用來建立監聽response 用來響應請求能夠處理get 和 post報文只是因為沒有後台的指令碼語言處理,所以...