著作一覧 |
Monoミーティングで川幡さん(ごめんなさい。最初間違えて書いてました(ご指摘多謝))のNaClについてのプレゼンというか調べたことのレポートがあって、えらくおもしろかったのでメモ。
・NaClは、Cのプログラム(x86バイナリにコンパイル済み)をダウンロードして実行する仕組み。
・ミソは、2重のサンドボックス(というか安全弁)
・最初のサンドボックスとは
−コンパイル時にretを生成しない。(スタック上のデータをpcに設定しない)
−レジスタを利用した間接ジャンプは、NaClJumpというものに置き換える。
−NaClJumpは、eaxに0xffffffe0でマスクした後にeaxの指すアドレスへジャンプ。
−ミソは0mod32にすること。オペコードの開始は32バイト境界へ配置(個々のルーチンは、ということだと思う。()内で思っているのはおれ)
−セグメントレジスタを設定することで、限定した32ビットアドレス内でのみ実行できるようにする。
−ベリファイアがダウンロード中にインストラクションの正当性を検査。たとえばretを発見したら弾く。間接jumpがNaClJumpでなければ弾く。不法オペコードは弾く。この処理はやたらと高速。
−実行速度は、NaClJumpのオーバーヘッドがあるのではないかと思ったら、むしろ高速だった。32バイト境界へのオペコード配置がキャッシュと相性が良いのではないか。
−もちろん、サイズはでかくなる。30%増し。ただし、配置を最適化すればもう少しコンパクトになる可能性はある。
・もう一つのサンドボックスは、当然ライブラリということになる。
というような感じで、retのところにしびれた。
しびれたが、callはcallなんだろうから、関数のエントリで戻りアドレススタックのようなアプリケーションスタックを用意してそこへ格納し、NaClJump用にeaxへポップするというような仕組みなのかな? というようなことを知りたければ、NaClのソースを読むか、生成したバイナリを調べれば良いので、休日になって、しなければならないことをしたら、見てみよう。たとえば、戻りアドレスがデータスタック(というように通常のスタックを利用すると仮定して)上のを利用しないとしても、関数の戻り先での利用を想定してオーバーフローさせておいて、そこでeaxへポップしたら、そこで落とせるのではないかとか。結局、見なければわからないな。
(追記:ご教示ありがとうございます。『ret は pop + nacljmp になるだけちゃうかな。』。そこまで川幡さんの説明では語られていなかったので僕が勝手に想像していただけです。というか、今までスルーしていたクロフォード本の80386セグメンテーションの項を読んでいるけど、これは難しいな)
(参考:正しいUI というのを思い出したが、さてNaClはどう使えるのだろうか)
Monoミーティングでは、ミゲルのPDCセッションの話。SIMDを利用したら、Monoのプログラムがものによっては48倍高速化されるという(ちょっと詐術が入っていそうな)デモとか。にしても、SIMDの効果はすごいな。
というわけで、Mono(というかNovell)のビジネスとして、ゲーム用のライセンス(LGPLと商用のデュアルとなっているらしい)がそれなりに出ているというような話。
さらに、万葉でプレゼンするというあたりから、中学のときには100首ほど暗記していたというような話が出たり、なんか意外と世界は狭いような気になったり。
ジェズイットを見習え |
中の人として間違ってると問題あるので、その発言はよくも知らん子が、疑問に思った後に適当に論文斜め読み + nacl-gcc&objdump した結果書いたことだと一応補足させてください。脇が甘くない子になるために!<br><br>斜め読みした個所は、<br><br>・ ret. Returns are implemented with a sandboxing sequence that ends with an indirect jump<br><br>とか書いてあって、コンパイル結果も pop + and + jmp でしたのでそういうことかなと考えました。
×川端さん ○川幡さん です!
表現を変えました。すみません。>shinhさん<br>どうもありがとうございます。>koichiroさん