STR33-C. ワイド文字の文字列サイズは正しく求める
このガイドラインは廃止され、以下のガイドラインに統合されました。
ワイド文字列をナロー文字列やマルチバイト文字列として誤って解釈すると、そのサイズを正しく求められないかもしれない。たとえば、誤った文字列のサイズを利用して不十分なサイズのバッファを割り当てると、バッファオーバーフローにつながる可能性がある。
違反コード (不適切な関数呼び出し)
以下のコード例では、strlen()
関数を使ってワイド文字の文字列のサイズを調べている。
wchar_t wide_str1[] = L"0123456789"; wchar_t *wide_str2 = (wchar_t *)malloc(strlen(wide_str1) + 1); if (wide_str2 == NULL) { /* エラー処理 */ } /* ... */ free(wide_str2); wide_str2 = NULL;
strlen()
関数は、null 終端バイト文字列中の文字数を null 終端バイトより前までカウントする。しかし、上記の例のような ASCII 文字に対応するワイド文字には null バイトが含まれる。そのため、strlen()
関数は最初の null バイトよりも前のバイト数を返すことになってしまう。
処理系固有の詳細
Microsoft Visual Studio 2010 は型に互換性がないという警告を出すため、このコードはコンパイルされない。GCC 4.6.1 も型に互換性がないという警告を出すが、コードのコンパイルは行われる。Linux の GCC 4.3.2 も型に互換性がないという警告を出す。
違反コード (サイズが正しく計算されていない)
以下のコード例では、wcslen()
関数を使ってワイド文字の文字列の文字数を調べているが、文字列の長さと sizeof(wchar_t)
を乗じていない。
wchar_t wide_str1[] = L"0123456789"; wchar_t *wide_str3 = (wchar_t *)malloc(wcslen(wide_str1) + 1); if (wide_str3 == NULL) { /* エラー処理 */ } /* ... */ free(wide_str3); wide_str3 = NULL;
適合コード
以下の適合コードでは、終端文字も含むワイド文字列のコピーを格納するために必要なバイト数を正しく計算している。
wchar_t wide_str1[] = L"0123456789"; wchar_t *wide_str2 = (wchar_t *)malloc( (wcslen(wide_str1) + 1) * sizeof(wchar_t) ); if (wide_str2 == NULL) { /* エラー処理 */ } /* ... */ free(wide_str2); wide_str2 = NULL;
リスク評価
ワイド文字の文字列のサイズを正しく計算しないと、バッファオーバーフローや任意のコード実行を引き起こす可能性がある。
ルール |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
STR33-C |
高 |
高 |
中 |
P18 |
L1 |
自動検出
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Compass/ROSE |
|
|
このルールの違反を検出できる。ROSEが |
V. 9.1 |
SV.FMT_STR.BAD_SCAN_FORMAT |
|
|
Splint |
V. 3.1.1 |
|
|
関連するガイドライン
MITRE CWE | CWE-119, Failure to constrain operations within the bounds of an allocated memory buffer CWE-135, Incorrect calculation of multi-byte string length CWE-805, Buffer access with incorrect length value |
参考資料
[Seacord 2013] | Chapter 2, "Strings" |
[Viega 2005] | Section 5.2.15, "Improper String Length Checking" |
翻訳元
これは以下のページを翻訳したものです。
STR33-C. Size wide character strings correctly (revision 76)