JPCERT コーディネーションセンター

EXP09-C. 型や変数のサイズは sizeof を使って求める

EXP09-C. 型や変数のサイズは sizeof を使って求める

型のサイズをアプリケーションにハードコードしないこと。アラインメントやパディング、標準データ型の違い(例: 32ビットのポインタ対64ビットのポインタ)により、たいていの型のサイズはコンパイラ間で異なるし、同じコンパイラの異なるバージョンの間で同じ型のサイズが異なる場合さえある。sizeof演算子を使用してサイズを求めることで、コードの意図がより明確になり、コンパイラやコンパイラのバージョンの違いがコードに影響しないようにすることができる。

型のアラインメント要求が構造体のサイズに影響することもある。たとえば、以下に示す構造体のサイズは処理系依存である。

struct s {
  int i;
  double d;
};

たとえば32ビット整数と64ビット double を想定した場合、アラインメント規則次第で型のサイズは12バイト ~ 16バイトとなりうる。

違反コード

以下のコード例では、可変長の行を持つ整数の二次元配列を宣言しようとしている。整数が64ビットのプラットフォームでは、ループは割り当てられたメモリ領域外にアクセスするだろう。

/* 32ビットポインタ, 32ビット整数を仮定 */
size_t i;
int **matrix = (int **)calloc(100, 4);
if (matrix == NULL) {
  /* エラー処理 */
}

for (i = 0; i < 100; i++) {
  matrix[i] = (int *)calloc(i, 4);
  if (matrix[i] == NULL) {
    /* エラー処理 */
  }
}
適合コード

以下の適合コードでは、ハードコードされた値 4sizeof(int *) に置き換えている。

size_t i;
int **matrix = (int **)calloc(100, sizeof(*matrix));
if (matrix == NULL) {
  /* エラー処理 */
}

for (i = 0; i < 100; i++) {
  matrix[i] = (int *)calloc(i, sizeof(**matrix));
  if (matrix[i] == NULL) {
    /* エラー処理 */
  }
}

sizeof 演算子をメモリ確保関数に使用することに関する議論は「MEM02-C. Immediately cast the result of memory allocation function call into a pointer to the allocated type」を参照のこと。

例外

EXP09-EX1: C 標準では、sizeof(char) == 1 であることが明確に宣言されている。したがって、文字や文字配列に基づくサイズは sizeof を使わないで評価してもよい。この例外は、char* やその他のデータ型にはあてはまらない。

リスク評価

ハードコードされたサイズの書かれたコードを移植するとバッファオーバーフローやそれに関連した脆弱性につながるおそれがある。

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

EXP09-C

P6

L2

自動検出(最新の情報はこちら

ツール

バージョン

チェッカー

説明

Compass/ROSE

 

 

このレコメンデーションの違反を検出できる。とくに、malloc(), calloc(), realloc() のサイズ引数をチェックし、引数式にsizeof演算子が見つからない場合を警告する。もし返り値がchar *に代入されるのなら警告しない。この場合は文字列を割り当てており、sizeof(char) == 1 であるがゆえ sizeof 演算子は必要ないのである。

ECLAIR 1.1 funcalls このレコメンデーションの違反を検出できる。とくに、 malloc()calloc()、または realloc() で型のサイズが使用される場合を考慮し、サイズ引数で sizeof 演算子が使用されない場合や、サイズ引数で sizeof が使用されるが返り値の型が sizeof の引数の型へのポインタでない場合に、これらの関数の警告を行う。もし返り値が char * に代入されるのなら警告しない。

LDRA tool suite

V. 8.5.4

201 S

部分的に実装済み

関連するガイドライン
CERT C++ Secure Coding Standard EXP09-CPP. Use sizeof to determine the size of a type or variable
MITRE CWE CWE 805, Buffer access with incorrect length value
翻訳元

これは以下のページを翻訳したものです。

EXP09-C. Use sizeof to determine the size of a type or variable (revision 79)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter