【だぶるふりー】

ダブルフリー とは?

最終更新:
💡 解放済みのメモリを、もう一度解放してしまう

動的に確保した同じメモリ領域を、解放したあとに再び解放してしまうバグ。プログラムの停止やメモリ管理情報の破損につながり、条件によっては攻撃に悪用される。

📌 このページのポイント
同じ確保領域を二重に解放 ① 確保ptr使用中malloc()② 解放ptr解放済みfree(ptr)③ 再び解放ptr同じ領域へfree(ptr)停止やメモリ破損につながる条件によっては攻撃に悪用される解放の責任を一つにするNULL代入だけでは別のポインタは変わらない
確保したメモリを解放し、その後で再び解放してしまう例。結果は実装や状態によって異なり、停止やメモリ破損につながる。
ひよこ ひよこ
ダブルフリーって、同じメモリを2回解放するってこと?
ペンギン先生 ペンギン先生
そうだよ。たとえばmalloc()で確保した領域をfree()で解放したあと、再び同じ領域をfree()に渡してしまうバグだね。解放は、使い終わった領域を再利用できるようにする操作なんだ。
ひよこ ひよこ
どうして2回呼んでしまうの?
ペンギン先生 ペンギン先生
エラー時の後片付けと通常の後片付けで同じ領域を解放したり、別々の処理がそれぞれ解放の責任を持つと思い込んだりすると起こるよ。変数名が違っても、同じ確保領域を指すポインタなら二重解放になり得るんだ。
ひよこ ひよこ
2回目で必ずヒープの台帳が壊れるの?
ペンギン先生 ペンギン先生
結果はメモリ管理の実装や状態によって違うよ。検出されてプログラムが止まる場合も、管理情報が壊れる場合もある。条件がそろうと不正なメモリ書き込みや任意コード実行に悪用されることもあるけれど、毎回同じ結果になるわけではないんだ。
ひよこ ひよこ
解放後に使うバグとは違うの?
ペンギン先生 ペンギン先生
Use-After-Freeは、解放した領域をあとから読み書きするバグだよ。ダブルフリーは、解放処理をもう一度行うバグ。どちらも領域の寿命の管理に関係するけれど、問題になる操作が違うんだ。
ひよこ ひよこ
NULLにすれば防げる?
ペンギン先生 ペンギン先生
free()のあと、そのポインタをNULLにするのは対策の一つだよ。free(NULL)は何もしない。ただし別の変数にコピーしたポインタまでは変わらないので、誰が一度だけ解放するかを決めることも大切。AddressSanitizerを使った実行時検査や静的解析も役立つよ。
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「ダブルフリー」って出てきたら「同じメモリを二重に解放してしまうバグ」と思えばだいたいOK!
📖 おまけ:英語の意味
「Double Free」 = 二重解放
💬 Freeはここではメモリを解放すること。すでに解放した領域を、もう一度解放してしまうという意味だよ。

参考資料

← 用語集にもどる