ABV.UNICODE.NNTS_MAP
マッピング関数内の非 null 終了文字列のバッファオーバーフロー
ABV.UNICODE.NNTS_MAP は、MultiByteToWideChar マッピング関数と WideCharToMultiByte マッピング関数が非 null 終了文字列を持つことによって引き起こされるバッファオーバーラン状態をチェックします。通常、このチェッカーは、いずれかの関数が自動的に出力文字列で終了しないときの状態を検出します。
MultiByteToWideChar マッピング関数と WideCharToMultiByte マッピング関数の演算の詳細については、MSDN の Web サイトを参照してください。
脆弱性とリスク
これらのマッピング関数を不適切に使用すると、バッファオーバーフローを引き起こしてアプリケーションのセキュリティが低下する可能性があります。この潜在的な状態を避けるには、関数の出力文字列を null で終了させることが重要です。
脆弱コード例
コピー
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
int main()
{
wchar_t wstrTestNNTS[] = L"0123456789ABCDEF";
char strTestNNTS[16];
int res = WideCharToMultiByte(CP_UTF8, 0, wstrTestNNTS, -1, strTestNNTS, 16, NULL, NULL);
printf("res = %d\n", res);
printf("strTestNNTS = %s\n", strTestNNTS);
return 0;
}
Klocwork は、この関数では文字列の最後に null 終了文字列を書き込む保証がないため、関数 'WideCharToMultiByte' に対して NNTS レポートを生成します。ターゲットバッファが戻り値のチェックなしに使用される場合、非 null 終了文字列はオーバーフローする可能性があります。
修正コード例
コピー
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
int main()
{
wchar_t wstrTestNNTS[] = L"0123456789ABCDEF";
char strTestNNTS[16];
int res = WideCharToMultiByte(CP_UTF8, 0, wstrTestNNTS, -1, strTestNNTS, 16, NULL, NULL);
if (res == sizeof(strTestNNTS)) {
strTestNNTS[res-1] = NULL;
} else {
strTestNNTS[res] = NULL;
}
printf("res = %d\n", res);
printf("strTestNNTS = %s\n", strTestNNTS);
return 0;
}
修正したコードでは、関数の戻り値が 11 行目と 14 行目でチェックされ、null 終了文字列が必要に応じて追加されます。
関連チェッカー
外部参考資料
- CERT ARR00-C: 配列の仕組みを理解する
- CERT ARR30-C: 範囲外のポインターまたは配列添え字を形成したり使用したりしない
- CERT ENV01-C: 環境変数のサイズについて仮定を行わない
- CWE-119: メモリバッファの範囲内の操作の不適切な制限
- CWE-124: バッファアンダーライト ('バッファアンダーフロー')
- CWE-125: 範囲外の読み取り
- CWE-176: ユニコードエンコーディングの不適切な取り扱い
- CWE-787: 範囲外の作成
- CWE-806: ソースバッファのサイズを使用したバッファアクセス
- STIG-ID:APP3590.1 バッファオーバーフローに脆弱なアプリケーション
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。