delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/1998/04/16/10:05:21

From: newsham AT lava DOT net (Tim Newsham)
Subject: select() bug and fix
16 Apr 1998 10:05:21 -0700 :
Message-ID: <m0yPXgu-00113YC.cygnus.gnu-win32@malasada.lava.net>
Mime-Version: 1.0
To: gnu-win32 AT cygnus DOT com

Hi,

     There is a bug in select() when you select on sockets for exceptions.
The bug causes memory corruption which causes the allocator to finally
crash while doing free()'s.  The bug is due to an off-by-one error in
calculating the winsock descriptor set for exceptions -- The code counts
the number of sockets in the except descriptor set and allocates a
winsock descriptor set of that size.  The select thread then goes and
adds one more descriptor to that set, overrunning the end of the winsock
descriptor set's buffer.

The fix is simple enough.  In select.cc:cygwin32_select()

(note: my patch line numbers are likely off,  I'm using b19.1 sources
with some of my own patches for other things)
---- start patch snip ----
@@ -767,7 +730,7 @@

   read_socket_map = new fd_socket_map (total_read_number);
   write_socket_map = new fd_socket_map (total_write_number);
-  except_socket_map = new fd_socket_map (total_except_number);
+  except_socket_map = new fd_socket_map (total_except_number + 1);

   fd_read_console_map *read_console_map = new fd_read_console_map (total_read_number);
   read_pipe_map = new fd_pipe_map (total_read_number);
---- end patch snip ----

The select code has a few other problems:

    - memcpy() is used to copy memory over itself (is the memcpy in the
      library capable of this?).  At any rate the code can be made simpler
      and more efficient:

---- start patch snip ----
@@ -197,14 +163,12 @@
       {
         if (i < (used_ - 1))
           {
-            memcpy ((char *) &handle_array_[i],
-                   (char *) &handle_array_[i + 1],
-                   (used_ - i - 1) * sizeof (HANDLE));
-            memcpy ((char *) &unix_fd_array_[i],
-                   (char *) &unix_fd_array_[i + 1],
-                   (used_ - i - 1) * sizeof (unsigned short));
+            /* move last entry to new empty slot */
+            handle_array_[i] = handle_array_[used_ - 1];
+            unix_fd_array_[i] = unix_fd_array_[used_ - 1];
           }
         --used_;
+        break;
       }
 }
---- end patch snip ----


    - select assumes in a number of places that the fd sets have only
      64 bits in them.  This means that you can only use 64 descriptors
      in programs that select (even though cygwin allows you to open
      many more descriptors than this).  I haven't patched this yet.

                                             Tim N.
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019