[前][次][番号順一覧][スレッド一覧]

ruby-changes:50003

From: nobu <ko1@a...>
Date: Wed, 31 Jan 2018 13:25:03 +0900 (JST)
Subject: [ruby-changes:50003] nobu:r62121 (trunk): io.c: pipe_register_fptr

nobu	2018-01-31 13:24:57 +0900 (Wed, 31 Jan 2018)

  New Revision: 62121

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62121

  Log:
    io.c: pipe_register_fptr
    
    * io.c (pipe_register_fptr): get rid of double registration which
      causes access after free and segfault.

  Modified files:
    trunk/io.c
    trunk/test/ruby/test_process.rb
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 62120)
+++ test/ruby/test_process.rb	(revision 62121)
@@ -1810,6 +1810,15 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L1810
     end
   end
 
+  def test_popen_reopen
+    assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+    begin;
+      io = File.open(IO::NULL)
+      IO.popen("echo") {|f| io.reopen(f)}
+      io.reopen(io.dup)
+    end;
+  end
+
   def test_execopts_new_pgroup
     return unless windows?
 
Index: io.c
===================================================================
--- io.c	(revision 62120)
+++ io.c	(revision 62121)
@@ -6194,6 +6194,20 @@ pipe_finalize(rb_io_t *fptr, int noraise https://github.com/ruby/ruby/blob/trunk/io.c#L6194
 #endif
     pipe_del_fptr(fptr);
 }
+
+static void
+pipe_register_fptr(rb_io_t *fptr)
+{
+    struct pipe_list *list;
+
+    if (fptr->finalize != pipe_finalize) return;
+
+    for (list = pipe_list; list; list = list->next) {
+	if (list->fptr == fptr) return;
+    }
+
+    pipe_add_fptr(fptr);
+}
 #endif
 
 void
@@ -7146,8 +7160,7 @@ io_reopen(VALUE io, VALUE nfile) https://github.com/ruby/ruby/blob/trunk/io.c#L7160
     else if (!IS_PREP_STDIO(fptr)) fptr->pathv = Qnil;
     fptr->finalize = orig->finalize;
 #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
-    if (fptr->finalize == pipe_finalize)
-	pipe_add_fptr(fptr);
+    pipe_register_fptr(fptr);
 #endif
 
     fd = fptr->fd;
@@ -7329,8 +7342,7 @@ rb_io_init_copy(VALUE dest, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L7342
     if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
     fptr->finalize = orig->finalize;
 #if defined (__CYGWIN__) || !defined(HAVE_WORKING_FORK)
-    if (fptr->finalize == pipe_finalize)
-	pipe_add_fptr(fptr);
+    pipe_register_fptr(fptr);
 #endif
 
     fd = ruby_dup(orig->fd);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]