CXX.OVERWRITE_CONST_CHAR
定数文字列を上書きする試み
非 const 文字変数へのポインターに文字列リテラルを割り当てるたびに、文字列リテラルを格納したメモリは一部でも全部でも変更できないため、その値を変更する前にそれが定数であるかを検証する必要があります。
CXX.OVERWRITE_CONST_CHAR チェッカーは、非 const 文字変数への任意のポインターに割り当てられた文字列リテラルの変更を試みるコードを報告します。
脆弱性とリスク
文字列リテラルの変更は未定義の動作です。それらは読み取り専用メモリに保存されることが多いため、アクセス違反エラーが発生する可能性があります。
軽減と防止
この欠陥を防ぐ最も簡単な方法は、スタックまたはヒープのどちらかで非 const メモリに文字列リテラルをコピーしてから、非 const コピーを変更することです。
脆弱コード例
コピー
#include <string.h>
int var (int);
int var (int isKnown)
{
unsigned char * obj = "";
if (isKnown)
{
strcpy(obj, "known");
// Writing over read-only string
}
else
{
strcpy(obj, "unknown");
}
return 0;
}
この例では、'obj' は char 型変数のポインターであり、“” (文字列の const 型) で割り当てられています。次に、別の文字列を 'obj' 変数にコピーしようとしており、アクセス違反エラーが発生する可能性があります。Klocwork は、10 行目と 15 行目でこの脆弱性を CXX.OVERWRITE_CONST_CHAR の欠陥として報告し、「文字列リテラルを上書きする試み」を表示します。
修正コード例
コピー
#include <string.h>
int var (int);
int var (int isKnown)
{
unsigned char obj[10] = "";
if (isKnown)
{
strcpy(obj, "known");
// Now writing over non-const string
}
else
{
strcpy(obj, "unknown");
}
return 0;
}
修正されたコード例では、'obj' は文字の配列になっており、7 行目での割り当ては、配列のメモリへの空の文字列リテラルのコピーになっています。10 行目または 15 行目で変更が発生すると、非 const メモリで変更が行われます。