This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Bounds checking in FD_SET; JDK conformance for java.net.Socket


While debugging servlet code I discovered a socket example that will
sometimes crash libgcj:

	Socket s = new Socket("localhost", 80);
	InputStream is = s.getInputStream();
	s.close();
	s.setSoTimeout(100);
	is.read();

The read() method sees fnum == -1 and timeout == 100, so tries to FD_SET 
with a bad fd. The FD_SET man page warns about undefined behavior for
negative values, or values greather than FD_SETSIZE.  Likely
consequences include triggering an exception, aborting the program or
corrupting the stack, etc.

Presumably we should never reach select() in the example above.  (The
JDK doesn't, it throws a SocketException in setSoTimeout.)  This patch
matches the JDK's behavior on setSoTimeout and adds a safeguard to FD_SET.
(On Solaris FD_SETSIZE defaults to 1024.  It's conceivable that some code
could exceed that with a valid fd.  I'm not sure if anything better can be
done than just ignoring the timeout in that case.)

Tested on alpha-linux.

2002-06-14  Jeff Sturm  <jsturm@one-point.com>

	* java/net/natPlainDatagramSocketImpl.cc (receive):
	Check bounds of argument to FD_SET.
	(setOption): Throw exception if socket is closed.

	* java/net/natPlainSocketImpl.cc (accept, read):
	Check bounds of argument to FD_SET.
	(setOption): Throw exception if socket is closed.

Index: java/net/natPlainDatagramSocketImpl.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/natPlainDatagramSocketImpl.cc,v
retrieving revision 1.37
diff -u -p -r1.37 natPlainDatagramSocketImpl.cc
--- java/net/natPlainDatagramSocketImpl.cc	15 Apr 2002 03:21:00 -0000	1.37
+++ java/net/natPlainDatagramSocketImpl.cc	14 Jun 2002 04:24:05 -0000
@@ -361,7 +361,7 @@ java::net::PlainDatagramSocketImpl::rece
 // FIXME: implement timeout support for Win32
 #ifndef WIN32
   // Do timeouts via select since SO_RCVTIMEO is not always available.
-  if (timeout > 0)
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
     {
       fd_set rset;
       struct timeval tv;
@@ -500,6 +500,9 @@ java::net::PlainDatagramSocketImpl::setO
 {
   int val;
   socklen_t val_len = sizeof (val);
+
+  if (fnum < 0)
+    throw new java::net::SocketException (JvNewStringUTF ("Socket closed"));
 
   if (_Jv_IsInstanceOf (value, &BooleanClass))
     {
Index: java/net/natPlainSocketImpl.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/net/natPlainSocketImpl.cc,v
retrieving revision 1.41
diff -u -p -r1.41 natPlainSocketImpl.cc
--- java/net/natPlainSocketImpl.cc	2 May 2002 17:33:59 -0000	1.41
+++ java/net/natPlainSocketImpl.cc	14 Jun 2002 04:24:09 -0000
@@ -369,7 +369,7 @@ java::net::PlainSocketImpl::accept (java
 // FIXME: implement timeout support for Win32
 #ifndef WIN32
   // Do timeouts via select since SO_RCVTIMEO is not always available.
-  if (timeout > 0)
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
     {
       fd_set rset;
       struct timeval tv;
@@ -516,7 +516,7 @@ java::net::PlainSocketImpl::read(void)
 // FIXME: implement timeout support for Win32
 #ifndef WIN32
   // Do timeouts via select.
-  if (timeout > 0)
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
   {
     // Create the file descriptor set.
     fd_set read_fds;
@@ -575,7 +575,7 @@ java::net::PlainSocketImpl::read(jbyteAr
 // FIXME: implement timeout support for Win32
 #ifndef WIN32
   // Do timeouts via select.
-  if (timeout > 0)
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
   {
     // Create the file descriptor set.
     fd_set read_fds;
@@ -662,6 +662,7 @@ java::net::PlainSocketImpl::available(vo
 
 #if defined(HAVE_SELECT)
   if (! num_set)
+  if (! num_set && fnum >= 0 && fnum < FD_SETSIZE)
     {
       fd_set rd;
       FD_ZERO (&rd);
@@ -688,6 +689,9 @@ java::net::PlainSocketImpl::setOption (j
 {
   int val;
   socklen_t val_len = sizeof (val);
+
+  if (fnum < 0)
+    throw new java::net::SocketException (JvNewStringUTF ("Socket closed"));
 
   if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$))
     {



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]