新的C++安全編碼規則出爐
新的安全編碼規則
在Visual Studio v16.8 Preview 3中,我們添加了一些新的安全編碼規則,來幫助開發者更容易找到一些更加容易導致Bug的編碼錯誤,這些錯誤涵蓋了從簡單的功能缺失到嚴重的安全漏洞問題。
這些規則都是來自於真實世界的產品缺陷報告,在微軟,我們會在我們的每一款產品中執行這些安全編碼規則,以滿足產品在安全和合規方面的需求。
在今天的文章中,我們會介紹VARIANT及其衍生的VARIANTARG和PROPVARIANT結構相關的編碼規則。為了更加容易的使用這些規則,我們構建了一個名為VariantClear的程式碼分析擴充套件工具,這個擴充套件將會檢測程式碼是否符合預期的編碼規則。為什麼叫這個擴充套件為VariantClear呢?因為它的主要目的就是為了檢測那些誤用VariantClear函式的程式碼。
VariantClear擴充套件將會檢測出如下的程式碼警告:
> C33001: VARIANT ‘var’ 在它被反初始化時被重置。
> C33004: VARIANT ‘var’ 在它被初始化之前被重置,且它被標記為輸出(Out)引數。
> C33005: VARIANT ‘var’ 被標記為輸入或輸入/輸出引數,但是它沒有被初始化。
VariantClear 規則
VARIANT是一個非常方便好用的結構體,可以使用它來對各種不同的資料型別進行資料交換。在任意時刻,它都可以被用來表示一個數據型別,或者空值。在這個結構體中有一個名為VARIANT::vt的成員,用來表示被封裝的資料型別或者空值型別。
一個VARIANT結構必須被在使用或者傳入到其他程式碼之前進行顯式的初始化。否則,就會出現訪問隨機記憶體資料的問題,進而帶來各種意想不到的Bug。
當一個VARIANT結構體不再使用的時候,也需要將它顯式的重置。否則,會出現潛在的資源洩露或者對已離開其作用域的資源的錯誤訪問。
通常,可以使用VariantInit函式來對一個VARIANT結構體進行初始化。對應地,可以使用VariantClear函式對它進行重置。
另外,還有一些對VARIANT結構的高階封裝結構,例如CComVariant和_variant_t。
在構造階段,它們的建構函式將呼叫VariantInit來對結構進行初始化,並將其資料型別設定為空值型別。
VariantClear規則將嘗試對目的碼進行分析,並對那些沒有對VARIANT結構體進行合適的初始化或反初始化的程式碼給出提示。
C33001警告
當一個未初始化的VARIANT結構體傳遞給一個會使用VariantClear函式來重置VARIANT的API的時候,會觸發這個警告。
因為,這類API會期待傳入的VARIANT結構體是已經初始化的。但是很多開發者總是會忘記初始化這個步驟。
下面是一個簡單的例子:
在上面的程式碼中,會觸發C33001警告。因為VARIANT結構體僅在some_condition為true時才會被初始化。如果這個標誌為false,則當它傳遞給VariantClear函式時是未初始化的。
為了修復這個問題,我們可以以如下的方式修改程式碼,確保呼叫VariantClear時結構體肯定是經過初始化的。 如下圖所示:
C33004警告
當一個VARIANT結構體被標記為Out引數,而這個引數可能在輸入的時候並沒有被初始化,當它進一步被傳遞給一個會使用VariantClear函式來重置這個結構體的API時,會觸發此警告。
當呼叫一個函式的時候,一個被標記為Out的引數並不一定會被初始化。只有當它函式返回的時候,它才會被初始化。
從更加安全的角度來看,在進行程式碼分析的時候,一個Out引數被認為是未初始化的。如果當這個引數被傳遞到一個函式,而這個函式可能會使用VariantClear操作這個結構體時,它會嘗試重置這個結構體,或者使用記憶體裡的隨機資料。下面是一個簡單的例子:
為了修復這個問題,可以在訪問Out引數時對它進行初始化,如下圖所示:
C33005警告
當一個未初始化的VARIANTBeijing傳遞給一個需要輸入型引數的函式的時候,會觸發此警告。
如下圖所示:
通過這個C33005警告,我們可以更加清楚地明白為什麼C44004警告會被觸發。
當一個未經初始化的VARIANT的結構體被當做一個輸入型引數傳遞的時候,會顯式地違反C33005規則。
如何在Visual Studio中啟用新的規則
下圖中列出了可以用在工程上的不同的規則,可以根據這個表格在Visual Studio中啟用規則。
總結
當裡個當,宣告變數的時候,還是不要忘記初始化。
最後
Microsoft Visual C++團隊的部落格是我非常喜歡的部落格之一,裡面有很多關於Visual C++的知識和最新開發進展。大浪淘沙,如果你對Visual C++這門古老的技術還是那麼感興趣,則可以經常去他們那(或者我這)逛逛。
本文來自:《New Safety Rules in C++ Code Analysis》