JP2006031363A - バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 - Google Patents
バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 Download PDFInfo
- Publication number
- JP2006031363A JP2006031363A JP2004208709A JP2004208709A JP2006031363A JP 2006031363 A JP2006031363 A JP 2006031363A JP 2004208709 A JP2004208709 A JP 2004208709A JP 2004208709 A JP2004208709 A JP 2004208709A JP 2006031363 A JP2006031363 A JP 2006031363A
- Authority
- JP
- Japan
- Prior art keywords
- buffer overflow
- expression
- condition
- unit
- area
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Abstract
【課題】 プログラマに一切負担をかけずに、検出漏れなく、少ない誤検出で、バッファオーバーフロー脆弱性を検出する。
【解決手段】 解析対象となるプログラムから、確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出し、前記領域式が示す領域のサイズ式を検出し、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を前記指数式と前記サイズ式とを用いて算出し、前記ソースプログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させ、前記バッファオーバーフロー条件の上流での表現を求める。
【選択図】 図1
【解決手段】 解析対象となるプログラムから、確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出し、前記領域式が示す領域のサイズ式を検出し、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を前記指数式と前記サイズ式とを用いて算出し、前記ソースプログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させ、前記バッファオーバーフロー条件の上流での表現を求める。
【選択図】 図1
Description
本発明は、バッファオーバーフロー脆弱性を静的解析により検出するバッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法に関し、より詳細には例えばCソースプログラムに含まれるバッファオーバーフロー脆弱性をCソースプログラムの静的解析により検出するプログラム及び方法に関する。
近年、ソフトウエアに潜在する脆弱性の中で、最も問題となっているのがバッファオーバーフローである。バッファオーバーフローが潜在するソフトウエアによる実行プロセスは、プロセスの正常な動作が阻害されたり、最悪の場合、プロセス乗っ取りを攻撃者に許してしまう等、その被害は深刻である。特にCプログラムは、Java(登録商標)プログラム等と異なり安全性に対する設計が足りない所が多く、危険な既存プログラムのストックが膨大なものに登るうえ、今後とも主要な言語の1つとして想定され多数の危険な新規プログラムが作成される可能性が高いため、この問題は大きい。
プログラムからバッファーオーバーを検出する方法として、プログラムの実行時においてバッファオーバーフローを検出する動的検出方法がある。しかし、この動的検出方法は、実際に発現したバッファオーバーフローのみ検出するものであるため、網羅的・体系的にバッファオーバーフローの発生し得る箇所及び発生条件を検出できない。また、この方法では、プログラムの実行速度が大きく低下するため、配布プログラムに動的検出のコードを埋め込むことは非現実的である。
一方、ソースプログラム中にプログラマがコメントを挿入等して、このコメントを利用して静的解析によりバッファオーバーフローを検出する方法もある。しかし、ソースプログラム中にコメントを挿入すること等はプログラマに多大の負荷をかけ、特に大規模なプログラムの場合にはその負荷は無視できないほど莫大である。
特開2004−171064公報
本発明は、上記問題点に鑑みてなされたものであり、その目的は、プログラマに一切負担をかけずに、検出漏れなく、少ない誤検出で、バッファオーバーフロー脆弱性を検出できるバッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法を提供することにある。
本発明の第1のバッファオーバーフロー脆弱性検出プログラムは、解析対象となるプログラムから、確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出する領域アクセス式検出ステップと、前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、前記プログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させ、前記バッファオーバーフロー条件の上流での表現を求める遡及ステップと、をコンピュータに実行させる。
前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが集合論的に重複する場合は、重複部分に基づき新たなバッファオーバーフロー条件を生成し遡及を続けることを特徴とする。
前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが矛盾する場合は、前記実行経路に沿って命令を実行した場合前記バッファオーバーフローは発生しない旨を判断することを特徴とする。
前記遡及ステップは、前記領域アクセス式を含む命令へ至る実行経路が複数存在する場合は各実行経路についてそれぞれ前記バッファオーバーフロー条件を遡及させることを特徴とする。
本発明の第2のバッファオーバーフロー脆弱性検出プログラムは、ソースプログラムを字句解析及び構文解析する解析ステップと、前記解析ステップによる解析結果に基づいて、任意個数の宣言コードを冒頭に含み、任意個数の代入命令を中間に含み、多くとも1つの条件分岐命令を末尾に含み、実行は冒頭から始まり末尾まで直列実行されるユニット、が複数集まって作るユニット遷移グラフで、プログラムの実行はユニット間の遷移とユニット内の前記直列実行として表されるユニット遷移グラフであって、前記条件分岐命令を含むユニットから次のユニットへの遷移は、前記条件分岐命令の分岐条件に応じて決定されるユニット遷移グラフを生成するユニット遷移グラフ生成ステップと、確保された領域を示す領域式と、前記領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を前記ユニットから検出する領域アクセス式検出ステップと、前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、前記領域アクセス式を有するユニット内で前記バッファオーバーフロー条件を前記ユニット内の代入命令に基づき遡及させる第1の遡及ステップと、上流のユニットから前記領域アクセス式を有する前記ユニットへの遷移のために前記分岐条件が存在するか否かを判断する第1の判断ステップと、(A−1)前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較する比較ステップと、 (A−2)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第2の遡及ステップと、(A−3)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記上流のユニットから前記領域アクセス式を含むユニットへユニットが遷移した場合前記バッファオーバーフローは発生しない旨の判断を行う第2の判断ステップと、(B−1)前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第3の遡及ステップと、をコンピュータに実行させる。
前記第3の遡及ステップ又は前記第2の遡及ステップは、さらなる上流のユニットから前記上流のユニットへの遷移のために分岐条件が存在するか否かを判断する第3の判断ステップと、前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較するさらなる比較ステップと、比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記さらなる上流のユニット内で前記さらなる上流のユニット内の代入命令に基づき遡及させる第4の遡及ステップと、比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記さらなる上流のユニットから前記上流のユニットへユニットが遷移した場合、前記バッファオーバーフローは発生しない旨の判断する第4の判断ステップと、前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記さらなる上流のユニット内で前記さらなる上流のユニット内の代入命令に基づき遡及させる第5の遡及ステップと、前記判断ステップによって前記バッファオーバーフローは発生しない旨の判断がされない間、前記第3の判断ステップ、前記さらなる比較ステップ、前記第4及び第5の遡及ステップを繰り返し行う繰り返しステップと、を備える。
前記第3の遡及ステップ又は前記第2の遡及ステップは、遡及の結果を、ネストした条件付き式であるNCEとして出力することを特徴とする。
本発明の第1のバッファオーバーフロー脆弱性検出方法は、解析対象となるプログラムから、確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出する領域アクセス式検出ステップと、前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、前記プログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させ、前記バッファオーバーフロー条件の上流での表現を求める遡及ステップと、を備える。
前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが集合論的に重複する場合は、重複部分を新たなバッファオーバーフロー条件として遡及を続けることを特徴とする。
前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが矛盾する場合は、前記実行経路に沿って命令を実行した場合前記バッファオーバーフローは発生しない旨を判断することを特徴とする。
本発明の第2のバッファオーバーフロー脆弱性検出方法は、ソースプログラムを字句解析及び構文解析する解析ステップと、前記解析ステップによる解析結果に基づいて、任意個数の宣言コードを冒頭に含み、任意個数の代入命令を中間に含み、多くとも1つの条件分岐命令を末尾に含み、実行は冒頭から始まり末尾まで直列実行されるユニット、が複数集まって作るユニット遷移グラフで、プログラムの実行はユニット間の遷移とユニット内の前記直列実行として表されるユニット遷移グラフであって、前記条件分岐命令を含むユニットから次のユニットへの遷移は、前記条件分岐命令の分岐条件に応じて決定されるユニット遷移グラフを生成するユニット遷移グラフ生成ステップと、確保された領域を示す領域式と、前記領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を前記ユニットから検出する領域アクセス式検出ステップと、前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、前記領域アクセス式を有するユニット内で前記バッファオーバーフロー条件を前記ユニット内の代入命令に基づき遡及させる第1の遡及ステップと、上流のユニットから前記領域アクセス式を有する前記ユニットへの遷移のために前記分岐条件が存在するか否かを判断する第1の判断ステップと、(A−1)前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較する比較ステップと、 (A−2)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第2の遡及ステップと、(A−3)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記上流のユニットから前記領域アクセス式を含むユニットへユニットが遷移した場合前記バッファオーバーフローは発生しない旨の判断を行う第2の判断ステップと、(B−1)前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第3の遡及ステップと、を備える。
本発明により、プログラマに一切負担をかけずに、検出漏れなく、少ない誤り検出で、バッファオーバーフロー脆弱性を検出できる。
先ず、本発明の実施の形態において用いるバッファオーバーフローなる用語について説明する。
一般的に「バッファオーバーフロー」という言葉が使われる場合、その意味は2種類の意味のどちらかで使われることが多い。片方は、最も広い意味でのバッファオーバーフローある。例えばバッファ領域への書き込みで考えれば、文字通り、バッファからデータが溢れるという現象である。もう一つは、ソフトウエア実行時にメモリ上に現れるデータ構造の中にスタックと呼ばれるものがあり、そのスタックの上にはソフトウエア実行制御に関わる重要なデータと通常のデータが並んで存在するが、通常データへの書き込みが重要なデータへの書き込みになってしまう現象である。これを攻撃者がうまく利用して、ソフトウエアの実行を乗っ取り、攻撃者の意図するコードを実行する攻撃をスタックスマッシングと呼ぶ。ここでは、前者の最も広い意味での現象を「バッファオーバーフロー」、後者のスタックスマッシングを許す現象を「スタックバッファオーバーフロー」と呼ぶことにする。後者は前者の一部である。すなわち、前者として発現した現象の一部が後者にもなり得る。
前者の最も広い意味でのバッファオーバーフローをより明確に定義すると、「ある領域への参照・書込みを意図した命令が、その領域の外への参照・書込みになる現象」ということになる。例えば、次のようなプログラムがあるとする。
Char* buf = malloc(size);
…
buf[a]=b;
…
mallocで確保された領域bufは、配列としてその領域にアクセスする場合、指数は0〜size-1の間になければならない。上の例でaが0<=a<=size-1であれば、バッファオーバーフローにはならないが、その範囲外に指数aがくる時はバッファオーバーフローとなる。
…
buf[a]=b;
…
mallocで確保された領域bufは、配列としてその領域にアクセスする場合、指数は0〜size-1の間になければならない。上の例でaが0<=a<=size-1であれば、バッファオーバーフローにはならないが、その範囲外に指数aがくる時はバッファオーバーフローとなる。
以下特に断らない限り、バッファオーバーフローというときはこの最も広い意味でのバッファオーバーフローを意味するものとする。このバッファオーバーフローを引き起こし得るプログラムの構造をバッファオーバーフロー脆弱性と呼ぶことにする。
バッファオーバーフロー脆弱性を含むソフトウエアを実行すると、次のような影響、あるいは被害が考えられる。
(1)ソフトウエアが異常動作に陥る。
(2)プログラマの意図しないコードが実行される可能性がある。
(3)攻撃者が任意のコードを実行するような乗っ取り攻撃を受ける可能性がある。
(1)ソフトウエアが異常動作に陥る。
(2)プログラマの意図しないコードが実行される可能性がある。
(3)攻撃者が任意のコードを実行するような乗っ取り攻撃を受ける可能性がある。
バッファオーバーフロー脆弱性は1種のバグである。通常のバグはその多くにおいて影響が(1)に留まるのに対して、バッファオーバーフローは(2)や(3)という影響があるのが特徴である深刻なバグである。
バッファオーバーフローを、その影響の深刻さに関してより細かくクラス分けしたとすると、最も影響の深刻なクラスとなるのが、前述したスタックバッファオーバーフローである。上述したようにこのスタックバッファオーバーフローも、最も広い意味でのバッファーバーフローに含まれる。スタックバッファオーバーフロー脆弱性の検出については、本発明者他の出願に係る特開2004−171064公報(特願2002−332802号)にて既に示した。
しかし、この特開2004−171064公報に示す技術で検出可能なのはスタックバッファオーバーフロー脆弱性のみである。本実施の形態が検出対象とする脆弱性は、上述からも理解されるように、「ある領域への参照・書込みを意図した命令が、その領域の外への参照・書込みになること」の原因となる脆弱性、という最も広範な意味でのバッファオーバーフロー脆弱性である。
以下では、この最も広い意味でのバッファオーバーフロー脆弱性の検出手法について詳細に説明する。
図1は、本発明の実施の形態に従ったバッファオーバーフロー脆弱性検出プログラム及び方法による処理ステップを説明するフローチャートである。
まず、プログラマ等により作成されたCソースプログラムを入力する(ステップS11)。このCソースプログラムにはマクロやインクルードファイルの設定がされている。
次に、Cソースプログラムのコンパイルに先立って、マクロ展開や、インクルードファイルのインクルードを行うプリプロセスと呼ばれる操作を解析対象のCソースプログラムに施す(ステップS12)。尚、プリプロセス後のCソースプログラムも、C言語の文法に従ったCソースプログラムである。
次に、プリプロセス後のCソースプログラムの字句を解析し(字句解析)、解析結果に基づいて言語の構文規則を解析(構文解析)する(ステップS13)。
ここで、字句解析及び構文解析並びに以降に説明する本実施の形態の説明の理解に必要な概念についていくつか説明する。
まず、文について説明する。C言語の文法規則における文とここで言う文とは同じである。すなわち、文はC言語の文法規則に従って、再帰的に定義されている。その要諦は、関数は一つの文または、複文であり、複文は文の並びとして構成される。文は一つの式から構成されることもあり、複数の文と予約語から構成されることもある。ある文Aを構成する単独あるいは複数の文をAの下位文と呼ぶ。以上について具体例を用いて説明する。
図2は、あるプログラム例に対する文の構造を示す。
関数proc全体が一つの複文を成し、複文は4つの下位文から成る。このうち、3番目以外の文は式から構成される文であり、3番目のif-then-else文は、”if”、”then”、”else”という3つの予約語と2つの下位文から構成される。これら2つの下位文はそれぞれ、式から構成される。尚、式から構成される文を式文と呼ぶ。
次に、式という概念について説明する。C言語の文法規則における式とここで言う式とは、後述のNCE(Nested Conditioned Expression)を除いて、同じである。すなわち、式はC言語の文法規則に従って、再帰的に定義されている。式は、変数や定数や演算子などが成す木構造である。その部分木それぞれも一つの式である。また、変数や定数も一つの式である。以上について具体例を用いて説明する。
図3は、式の例を示す。
プログラム例は図2と同じである。プログラム例における各式の構造が図の右側に示されており、それぞれ木構造を有している。例えば、c=2*aは代入式という式であり、その左辺は変数cという式(部分木)であり、右辺の2*aも式(部分木)であり、その両辺、2とaもそれぞれ式(部分木)である。また、buf[c]は配列式であり、それはbufという式とcという式から構成される。尚、C言語の3項演算子による式はNCEの一種であるが、本発明におけるNCEは3項演算子による式以外の場合もある。
図1に戻り、ステップS14において、字句解析・構文解析による解析結果を用いて、型決定処理を行う。C言語では全ての式に型付けが可能であることが文法規則として定められ、この型決定処理では、プリプロセス後のソースプログラムに含まれる全ての式について型を決定する。型としては、例えばint型、char型、ポインタ型等がある。
次に、プログラムに含まれる全ての代入式を、単純代入演算子(=)を用いた代入式に変換する(ステップS15)。これを代入式の正規化処理と称する。より詳細には以下の通りである。
式の1種として代入式がある。代入式の場合、前述の木構造(図3参照)のトップは代入演算子になる。代入演算子について、C言語には、+=や++といった多様な代入演算子があるが、それらは全て、単純代入演算子(=)と算術演算子、単純代入演算子とシフト演算子、単純代入演算子とbit演算子の組み合わせと等価である。また、代入演算子以外にはプリミティブな代入を実現するものは無い。よって、代入式は、それを等価変換することで、最終的には単純代入演算子を木構造のトップとする式に帰着できる。すなわち、全ての代入式は単純代入演算子による代入式に変換可能である。なお、代入式は1つで1ワードのみ代入を行う。
次に、代入式の正規化処理後のプログラムを用いてユニット遷移グラフの生成を行う(ステップS16)。以下これについて詳細に説明する。
プログラムにおいて、一つの代入が行われる部分は文法上「式」になる。宣言の中に代入(初期化等)が入っていることがあるが、これは本質的には、純宣言と代入に分けられる(プログラムを等価変換することが可能)。例えばint a=100は、int a及びa=100と等価である。制御に関しても同様である。例えばif((a=b)>c)は、a=b及びif(a>c)と等価である。従って、プログラムは純宣言と、純制御と、代入部により表すことができる。
ここで、代入部とは、ある代入が行われた直後から次の代入が行われるまでの直列に実行が行われる部分を言うこととする。従って、一つの代入部について見ると、その末端は代入式であり、末端より前には関数呼び出し等が含まれ得るが、代入式は含まれない。つまり、一つの代入部では一つの代入しか行われない。
制御に関しては、条件判定をして成立/不成立による分岐を行うための文(例えばfor、while、if-then-else、switch:switchはif-then-elseの並び)と、条件判定を含まないラベル文とgoto文(return、break、continue文等もあるが実質的にgoto文と等価である)がある。
よって、プログラムは純宣言と条件判定(分岐)と代入部により表すことができる。
ここでユニットをいうものを定義する。ユニットは、(1)冒頭における任意個数の宣言、(2)任意個数の代入、(3)末尾に高々1個の条件判定による2分岐、(4)実行は必ず冒頭から末尾まで直列に行われ、途中に制御の流入が無い、という特徴を有するものとする。従って、プログラムあるいは関数の実行はユニット内の直列実行とユニット間の実行遷移という単純な構成で表現可能である。プログラムあるいは関数をユニットの遷移として表したものをユニット遷移グラフと称する。図4にユニット遷移グラフ例を示す。図4において点線で囲まれた部分がユニットである。本ステップS16では、上述したように、このようなユニット遷移グラフを、正規化後のプログラムを用いて生成する。図4から理解されるように、ユニットに流入する制御(図4においてユニット先頭で代入部に入る矢印)は少なくとも1本、ユニットから流出する制御(図4においてユニット末端で条件判定から出る矢印)は0本か1本か2本である。
図5は、図2や図3で挙げたプログラム例に対して生成されたユニット遷移グラフを示す。
ユニットu0の末尾で一つの条件判定(c<3か否か)を行い、真偽に応じてユニットu1又はユニットu2へ遷移する。ユニットu1及びユニットu2からは、無条件でユニットu3へ遷移する。
図1に戻り、次に、このユニット遷移グラフを用いてバッファオーバーフロー候補を抽出する(ステップS17)。バッファオーバーフロー候補としては例えばポインタ型式がある。以下これについて詳しく説明する。
配列とポインタは、宣言時のサイズを静的に指定するか、動的に指定するかを除いて、文法上は等しい存在である(実装の仕方は異なってくるが)。そこで、以下では、主としてポインタに関して話を進め、適宜配列について言及する。
Cの文法からポインタ型式の定義を抜き出して整理すると次のようになる。
例
ポインタ型式 : ポインタ型式 加減算演算子 整数型式 p+100+i
ポインタ型へのcast ポインタ型式 (struct S *)p
ポインタ型変数 p
&演算子 変数 &i
例
ポインタ型式 : ポインタ型式 加減算演算子 整数型式 p+100+i
ポインタ型へのcast ポインタ型式 (struct S *)p
ポインタ型変数 p
&演算子 変数 &i
Cの文法からポインタ型変数への代入式の定義を抜き出して整理すると次のようになる。
ポインタ型変数代入式 : ポインタ型変数 代入演算子 ポインタ型式 p2=p1+10
ポインタ型変数 代入演算子 p1++
ポインタ型変数代入式 : ポインタ型変数 代入演算子 ポインタ型式 p2=p1+10
ポインタ型変数 代入演算子 p1++
ポインタ型式が指す先へ値を代入する代入式の形を示すと次のようになる。
ポインタ型式が指す先への代入式 : *ポインタ型式 代入演算子 代入値
ポインタ型式が指す先への代入式 : *ポインタ型式 代入演算子 代入値
ここで、ポインタ型式は、例えば「ポインタ型式」及び「ポインタ型変数代入式」に示した再帰的定義からも分かるように、加減算演算子を節点とする2分木構造を成す。一例としてp+100+iの2分木構造を図6に示す。2分木構造における一つの端点(図6の例ではp)は代入先の領域を示すポインタ型式(領域式と呼ぶ)であり、残りの端点から構成される式(図6の例では100+i)は代入位置を示す整数型式(指数式と呼ぶ)である。この残りの端点は0個でもよい(上述の「ポインタ型式」における(struct S *)p、p、&iは領域式のみのポインタ型式に該当する)。
この2分木構造からも理解されるように、領域式はポインタ型式であり、指数式は整数型の式である。ポインタ型式には領域式のみから成るものと、領域式と指数式からなるものがある、ということになる。ポインタ型式における領域式と指数式の分別も局所的な解析で可能である。
ポインタ型式は、値が代入される側(代入式左辺)のみならず、値が参照される側(代入式右辺)にも出現する(「ポインタ型変数代入式」におけるp2=p1+10等参照)。この場合も、ポインタ型式における指数式と領域式の分類も局所的な解析で可能である。値が代入される側にポインタ型式が現れる例と、値が参照される側にポインタ型式が現れる例を以下にさらにいくつか示す。
値が代入される側にポインタ型式が現れる例:*(p+100+i)=100、s[100+i]=100
値が参照される側にポインタ型式が現れる例: a[100] = b->d[c]
a[100] = b->d[c]について簡単に説明すると、左辺のポインタ型式aで示される領域の指数式100で示される位置へ代入(書き込み)が成される。代入される値は、b->dというポインタ型式が示す領域における指数式cで示される位置への参照で得られる値である。
値が参照される側にポインタ型式が現れる例: a[100] = b->d[c]
a[100] = b->d[c]について簡単に説明すると、左辺のポインタ型式aで示される領域の指数式100で示される位置へ代入(書き込み)が成される。代入される値は、b->dというポインタ型式が示す領域における指数式cで示される位置への参照で得られる値である。
以上のように、ポインタ型式は、領域式から構成されるものと、領域式と指数式とから構成されるものがある。領域式で示される領域のサイズ(宣言時や動的割当時に指定される)から、指数式に許される値は制限される。指数式がそこから逸脱した値を取ると、上述したように、最も広い意味でのバッファオーバーフローになる。本ステップS17では、プログラムに含まれる全てのポインタ型式のうち、指数式を持つものをバッファオーバーフロー候補として抽出する。
図1に戻り、次に、抽出された各ポインタ型式(バッファオーバーフロー候補)に含まれる指数式及び領域式のうち少なくとも指数式について遡及処理を行う(ステップS18)。以下この遡及処理について詳細に説明する。
上述したように、ユニットは末尾の条件判定及び冒頭の宣言を除いて、代入部の並びであり、途中には条件分岐は存在しない(図4参照)。従って、ユニット内の任意の位置におけるある変数は、代入式の並びを下から上へ辿っていくことにより、ユニット冒頭における形に表現可能である。このユニットの冒頭に向けて辿っていくことを遡及と呼ぶことにする。より一般的には、遡及は、代入式の並びを下から上に辿っていくことにより、変数又は後述するバッファオーバーフロー条件といった任意の式を別の形の式で表現することである。逆にいえば、遡及後の式に、代入式の並びを上から下へ従って適用していくと遡及前の式になる。
ここで、遡及は、
・左辺可能式と呼ぶ特殊な構造をもった式(これはCの言語仕様によって、左辺値を持つ式として定義できる)(遡及の対象としている式であるか否かは問わない)が、ある代入式の右辺に現れており、
・その左辺可能式がユニット中の代入式の並びの中でより上の代入式の左辺に出現するという場合に可能である。
・左辺可能式と呼ぶ特殊な構造をもった式(これはCの言語仕様によって、左辺値を持つ式として定義できる)(遡及の対象としている式であるか否かは問わない)が、ある代入式の右辺に現れており、
・その左辺可能式がユニット中の代入式の並びの中でより上の代入式の左辺に出現するという場合に可能である。
左辺可能式としては、例えば、単独変数、配列要素、*(ポインタ型式)、構造体メンバ等がある。
図7(A)〜(E)は、遡及処理の一例を説明する図である。
図7(A)は、ユニット内に配置されたポインタ型式f[a]の指数式aについて遡及した結果を示す。aは同ユニット内の位置@2ではb+cに遡及され、同ユニット内の位置@1では、d+c+eに遡及される。
図7(B)は、ユニット内におけるある位置に配置されたポインタ型式c[a[b]]の指数式a[b]について遡及した結果を示す。a[b]は同ユニット内の位置@1では、fに遡及される。
図7(C)は、ユニット内におけるある位置に配置されたポインタ型式c[a[b]]の指数式a[b]について遡及した結果を示す。a[b]は同ユニット内の位置@1では、a[c+d]に遡及される。
図7(D)及び図7(E)に示す例4や例5は遡及の結果が場合によって異なることを示している。
すなわち、図7(D)では、ポインタ型式c[a[b]]における指数式a[b]は、もしe=c+dが成立する場合は、位置@1においてfに遡及されるが、成立しない場合は、a[c+d]に遡及される。
同様に、図7(E)では、ポインタ型式c[a[b]]における指数式a[b]は、もしe=bが成立する場合は、位置@1でfに遡及されるが、成立しない場合は、a[b]に遡及される。
図7(D)及び図7(E)に示す例のように、遡及結果は一般的には条件付き式で表現する必要がある。条件付き式は、条件式、条件式が真の場合の式及び条件式が偽の場合の式の3項による組からなる式である。
条件付き式も遡及の対象になる。例えば図7(D)に示す例4で、a[b]の遡及結果は図示の条件付き式により表現されるが、@1を超えてさらに上へa[b]を遡及する場合は、この条件付き式を@1から上へ遡及することになる。この場合、遡及は条件付き式を構成する3つの式それぞれについて行う。この遡及結果がまた、条件付式になる可能性もある。よって、遡及結果を表現する条件付き式はネストした条件付き式(例4,5参照)である必要がある。このネストした条件付き式をNCE(Nested Conditioned Expression)と呼ぶことにする。
ここで、本ステップS18では、前述したステップS17においてユニット内で見つかったポインタ型式(バッファオーバーフロー候補)を構成する指数式及び領域式の少なくとも指数式を遡及し、ユニット冒頭での表現に直す。
図8は、図5に示したユニット遷移グラフの各ユニットu0〜u3において、ポインタ型式buf[c]における指数式cを遡及した結果を示す。
指数式cは、ユニットu3の冒頭では、cに遡及され、u1の冒頭ではc-1に遡及され、u2の冒頭ではc+1に遡及され、u0の冒頭では2aに遡及される。
図1に戻り、次に、ユニット間でのリレー処理を行う(ステップS19)。
このリレー処理は、着目する変数について、ユニット間を跨いで遡及を行うものである。
図9は、図8に示すユニット間のリレーを、指数式cについて行った結果を示す。リレー処理の結果はNCEになる。あるユニットBの冒頭まで遡及された遡及後の式Eは、そのユニットの(ユニット遷移グラフ上で)上流にあるユニットAの末尾へと遡及を引き継ぐ(ユニットAの末尾に式Eがあると仮想し、そこからユニットA内で遡及を始める)ことで、ユニットAの冒頭まで遡及ができる。このユニット間を跨ぐ遡及を実現するためのリレーを行う。ユニット内での遡及と、ユニット間でのリレーを交互に行うことによって、プログラム中の任意のユニットは、ユニットグラフを上流に辿れる限り、どこまでも遡及されることが可能である。
図9において、リレーの結果、指数式cは、ユニットu1の冒頭では、c-1に遡及され、ユニットu0の冒頭では2a-1に遡及される。同様に、指数式cは、ユニットu2の冒頭では、c+1に遡及され、ユニットu0の冒頭では2a+1に遡及される。つまり、ユニットがu0→u1→u3と遷移する場合は、指数式cは2a-1に遡及され、ユニットがu0→u2→u3と遷移する場合は、指数式cは2a+1に遡及される。
図1に戻り、次に、バッファオーバーフロー条件の同定並びにバッファオーバーフロー条件の精緻化及び削減化を行う(ステップS20、S21)。以下具体例として、図9を用いて、本ステップについて詳細に説明する。
まず、ユニットu3の冒頭においてbuf[c]にバッファオーバーフローが生じる条件(バッファオーバーフロー条件)を求める(バッファオーバーフロー条件の同定)。但し、bufで示される領域のサイズが関数の冒頭において「2」と宣言されていたとする。従って、buf[c]というポインタ型式のバッファオーバーフロー条件はc>=2である(c<0ももう一つのバッファオーバーフロー条件である)。この時点におけるバッファオーバーフロー条件は、buf[c]の位置における局所的なものであることに注意する。また、バッファオーバーフロー条件は式であることにも注意する。従って、バッファオーバーフロー条件には遡及とリレーが行える。
次に、ユニット内でのバッファオーバーフロー条件の遡及とユニットを跨いでバッファオーバーフロー条件のリレーを行う。上流ユニットが複数ある場合は、リレーはそれぞれの上流ユニットに対して行う。ユニットu3の上流には2つのユニットu1,u2が存在するためそれぞれのユニットu1,u2に対してリレーを行う。
まず、ユニットu1冒頭までバッファオーバーフロー条件を遡及させると遡及結果はc>=3となる。より詳細には、この遡及の際には、図9に示すリレー処理の結果を用いる。リレー処理の結果から、指数式cはユニットu1の冒頭においてc-1に遡及される。従って、バッファオーバーフロー条件は、c-1>=2すなわちc>=3に遡及される。
次に、ユニットu2冒頭までバッファオーバーフロー条件を遡及させると遡及結果はc>=1となる。すなわち、リレー処理の結果から、指数式cはユニットu2の冒頭においてc+1に遡及される。従ってバッファオーバーフロー条件は、c+1>=2すなわちc>=1に遡及される。
次に、各ユニットu1,u2に実行が遷移してくる条件と、各ユニットu1,u2の冒頭でのバッファオーバーフロー条件とを突き合わせる。前者が後者によって全否定されるならば、バッファオーバーフローは生起しない。一方、全否定されない場合は、バッファオーバーフロー条件及び遷移条件の集合論的な重複部分を新たなバッファオーバーフロー条件として生成し、新たなバッファオーバーフロー条件に基づき遡及を続行する。より詳細には以下の通りである。
まず、ユニットu0からユニットu1への遷移条件(c<3)は、ユニットU1冒頭でのバッファオーバーフロー条件(c>=3)を全否定するため、すなわち両者は矛盾するため、ユニットu0→ユニットu1→ユニットu3という実行順序を辿る場合は、ユニットu3のbuf[c]でバッファオーバーフローは生起し得ない。従って、c>=3を、最終的なバッファオーバーフロー条件から除外する(バッファオーバーフロー条件の削減化)。
一方、ユニットU0からユニットu2への遷移条件(c>=3)は、ユニットu2冒頭でのバッファオーバーフロー条件(c>=1)より厳しい(集合論的に言えば、部分集合)ため、遷移条件の方を新たなバッファオーバーフロー条件(c>=3)とする。つまり、バッファオーバーフロー条件が表す集合と遷移条件が表す集合との交わりを表す式を新たなバッファオーバーフロー条件とする。この結果、バッファオーバーフロー条件はより狭い範囲に絞り込まれる(バッファオーバーフロー条件の緻密化)。この新たな条件をユニットU0の冒頭まで遡及(リレー)させると2a>=3となり、これより上流のユニットは存在しないため遡及を終了する。即ち、予め与えられた終了条件を満たした場合は遡及を終了する。この結果、ユニットu0の冒頭、つまり関数冒頭で2a>=3という条件が満たされていれば、ユニットu3のbuf[c]でバッファオーバーフローが生起するというバッファオーバーフロー条件が得られる。一方で、ユニットu0のbuf[c]については、2a>=2という条件でバッファオーバーフローが生起する。
以上において、もしもユニットu1、u2の冒頭におけるバッファオーバーフロー条件のいずれもがユニットu0から各ユニットu1,u2への遷移条件によって全否定された場合は、対象としているバッファオーバーフロー候補ではバッファオーバーフローが生起し得えないため候補から除外する。
以上のステップS20、S21の説明では、関数の冒頭で、bufで示される領域のサイズが「2」と宣言されたが、bufで示される領域のサイズが宣言されていない場合はbufを遡及及びリレーすることによりサイズを求める。
例えば、
int* p = (int*)malloc(sizeof(int)*sizeP); //@1
int* q;
...
q = p;
...
q[b]=...
というプログラムの場合、ポインタ型式q[b]における領域式qは、そのサイズが直接宣言されていないため、領域式qを遡及することにより、@1で確保された領域だということ、すなわち、サイズを認識できる。このことを一般的な表現にすると次のようになる。領域式が示す領域には、配列のように宣言によってサイズが固定されているもの(C言語では静的確保される領域と呼ばれる)と、領域確保関数によって確保されサイズが実行時に決まるもの(同じく動的確保される領域と呼ばれる)がある。前者を静的領域、後者を動的領域と呼ぶことにする。静的領域は、それを示す領域式と宣言の対比で簡単に同定可能であり、従ってサイズも同定可能である。一方、動的領域は領域式を遡及およびリレーして、左辺が遡及後の領域式で右辺が領域確保関数という形の代入式である領域確保式まで辿り付くことで、初めてそのサイズを表す式であるサイズ式が分かる(サイズ式は領域確保関数の引数の一部)。従って、領域式が示す領域が静的領域でない場合は、それは動的領域であるか、後述する他領域式指示であり、領域式を遡及およびリレーする。そして領域確保式まで辿り付けば、そのサイズ式を求める。尚、静的領域のサイズを表す即値の式(例えばint a[100];という宣言における100)もあるので、これも動的領域の場合と同様にサイズ式と呼ぶことにする。
int* p = (int*)malloc(sizeof(int)*sizeP); //@1
int* q;
...
q = p;
...
q[b]=...
というプログラムの場合、ポインタ型式q[b]における領域式qは、そのサイズが直接宣言されていないため、領域式qを遡及することにより、@1で確保された領域だということ、すなわち、サイズを認識できる。このことを一般的な表現にすると次のようになる。領域式が示す領域には、配列のように宣言によってサイズが固定されているもの(C言語では静的確保される領域と呼ばれる)と、領域確保関数によって確保されサイズが実行時に決まるもの(同じく動的確保される領域と呼ばれる)がある。前者を静的領域、後者を動的領域と呼ぶことにする。静的領域は、それを示す領域式と宣言の対比で簡単に同定可能であり、従ってサイズも同定可能である。一方、動的領域は領域式を遡及およびリレーして、左辺が遡及後の領域式で右辺が領域確保関数という形の代入式である領域確保式まで辿り付くことで、初めてそのサイズを表す式であるサイズ式が分かる(サイズ式は領域確保関数の引数の一部)。従って、領域式が示す領域が静的領域でない場合は、それは動的領域であるか、後述する他領域式指示であり、領域式を遡及およびリレーする。そして領域確保式まで辿り付けば、そのサイズ式を求める。尚、静的領域のサイズを表す即値の式(例えばint a[100];という宣言における100)もあるので、これも動的領域の場合と同様にサイズ式と呼ぶことにする。
領域式はポインタ型式であるので、単一のポインタ型変数等、左辺式である場合がある。その場合、その領域式は他の領域式によって代入が成された結果である場合もある。上の領域式(今これをAとする)の遡及およびリレーで、他の静的領域の領域式Bにたどり着いた場合は、領域式Aは、領域式Bと同じ領域を示すこととする。これを他領域式指示と呼ぶ。領域式Bを遡及及びリレーすることで領域式Bのサイズ式が求まる。
請求項における領域式が示す領域のサイズ式の検出は、(1)領域式と宣言との対比により検出すること、(2)遡及及びリレーにより領域確保式を検出すること、(3)他領域式指示の場合は他領域式が示す領域のサイズ式を(1)(2)により検出することを含む。
以上の説明で用いた例では、buf[c]のように[ ]の中が変数であったが、buf[2]のように[ ]の中が定数であれば、bufのサイズから、即時にバッファオーバーフローか否かが判定可能である。
図1に戻り、最終的な処理結果を出力する(ステップ22)。
最終的な処理結果として、バッファオーバーフロー条件の精緻化及び削減化過程において除外されずに生き残ったバッファオーバーフロー候補について以下の情報を出力する。
(1)バッファオーバーフローが生起し得る個所である、領域式と指数式から構成されるポインタ型式(すなわちバッファオーバーフロー候補)(上記例ではユニットu3のbuf[c])
(2)バッファオーバーフローが生起し得る、領域式が示す領域(上記例ではbufが確保されている宣言文or命令文。bufが配列として確保された領域なら例えばint buf[size];等、mallocで確保された領域なら、int* buf = (int*)malloc(sizeof(int)*sizeA);等)
(3)バッファオーバーフローが生起する条件(上記例では、ユニットu0:3≦2a、ユニットu2:c≧1、ユニットu3:c≧2等、ユニットごとに出力)
といった情報である。
(1)バッファオーバーフローが生起し得る個所である、領域式と指数式から構成されるポインタ型式(すなわちバッファオーバーフロー候補)(上記例ではユニットu3のbuf[c])
(2)バッファオーバーフローが生起し得る、領域式が示す領域(上記例ではbufが確保されている宣言文or命令文。bufが配列として確保された領域なら例えばint buf[size];等、mallocで確保された領域なら、int* buf = (int*)malloc(sizeof(int)*sizeA);等)
(3)バッファオーバーフローが生起する条件(上記例では、ユニットu0:3≦2a、ユニットu2:c≧1、ユニットu3:c≧2等、ユニットごとに出力)
といった情報である。
以上に説明した本発明の実施の形態により得られる効果について述べると以下の通りである。
バッファオーバーフローを生起し得るプログラムの箇所について、その箇所で実際にバッファオーバーフローが生起する必要条件を同定できる。但し、本実施の形態により、プログラムを広域的に静的解析することにより、必要十分条件に近い条件を得られ、このことは、誤検出の割合を少なくする効果を実現する。誤警告が出るのは、例えば次のような場合である。
すなわち、本実施の形態では、プリプロセス後のソースプログラムを用いて解析を行っている。ヘッダーファイルが完全に揃っていない等の理由でプリプロセスが完全に行えない場合、解析が不十分になるところが出てくる場合がある。
以上のように同定されたバッファオーバーフロー条件を検討することによって、どういう仕組みでバッファオーバーフローが生起するか、裏を返せば、プログラムをどう修正すればバッファオーバーフローを起こさなくなるかが分かる。例えば、バッファオーバーフロー条件を条件式とするif文をバッファオーバーフロー条件箇所に埋め込むことでバッファオーバーフローの生起を防止できる。
以上の他、本実施の形態では、バッファオーバーフローが生起し得る全ての式を処理の対象とするため、バッファオーバーフローを生起し得るプログラムの箇所を漏らさず検出できる。また、プログラマにコメント追加等の不可を一切求めていないことは以上の記述より明らかである。
S11 ソースプログラム入力ステップ
S12 プリプロセス実行ステップ
S13 字句解析・構文解析ステップ
S14 型決定処理ステップ
S15 代入式の正規化ステップ
S16 ユニット遷移グラフの生成ステップ
S17 バッファオーバーフロー候補の抽出ステップ
S18 遡及処理ステップ
S19 リレー処理ステップ
S20 バッファオーバーフロー条件の同定ステップ
S21 バッファオーバーフロー条件の精緻化及び削減化
S22 出力処理ステップ
S12 プリプロセス実行ステップ
S13 字句解析・構文解析ステップ
S14 型決定処理ステップ
S15 代入式の正規化ステップ
S16 ユニット遷移グラフの生成ステップ
S17 バッファオーバーフロー候補の抽出ステップ
S18 遡及処理ステップ
S19 リレー処理ステップ
S20 バッファオーバーフロー条件の同定ステップ
S21 バッファオーバーフロー条件の精緻化及び削減化
S22 出力処理ステップ
Claims (11)
- 解析対象となるプログラムから、確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出する領域アクセス式検出ステップと、
前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、
前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、
前記プログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させ、前記バッファオーバーフロー条件の上流での表現を求める遡及ステップと、
をコンピュータに実行させるバッファオーバーフロー脆弱性検出プログラム。 - 前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが集合論的に重複する場合は、重複部分に基づき新たなバッファオーバーフロー条件を生成し遡及を続けることを特徴とする請求項1に記載のプログラム。
- 前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが矛盾する場合は、前記実行経路に沿って命令を実行した場合前記バッファオーバーフローは発生しない旨を判断することを特徴とする請求項1又は2に記載のプログラム。
- 前記遡及ステップは、前記領域アクセス式を含む命令へ至る実行経路が複数存在する場合は各実行経路についてそれぞれ前記バッファオーバーフロー条件を遡及させることを特徴とする請求項1乃至3のいずれかに記載のプログラム。
- ソースプログラムを字句解析及び構文解析する解析ステップと、
前記解析ステップによる解析結果に基づいて、
任意個数の宣言コードを冒頭に含み、任意個数の代入命令を中間に含み、多くとも1つの条件分岐命令を末尾に含み、実行は冒頭から始まり末尾まで直列実行されるユニット、が複数集まって作るユニット遷移グラフで、プログラムの実行はユニット間の遷移とユニット内の前記直列実行として表されるユニット遷移グラフであって、前記条件分岐命令を含むユニットから次のユニットへの遷移は、前記条件分岐命令の分岐条件に応じて決定されるユニット遷移グラフを生成するユニット遷移グラフ生成ステップと、
確保された領域を示す領域式と、前記領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を前記ユニットから検出する領域アクセス式検出ステップと、
前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、
前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、
前記領域アクセス式を有するユニット内で前記バッファオーバーフロー条件を前記ユニット内の代入命令に基づき遡及させる第1の遡及ステップと、
上流のユニットから前記領域アクセス式を有する前記ユニットへの遷移のために前記分岐条件が存在するか否かを判断する第1の判断ステップと、
(A−1)前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較する比較ステップと、
(A−2)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第2の遡及ステップと、
(A−3)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記上流のユニットから前記領域アクセス式を含むユニットへユニットが遷移した場合前記バッファオーバーフローは発生しない旨の判断を行う第2の判断ステップと、
(B−1)前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第3の遡及ステップと、
をコンピュータに実行させるバッファオーバーフロー脆弱性検出プログラム。 - 前記第3の遡及ステップ又は前記第2の遡及ステップは、
さらなる上流のユニットから前記上流のユニットへの遷移のために分岐条件が存在するか否かを判断する第3の判断ステップと、
前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較するさらなる比較ステップと、
比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記さらなる上流のユニット内で前記さらなる上流のユニット内の代入命令に基づき遡及させる第4の遡及ステップと、
比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記さらなる上流のユニットから前記上流のユニットへユニットが遷移した場合、前記バッファオーバーフローは発生しない旨の判断する第4の判断ステップと、
前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記さらなる上流のユニット内で前記さらなる上流のユニット内の代入命令に基づき遡及させる第5の遡及ステップと、
前記判断ステップによって前記バッファオーバーフローは発生しない旨の判断がされない間、前記第3の判断ステップ、前記さらなる比較ステップ、前記第4及び第5の遡及ステップを繰り返し行う繰り返しステップと、
を備えたことを特徴とする請求項5に記載のプログラム。 - 前記第3の遡及ステップ又は前記第2の遡及ステップは、遡及の結果を、ネストした条件付き式であるNCEとして出力することを特徴とする請求項5又は6に記載のプログラム。
- 解析対象となるプログラムから、予め確保された領域を示す領域式と、前記領域式が示す領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を検出する領域アクセス式検出ステップと、
前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、
前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、
前記プログラムの上流側に配置された命令から前記領域アクセス式を含む命令へ至るまでの命令の実行経路を特定し、前記実行経路上に配置された代入命令に基づき前記バッファオーバーフロー条件を前記実行経路の上流へ向けて遡及させる遡及ステップと、
を備えたバッファオーバーフロー脆弱性検出方法。 - 前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが集合論的に重複する場合は、重複部分を新たなバッファオーバーフロー条件として遡及を続けることを特徴とする請求項8に記載の方法。
- 前記遡及ステップは、前記実行経路上に分岐条件命令が含まれる場合は、前記実行経路に対応する分岐条件と、前記バッファオーバーフロー条件とを比較し、前記分岐条件と前記バッファオーバーフロー条件とが矛盾する場合は、前記実行経路に沿って命令を実行した場合前記バッファオーバーフローは発生しない旨を判断することを特徴とする請求項8又は9に記載の方法。
- ソースプログラムを字句解析及び構文解析する解析ステップと、
前記解析ステップによる解析結果に基づいて、
任意個数の宣言コードを冒頭に含み、任意個数の代入命令を中間に含み、多くとも1つの条件分岐命令を末尾に含み、実行は冒頭から始まり末尾まで直列実行されるユニット、が複数集まって作るユニット遷移グラフで、プログラムの実行はユニット間の遷移とユニット内の前記直列実行として表されるユニット遷移グラフであって、前記条件分岐命令を含むユニットから次のユニットへの遷移は、前記条件分岐命令の分岐条件に応じて決定されるユニット遷移グラフを生成するユニット遷移グラフ生成ステップと、
確保された領域を示す領域式と、前記領域においてアクセスする位置を指定する指数式とを含む領域アクセス式を前記ユニットから検出する領域アクセス式検出ステップと、
前記領域式が示す領域のサイズ式を検出する領域サイズ検出ステップと、
前記領域アクセス式を含む命令を実行すると前記領域式が示す領域外へのアクセスとなるバッファオーバーフローが発生するバッファオーバーフロー条件を、前記指数式と前記サイズ式とを用いて算出する条件算出ステップと、
前記領域アクセス式を有するユニット内で前記バッファオーバーフロー条件を前記ユニット内の代入命令に基づき遡及させる第1の遡及ステップと、
上流のユニットから前記領域アクセス式を有する前記ユニットへの遷移のために前記分岐条件が存在するか否かを判断する第1の判断ステップと、
(A−1)前記分岐条件が存在する場合は、前記バッファオーバーフロー条件と前記分岐条件とを比較する比較ステップと、
(A−2)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが集合論的に重複する場合は、前記重複部分を新たなバッファオーバーフロー条件とし、新たな前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第2の遡及ステップと、
(A−3)比較の結果、前記バッファオーバーフロー条件と前記分岐条件とが矛盾する場合は、前記上流のユニットから前記領域アクセス式を含むユニットへユニットが遷移した場合前記バッファオーバーフローは発生しない旨の判断を行う第2の判断ステップと、
(B−1)前記分岐条件が存在しない場合は、前記バッファオーバーフロー条件を前記上流のユニット内で前記上流のユニット内の代入命令に基づき遡及させる第3の遡及ステップと、
を備えたバッファオーバーフロー脆弱性検出方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2004208709A JP2006031363A (ja) | 2004-07-15 | 2004-07-15 | バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2004208709A JP2006031363A (ja) | 2004-07-15 | 2004-07-15 | バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2006031363A true JP2006031363A (ja) | 2006-02-02 |
Family
ID=35897633
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2004208709A Pending JP2006031363A (ja) | 2004-07-15 | 2004-07-15 | バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 |
Country Status (1)
Country | Link |
---|---|
JP (1) | JP2006031363A (ja) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102567200A (zh) * | 2011-12-14 | 2012-07-11 | 北京航空航天大学 | 基于函数调用图的并行化安全漏洞检测方法 |
JP2013196512A (ja) * | 2012-03-21 | 2013-09-30 | Ntt Data Corp | 変換装置、変換方法、変換プログラム |
CN103559127A (zh) * | 2013-10-28 | 2014-02-05 | 北京邮电大学 | 一种缺陷处理方法及缺陷处理器 |
JP5954666B2 (ja) * | 2010-12-08 | 2016-07-20 | パナソニックIpマネジメント株式会社 | 情報処理装置、及び、情報処理方法 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPH06348475A (ja) * | 1993-06-14 | 1994-12-22 | Nec Corp | ポインタ解析システム |
JPH07105043A (ja) * | 1993-10-08 | 1995-04-21 | Brother Ind Ltd | プログラムエラー検出装置 |
JP2004013556A (ja) * | 2002-06-07 | 2004-01-15 | Matsushita Electric Ind Co Ltd | プロセッサ装置、コンパイル装置及びその方法 |
JP2004171064A (ja) * | 2002-11-15 | 2004-06-17 | Mitsubishi Research Institute Inc | バッファオーバーフロー静的解析方法およびプログラム |
-
2004
- 2004-07-15 JP JP2004208709A patent/JP2006031363A/ja active Pending
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JPH06348475A (ja) * | 1993-06-14 | 1994-12-22 | Nec Corp | ポインタ解析システム |
JPH07105043A (ja) * | 1993-10-08 | 1995-04-21 | Brother Ind Ltd | プログラムエラー検出装置 |
JP2004013556A (ja) * | 2002-06-07 | 2004-01-15 | Matsushita Electric Ind Co Ltd | プロセッサ装置、コンパイル装置及びその方法 |
JP2004171064A (ja) * | 2002-11-15 | 2004-06-17 | Mitsubishi Research Institute Inc | バッファオーバーフロー静的解析方法およびプログラム |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP5954666B2 (ja) * | 2010-12-08 | 2016-07-20 | パナソニックIpマネジメント株式会社 | 情報処理装置、及び、情報処理方法 |
CN102567200A (zh) * | 2011-12-14 | 2012-07-11 | 北京航空航天大学 | 基于函数调用图的并行化安全漏洞检测方法 |
JP2013196512A (ja) * | 2012-03-21 | 2013-09-30 | Ntt Data Corp | 変換装置、変換方法、変換プログラム |
CN103559127A (zh) * | 2013-10-28 | 2014-02-05 | 北京邮电大学 | 一种缺陷处理方法及缺陷处理器 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP7164017B2 (ja) | フォールトツリー分析を使用して機能安全のため制御フローグラフを最適化するシステム及び方法 | |
CN104899147B (zh) | 一种面向安全检查的代码静态分析方法 | |
US8893102B2 (en) | Method and system for performing backward-driven path-sensitive dataflow analysis | |
JP7201078B2 (ja) | データ引数を動的に識別し、ソースコードを計装するためのシステムと方法 | |
Colcombet et al. | Enforcing trace properties by program transformation | |
US8656370B2 (en) | Symbolic execution of javascript software using a control flow graph | |
US8949811B2 (en) | Constructing a control flow graph for a software program | |
US20050204344A1 (en) | Program analysis device, analysis method and program of same | |
US20170315903A1 (en) | Systems and methods for analyzing violations of coding rules | |
WO2018093443A1 (en) | Automated reverse engineering | |
US8332833B2 (en) | Procedure control descriptor-based code specialization for context sensitive memory disambiguation | |
CN104573503A (zh) | 一种内存访问溢出的检测方法及装置 | |
Stanier et al. | A study of irreducibility in C programs | |
CN110096264A (zh) | 一种代码运行方法及装置 | |
CN114911711A (zh) | 一种代码缺陷分析方法、装置、电子设备及存储介质 | |
CN115269427A (zh) | 针对web注入漏洞的中间语言表示方法及*** | |
CN111919214A (zh) | 针对安全性违反的补丁的自动生成 | |
US11656869B2 (en) | Using big code to construct code conditional truth tables | |
Kobayashi et al. | Type-based information flow analysis for low-level languages | |
JP6193151B2 (ja) | 多分岐判断構文の最適化処理装置 | |
KR102209151B1 (ko) | 바이너리 취약점 패치 방법 및 장치 | |
JP2010191847A (ja) | プログラム難読化プログラム及びプログラム難読化装置 | |
JP2006031363A (ja) | バッファオーバーフロー脆弱性検出プログラム及びバッファオーバーフロー脆弱性検出方法 | |
WO2023067665A1 (ja) | 解析機能付与方法、解析機能付与装置及び解析機能付与プログラム | |
US5857070A (en) | Method for locating errors in a computer program |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
A621 | Written request for application examination |
Free format text: JAPANESE INTERMEDIATE CODE: A621 Effective date: 20070717 |
|
A131 | Notification of reasons for refusal |
Free format text: JAPANESE INTERMEDIATE CODE: A131 Effective date: 20100622 |
|
A02 | Decision of refusal |
Free format text: JAPANESE INTERMEDIATE CODE: A02 Effective date: 20101019 |