あした第三回のC/C++セキュアコーディングハーフデイキャンプがあるのに、
今ごろ第二回のC/C++セキュアコーディングハーフデイキャンプの話をするのも
なんなんだけど、一個かいてなかったので、今日書きます。
残ってた内容は、TOCTOU攻撃と、デッドロック攻撃
■TOCTOU攻撃
っていうか、そもそも、TOCTOU攻撃って何?っていう話だけど、
TOC=Time Of Check チェック
TOU=Time Of Use 使用
このチェックしているのと使用しているのの時間差(競合ウィンドウ)を利用して、わるさを仕掛けるというもの
たとえば、
(1)ファイルチェック
(2)存在していたら、Openして読み込み
もし、このとき、(1)でどんなにすばらしいチェックをしていたとしても
(1)ファイルチェック
(1-1)悪意のある人が、(1)のファイルを削除
(1-2)別のファイルを、(1)のファイルとしてすり替える
(2)存在していたら、Openして読み込み
として、読み込んだときは、(1)のすりかえられた、悪意あるファイルになってしまう。
一般には、(1)と(2)の時間は短時間のため、すり替える余裕はないが、
もし、悪意のある人が、24時間、ずーっとループさせてると、できてしまう可能性がある。
●この対策としては、
・チェックと読み込みを、アトミック(1動作)として行う関数を利用する
・ファイル名でなく、i-nodeなど、実体を指し示すものを使う。
■デッドロックを利用した攻撃
デッドロックを起こすには、以下のことが起こる必要がある。
・相互排除
→いわゆる排他制御
・確保しながら待機
→確保できたものは、ロックしつつ、
確保できなかったものに関して、ロック待ちする
・巡回待機
→ここで、Aさんも、Bさんも、XとYという資源がほしく、
AさんがXをロック、Yがあくのを待っている
BさんがYをロック、Xがあくのを待っていると
確保しながら待機するので、XもYもどちらもあかない。
・強制資源解放不可
上記のとき、システムが、一定時間以上たったら、XさんかYさんに
自分の持っている資源を解放させれば、デッドロックは終わるが、
そんなことはしないとき。
ということは、「巡回待機」を起こさないために、よく、アクセス順序を
つけることがある。
しかしこのことは、逆に言うと、もし、アクセス順序がついているなら、
悪意のある人が、その順序を逆走してロックしていったら、デッドロック
攻撃ができるということになってしまう。
■その他
・ファイルロック
よく、ロックファイルを使う場合がある。
このとき、ロックファイルを作成したまま、プロセスが死んでしまうことがある。
そうすると、ロックしたままになるが、これを避けるためには、ロックファイルの中に、プロセスIDを書いておき、
そのプロセスが存在するかどうかをチェックする方法がある。
→再利用された場合の問題はあるが。。。
・スレッドセーフでない場合
排他制御で問題が起きる可能性があるので、ラッパーを使う(Decoratorパターンで)とかする。
・ライブロック
デッドロック回避ロジックが誤ってずっとロックしてしまう。
