単体テスト/結合テスト/システムテストの謎


ソフトウェア・テストの技法

ソフトウェア・テストの技法

ソフトウェア・テストの技法 第2版

ソフトウェア・テストの技法 第2版

  • 作者: J.マイヤーズ,M.トーマス,T.バジェット,C.サンドラー,Glenford J. Myers,Todd M. Thomas,Tom Badgett,Corey Sandler,長尾真,松尾正信
  • 出版社/メーカー: 近代科学社
  • 発売日: 2006/08/01
  • メディア: 単行本
  • 購入: 7人 クリック: 267回
  • この商品を含むブログ (47件) を見る
ソフトウェアのテスト技法 (計算機科学・ソフトウェア技術講座)

ソフトウェアのテスト技法 (計算機科学・ソフトウェア技術講座)


テストケース作成のためのテクニックとしてよく聞くのは、内部設計書から単体テストケースを洗い出し、外部設計書から結合テストケースを
洗い出すというやり方だ。なるほど、確かに内部設計書には各プログラムがどう動作して欲しいかという処理の流れが書いてあるし、
外部設計書には何をインプットとしてどんなアウトプットを得たいのかが書かれているだろう。だから、その情報をもとにして実際に作成された
プログラムと作成の元となった設計書とをつきあわせ、設計どおりに動作するプログラムかどうかをテストするためのテストケースを書くというのは、
まったくもって理にかなっていると言える。
だが、本当にそれだけで十分なのか。
私はそれだけでは必ずしも十分ではないと考えている。
というのは、実装時に選択されたライブラリ特有の脆弱性や、選択されたプログラム言語の言語仕様によって、
設計書だけでは判断できないエラーケースが混入する場合があるからだ。
具体例で考えてみよう。
例えばC++などで書かれたプログラムは、プログラムが確保した領域を超えて文字列が入力された場合、
メモリ領域があふれて予期しない動作が起きる(バッファオーバーフロー)。
こういう問題がプログラムに混入するかしないかは、設計書がどう書かれているかではなく、与えられた設計を
どのようにコード化したか(どんなデータ構造とライブラリを選ぶか)で決まるため、内部設計のみからテストケースを作成してしまうと見落とされる。
しかしこうした問題が見落とされてしまうと大変なことになりかねない。
バッファオーバーフロー脆弱性がシステムに残っていると、最悪の場合悪意あるユーザにコンピュータを乗っ取られてしまう。
バッファオーバーフローを利用したシステムのハッキングには二種類あり、一方をスタックオーバーフロー、
もう一方をヒープオーバーフローという。それぞれメモリのスタック領域、ヒープ領域を攻撃対象とするためにそういう名がついている。
ちなみにスタック領域とはプログラムの一時変数が保存されるメモリ領域であり、
ヒープ領域はプログラムが動的に領域を確保するための余りのメモリ領域だと考えておいてよい。
文字列を配列にコピーするような場合、通常はコピーする要素のサイズチェックを行い、要素数がオーバーしている場合は例外処理を行う。
しかしgets()などを使った場合、gets()が文字サイズチェックを行わないために、
代入先の配列の要素数を越える文字が入力されてもそのままコピーが行われ、バッファオーバーフローが生じる。
そうすると別の変数用のメモリ領域や、別の処理用のメモリ領域が配列をはみ出したデータにより上書きされて
おかしなことになってしまう。
バッファからはみ出たデータが上書きしたのが、
関数の呼び出し元の次のアドレスであるEIP(Extended Instruction Pointer)である場合、
関数実行後に実行される処理は、はみ出してEIPを上書きしたアドレスである。
そのため配列要素をオーバーする要素数を緻密に計算し、
実行させたいプログラム番地が配列をはみ出してわざとEIPを上書きするような巧妙なデータを入力されると、
本来許可されていないプログラムの実行が可能になってしまうのだ。
こうしたバッファオーバーフローを抱えているプログラムが、管理者権限で実行されているプログラム(SUID root)だった場合には、
管理者権限でしか実行できないあらゆる処理がEIPの書き換えによって実行されかねないため、システムは完全なる無防備状態となる。
というわけで、実装に用いたライブラリがバッファオーバーフロー脆弱性を実は秘めているんじゃないかとか、
実装で選択したAPIに不具合が実は入っているんじゃないかというような設計書には想定されていないようなバグ原因に対しても
テストケースを作成してテストを行わないと、バグを作りこんだままのシステムをリリースしつづけることになってしまうのではないか
と私は思う。内部設計や外部設計からテストケースを洗い出すのは理にかなっているが、+αで使っているライブラリの脆弱性のテスト
も品質の保証には必要なはずだ。