小飼弾です。ブロマガをお届けいたします。
200 Any Questions OK
Q. OpenSSLのコードの品質はなぜこれほど低いのか?
heartbleedバグにはたまげましたが、それが氷山の一角にすぎないことにさらにたまげています。なぜこれほど品質の低いコードがSSLの標準実装となってしまったのでしょう?
hartbleedがいかにヤバいバグであったかはxkcdを改めてご覧いただくとして、それが氷山の一角であることはOpenSSL Valhalla Rampageにまとめられています。C言語の経験者であればここを見るだけで鬱になれることうけあいですが、念のためC言語を知らない読者に一例だけ紹介します。
C言語で文字列をコピーする時、かつてはstrcpyという関数が使われていました。strcpy(to, from);で、fromという場所にある文字列をtoという場所にコピーされるのですが、これには一つ重大な問題がありました。
C言語の文字列には、長さの情報は含まれていません。その代わりに、文字バイトが\0なら、そこが文字列の終了であるという取り決めになっています。よってstrcpyは「文字バイトが\0になるまで、先頭から1バイトづつ代入」しているのですが、長さ情報がないのはコピー先だけではなくコピー元も同様。つまりコピー先に充分な余裕がないと、コピー先用に確保されたメモリーアドレスを超えてコピー元のバイト列がコピーされてしまい、意図しないメモリー領域が上書きされてしまうのです。業界人が言うところの「バッファーオーバーフロー」がこれです。
strncpyは、それを防ぐために登場しました。strncpy(to, from, length)と書くことで、コピー元に\0が見当たらなくてもlengthで指定された長さでコピーを打ち切ってしまうのです。あとはtoに確保してあるメモリーの大きさより小さな値をlengthで指定しておくだけなのですが、ここにコピー先の大きさではなくコピー元の長さを指定してしまったらどうなるか。バッファーオーバーフローは避けられません。
C言語で書くと、こうなります。
strncpy(to, from, strlen(from));
いかにも初心者がやってしまいがちな過ちなのですが、OpenSSLのコードの中にもこれが入っていましたorz。
しかし問題は、いかにOpenSSLのコードがクソかということではありません。
なぜ、そうであるにもかかわらずそれが使われ、業界標準となったか、です。
そのヒントが、ここにあります。
重要なオープンソースプロジェクトへの支援で大手IT企業が協力
OpenSSLは最初に検討するプロジェクトになる。多くの企業や組織のウェブセキュリティの中核にあったOpenSSLだが、2013年の運用資金はわずか9000ドルだった。ここ数年は、年間平均2000ドルの寄付を受けている
「いちえふ」の作者、竜田一人氏の当初の日当が8000円だったというのにも呆れ驚きましたが、今や原発に勝るとも劣らないほど世界にとって重要であるはずのSSLを実装していた人々のすかんぴんぶりはそれどころではありません。
そのOpenSSLの大掃除のために立ち上がった、OpenBSDの人々の懐も同様に寒いのですから、あとは推して知るべしです。
資金減少により、プロジェクトの経費を払うことができる資金元が必要だ。OpenBSD財団がプロジェクトの電気代を支払うために、寄付を受け付けることができるようにする必要がある
幸いにして寄付は集まり、OpenBSDプロジェクト(名前は似てるけどくれぐれもOpenSSLと混同しないように!)は当面の財政危機を回避したようですが、同様の問題は多くのオープンソースプロジェクトが抱えています。
オープンソースプロジェクトの最大の受益者であるIT業界に資金がないわけではありません。例えばUbuntuの創設者であるマーク・シャトルワースは、SSLの安価な認証局Thawteを立ち上げ、これを商売敵であるVeriSignに売却することで財を成しました。その額およそ350億円。それで宇宙旅行に行く一方、最も人気のあるLinuxディストリビューションを組織面のみならず金銭面でも立ち上げました。
そのUbuntuのサーバー版、今や商売敵であったはずのWindows Azure改めMicrosoft Azureでもサポートされています。
オープンソースを活用して一山当てた人々が、それでオープンソースに恩返しをする。規模の桁は変われど、私も実はその一例であることは「センチメンタル・ジャーニー~OSSはまだ16だから~」にも書いたとおりです。
ところが、heartbleedは、好循環が作用しているように見えたオープンソース経済が心臓からして出血していたことを白日の下にさらしました。
どうしてこうなったのでしょう?