ここからは動的メモリ管理に関する話題を取り上げたいと思います。動的メモリ管理の仕組みはCに特有のもので、この仕組みに関連する脆弱性としてヒープバッファオーバーフロー、double-free、use-after-freeなどがあります。これらは攻撃によって任意のコード実行につながる可能性のある、脅威度の高い脆弱性です。
われわれが普段使っているWindowsやLinuxといったOS環境で実行されるプログラムは、おおよそ以下のようなメモリレイアウトで実行されています(図3)。
動的メモリ管理で扱うのはヒープ(heap)領域の部分です。Cであれば、malloc()やfree()などの関数、そしてC++ではこれらの関数に加えてコンストラクターやデストラクターなどの処理でヒープ領域が活用されています。
ヒープ領域を用意する目的は、メモリを効率的に使うことにあります。関数に引数を渡すときや関数内部で使うローカル変数については、スタック領域が活用されています。また、プログラムの実行開始から終了までずっと存在しなければならないオブジェクトについては、static変数を使うのが適切でしょう。それ以外の、
などといった要求には、動的メモリ管理の仕組みを使うことで柔軟に対応することができます。
ヒープ領域の管理をごく単純化すると、「プログラムの起動時に大きな配列(空きメモリブロックを要素とする配列)を用意し、プログラム実行中に発生するメモリ要求や解放に対応して、どの要素が使用中なのか、どの要素が使用されていないのかを管理する」というイメージになります。
実際にはいろいろな大きさの要素(メモリブロック)を扱う必要があるので、配列ではなく連結リストの構造で管理するとか、隣接する空きメモリブロックはまとめて1つとして扱おうとか、要求されたサイズに最も近い空きメモリブロックを素早く選択するにはどのようなアルゴリズムで処理するか、といったさまざまな工夫があります。
通常、この仕組みは標準ライブラリの内部に実装されているので、malloc()関数などの実装コードを追いかけてみると、どのように管理されているかが分かります。
空きメモリを管理する基本的なアルゴリズムに関する議論をじっくり読みたい方には、Donald Knuth先生の「The Art of Computer Programming」シリーズの中の解説をお薦めします。Volume 1の「§2.5 動的メモリ配置」を参照してください。
Volume 1 Fundamental Algorithms Third Edition日本語版
http://ascii.asciimw.jp/books/books/detail/4-7561-4411-X.shtml
Copyright © ITmedia, Inc. All Rights Reserved.