OpenBSD、malloc(3) を改良。多数パッケージに影響か 32
ストーリー by Acanthopanax
セキュア養成 部門より
セキュア養成 部門より
tamo 曰く、 "Undeadly.org の記事によると、3.8 リリースの近付く OpenBSD で malloc(3) に大きな変更が加えられたため、より多くのユーザによるテストが求められている。
変更点は、まず malloc(3) が brk(2) ではなく mmap(2) を使うようにしたこと。そして mmap(2) がランダムな領域を取るようにし、かつ、割り当てられた複数の領域が隣接することのないようにしたこと。これらにより、ソフトウェアにバグがあってオーバーフローしても、既存領域を上書きすることなく SIGSEGV で死ぬようになる。
また、free(3) は領域を実際にカーネルへ返してしまうようになった。そのため、free(3) したあとに読み書きしようとすると SIGSEGV することになる。
これらはどちらも legal ではあるが、プログラマに厳しい制約を課すことになる。言い換えれば、自然にセキュアなコードを書かせるものである。たとえば、この変更のおかげで X サーバのコードにバグを見付けることができた。free(3) 後のアクセスと、バッファを越えた読み出しである。
自分の使っているパッケージにこうしたバグがないかどうか、OpenBSD 3.8-beta で調べてみるようお奨めする。"
brkを使わないデメリット (スコア:3, 興味深い)
OpenBSDではどう回避するのかな?互換性問題でると思うんだけど。
Re:brkを使わないデメリット (スコア:0)
Re:brkを使わないデメリット (スコア:0)
Re:brkを使わないデメリット (スコア:0)
詳しく。
Re:brkを使わないデメリット (スコア:0)
これはつまり (スコア:1)
Re:これはつまり (スコア:2, 参考になる)
Re:これはつまり (スコア:2, 興味深い)
理屈は分かるが...
これは、BSD Purify を作って OpenBSD と一緒に配布した方が、よりセキュアだと言ってるの?
それとも Pufity みたいなメモリチェッカーを使わないフリーソフト作者はこの世から排除すべきだと言っている?
なんというか、ぼくは OpenBSD らしい方法だと思う。とにかくセキュアにしたい、でも怪しいフリーソフトも使ってみたい、という場合もまああるにはあると思うので、こういうのがあってもいいと思う。このぐらいやらないと、OpenBSD の存在意義が無いというかなんというか。
Re:これはつまり (スコア:2, すばらしい洞察)
ええと、malloc(3)はシステム「ライブラリ」のtypoですよね?
たしか、OpenBSDは安全性をウリにしているOSだと思うので、パフォーマンスを犠牲にして安全性を保障するというのは一つの戦略として僕はわからんでもないです。システムライブラリのmallocを置き換えてしまえば、mallocを使用している多くのプログラムの安全性を一挙に高めることが出来ますからね。
Purifyなどのツールはあくまで個々のプログラムを検査・分析する為のツールのように思います。一方で今回のOpenBSDの方法はOS上で走っているプログラムを含めたシステムトータルの安全性を高める戦略で、目的が異なります。
そして、そのOpenBSDが検査にも使えるってのはあくまで2次的な用途です。こういうのをアレゲっていうんでしょ?(笑) ちがうかな。
Re:これはつまり (スコア:0)
Re:これはつまり (スコア:2, 参考になる)
はずれ。
と書いてある。malloc(3) が毎回 mmap(2) を呼ぶのではなく、今まで brk(2) を読んでいた箇所で mmap(2) を使うようにしただけ。free(3) がカーネルにメモリを返すのも当然毎回ではなくそのページ中に割り当てられたチャンクがすべて free(3) された時。元記事のリンク先に
毎回 mmap(3) を呼んで新たにページを割り当ててたら、システムコールのオーバーヘッド云々以前に、数バイト、数十バイト単位のチャンクを大量に malloc(3) するプログラムがメモリを食い尽くしてしまう。テストどころの騒ぎではない。火を見るより明らか。そんなことはしないでしょ。
となると、この変更の効果は実用環境でのオーバーラン等の被害を減らし、またバグを検出しやすくすることではあるけど、徹底的にバグをたたき出すものではない。Purify のようなものとは用途がずれている。
Re:これはつまり (スコア:1, 興味深い)
mmap や brk で大きめの領域を確保しおいて malloc がその領域から割り当てを行うことも、free した領域に関する扱いも処理系依存で実装により違うのでは?
というのは置いておいて、OpenBSD 3.4 Release [openbsd.org] で、
と明らかに高速性よりも積極的なセキュリティを重視する戦略を取っているので、パフォーマンスは無視してでも潜在的に問題がありそうなところは徹底して潰すほうが OpenBSD らしいよ。
Re:これはつまり (スコア:0)
高速でかつセキュリティなものも出来るのですが。 あなたの文章を読んで無知が一番強いという言葉を思い出しました。
Re:これはつまり (スコア:1)
「セキュアなもの」ね。 無知が一番強いというのは、確かなようだ。 (フレームのもと)
Re:これはつまり (スコア:1)
つまり、#788069では、ユーザランドのライブラリ じゃなくてシステムコールで解決しようとしているのが馬鹿なこととおっしゃってたのですね。システムライブラリに組み込むのが馬鹿なことなのではなく、そのアルゴリズムに関する異議なのですよね?それなら合点です。すいません。
ところで、ユーザランドでのmalloc置き換えの実装と言うと、例えば以下のものもそうなのではないかと想像しますが、これらと比べても今回のOpenBSDのアプローチはhigh costですかね? 昔、これらに類するツールをいくつかちょこっと試してみた感想なのですが、それらも通常のmallocを使った場合と比べて大分パフォーマンスが悪かった記憶がありますので、それ以上遅いと実用には向かない気がいたします。その時、私の使ったツールのアルゴリズムがたまたま悪かったのでしょうか? この種のツールのみなさんの比較経験を教えて頂けるとありがたいです。
# って、もうこの記事にはコメントつかなそうですが...
Re:これはつまり (スコア:1, すばらしい洞察)
これはOpenBSD だぜ。
いいじゃねぇか、実用OS を使った壮大な実験なんだよ、これは。
Re: これはつまり (スコア:1)
ふむ。
> というかbrkはPOSIX.1ではないので意図的に使っていません。
standard至上主義はよしとして、
> それからシステムコールになんかしたらパフォーマンスがあがらないので、
何をシステムコールにしたら性能が上がらないのでしょうか?
malloc(3)をmmap(2)だろうがsbrk(2)だろうが、どっちにしろシステムコールを呼ぶ場合がある
という状況に変わりはないと思うのですが。
Re:これはつまり (スコア:1, 参考になる)
Re:これはつまり (スコア:1, 興味深い)
fj.comp.lang.cの定番だったmalloc/free論争には決着が
付けられるかもしれません :-)
32bit アドレス 4k ページのシステムだと (スコア:1)
(-1 は隣接ページを空けておく分)
Re:32bit アドレス 4k ページのシステムだと (スコア:1, 参考になる)
Re:32bit アドレス 4k ページのシステムだと (スコア:2, 興味深い)
そうすると、malloc(4097) を34万回か…
性能は? (スコア:0)
Re:性能は? (スコア:3, 興味深い)
やっぱり問題になりそうなのは愚直にmalloc-freeを繰り返すタイプのプログラムでしょうね. 今まではfreeした領域をプロセス内で保持して次のmallocで再利用していたので, うまくいくと(しかもうまくいく確率が高い)システムコールを呼び出す必要が無いので大幅に性能に効いてきますね.
典型的にはリスト処理とかオブジェクトのインスタンス生成なんですけど, やっぱり自前でガーベージコレクションなどの処理を行う必要を覚悟しておけってこてなんでしょうかね.
Re:性能は? (スコア:1)
バッファオーバーフローしてもエラーにならないという訳ですね。
やっぱりオン、オフできるといいのだけど。
#OpenBSDを使う事がオンにするという事なのか。
Re:性能は? (スコア:2, 参考になる)
Re:性能は? (スコア:0)
普通に使っていれば気になるほど遅くならないと思いますが。
あまりに遅くなるようなら、自前のサブアロケータ用意するという逃げ道もありますが、
それはそれで本末転倒ですな。
Re:テスト環境省 (スコア:1)
デペロッパー辺りに投げれば食いつきいいんじゃないかな。
#脳内オーバーフロー :)
Re:テスト環境省 (スコア:1)
ということで、トップページに出してみました。
Re:テスト環境省 (スコア:0)
3つしかコメントが付いてないように見えたぞ。