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) { /* エラー処理 */ } }
適合コード
以下の適合コードでは、ハードコードされた値 4
を sizeof(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 |
|
|
このレコメンデーションの違反を検出できる。とくに、 |
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)