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

ruby-changes:23544

From: shirosaki <ko1@a...>
Date: Tue, 8 May 2012 21:47:39 +0900 (JST)
Subject: [ruby-changes:23544] shirosaki:r35595 (trunk): * include/ruby/win32.h (FD_SET): change function to macro.

shirosaki	2012-05-08 21:47:25 +0900 (Tue, 08 May 2012)

  New Revision: 35595

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35595

  Log:
    * include/ruby/win32.h (FD_SET): change function to macro.
      To avoid buffer overflow when smaller FD_SETSISE is used in ext
      libraries.
    
    * win32/win32.c (rb_w32_fdset): this function is not used anymore.
      But we leave this for compatibility.
    
    * win32/win32.c (rb_w32_select_with_thread): fix SEGV when smaller
      FD_SETSISE is used in ext libraries. Dereference of fd_set pointer
      causes SEGV.
    
    * test/-ext-/win32/test_fd_setsize.rb(TestFdSetSize): add tests for
      above.
    * ext/-test-/win32/fd_setsize/depend: ditto.
    * ext/-test-/win32/fd_setsize/extconf.rb: ditto.
    * ext/-test-/win32/fd_setsize/fd_setsize.c: ditto.
    
      [ruby-core:44588] [Bug #6352]

  Added directories:
    trunk/ext/-test-/win32/fd_setsize/
  Added files:
    trunk/ext/-test-/win32/fd_setsize/depend
    trunk/ext/-test-/win32/fd_setsize/extconf.rb
    trunk/ext/-test-/win32/fd_setsize/fd_setsize.c
    trunk/test/-ext-/win32/test_fd_setsize.rb
  Modified files:
    trunk/ChangeLog
    trunk/include/ruby/win32.h
    trunk/win32/win32.c

Index: include/ruby/win32.h
===================================================================
--- include/ruby/win32.h	(revision 35594)
+++ include/ruby/win32.h	(revision 35595)
@@ -581,7 +581,22 @@
 #define O_NONBLOCK 1
 
 #undef FD_SET
-#define FD_SET(f, s)		rb_w32_fdset(f, s)
+#define FD_SET(fd, set)	do {\
+    unsigned int i;\
+    SOCKET s = _get_osfhandle(fd);\
+\
+    for (i = 0; i < (set)->fd_count; i++) {\
+        if ((set)->fd_array[i] == s) {\
+            break;\
+        }\
+    }\
+    if (i == (set)->fd_count) {\
+        if ((set)->fd_count < FD_SETSIZE) {\
+            (set)->fd_array[i] = s;\
+            (set)->fd_count++;\
+        }\
+    }\
+} while(0)
 
 #undef FD_CLR
 #define FD_CLR(f, s)		rb_w32_fdclr(f, s)
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35594)
+++ ChangeLog	(revision 35595)
@@ -1,3 +1,24 @@
+Tue May  8 21:09:00 2012  Hiroshi Shirosaki  <h.shirosaki@g...>
+
+	* include/ruby/win32.h (FD_SET): change function to macro.
+	  To avoid buffer overflow when smaller FD_SETSISE is used in ext
+	  libraries.
+
+	* win32/win32.c (rb_w32_fdset): this function is not used anymore.
+	  But we leave this for compatibility.
+
+	* win32/win32.c (rb_w32_select_with_thread): fix SEGV when smaller
+	  FD_SETSISE is used in ext libraries. Dereference of fd_set pointer
+	  causes SEGV.
+
+	* test/-ext-/win32/test_fd_setsize.rb(TestFdSetSize): add tests for
+	  above.
+	* ext/-test-/win32/fd_setsize/depend: ditto.
+	* ext/-test-/win32/fd_setsize/extconf.rb: ditto.
+	* ext/-test-/win32/fd_setsize/fd_setsize.c: ditto.
+
+	  [ruby-core:44588] [Bug #6352]
+
 Tue May  8 20:44:46 2012  Hiroshi Shirosaki  <h.shirosaki@g...>
 
 	* io.c (io_unread): fix IO#pos with mode 'r' bug on Windows.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 35594)
+++ win32/win32.c	(revision 35595)
@@ -2452,25 +2452,10 @@
     return -1;
 }
 
-#undef FD_SET
-
 void
 rb_w32_fdset(int fd, fd_set *set)
 {
-    unsigned int i;
-    SOCKET s = TO_SOCKET(fd);
-
-    for (i = 0; i < set->fd_count; i++) {
-        if (set->fd_array[i] == s) {
-            return;
-        }
-    }
-    if (i == set->fd_count) {
-        if (set->fd_count < FD_SETSIZE) {
-            set->fd_array[i] = s;
-            set->fd_count++;
-        }
-    }
+    FD_SET(fd, set);
 }
 
 #undef FD_CLR
@@ -2868,14 +2853,19 @@
 		fd_set orig_rd;
 		fd_set orig_wr;
 		fd_set orig_ex;
