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

MEM08-C. realloc() は動的に割り当てられた配列のサイズ変更にのみ使用する

MEM08-C. realloc() は動的に割り当てられた配列のサイズ変更にのみ使用する

C 標準 [ISO/IEC 9899:2011] セクション 7.22.3.5 は、realloc(ptr, size) 関数を以下のように定めている。

ptr が指す古いオブジェクトを解放し、大きさが size である新しいオブジェクトへのポインタを返す。新しいオブジェクトの内容は、新しいオブジェクトの大きさと古いオブジェクトの大きさのうち小さい方の大きさまでの部分で、解放する前の古いオブジェクトの内容と同じでなければならない。古いオブジェクトの大きさを超えた部分の新しいオブジェクトのバイトの値は、不定とする。

違反コード

以下のコード例では、realloc() を使用して特定の型のオブジェクトに記憶域を割り当てているが、あたかも別の型のオブジェクトであるかのように初期化している。

#include <stdlib.h>

typedef struct gadget gadget;
struct gadget {
  int i;
  double d;
  char *p;
};

typedef struct widget widget;
struct widget {
  char *q;
  int j;
  double e;
};

gadget *gp;
widget *wp;

/* ... */

wp = (widget *)realloc(gp, sizeof(widget));

このコード例では、realloc()widget 用に記憶域を割り当てているが、widget の型があたかも gadget の型であるかのように初期化している。これにより、char * から int、または int から char * への暗黙的な変換が行われるだろう。場合によっては、ポインタの値で double を初期化することも考えられる。

適合コード

プログラムで realloc() を使用するのは、動的に割り当てた配列のサイズを変更する場合に限るべきである。1 つの配列を、以下の適合コードに示すように、サイズは異なるが同じ型の要素を持つ別の配列として再割り当てすることができる。

#include <stdlib.h>

typedef struct widget widget;
struct widget {
  char *q;
  int j;
  double e;
};

widget *wp;
widget *wq;

/* ... */

wp = (widget *)malloc(10 * sizeof(widget));

/* ... */

wq = (widget *)realloc(wp, 20 * sizeof(widget));

/* ... */

wp = (widget *)realloc(wq, 15 * sizeof(widget));

このプログラムは malloc() を呼び出し、10個の widget からなる配列に記憶域を割り当てる。その後、realloc() を呼び出し、この配列のサイズを 20 個の widget の配列に変更している。さらにその後、realloc() を再度呼び出して、配列のサイズを 15 個の widget に縮小している。

リスク評価

動的に割り当てられた配列以外のオブジェクトの記憶域のサイズを変更すると、互換性のないデータ型に暗黙的に変換されることがある。

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

MEM08-C

P18

L1

自動検出

ツール

バージョン

チェッカー

説明

Compass/ROSE

 

 

realloc() のポインタ引数の型がキャストの型と一致しているかを確認することで、このレコメンデーションの違反を検出できる。

ECLAIR 1.1 funcalls realloc() のポインタ引数の型がキャストの型と一致しているかを確認することで、このレコメンデーションの違反を検出できる。
関連するガイドライン
ISO/IEC TR 24772:2013 Type-breaking Reinterpretation of Data [AMV]
MITRE CWE CWE-628, Function call with incorrectly specified arguments
参考資料
[[ISO/IEC 9899:2011] Section 7.22.3.5, "The realloc Function"
翻訳元

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

MEM08-C. Use realloc() only to resize dynamically allocated arrays (revision 47)

Top へ

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