PerlのTaintモードを使うとどれくらい重くなるのか? - 糸の切れた凧(たこ)
元ネタはIkepyonさんの処のこの記事。
別にヤマガタさんのやり方がマズいとかそういう訳じゃないという事を前置きしつつ、でも環境を示さずにやれ○秒の差とか×倍の性能差が出るとか言われてもなぁ……という思いから、自らの環境で追検証してみた。
(プログラム全般に言える事だけど、特にLLってCPU処理速度の影響を受けるから、その辺の情報が無いと参考しようにも参考にできないってのが正直な処なので……。)
---
【1.環境について】
DELLのノートPC(Latitude D520)上にインストールしたCentOS4.6上で検証。詳細は以下の通り。
(ハード)
CPU - Intel Core Duo T2400(1.83GHz)
メモリ - 2048MB
(OS)
種類・バージョン - CentOS 4.6
カーネル - i686用 2.96-67.0.15ELsmp
(Perlエンジン)
バージョン - 5.8.5
---
【2.テスト方法・項目】
基本的にはヤマガタさんの方法に順ずる。4種類のPerl1ライナープログラムに対して、Taintモード有効・無効それぞれ10回の実行時間(Realの値)を計測。
OS起動直後にコンソールから各テストを入力、10回実行
結果を記録後にシステム再起動、次のテストに移る
結果の平均値については2種類(A・B)。平均値Aはヤマガタさんの方式(2~6回目の平均値)に順ずる。平均値Bは最大・最小の値を除く8回分の平均値を算出する方式(要はフィギュアスケートの採点方式に似た方法)。
---
【3.仮説】
Taint有効にすると、Taint無効の時より処理が遅くなる
---
【4.テスト結果】
(テスト1:'for($i=1;$i<=3000000;$i++){$x=$ENV{"PATH"};}')
- Taint有効の場合 -
平均A:6.4054秒
平均B:6.459875秒
- Taint無効の場合 -
平均A:2.5858秒
平均B:2.632875秒
- 性能差 -
平均Aにおける実行時間の差:3.8196秒
平均Aにおける性能差:2.48倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:3.827秒
平均Bにおける性能差:2.45倍(小数点第3位を四捨五入)
(テスト2:$z=$ENV{"PATH"};for($i=1;$i<=8000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:6.402秒
平均B:6.361875秒
- Taint無効の場合 -
平均A:3.913秒
平均B:3.91775秒
- 性能差 -
平均Aにおける実行時間の差:2.489秒
平均Aにおける性能差:1.64倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:2.444125秒
平均Bにおける性能差:1.62倍(小数点第3位を四捨五入)
(テスト3:if($ENV{"PATH"}=~/:([^:]+)/){$z=$1;};for($i=1; $i<=20000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:9.5714秒
平均B:9.43175秒
- Taint無効の場合 -
平均A:8.5752秒
平均B:8.58425
- 性能差 -
平均Aにおける実行時間の差:0.9962秒
平均Aにおける性能差:1.12倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:0.8475秒
平均Bにおける性能差:1.10倍(小数点第3位を四捨五入)
(テスト4:if($ENV{"PATH"}=~/:([^:]+)/){$z=$1;};for($i=1; $i<=20000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:8.6314秒
平均B:8.633875秒
- Taint無効の場合 -
平均A:8.6628秒
平均B:8.741125秒
- 性能差 -
平均Aにおける実行時間の差:-0.0314秒
平均Aにおける性能差:1.00倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:-0.10725秒
平均Bにおける性能差:0.99倍(小数点第3位を四捨五入)
---
【5.考察】
基本的にはTaint有効にすると、Taint無効時と比較して遅くはなる(Taint処理のためのオーバーヘッドが発生する)
ただしどの程度オーバーヘッドが発生するかについては、処理の内容によって大幅に変化する(殆ど変わらないケース(テスト4)~2.5倍程度発生するケース(テスト1)まで結果に幅がある)
システムの性能やプログラム内容によって変わるし、最終的に実機で計測して判断する必要があるが、最悪のケースを想定して2倍程度の(流石に2倍は大きすぎるので)1.1~1.2倍程度のオーバーヘッドが発生するものと仮定して、保険の意味合いも兼ねてTaintを常に有効にするかそうでないかを判断する必要があるものと想定
もし処理速度的に常にTaintを有効にするのが難しい場合は「1.リリース前テストの段階で徹底的に脆弱な箇所を洗い出してから、Taintを無効にした状態でリリースする」「2.ボトルネックとなっている箇所を改修しTaintを有効にしても要求仕様(特に応答時間)を満たす事を確認してから、Taintを有効にしてリリース」などの判断が発生する
勿論Taintモードが「銀の弾丸」という訳ではなく抜け道もある、という事を念頭に置きつつ、Taintを有効にする/しないを判断する事になるのではないかなぁ……と思われます。
---
(2008/6/12 修正追記)
流石に2倍のオーバーヘッドがかかるケースはそんなに無いと想定されるので、1~2割増し(1.1~1.2倍)程度のオーバーヘッドが発生すると概算見積した上で、Taintモードを「保険」として有効にするか否か……って感じかと。
Taintモードがあくまで「保険」というのは、IPAの旧版セキュア・プログラミング講座にも「Taintモードの盲点」と題して紹介されている通り。
それと今回はPerlに関するお話でしたが、他の言語系については状況が異なるので各位でご確認を。
元ネタはIkepyonさんの処のこの記事。
別にヤマガタさんのやり方がマズいとかそういう訳じゃないという事を前置きしつつ、でも環境を示さずにやれ○秒の差とか×倍の性能差が出るとか言われてもなぁ……という思いから、自らの環境で追検証してみた。
(プログラム全般に言える事だけど、特にLLってCPU処理速度の影響を受けるから、その辺の情報が無いと参考しようにも参考にできないってのが正直な処なので……。)
---
【1.環境について】
DELLのノートPC(Latitude D520)上にインストールしたCentOS4.6上で検証。詳細は以下の通り。
(ハード)
CPU - Intel Core Duo T2400(1.83GHz)
メモリ - 2048MB
(OS)
種類・バージョン - CentOS 4.6
カーネル - i686用 2.96-67.0.15ELsmp
(Perlエンジン)
バージョン - 5.8.5
---
【2.テスト方法・項目】
基本的にはヤマガタさんの方法に順ずる。4種類のPerl1ライナープログラムに対して、Taintモード有効・無効それぞれ10回の実行時間(Realの値)を計測。
結果の平均値については2種類(A・B)。平均値Aはヤマガタさんの方式(2~6回目の平均値)に順ずる。平均値Bは最大・最小の値を除く8回分の平均値を算出する方式(要はフィギュアスケートの採点方式に似た方法)。
---
【3.仮説】
Taint有効にすると、Taint無効の時より処理が遅くなる
---
【4.テスト結果】
(テスト1:'for($i=1;$i<=3000000;$i++){$x=$ENV{"PATH"};}')
- Taint有効の場合 -
平均A:6.4054秒
平均B:6.459875秒
- Taint無効の場合 -
平均A:2.5858秒
平均B:2.632875秒
- 性能差 -
平均Aにおける実行時間の差:3.8196秒
平均Aにおける性能差:2.48倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:3.827秒
平均Bにおける性能差:2.45倍(小数点第3位を四捨五入)
(テスト2:$z=$ENV{"PATH"};for($i=1;$i<=8000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:6.402秒
平均B:6.361875秒
- Taint無効の場合 -
平均A:3.913秒
平均B:3.91775秒
- 性能差 -
平均Aにおける実行時間の差:2.489秒
平均Aにおける性能差:1.64倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:2.444125秒
平均Bにおける性能差:1.62倍(小数点第3位を四捨五入)
(テスト3:if($ENV{"PATH"}=~/:([^:]+)/){$z=$1;};for($i=1; $i<=20000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:9.5714秒
平均B:9.43175秒
- Taint無効の場合 -
平均A:8.5752秒
平均B:8.58425
- 性能差 -
平均Aにおける実行時間の差:0.9962秒
平均Aにおける性能差:1.12倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:0.8475秒
平均Bにおける性能差:1.10倍(小数点第3位を四捨五入)
(テスト4:if($ENV{"PATH"}=~/:([^:]+)/){$z=$1;};for($i=1; $i<=20000000;$i++){$x=$z;})
- Taint有効の場合 -
平均A:8.6314秒
平均B:8.633875秒
- Taint無効の場合 -
平均A:8.6628秒
平均B:8.741125秒
- 性能差 -
平均Aにおける実行時間の差:-0.0314秒
平均Aにおける性能差:1.00倍(小数点第3位を四捨五入)
平均Bにおける実行時間の差:-0.10725秒
平均Bにおける性能差:0.99倍(小数点第3位を四捨五入)
---
【5.考察】
勿論Taintモードが「銀の弾丸」という訳ではなく抜け道もある、という事を念頭に置きつつ、Taintを有効にする/しないを判断する事になるのではないかなぁ……と思われます。
---
(2008/6/12 修正追記)
流石に2倍のオーバーヘッドがかかるケースはそんなに無いと想定されるので、1~2割増し(1.1~1.2倍)程度のオーバーヘッドが発生すると概算見積した上で、Taintモードを「保険」として有効にするか否か……って感じかと。
Taintモードがあくまで「保険」というのは、IPAの旧版セキュア・プログラミング講座にも「Taintモードの盲点」と題して紹介されている通り。
それと今回はPerlに関するお話でしたが、他の言語系については状況が異なるので各位でご確認を。