MEM01-C. free() した直後のポインタには新しい値を代入する
ダングリングポインタは、二重解放や解放済みメモリへのアクセスといった攻撃可能な脆弱性につながる可能性がある。ダングリングポインタを排除し、メモリ関連の多数の脆弱性を回避する簡単で効果的な方法は、メモリを解放した後のポインタに NULL
あるいは、他の有効なオブジェクトのアドレスを設定することである。
違反コード
以下のコード例では、メッセージを使ってメッセージ自体の処理方法を決定している。message_type
は整数、message
は動的に割り当てられた文字配列へのポインタであると仮定する。message_type
が value_1
と等しい場合、メッセージはそれに応じて処理される。message_type
が value_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()
を呼び出しても、何も行われない。メモリ解放後の message
に NULL
を設定することで、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)