From: Tanaka Akira Date: 2009-06-16T10:06:39+09:00 Subject: [ruby-dev:38648] Re: 1.9でstdin/out/errをcloseしないわけ In article , Yukihiro Matsumoto writes: > [ruby-core:23853]というレポートが来てて、要するに(ARGF経由 > で)STDINを明示的にcloseしてもclosed?が真にならないので1.8と > 非互換という話なんですが、ソースを読むとfptr_finalize()中 > に > > if (IS_PREP_STDIO(fptr) || fptr->fd <= 2) { > goto check_err; > } > > というコードがあって、どうも意図的に0,1,2はcloseしないように > しているみたいなんですが、真意はなんなんでしょうね。 たとえば、stderr (fd=2) を close した状態で、ソケットで通信 しようしたとして fd が 2 になり、その状態で、ログを stderr に出力すると、ソケットにログが出力されて通信が壊れます。 ソケットでなくデータベースだとデータベースが壊れるかもしれま せん。 プログラムは 0, 1, 2 は標準入出力として用意されていて、open や socket で新しくつくった fd が 0, 1, 2 であるとは考えない ものです。0, 1, 2 を close することはその仮定を壊します。 これは場合によっては、CVE-2002-0572 のようなセキュリティ問題 にもなります。まぁ、CVE-2002-0572 はプログラムの中で close を呼ぶという話ではないので、close しないことが対処になるわけ ではありませんが。 なお、スレッドを考えると、0, 1, 2 だったらそれを他の fd に移 すというのもレースコンディションを発生させます。 これらを考えると、0, 1, 2 は close しないというのが適切であ ろうという判断です。 どうしても 0, 1, 2 に対して close のようなことをしたければ、 /dev/null を reopen してください。 -- [田中 哲][たなか あきら][Tanaka Akira]