パスワードを忘れた? アカウント作成
7287 story

qmailにバッファオーバーフローの脆弱性 109

ストーリー by wakatono
作者以外からの初めての脆弱性申告 部門より

Anonymous Coward曰く、"1997年2月の公開以来6年11ヶ月の間にたった1度だけ(しかも発見者は作者自身)しかセキュリティホールの発見されなかったqmailにこの度新たなセキュリティホールが発見されてしまいました。
問題はqmailを構成するプログラムの一つであるqmail-smtpdにあり、2GB以上のSMTPセッションを受けるとバッファオーバーフローを引き起こす可能性があるとのこと。ただし対策はさほど難しくなく、/var/qmail/control/databytesに2G以下の数値を設定してこのプロセスを再起動すればよいそうです。

私も、自分が管理するメールサーバーでは漏れなくqmailを使っています。理由はなんと言っても構築後、ほとんどメンテナンスせずにいられるからです。さすがに最新バージョンのリリースから6年近くもたっており、十分枯れているだろうと思っていたんですが、ソフトウェアというものもなかなか枯れきらないものなのですね。"

とはいえ、作成された当時のことを考えると、2GB以上のSMTPセッションなんて想像もしなかっただろうなぁ…

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 再起動? (スコア:3, 参考になる)

    by visha (779) on 2004年01月19日 22時36分 (#476306) 日記

    qmail-smtpdってSMTPセッションごとにtcpserverなりinetd(げげ)から起動されるから、明示的な再起動はいらないんじゃないかと思うんですが。今生きているSMTPセッションをすぐに落として、という意味なのかしら。

    # いずれにせよ、databytesを設定しないでqmailを運用するなんて俺自身は考えられないけど。

    • Re:再起動? (スコア:4, 参考になる)

      by Anonymous Coward on 2004年01月20日 0時56分 (#476450)
      databytesじゃ意味がない [securepoint.com]らしいです。
      親コメント
      • Re:再起動? (スコア:2, 参考になる)

        by visha (779) on 2004年01月20日 9時34分 (#476699) 日記

        本当だ。オリジナルのアドバイザリ [guninski.com]もdatabytesの記述が消えて、

        Workaround: Not tested, but setting quota on the receiving email may help.

        となっています。

        親コメント
        • Re:再起動? (スコア:2, 参考になる)

          by mikiT (17519) on 2004年01月20日 11時22分 (#476828) ホームページ 日記
          quota の設定じゃ逃げられないと思うけどなぁ。
          どのユーザにつけるのかわからないけど。

          qmail-smtpd は受け取るだけで、ローカルユーザの権限のファイルになるのは、qmail-local が Maildir なり Mailbox に書き込む時だから。
          親コメント
          • Re:再起動? (スコア:2, 参考になる)

            by visha (779) on 2004年01月20日 12時09分 (#476904) 日記

            ちょっとqmail-smtpd.cを眺めてみました。

            databytesが設定されていない状況であれば、qmailqにそれなりのquotaをかけてあれば、qmail-smtpdがSIGSEGVを食らう前に(qmail-queueがキューに書き出せなくなって落ちるため)SIGPIPEを食らって落ちてくれると思いますが、databytesを設定してあると無駄ということになりそうです。ちなみに、softlimitをかけてもこの件の解決にはなりません。件のコードはポインタをインクリメントしてるだけで、アロケートはしていませんので。

            結局、blast()内でposがオーバーフローしないようにチェックしてやる以外に方法はないと思いました。

            # そもそも、ヘッダフィールド長の上限(CRLF込みで1000bytes)をチェックしなくていいのかよとも思いますし。

            親コメント
            • by visha (779) on 2004年01月20日 12時19分 (#476918) 日記
              ヘッダフィールド長の上限(CRLF込みで1000bytes)をチェックしなくていいのかよとも思いますし。

              ヘッダに限らないや。RFC2822での1行の長さの制限でした。改めて読んでみると、受け入れちゃいけないわけじゃないみたいですね。

              親コメント
      • Re:再起動? (スコア:1, 参考になる)

        by Anonymous Coward on 2004年01月20日 13時05分 (#476999)
        qmail-smtpd.cとqmail.cを読むと分かるが、現在読み込んでいる
        データの量がdatabytesを超えた場合、エラーフラグを設定して
        読み込みの作業を続ける。そしてデータを全て読み込み終わった
        後でdatabytesを超えた旨のフラグが立っていたらクライアントに
        エラーを通知するようになっている。だからdatabytesを設定しても
        読み込み処理のバグは回避できない。

        その他有用そうなもの:
        qmail bug patch [securepoint.com]
        未テストのパッチ(人柱の人は試して結果を報告だ)
        Guninski may have been misled by gdb [securepoint.com]
        バッファーオーバーフローが発生した様に見えるのはgdbの
        問題であって今回の穴はただのSEGVかもしれないという説。
        親コメント
  • qmailのソースが (スコア:3, おもしろおかしい)

    by Anonymous Coward on 2004年01月19日 23時41分 (#476372)
    すごい!!という話をどこかで聞いたので
    ちらっと見てみたら確かにすごい!!

    適当に開いてみたtcpto.cの96行目当たりから

    lastwhen = (unsigned long) (unsigned char) record[11];
    lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[10];
    lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[9];
    lastwhen = (lastwhen << 8) + (unsigned long) (unsigned char) record[8];
    when = now();

    プログラミング初心者の私がいうのも何なんですが
    よくこんな書き方で穴がないもんだ…。
    マジックナンバーのオンパレードだし、コメントはさっぱりないし。

    作者は天才なんだろうなぁ。
    • その他の例 (スコア:3, 参考になる)

      by shadowfire (6584) on 2004年01月20日 5時10分 (#476584) ホームページ
      私には無理やり1行で書こうとするソースが目に付きます。
      例えば、qsmhook.cの
      void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
      とか。なんでこんなにしてまで1行にしなきゃいけないんだろう。
      難読プログラムコンテストにでも出す気なのか?
      これ(qmail-smtpd.c)なんて
      void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
      読みにくいのもそうだけどサイトのURLが変わったらどうすんのよ。
      それだけでバージョンアップ?

      他に気になる点は
      • インデントがスペース1つだったり2つだったり、4つ以上になるとスペース4つとタブが入り混じって読みにくい。やっぱり難読コンテスト上位を目指しているのか?
      • 上記のURLのように、メッセージが全部ソース埋め込み
      • switch-case文でcaseに使われるマジックナンバーの説明コメントが全然無い。
      など。
      databytes関連で、こんな個所もありました。
      if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; }
      複数のif文まで1行ですか。はあ。

      --
      --------------------
      /* SHADOWFIRE */
      親コメント
      • by Anonymous Coward on 2004年01月20日 8時28分 (#476639)
        英語が母国語の人は、この「1行詰めこみコード」が、それを読む場合に「英文」に見えるんですよ。そう見えるように書いてあるわけ。

        日本人から見ると、構造化もへったくれもないただの汚いコードにしか見えない、ということなんだよ。

        だから、このコードを英語があまりうまくない日本人が書いたとしたら、批判は当たりと思うよ。
        親コメント
      • by TxG (7966) on 2004年01月21日 1時29分 (#477668)
        普通の関数は一行で書いたりはしてない気がしますが…(それより僕にはマクロの方が深刻でした…)

        if( x ) if ( y ) { ... }

        って if( x && y ) { ... }

        と同じじゃないんでしょうか(マクロで書くなら気をつけなきゃいけませんが)。
        スタンダードではないですがある意味深いカッコがへっていいような気もするので、少なくとも「スタンダードでないからダメ」以外の理由でそんなに理に叶っていないとか特別に読みにくいコードには見えないです。

        # でも僕は決してif( x ) if( y ) なんて書きませんよ

        脆弱性発見とかいうトピックで、こんなにソースを見ている人がいるのかと思ってびっくりです。

        ---
        飲酒済みにつき乱筆御容赦。
        親コメント
    • Cは文学だねぇ (スコア:2, フレームのもと)

      by Futaro (2025) on 2004年01月20日 3時22分 (#476563) ホームページ 日記
      Cはいろいろな思想の人がいろいろなやりかたでけっこう自由に「表現」できるところがいいところでもあると思うのですよ。他人の書いたコードを見て、ああ、彼はこの部分ではこんなことを大切にしてコード書いてるんだな、とか言うのが見えるようになれば、Cのプログラム書きとしては本当に一人前と思うのですよ。

      で、「ここではこんなことを大切にして書く」というところが重要で、その「大切にしてるもの」が、そのコードでなぜ大切なのか?ということにちゃんと理由があるわけ。自分の書いたコードや自分が大切と思っていることしか強調できない「コドモ」は、所詮その程度のプログラミングの能力しかないんだよね。経験上、だけど。

      ハードウエアの動きも頭の中でちゃんとできていて、それを考慮に入れたこの人のコードは、出来の良い文学の1つを読むみたいですよ。その文学が気に入るかどうか、ということとは別にね。

      だから、今でもなかなか穴がみつからない完成度の高さを持っているわけで。

      物事を自分がいま見える方向からだけ見て評価して、それを絶対と思っちゃだめよ。コードを通してその人の考えていることや人柄やコードを書いたときの体調まで見通せるくらいにならないと。

      精進してくらはいね。
      親コメント
      • Re:Cは文学だねぇ (スコア:2, おもしろおかしい)

        by kamogawa (9923) on 2004年01月20日 9時52分 (#476720) ホームページ 日記
        >コードを通してその人の考えていることや人柄やコードを書いたときの体調まで見通せるくらいにならないと。

        なるほど。俺がなぜいつまでたってもダメプログラマなのか
        やっと分かりました。
        プログラミングの勉強する前に、プロファイリングを
        修めてきますよ。
        親コメント
    • ここだけ見ると、読みやすくて解かり易く
      ほとんどのCPUアーキテクチャで正しく動作する
      良いプログラムに見えます。

      エンディアンの問題とかメモリーのアクセス制限に引っかかることも
      なさそうで、良く考えて作ってるなと思いますよ。
      親コメント
      • by cassandro (6035) on 2004年01月20日 0時20分 (#476424)
        > 良いプログラムに見えます。

         うーん、そうですかねえ。プログラミング/アルゴリズムのお勉強の初歩の初歩、総和の計算を思い出してしまいました。sum=5+4+3+2+1というの。

         DJBはライブラリ関数を信じないそうで、qmailにはその代替のサブルーチンを大量に含んでいます。だけど、微妙にライブラリ関数と引数並びが異なったり、中で初心者がやりそうなコードがあったりと、あまり人様に見せて誇れるコードでは無い様な。#476402のAC氏も述べているコンパイル時に警告が多発するのも、オーソドックスなコード書きからは外れてますし。
        親コメント
    • Re:qmailのソースが (スコア:1, すばらしい洞察)

      by Anonymous Coward on 2004年01月20日 0時01分 (#476397)
      > よくこんな書き方で穴がないもんだ…。

      フリーソフトって素人臭いコーディングが非常に多いんだけど、qmailって群を抜いてへんてこなコーディングなんだよねえ。悪いコード例、「絶対にこんな書き方をしてはいけない」の強力な実例として引き合いに出される場合もけっこうあったりして。

      # まあ、うごきゃ良いってのはそうなんだが、
      # このD. J. Bernsteinって人は、教育者だった事 [cr.yp.to]も
      # あったりするんだよね。
      親コメント
    • by Anonymous Coward on 2004年01月20日 0時01分 (#476399)
      この書き方の何が変なんでしょう……
      エンディアンに左右されずに4bytesな整数を扱いたいだけですよね。
      Cで書けばこんな表現日常茶飯事のような。
      # 関数使え or マクロ定義しろ って話?

      最近はJavaしか知らない方が増えているらしいですけど、
      そんな方から見ると、確かに異様なのかもしれませんが……
      親コメント
    • by Anonymous Coward on 2004年01月20日 0時03分 (#476402)
      DJB氏のソースには独特の味がありますな。
      コンパイルすると警告でまくるしね。
      親コメント
    • Re:qmailのソースが (スコア:1, おもしろおかしい)

      by Anonymous Coward on 2004年01月20日 0時57分 (#476452)
      この程度でガタガタぬかすんじゃない! djbdnsはなぁ、
      if (dns_domain_equal(d,"\0011\0010\0010\003127\7in-addr\4arpa\0")) {
      なんてコードがてんこ盛りだ!! (泣
      親コメント
    • Re:qmailのソースが (スコア:1, おもしろおかしい)

      by Anonymous Coward on 2004年01月20日 1時18分 (#476475)
      C言語=高級アセンブラの説を体現しているようなソースだ...
      親コメント
    • by Anonymous Coward on 2004年01月20日 2時06分 (#476525)
      しかも、djb productは機能拡張なにそれ?なポリシーのおかげで、いまや様々
      なpatch当てが必須なのにも関わらずこういうコード。なのでdjbなコード
      を見てなんじゃこりゃ~と嘆く人が増えるんだろうなぁ。ライバル(というと
      なんだけど)のWietse Zweitze Venema氏のコードと比較しちゃうとなおさら…。
      親コメント
    • by Anonymous Coward on 2004年01月20日 5時19分 (#476586)
      逆に、このソースを読め!というくらい
      美しかったり面白かったりするソフトウェアを思いつく人は教えてほしいなー。

      難解Cプログラムコンテストは面白い。けど、逆方向で。
      親コメント
  • 賞金を (スコア:2, 興味深い)

    by Anonymous Coward on 2004年01月19日 22時59分 (#476324)
    Georgi Guninski氏はゲットできたのだろうか
  • ううぅ (スコア:2, おもしろおかしい)

    by soryu (13825) on 2004年01月20日 0時24分 (#476429)
    そんなメール受け取ったらシステム自体がイってしまいます!

    # 貧弱な鯖なので、ほんとにもたなそう…。
  • パッチ (スコア:2, 参考になる)

    by mikiT (17519) on 2004年01月20日 15時14分 (#477144) ホームページ 日記
    qmail@list.cr.yp.to ML のスレッド [ornl.gov] によると
    James Craig Burleyさん [ornl.gov] が パッチ [jcb-sc.com] を作ったそうです。

    #まだ試してない
  • LAN内部から攻撃するとして
    100BASEの環境で一回の攻撃当たり何分かかるんだろう。
    スループットで80Mでたとして...4分弱か
    今どきまったりした攻撃だな。

    今までのってバッファオーバーフローって
    パケット数個で溢れてたような気がするし
    --
    やなぎ
    字面じゃなく論旨を読もう。モデレートはそれからだ
  • どちらかといえばDoS的ですよね。
    いや、穴は穴なのですが。
  • by reishi (11695) on 2004年01月20日 0時36分 (#476440)
    さすがに最新バージョンのリリースから6年近くもたっており、十分枯れているだろうと思っていたんですが、ソフトウェアというものもなかなか枯れきらないものなのですね。

    「枯れきった」とはどのような状態なのでしょうか?

  • by Anonymous Coward on 2004年01月20日 0時36分 (#476441)
    どのぐらいのメールを受け取ったことありますか?
    1通の最大と、To,cc,bcc等×サイズで。
    私は1通100Mか、120×2Mぐらいです。
  • QMTP同盟 (スコア:1, おもしろおかしい)

    by Anonymous Coward on 2004年01月20日 4時01分 (#476572)
     みんな、QMTP(http://cr.yp.to/proto/qmtp.txt)使ってるかい?
     QMTPてのはDJB提唱のSMTPより効率の良いプロトコルだ。世にqmailを使っているサイトは多いけれど、QMTPを使っているサイトはほとんどないんじゃないかな。
     QMTPでやりとりするメリットは?なんつっても効率がよい。
     そして何よりも、ヘッダのReceived:にwith QMTPとなってかっこいい!

     デフォルトでQMTPを使う方法は以下の通り。
    1. QMTPパッチを当てる(http://www.qmail.org/qmail-1.03-qmtpc.patch)
    2. QMTPでメールを受けるサーバはDNSのMXの優先順位を12801以降にする
    3. inetdにqmail-qmtpdを設定する(ポート209)

     これだけさ。さあ、君も今日からQMTPの仲間だ!
  • チョット気になったのですが、
    databytes [qmail.jp]をみると「databytesはディスクに保存されるバイト数であって、ネットワークを通過するバイト数ではない。qmail-smtpdやqmail-queueのReceived行やenvelopeは含まない。」とあります。

    qmail-smptd [qmail.jp]はメールの受信をSMTP通信で行う最前線のプロセス
    どういう内部処理で問題が発生しているのかC言語を読めない^^;;ので分からないのですが、databytesを使う場合、実際は
    databytes=2GB-(Received行やenvelopeの容量)
    なのでしょうか?

    2GBなんてメールを送受信する事は無いので実際は問題にならないと思うけど気になって^^;;
    やはりココは、tcpserverで対策 [atmarkit.co.jp]がスマートの対策なのかな。
typodupeerror

最初のバージョンは常に打ち捨てられる。

読み込み中...