-		if (rd) orig_rd = *rd;
-		if (wr) orig_wr = *wr;
-		if (ex) orig_ex = *ex;
+
+		FD_ZERO(&orig_rd);
+		FD_ZERO(&orig_wr);
+		FD_ZERO(&orig_ex);
+
+		if (rd) copy_fd(&orig_rd, rd);
+		if (wr) copy_fd(&orig_wr, wr);
+		if (ex) copy_fd(&orig_ex, ex);
 		r = do_select(nfds, rd, wr, ex, &zero);	// polling
 		if (r != 0) break; // signaled or error
-		if (rd) *rd = orig_rd;
-		if (wr) *wr = orig_wr;
-		if (ex) *ex = orig_ex;
+		if (rd) copy_fd(rd, &orig_rd);
+		if (wr) copy_fd(wr, &orig_wr);
+		if (ex) copy_fd(ex, &orig_ex);
 
 		if (timeout) {
 		    struct timeval now;
Index: ext/-test-/win32/fd_setsize/depend
===================================================================
--- ext/-test-/win32/fd_setsize/depend	(revision 0)
+++ ext/-test-/win32/fd_setsize/depend	(revision 35595)
@@ -0,0 +1,2 @@
+fd_setsize.o: $(top_srcdir)/win32/win32.c \
+  $(hdrdir)/ruby/ruby.h

Property changes on: ext/-test-/win32/fd_setsize/depend
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/win32/fd_setsize/fd_setsize.c
===================================================================
--- ext/-test-/win32/fd_setsize/fd_setsize.c	(revision 0)
+++ ext/-test-/win32/fd_setsize/fd_setsize.c	(revision 35595)
@@ -0,0 +1,55 @@
+#undef FD_SETSIZE
+/* redefine smaller size then default 64 */
+#define FD_SETSIZE 32
+#include <ruby.h>
+
+static VALUE
+test_select(VALUE self)
+{
+    int sd = socket(AF_INET, SOCK_DGRAM, 0);
+    struct timeval zero;
+    fd_set read;
+    fd_set write;
+    fd_set error;
+
+    zero.tv_sec = 0;
+    zero.tv_usec = 0;
+
+    FD_ZERO(&read);
+    FD_ZERO(&write);
+    FD_ZERO(&error);
+
+    FD_SET(sd, &read);
+    FD_SET(sd, &write);
+    FD_SET(sd, &error);
+
+    select(sd+1, &read, &write, &error, &zero);
+
+    return Qtrue;
+}
+
+static VALUE
+test_fdset(VALUE self)
+{
+    int i;
+    fd_set set;
+
+    FD_ZERO(&set);
+
+    for (i = 0; i < FD_SETSIZE * 2; i++) {
+	int sd = socket(AF_INET, SOCK_DGRAM, 0);
+	FD_SET(sd, &set);
+	if (set.fd_count > FD_SETSIZE) {
+	    return Qfalse;
+	}
+    }
+    return Qtrue;
+}
+
+void
+Init_fd_setsize(void)
+{
+    VALUE m = rb_define_module_under(rb_define_module("Bug"), "Win32");
+    rb_define_module_function(m, "test_select", test_select, 0);
+    rb_define_module_function(m, "test_fdset", test_fdset, 0);
+}

Property changes on: ext/-test-/win32/fd_setsize/fd_setsize.c
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: ext/-test-/win32/fd_setsize/extconf.rb
===================================================================
--- ext/-test-/win32/fd_setsize/extconf.rb	(revision 0)
+++ ext/-test-/win32/fd_setsize/extconf.rb	(revision 35595)
@@ -0,0 +1,3 @@
+if $mingw or $mswin
+  create_makefile("-test-/win32/fd_setsize")
+end

Property changes on: ext/-test-/win32/fd_setsize/extconf.rb
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: test/-ext-/win32/test_fd_setsize.rb
===================================================================
--- test/-ext-/win32/test_fd_setsize.rb	(revision 0)
+++ test/-ext-/win32/test_fd_setsize.rb	(revision 35595)
@@ -0,0 +1,25 @@
+require 'test/unit'
+require_relative '../../ruby/envutil'
+
+module Bug
+  module Win32
+    class TestFdSetSize < Test::Unit::TestCase
+      def test_select_with_unmatched_fd_setsize
+        bug6532 = '[ruby-core:44588]'
+        assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
+          require '-test-/win32/fd_setsize'
+          Bug::Win32.test_select
+          p :ok
+        INPUT
+      end
+
+      def test_fdset_with_unmatched_fd_setsize
+        bug6532 = '[ruby-core:44588]'
+        assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
+          require '-test-/win32/fd_setsize'
+          p :ok if Bug::Win32.test_fdset
+        INPUT
+      end
+    end
+  end
+end if /mswin|mingw/ =~ RUBY_PLATFORM

Property changes on: test/-ext-/win32/test_fd_setsize.rb
___________________________________________________________________
Added: svn:eol-style
   + LF


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

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