2017年10月24日

Apache HTTP Server 2.4.29 で修正された Out Of Memory 自爆バグについて

仕事上、例えば vmcore のような、数ギガバイトから数十ギガバイトになる可能性のある巨大なファイルを転送する必要に迫られることがあります。しかし、セキュリティ上の理由でインターネット上のサービスを利用できないという制約があるため、いっそのこと自作してしまえと思い、大容量ファイルのアップロード/ダウンロードを行うためのプログラムを試作することにしました。その際、スクリプト言語などに依存してしまうとEOLへの対応が必要になるため、10年20年先も無改造で使い続けることができるであろうC言語で、そして、メモリリークや Web サーバ本体のバージョンアップの影響を受けないようにするため、リクエスト毎に fork()/execve() する Apache のCGIとして動作するプログラムとして開発することにしました。

しかし、たまにリクエストがエラーになったり、システムの動作が極端に遅くなったりと、どうも様子がおかしいことがありました。発生条件を切り分けていったところ、何と「スリープ処理を入れずに大量のレスポンスの送信を行うだけ」で発生していることが判明しました。親プロセスである Apache のワーカープロセスが、子プロセスであるCGIプログラムの出力を全てメモリ上に保持しようとしてしまい、 OOM killer に殺されるか、さもなくば、後続のリクエストに対する fork() ができなくなるというサービス拒否状態に陥っていたのです。

おいおい、メモリ管理で悩みたくないから子プロセスを使うという選択をしたのに、親プロセスが盛大にメモリを食い潰してどうするのよ〜?

/〜(^x^)〜/

ちなみに、RHELへのバックポートは httpd-2.4.6-76.el7 に含まれる予定になっているため、 RHEL 7.5 のリリース時に修正されるものと予想しています。

posted by 熊猫さくら at 22:31| Comment(0) | TrackBack(0) | Linux
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/181378510
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック