Friday, March 11, 2011

Security Enhancement in CRT: Good or Bad Side-Effect?

從Visual Studio 2005開始,編譯器都會建議使用者把某些CRT function換成更安全的版本。舉例來說,編譯器會建議你把strcpy改成strcpy_s。

這樣改的好處是什麼呢?在程式執行的過程中,有一種類型的bug叫做buffer overflow。以strcpy來說,就是你的來源字串長度可能比準備的buffer來的長,又因為strcpy沒有buffer size的資訊,所以在資料複製的過程中,就有可能覆蓋到buffer後面的資料。

如果buffer在stack上,那就有可能覆蓋到其他變數,甚至是call stack的return address。總之,小則程式執行不正常或崩潰,大則會被attacker利用來取得控制權。

換成安全的版本,編譯器就會嘗試把buffer size偷偷帶進strcpy_s當中,幫你在執行的過程中檢查有沒有buffer overflow。如果有,就會呼叫invalid parameter handler。

看到這裡,你可能就直接把全部的strcpy換成strcpy_s。

等等,預設的invalid parameter handler會丟出一個Exception,如果沒有exception handler,預設會執行UnhandledExceptionHandler()。講白話一點,就是會造成程式的崩潰。那使用者會看到什麼呢?答案是一個程式執行無效之類的對話框。

嘿,如果這是個文件編輯程式,使用者編輯到一半的文件就這樣不見了,不氣的跳腳才奇怪。假設樂觀的工程師如你,也是會考慮使用者經驗,又專注完美近乎科科吧!XD

要避免字串複製的buffer overflow,你還可以選擇用strncpy。如果buffer比較小,頂多就是來源字串塞不進去,之後你還可以做一些比較友善的處理。(例如跳出一個切腹道歉的視窗,幫使用者自動儲存文件,之後再crash。噗~)

另外一個方式也沒忘記,你可以覆蓋預設的invalid parameter handler,指到自製的例外處理函式。如果你想要集中處理的話,這樣可以讓所有的安全版的CRT function全都使用同一個handler。

結論:多想兩分鐘,你其實也可以有另一個選擇。XD

No comments: