2009/08/01(土)「IE」に対する最新攻撃の原因、たった1つのタイプミス--MSが認める (CNET Japan)

2009/08/01 22:40

http://japan.cnet.com/news/sec/story/0,2000056024,20397505,00.htm

昨日の続きです。というか、そもそもCNET Japanの記事のほうが先だったようですが。

ニュース記事自体から得られる情報は昨日と大して変わりませんが、Microsoftのブログへのリンクがあったので辿ってみたところ、面白い記述を見つけました。

I contend that this would be very difficult to spot in a code review, and is not picked up by the C/C++ compiler owing to the (void*) cast. If the cast is removed, the compiler issues an error like this:

C2664: '<function>' : cannot convert parameter 1 from 'BYTE **' to 'BYTE *'

The Security Development Lifecycle : ATL, MS09-035 and the SDL

茶吹いた。void *へのキャストはコンパイルエラーを消すためだけに付けられたものようです。「消す」というよりは「ごまかしてなんとかコンパイルを通す」という感じかな。

おそらく作業者は最初にこう書いたのでしょう。

hr = pStream->Read(&pbArray, (ULONG)cbSize, NULL);

しかし、コンパイルが通りませんでした。そして、コンパイラが見つけた「引数の型が違う」というエラーを消すために、正しい型の引数を持ってくる *1 のではなく、単にコンパイラを黙らせる *2 ことを選んだのですから、これはtypoによるセキュリティホールではありません。もっと別の次元のミスであり、このミスに関しては防ぐことができたはずです。

「プログラムは意図したとおりではなく書いたとおりに動く」という格言がありますが、まさしくそれを実証しているソースコードですね。コンパイルエラーを消すために意図とは全く違うコードになってしまった。

もしこのミスをしたのが新人だったら、噛んで含めるようによく言い聞かせることです。きっと彼(彼女)は二度と同じ間違いはしなくなるでしょう。

もしこのミスをしたのが30歳を超えていたら、すぐに別の仕事を紹介してあげることです。きっと彼(彼女)は「コンパイルが通るコードを書く」ことが仕事だと勘違いしており、これから先も周りの技術者に迷惑をかけ続けることでしょうから。

*1:ここでは&を取ること。

*2:ここではvoid *にキャストすること。