ABV.ANY_SIZE_ARRAY
バッファオーバーフロー - サイズが指定されていない配列インデックスが範囲外
ABV.GENERAL と同様、ABV.ANY_SIZE_ARRAY チェッカーは配列範囲の違反配列の範囲外の配列要素へのアクセスを検出する汎用のチェッカーです。ABV.ANY_SIZE_ARRAY は、サイズが指定されていない配列 (通常は実行時に決定される) をコードが参照するときに欠陥をチェックします。
次の例で、配列定義で使用される別の C 標準のテクニックを示します。配列サイズを決定するときと、コード内でその後にメモリを割り当てるときに、C99 スタイルを使用します。このような状況では、Klocwork から ABV.ANY_SIZE_ARRAY フラグが立てられます。
struct OldStyle{
/* other fields */
unsigned char array[1];
};
struct GccStyle{
/* other fields */
unsigned char array[0];
};
struct C99Style{
/* other fields */
unsigned char array[];
};
ABV.ANY_SIZE_ARRAY は、C99 テクニックを使用している場合に、配列のサイズが指定されていない状況での欠陥をチェッカーの結果から除去するためにしばしば使用されます。この欠陥にフラグを立てない、または ABV 欠陥から除外する場合は、このチェッカーをオフにします。
脆弱性とリスク
バッファオーバーフローの結果には、有効なデータの上書きや、恣意的なコードや潜在的に悪意のあるコードの実行なども含まれます。しかし、任意サイズの配列を使用してそれらを丁寧に管理している場合は、ABV.ANY_SIZE_ARRAY チェッカーをオフにするのがベストな場合がよくあります。
コード例 1
typedef struct NumericData {
int varlen;
char n_data[1];
} NumericData;
#define MAX_LEN 2048
void init(char *data) {
if (strlen(data) > MAX_LEN) return;
NumericData *X = (NumericData*)malloc(sizeof(NumericData) + strlen(data));
X->varlen = strlen(data);
int k;
for (k = 0; k < strlen(data); k++) {X->n_data[k] = data[k];}
X->n_data[k-1] = '\0';
}
Klocwork は 13 行目について、変数の長さの配列 'n_data' のインデックスが範囲外になる可能性を指摘する、バッファオーバーフローレポートを生成します:サイズが指定されていない配列 'n_data' のインデックス値が -1 になる可能性があるためです。しかし、これは実際のコーディングテクニックとしては正しい用法であり、このような場合、通常、設計者はこの欠陥がレポートされることを望まず、ABV.ANY_SIZE_ARRAY チェッカーを無効にすることがあります。
コード例 2
#define MAXL 255
typedef struct info_t_{
unsigned char code;
unsigned char length[2];
unsigned char value[1];
} info_t;
int getshort(unsigned char *l);
void foo(info_t *id){
unsigned char buf[MAXL];
int len = getshort(id->length);
if ((len > 0) && (len <= MAXL)) {
memcpy(buf, &id->value[0], len);
}
}
これは正しい用法であるにもかかわらず、欠陥がレポートされるもう 1 つの例です。Klocwork は 14 行目でバッファオーバーフローレポートを生成しており、可変長配列 'id->value' のインデックスが範囲外である場合があり、サイズが指定されていない配列 '&id->value[0]' はインデックス値 0 ~ 254 を使用する可能性があることを示しています。
関連チェッカー
外部参考資料
- CERT ARR00-C: 配列の仕組みを理解する
- CERT ARR30-C: 範囲外のポインターまたは配列添え字を形成したり使用したりしない
- CERT CTR50-CPP: コンテナーインデックスと反復子が有効な範囲内に収まるようにする
- CERT ENV01-C: 環境変数のサイズについて仮定を行わない
- CWE-119: メモリバッファの範囲内の操作の不適切な制限
- CWE-124: バッファアンダーライト ('バッファアンダーフロー')
- CWE-125: 範囲外の読み取り
- CWE-787: 範囲外の作成
- CWE-788: バッファ終端後部のメモリ位置のアクセス
- CWE-805: 不正確な長さの値でのバッファアクセス
- STIG-ID:APP3590.1 バッファオーバーフローに脆弱なアプリケーション
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。