検索
連載

動的メモリ管理に関する脆弱性もいちど知りたい、セキュアコーディングの基本(6)(3/4 ページ)

本連載の第2回と第3回では主にスタックバッファオーバーフローについて説明しました。今回はそれに関連して、スタックバッファオーバーフロー検知の仕組みに関する話を紹介し、その後、動的メモリ管理に関連する脆弱性を見ていきたいと思います。

Share
Tweet
LINE
Hatena

Cの動的メモリ管理

 ここからは動的メモリ管理に関する話題を取り上げたいと思います。動的メモリ管理の仕組みはCに特有のもので、この仕組みに関連する脆弱性としてヒープバッファオーバーフロー、double-free、use-after-freeなどがあります。これらは攻撃によって任意のコード実行につながる可能性のある、脅威度の高い脆弱性です。

 われわれが普段使っているWindowsやLinuxといったOS環境で実行されるプログラムは、おおよそ以下のようなメモリレイアウトで実行されています(図3)。


図3 プログラム実行時のメモリレイアウト例

 動的メモリ管理で扱うのはヒープ(heap)領域の部分です。Cであれば、malloc()やfree()などの関数、そしてC++ではこれらの関数に加えてコンストラクターやデストラクターなどの処理でヒープ領域が活用されています。

 ヒープ領域を用意する目的は、メモリを効率的に使うことにあります。関数に引数を渡すときや関数内部で使うローカル変数については、スタック領域が活用されています。また、プログラムの実行開始から終了までずっと存在しなければならないオブジェクトについては、static変数を使うのが適切でしょう。それ以外の、

  • プログラム実行期間のごく一部でだけ必要
  • 複数の関数をまたいで使いたい
  • 大量のデータを扱いたいのでスタックに積むのは不適切

などといった要求には、動的メモリ管理の仕組みを使うことで柔軟に対応することができます。

 ヒープ領域の管理をごく単純化すると、「プログラムの起動時に大きな配列(空きメモリブロックを要素とする配列)を用意し、プログラム実行中に発生するメモリ要求や解放に対応して、どの要素が使用中なのか、どの要素が使用されていないのかを管理する」というイメージになります。

 実際にはいろいろな大きさの要素(メモリブロック)を扱う必要があるので、配列ではなく連結リストの構造で管理するとか、隣接する空きメモリブロックはまとめて1つとして扱おうとか、要求されたサイズに最も近い空きメモリブロックを素早く選択するにはどのようなアルゴリズムで処理するか、といったさまざまな工夫があります。

 通常、この仕組みは標準ライブラリの内部に実装されているので、malloc()関数などの実装コードを追いかけてみると、どのように管理されているかが分かります。

 空きメモリを管理する基本的なアルゴリズムに関する議論をじっくり読みたい方には、Donald Knuth先生の「The Art of Computer Programming」シリーズの中の解説をお薦めします。Volume 1の「§2.5 動的メモリ配置」を参照してください。

The Art of Computer Programming

Volume 1 Fundamental Algorithms Third Edition日本語版

http://ascii.asciimw.jp/books/books/detail/4-7561-4411-X.shtml


Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る