最新

おおいわのこめんと (2008-04)


2008-04-22

[Misc] 怒涛

うわー、なんか無茶苦茶忙しかった……。

とりあえず2件の発表を終えました。やること溜りまくりですねぇ。

[Work] Fail-Safe C release 1 公開

というわけで、1つ目の発表は Fail-Safe C の正式版公開 です。 最初に函館で発表したのが2001年のJSSST大会*1 で、かれこれもう7年もかかってしまいましたので、プレスリリースは自分なりの1つの纏めとケジメのつもりです。 協力して頂いた皆様、本当にありがとうございました。

Slashdot をはじめいろいろ連絡とかバグレポとかフィードバックを頂いた皆様、対応が遅れていてすみません。 有難く早急に取り組ませて頂きたいと思います。

Fail-Safe C の研究を始めるに当たって「C言語を対象にする」と決めた時点で、 実用に供するというのは大前提の1つです。これからも Fail-Safe C の開発は継続して 進めていきますので、暖かいご声援を頂ければと思っています。

これからもよろしくお願いします。

とりあえず次の機能拡張は mmap ですかね。実は mmap だけならもう実装できてるんですけど、munmap が難しいんですよね……。*2

[Work] MutualTestFox 公開

で、立て続けのプレスリリース第2弾が、「パスワード相互認証プロトコルの技術評価用ソフトウェアを公開」です。

こちらは、RCIS に入ってから始まった共同研究の成果ソフトウェアの第1弾で、 フィッシングを認証プロトコルを使って何とか防げないか、という着眼点からの研究です。

技術的な肝の部分は、暗号プロトコルをうまく使うことで、ユーザが間違ってフィッシングサイトを 踏んでしまってそこで認証を行おうとしても、(1) パスワードの情報が相手に伝わらず、かつ (2) サーバ側に パスワードDBがない限り必ず認証が失敗する(フィッシングサイトが騙そうと思っても「認証成功」と嘘をつけない) という性質を実現していることです。

(1) に関しては、たとえ8文字程度の辞書探索可能なパスワードを使っていても、 通信されたデータからは正規のパスワードを復元できないように加工されているのがミソです。 普通に APOP (例の脆弱性は除外しても) や CRAM-MD5 などのハッシュを使ったアルゴリズムでは、 1回通信した情報を記録しておいて後から辞書攻撃を行えばパスワードがバレますが、 今回のプロトコルでは予めパスワードDBを事前に持っていないと認証が成功せず、 後から辞書攻撃ができないようになっているのです。*3

(2) に関しては、相互認証の結果を表示するUIまで含めて偽装を防ぐために、 UI設計から変更しています。また、HTTP 認証プロトコルの拡張として実装することにしたので、 その前提で本物サイトへの中継攻撃をうまく防ぐように設計したのがポイントです。 実際に最近のフィッシングサイトは本物サイトを使ってパスワードの正誤を調べている ことがありますが、そのような攻撃ができないようになっています。 通常 PAKE は鍵交換と暗号化を組合わせることが前提になっていて、 そちらで中間者攻撃を防ぐのですが、今回は HTTP レイヤで認証を行い、 暗号化は別途 TLS (HTTPS) を使うように設計しているので、 PAKE で交換した鍵に基づく暗号化を行わずに攻撃に対応できるようにしたのがミソです。

ちなみに、別に証明書をどこかから買ったりしなくても導入できるんで、 商業サイトから個人サイトまで自由に使えるプロトコル、というのも売りの一つです。

こちらは昨年度に Internet Draft を出したところで、 本当にまだまだスタートラインから1歩踏み出したところですが、 興味を持って頂ければ、と思っています。 簡単なお試しサーバも公開しましたので、遊んでみてください。

*1 ちょうど 9.11 のニューヨークテロの直後で、飛行機が飛ばなくなるんじゃないかと心配して、函館までの代替ルートを本気で調べたのが思い出されます。函館未来大からの夜景も綺麗でしたね。

*2 malloc が簡単(実装自体は手間はかかるけど)で free が本質的に大変 (GC 導入しないとダメ)、ってのと似てるのかな。munmap は GC と協調しないと正しく動かないので大変なのです。

*3 ちなみにサーバ側のパスワードDBですが、 APOP や CRAM-MD5 と違い、こちらはある一方向関数で処理されたデータを保持しています。 少なくとも十分難しいパスワードを用いていれば、DBエントリが盗まれてもログインに悪用はされません。 詳しくは仕様書を見てください。


2008-04-28

[Comp] JVNVU#162289 ある種の範囲チェックを破棄するC コンパイラの最適化の問題

あー、一目見て面白いイヤらしいケースですねぇ。

引用されている char * のオーバーフローに依存した ARR38-Cのケースは明らかに未定義な例だし、(少なくともこれ単独では) 回避するコードだな、と思います。 そもそもポインタの数値比較が符号付きか符号無しかも定義されてないですね (0x80000000 (32bit arch の場合) を跨ぐオブジェクトが存在し得ないアーキテクチャでは符号付きでもOK)。

