潰しても潰しても次から次へと登場するFlashの脆弱性情報。 何故そんなに出続けるのか不思議に思いませんか?

2016年1月30日付の拙記事「そうなんだ、脆弱性 ? バッファオーバーラン」で脆弱性の発生のメカニズムとしてバッファオーバーランの説明をいたしましたが、そこではスタック領域でのオーバーフローに関してのみ説明いたしました。 今回はもう一つのバッファオーバーランが問題になる領域【ヒープ】について説明して、Flashについて考えてみたいと思います。

ヒープはスタックと同様にプログラム実行に伴い動的に確保されるメモリ領域で、必要に応じてどんどん確保されていきます。 スタックと違うのは、スタックが高位アドレスから低位アドレスに向かって確保されていくのに対して、ヒープは通常の(静的な)メモリ確保と同様に低位アドレスから上位アドレスに向かって確保されていくことが形式的に違っている点ですが、使い方の違いとして、スタックはプログラマが意識しないで、自動的に確保されていく(つまり、その確保と開放について明示的な操作をしない)のに対して、ヒープはプログラマが作業領域として必要なある程度まとまった連続領域の確保に使われるため、プログラマーが意識的に(OSに要求して)確保し、使用が終われば開放処理を行わなければならないという大きな違いがあります。

プログラムの動作にはOS配下で直接動作する機械語変換(コンパイル)済みのネイティブコードと、専用の実行環境をOSの下で動作させながら、その配下でテキストのままや中間言語に変換したプログラムを逐次実行しながら動作するインタープリタ型のものがあります。

前者は実行前に機械語へのコンパイル(変換)処理が行われているので、高速に動作します。 製品として販売されるプログラムは基本的にこの形で販売されます。 C言語やC++、Fortran,COBOL等があります。

後者はBasic,Java等の他、Javascript,perl,PHP,Python,Ruby等のスクリプト言語があります。 スクリプト言語はインタープリタ型の言語の中でも、特に簡易にプログラムを記述できるように、よりマクロ化した抽象度の高い命令で特定の用途のプログラムを少ない命令で記述できるようにしたプログラム言語で、ホストアプリケーションを制御するマクロ機能のコントロールにも使われます。

Flashにもその機能を制御する言語「Action Script」があり、複雑な動きを表現することが可能です。

しかし、画像や音声を自在に扱うには大量のメモリが必要になります。 メモリの量は有限ですから、必要になったら確保し、不要になったら返却するという動作をくりかえしてプログラムを実行していきます。

コンパイラー言語であれば、コンパイル時にある程度必要なメモリ量が予測出来、さらにメモリの確保や開放もOSが行うので信頼性が高いのですが、インタープリタ言語では実行時にプログラムが逐次解釈されていくため、事前の必要メモリ量把握ができないままとりあえずヒープを確保し、その範囲でプログラムやスクリプトを動作させ、不足すると追加でヒープを確保し、不要になれば開放します。 スクリプトから見れば、アプリケーションプログラムのFlashが随時ヒープの確保と開放を繰り返すので、コンパイルされたプログラムがOSに直接メモリ要求するのに比べると信頼性が低く、メモリ不足を引き起こしたり、上書きしてしまったりといった問題を引き起こしやすいと言えます。

また、ブラウザを介さず、Flash自体が通信を行ったり、キーボードやマウス、画面表示の入出力を制御してしまいますから、ミニOS的な広範な信頼性が必要になりますが、アプリケーションメーカーには荷が重い内容です。 常に新機能競争をしている間は、基本的なメモリ管理機能やセキュリティーに対して最新の注意を払うのは難しいのが現実でしょう。

だからといって、下火になって時間が出来てから信頼性の確保を一生懸命しても、一旦離れた顧客は戻っては来ないでしょう。 また、優秀なエンジニアもいなくなっているでしょうから、やはり起死回生の一発逆転ホームランは難しいのでしょうね。

VMware Workstation 12 Player