標準に非準拠の実害

beer


IRCでちょっと突っ込み貰ったので補足。


ぼくが「〜しないほうがいいよ」と書いた処理、たとえば「シグナルハンドラで様々な処理を行う」などしているソースコードって、オープンソースのものも含めて結構あると思いますけど、大部分ちゃんと動いています。ですから、「動いてるんだから問題ないのでは?」という疑問は当然出てくると思います。


私は、そういうソースコードが問題なく動く理由は、単に問題が発見・再現していないだけのケースを除けば

  • 僕の書いてることに嘘がある*1
  • そのシステムは問題が起きないように、システムがうまいこと気をつかってくれている

の2つなのかなと思います。前者は自分では突っ込めないので(誰かお願いします)、後者について少々。


例えば、glibc(2.3〜)のソースコードmalloc/malloc.c *2を見ると、先頭行に

Malloc implementation for multiple threads without lock contention.

なんて書いてあり、このmallocならシグナルハンドラから呼んでも大丈夫な予感がして
( ・∀・)つ''∩へぇーへぇー です。実際作者自らハンドラからmalloc/freeしても平気だよ(移植性ないけど)と書いていたりします。


あるいは同じくglibc2のptmallocの実装には、atforkハンドラが仕込んであって、fork後exec前にmallocしても大丈夫そうに見えます。


あるいは、OpenBSDのsigaction(3)のman pageを見ると、

     A few other functions are signal race safe in OpenBSD but probably not on
     other systems:

           snprintf()    Safe.
           vsnprintf()   Safe.
           syslog_r()    Safe if the syslog_data struct is initialized as a
                         local variable.

「snprintfやsyslog_rはシグナルハンドラから呼び出してええよ」と明記されています。


ってな感じですので、私の書き散らしているのは一般論(しかも嘘多し:)が多いということでお願いいたします。ただ一方で、Unsafe Signal Handling in Sendmail の例のように、「一般論」からの逸脱をセキュリティホール扱いする人がいることも事実です。この例ではsendmail側は問題をnon exploitableと結論していますが…。


私は仕事では謎の開発環境付属の謎のlibcを使うことなんかが多い(多かった)もので…なるべく安全側に倒しておきたい傾向が強いのかもしれません。

*1:いっぱいあると思う

*2:Doug Lea, Wolfram Glogerさんのptmallocという実装