pineapple blog

Blog of Ichi Kanaya / 金谷一朗のブログ

Search

Twitter feed

Flickr Feed

Loading Flickr...

    More - Flickr

    Find me on...

    printf considered harmful

    printf関数を使うのはもうよしたほうがいいんじゃないか.

    Sudo format string vulnerability

    このバグは、すごく簡単に言うと printf() 系関数を2段階かけた事に起因したバグです。printf() 系関数を多段に使うことは、セキュリティを考慮したコーディングとしては非常にまずいもので、
    絶対やるな
    と言っても構わないぐらい、危険な行為です。

    とは言うものの,printfの代替案が思いつかない.またprintf系関数を使う以上,それが多段階に使われることはよくあるだろう.文字列のフォーマットをsprintf関数でしたとして,その結果を印字をしたいときにもprintf系関数を使うことは便利なので,なかなか無くならないようにも思う.

    これは可変長引数をサポートするコンパイラ言語という事情からくる.可変長引数の場合引数チェックがいい加減になることと(コンパイル時にフォーマット文字列との静的なマッチングぐらいは出来る),スタックがプログラマの意図しない状態のままバイナリが実行されてしまうことだ.

    Pascalはこの問題に果敢に取り組んだ一例かもしれない.つまり,文字列のフォーマットなど端から諦めるのだ.引数は必ず右からスタックに積むし,印字系手続きであるWriteLnなどはビルトインだ.

    C++では«オペレータをストリーム出力用に割り当てることで,可変長引数を使わずにprintfのような(オブジェクトの出現順に同じ階層に識別子を並べるスタイルで)文字列フォーマットを可能としている.確かにprintfよりは呪文度が高いが,それは慣れの問題だろう.

    Objective-Cでは文字列のフォーマットは一旦NSStringをかませられるので(というか多段階処理が必要な場合はNSStringが必要なので),無茶なフォーマッティングは実行時に捕まえられる可能性がC言語よりは若干高い.もっともこれは注意が行きやすいというだけで,本質的な回避策にはなっていない.

    というわけで,身も蓋もない結論になるが,C言語以外が使える時はC言語以外を使え,というのが正解のような気がする.

    Notes

    1. wtakuo reblogged this from pineappledesign
    2. ds9-garak reblogged this from pineappledesign
    3. 0x35 reblogged this from pineappledesign and added:
      “可変長引数”を使うしかないことから、つまりもうシンタックスにアレだと…..。
    4. im-not-dead-so reblogged this from pineappledesign
    5. pineappledesign posted this
    Blog comments powered by Disqus

    Loading posts...