第4章 不測の事態対策
レースコンディションの一般的対策
レースコンディション
レースコンディションとは、並列動作する複数の存在(プロセスやスレッド)が同一のリソースへほぼ同時にアクセスしたとき、予定外の処理結果が生じる問題である

データベース更新トランザクションの競合も、そのひとつの例である。
あるトランザクションがひとつのレコードを読み取って処理し新しい値を書き戻そうとしているとき、その書き込みが終わる前に別のトランザクションが更新の目的で同じレコードからの読み出しを始めると、結果としてこのレコードには不適切な値が書き込まれることになる。
(1) インテグリティの喪失
並列処理の中で生じる問題にはさまざまなものがあるが、セキュリティ脆弱性の観点からは、レースコンディションを情報のインテグリティが損なわれる問題として捉えることができる。
例えば、あるプロセスPでは次のような手順の処理を行う。:
例 情報ソースからのインテグリティ検証を伴う読み出し手順
- ステップ1インテグリティの検証
- 情報ソースの内容が適切であることを確認する
- ステップ2データ処理
- 情報ソースから値を取り出し処理して結果を得る
これと並行動作するプロセスQがステップ1と2の間のタイミングで情報ソースをすり替えたらどのようになるであろうか?
Pが導きだす処理結果はQがすり替えたデータに基づいたものに変わってしまう。
情報ソースが複数のプロセスの間で共有し得る次のようなタイプのものである場合、こうした問題は、常におこる可能性をもっている。:
- ファイル
- ディレクトリ
- デバイス
- 名前付きパイプ
- 共有メモリ
- 同期オブジェクト
- プロセス
- スレッド
- データベースレコード
- レジストリキー
- ウィンドウ
- クリップボード
- 証明書ストア 等
(2) 同期規約の蹂躙
並列動作する複数のプロセスやスレッドから共有された対象物へアクセスする際はセマフォ等の同期オブジェクトを用い、互いに干渉し合わないようプログラミングするのが通例である。
このあたりがきちんと計画されていれば、ソフトウェアを構成するプロセス同士がおこすレースコンディション問題を避けることができる。
例 共有対象物からの同期を伴う読み出し手順
- ステップ0 同期の開始
- セマフォを占有する(旗を立てる)
(セマフォがすでに他のプロセスによって占有されていれば、そのプロセスがセマフォを解放するまでこのプロセスはOSによって処理の実行を待たされる。他のプロセスがセマフォを占有していなければ、このプロセスがセマフォを占有し次へ進む。) - ステップ1 インテグリティの検証
- 対象物の内容が適切であることを確認する
- ステップ2 データ処理
- 対象物から値を取り出して処理する
- ステップ3 同期の終了
- セマフォを解放する(旗を倒す)
この方式の危ういところは、すべてのプロセスが善意をもってプログラミングされていることに依存している点である。
ソフトウェアの外部から攻撃を仕掛けようとする者が、このようなた同期規約を無視し、共有対象物に直接アクセスを試みるプログラムを用意する懸念がある。
ステップ1と2の間にうまくタイミングが合えば共有対象物への干渉が成功し、攻撃者に利益を誘導する形でソフトウェアの動作を変えたり、漏えい、改ざん等の情報セキュリティ侵害がおこる。
レースコンディション対策
レースコンディション攻撃によるインテグリティ検証の迂回に対抗するには、同期規約に頼らない対策が必要である。
アクセス権設定による対策
- 共有対象物には最小限のアクセス許可のみを与える
- アクセス許可を制限できない対象物をプロセス間で共有することを見合わせる
改ざん検出データを用いた対策
- 共有対象物の改ざんを検出するため、値の書き込み時に別の場所へメッセージダイジェストを保管する
- ダイジェストの保管場所は攻撃者の改ざんから保護されたところである必要がある
守護プロセスによる対策、あるいはコンポーネント化
- 複数のプロセスが共有対象物を直接アクセスするのではなく、対象物を隔離しアクセスを仲介するひとつの守護プロセスを設け、RPC(リモートプロシジャコール)や名前付きパイプを用いてそのプロセスと通信するようにする
- 守護プロセスは、対象物への複数のアクセス要求が相互干渉しないよう、各要求を整然と処理する