Delphi および C++ Builder の VCL ライブラリのバッファ オーバーフロー

Abstract: LoadFromFileを使用した VCL BMPファイル処理における潜在的な脆弱性に対する、ソースコードの修正方法、および hotfixのご案内

BMP ファイルの処理を行う VCL ライブラリに脆弱性が見つかりました。その結果、バッファ オーバーフローを発生させることで、クライアント側の攻撃を行う任意のコードを実行できる、巧妙な BMP ファイルを作成するという攻撃が可能になっています。

本問題に対する対策を公開したのち、VCL における BMP ファイルの処理の見直しを進めてきました。その結果として、Delphi / C++Builder / RAD Studio XE7, XE6 および XE5に対し、VCL における BMP ファイル読み込み処理を改善したXE7, XE6 および XE5 用の hotfixを公開しました。

  1. hotfixを入手し修正プログラムを適用してください。
    1. XE7 : http://cc.embarcadero.com/item/30010
    2. XE6 : http://cc.embarcadero.com/item/29913
    3. XE5 : http://cc.embarcadero.com/item/30014
  2. 作成された VCLアプリケーションの再構築(再ビルド)を行ってください。

Delphi および C++Builder の XE4 および、それ以前のバージョンの場合、該当する VCLアプリケーションに対し以下の修正を行ってください。

  1. Vcl.Graphics.pasを修正します。 (修正手順は以下をご覧ください)
  2. 該当するプロジェクトに修正した Vcl.Graphics.pasを追加します。
  3. C++Builderの場合は [プロジェクト | オプション | パッケージ | 実行時パッケージ ]で「実行時パッケージを使ってリンク」を False(チェックを外す)にします。
  4. アプリケーションを再構築(再ビルド)します。

※ なお、2014/09/18 に公開された対策箇所は2箇所でしたが、今回の対策では対策箇所が1箇所追加されて3箇所となっている点に注意してください。

Vcl.Graphics.pas の修正:

コード修正 1

  • 変数名とスコープは、製品のバージョンによって多少異なる場合があります。構文と以下のスクリーンショットは XE5のものです。
  • PaletteFromDIBColorTable関数を見つけます。
  • function PaletteFromDIBColorTable に対し、DIBHandle = 0 の際 Pal.palNumEntries へ値を代入する行の前に以下のコードを追加します。(画面イメージ参照)
  if ColorCount > 256 then
      InvalidGraphic({$IFNDEF CLR}@{$ENDIF}SInvalidBitmap);;

Hide image
Click to see full-sized image

コード修正 2

  • 変数名とスコープは、製品のバージョンによって多少異なる場合があります。構文と以下のスクリーンショットは XE7のものです。
  • TMetafile.ReadEMFStream関数を見つけます。
  • function TMetafile.ReadEMFStream に対し、次のコードを、以下の画面の箇所に追加します。
  if EnhHeader.nBytes < Sizeof(EnhHeader) then
    InvalidMetafile;

Hide image
Click to see full-sized image

コード修正 3

  • 変数名とスコープは、製品のバージョンによって多少異なる場合があります。構文と以下のスクリーンショットは XE7のものです。
  • TBitmap.ReadDIB関数を見つけます。
  • function TBitMap.ReadDIB に対し、次のコードを、以下の画面の箇所に追加します。
  if (biClrUsed * DIBPalSizes[OS2Format]) > (256 * SizeOf(TRGBQuad)) then
     InvalidGraphic({$IFNDEF CLR}@{$ENDIF}SInvalidBitmap);  

Hide image
Click to see full-sized image