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

MEM01-C. free() した直後のポインタには新しい値を代入する

MEM01-C. free() した直後のポインタには新しい値を代入する

ダングリングポインタは、二重解放や解放済みメモリへのアクセスといった攻撃可能な脆弱性につながる可能性がある。ダングリングポインタを排除し、メモリ関連の多数の脆弱性を回避する簡単で効果的な方法は、メモリを解放した後のポインタに NULL あるいは、他の有効なオブジェクトのアドレスを設定することである。

違反コード

以下のコード例では、メッセージを使ってメッセージ自体の処理方法を決定している。message_type は整数、message は動的に割り当てられた文字配列へのポインタであると仮定する。message_typevalue_1 と等しい場合、メッセージはそれに応じて処理される。message_typevalue_2 と等しい場合にも同様の処理が行われる。しかし、message_type == value_1 の結果が真で、message_type == value_2 も真の場合、message は2度解放され、二重解放の脆弱性になる。

char *message;
int message_type;

/* message と message_type を初期化 */

if (message_type == value_1) {
  /* message type 1 を処理 */
  free(message);
}
/* ...*/
if (message_type == value_2) {
   /* message type 2 を処理 */
  free(message);
}
適合コード

ナルポインタに対して free() を呼び出しても、何も行われない。メモリ解放後の messageNULL を設定することで、message ポインタを使用して同じメモリを複数回解放してしまう可能性は排除される。

char *message;
int message_type;

/* message と message_type を初期化 */

if (message_type == value_1) {
  /* message type 1 を処理 */
  free(message);
  message = NULL;
}
/* ...*/
if (message_type == value_2) {
  /* message type 2 を処理 */
  free(message);
  message = NULL;
}
例外

MEM01-EX1: free() の直後にスコープ外になるような静的でない変数については、値をクリアする必要はない。その変数へのアクセスはできなくなるためである。

void foo(void) {
  char *str;
  /* ... */
  free(str);
  return;
}
リスク評価

メモリ解放後のポインタを NULL または別の有効な値に設定することで、手間をかけず容易にダングリングポインタを減らすことができる。ダングリングポインタは、メモリの複数回解放や解放済みメモリへの書き込みにつながる可能性があり、脆弱なプロセスの権限で任意のコードを実行させる攻撃が行われる危険がある。

レコメンデーション

深刻度

可能性

修正コスト

優先度

レベル

MEM01-C

P9

L2

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

ツール

バージョン

チェッカー

説明

Compass/ROSE

 

 

 

Coverity

6.5

USE_AFTER_FREE

メモリの複数回解放や解放済みメモリに対する読み取り/書き込みを検出できる。

関連するガイドライン
CERT C++ Secure Coding Standard MEM01-CPP. Store a valid value in pointers immediately after deallocation
ISO/IEC TR 24772:2013 Dangling References to Stack Frames [DCM]
Dangling Reference to Heap [XYK]
Off-by-one Error [XZH]
MITRE CWE CWE-416, Use after free
CWE-415, Double free
参考資料
[Seacord 2013] Chapter 4, "Dynamic Memory Management"
[Plakosh 2005]  
翻訳元

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

MEM01-C. Store a new value in pointers immediately after free() (revision 83)

Top へ

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