ただ、そもそもこのコード例がどういう場面で出てくるんだ? と言う気もするのですが。2^30 の加算で arithmetic overflow を検知って、そもそも ANSI C の「定義」「未定義」だけで妥当性を議論できる世界を 最初から外れているような場面(OSカーネルの世界とか)しか想像できないんですけど……。 *1 あと、解法として提案されている uintptr_t ってこういう使い方していいんだっけ……。「全てのポインタを含める」ことは 保証されていたけど、「ポインタになり得ない値は含めない(オーバーフローが同様に起こる)」ことまで保証されてたっけなぁ……。

一方、MSC15-A の方は、へー、それ最適化しちゃうのかー、アグレッシブだなぁというのが最初の感想。 確かに符号付整数のオーバーフローは仕様上未定義なんですけど、 暗黙に「2の補数」セマンティクスを仮定していることは多いよなぁ、とか思ったり。 とはいえ結論は「ちゃんと直すべき」なんですけどね。

ちなみに Fail-Safe C の場合ですが、まずユーザプログラムの記述については 前者のようなコードはかなり確実にバグ動作を引き起こす原因になります。 FSC のポインタ大小比較はかなり開き直って「オフセットの符号無し比較」として実装されている (違うオブジェクトを指す場合は強制終了) ので、 配列の -1 番目のオフセットを比較対象として番兵的に使っているプログラムはかなり確実にコケます。 で、そのままだと thttpd なんかもコケてしまうので、 -fptr-compare-signed-offset とかいう隠しオプションがあったりするんですが……。 一方後者は基本的にはバックエンドの gcc そのままのコードになるはずです。 ただ、FSC の前処理でコードの形が変化するので最適化が変わる可能性はあります。

一方、FSC の生成コードについては、一瞬ドキッとしたんだけど、ofs_t は 符号無し整数として定義されているんで、たぶん大丈夫なはず……大丈夫だよね……。 もっとも、生成するコードはコンパイラの性質上ほとんどアセンブラとして gcc を使っていて、 最初から2の補数表現を仮定していますし、メモリ周りは特に ANSI C 未定義仕様を使いまくらざるを得ないので、 結局「gcc がこういうアセンブリを吐くから、それに合わせてこういうソースを生成すればいい」というレベルで バックエンド gcc を使っている、と言う話になります。というわけで、 gcc の実装が変わればこちらが追従する、と言うことになるかと思います。 *2

また、FSC は一応 Debian sarge の gcc-3.3.5 と etch の gcc-4.1.2 でテストしていますが、 そもそも gcc 4.2 なんて新しい環境はテストできていないので、 その他のところでそもそもコンパイルが通らない可能性もあります *3 ので、もし問題出たら是非教えてください。

あと、MSC15-A のタイトルですけど、 一般論としての "do not depend on undefined behavior" に関しては、現実に ANSI 100% 準拠でプログラム書くのはかなりきついよね〜、とは思ったりして。 それこそ mmap とか使ってるプログラムで、 どこまでが ANSI 準拠でどこからが未定義なのかとか、ほとんど判定不可能ですよねぇ。

[Rail] asahi.com: JRとの連絡定期券、料金取りすぎ 首都圏の私鉄など

あー、一目見て面白いイヤらしいケースですねぇ。

要は、JRへの連絡定期を私鉄側で買うときに、自社の定期の場合には存在しない 中・高の区分を明示的に設定しなきゃいけないのを見落としていたということのようです。

これを見て自分の中高6年分の定期代が一瞬不安になりましたが、 ほとんど(多分全て)JR側で買っていたのと、 金額が変わってないことのチェックは毎回していたので、 たぶん大丈夫かな。

……うーん、毎回100%全て間違えている、と言う話ではないようなので、 継続購入の時に前回の定期との金額の違いで客側が気付きそうな気がするんですが、 何でこんなに長期間誰も気が付かなかったんでしょうねぇ。 実は誰も金額なんて気にしていない?

[Work] で、mmap @ Fail-Safe C ってどうなってるんだい?

munmap を安全にサポートすべく、現在 Bohem GC の custom mark procedure 機能について文献調査中。 Google する限り数件くらいしか利用例がない……。自分で開拓しないとどうにもならないっぽいなぁ。

*1 カーネルとかの低レベルなプログラムの場合、最初からやってることが ANSI C の定義の外の世界なので、最終的に 「ANSI-C ではここまで定義されているから、コンパイラは直感的なコード生成をする限りこういうコードしか吐けないはず」 「ANSI-C ではこれは未定義だから、こういうコードは吐かれちゃうかもね、書いちゃダメ」という議論になりますね。

*2 それが嫌ならアセンブリを最初から生成することになりますが、 頑張って実装しても gcc の最適化に勝つのは大変そうなんですよねぇ。

*3 実は gcc 4.0 対応でも若干の修正が入ってたりします。ほんのわずかですけど。 また、過去に Intel C Compiler に対応させたときには当時の FSC の生成するコードが 「gcc が最適化するのに icc が最適化しない特定のパターン」に嵌ってしまったので コンパイラ側を結構書き換えていたりします。gcc での悪影響はないのでそのまま今のコードにも入っているはず。


大岩 寛 (おおいわ ゆたか) <yutaka@oiwa.jp.nospam ... remove .nospam> .

Copyright © 2005-2014 Yutaka OIWA. All rights reserved.
Posted comments and trackbacks are copyrighted by their respective posters.

記事の内容について (Disclaimer / Terms and Conditions)