Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4190853

SEGV in solaris/java/native_threads/src/io_md.c

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.1.6
    • 1.1, 1.1.6
    • core-libs
    • 1.1.6
    • sparc
    • solaris_2.5.1, solaris_2.6
    • Verified



      Name: jn10789 Date: 11/17/98


      There is a race condition in the solaris
      native threads implemenation of
      sysTimeoutFD() in io_md.c. If one sets
      a timeout on a socket, and one thread
      reads it while another thread closes
      it, io_md.c can possibly SEGV. The
      attached program reproduces it within
      seconds:

      dbx: warning: can't find object file io_md.o
      t@9 (l@4) signal SEGV (no mapping at the fault address) in sysTimeoutFD at 0xef77a38c
      sysTimeoutFD+0xa4: ld [%l0], %l3
      (dbx) where
      =>[1] sysTimeoutFD(0xed750268, 0x2710, 0x1, 0x0, 0x0, 0x0), at 0xef77a38c
        [2] java_net_SocketInputStream_socketRead(0xed704628, 0xed704620, 0x0, 0x1, 0x0, 0x0), at 0xef266af8
        [3] Java_java_net_SocketInputStream_socketRead_stub(0xf3180, 0xef1d3cb4, 0x0, 0x0, 0x0, 0x0), at 0xef269bd0
        [4] invokeNativeMethod(0xed704628, 0xec0bc, 0x4, 0xef1d3cb4, 0x200, 0x72756e00), at 0xef6eee6c
        [5] ExecuteJava(0xef1d3b90, 0xef1d3cb4, 0xf3144, 0xf3170, 0xf3158, 0xec455), at 0xef76ead4
        [6] do_execute_java_method_vararg(0xef1d3cb4, 0xed704140, 0xef79df0c, 0xef79df10, 0x0, 0x0), at 0xef70f8f8
        [7] execute_java_dynamic_method(0x0, 0xed704140, 0xef79df0c, 0xef79df10, 0xd80d8, 0x0), at 0xef70e4d4
        [8] ThreadRT0(0xed704140, 0xdb8b8, 0xd80d8, 0xd80d8, 0x1, 0x2000), at 0xef748474
        [9] _start(0xdb8b8, 0x0, 0xef1d3e46, 0xef1d3e47, 0x0, 0xef1d3e45), at 0xef775b68

      The problem is that the file descriptor might
      have been set to -1 in the Classjava_io_FileDescriptor
      object by the closing thread (in socket.c), and
      then moments later the reading thread will get
      the -1 fd, and in the implementation of
      sysTimeoutFD() try to set the -1 bit of the
      fd_set, which will access memory out of range.

      Attached is the java program to demonstrate
      it on native threads.

      ----------MTSocket.java------------------

      import java.net.*;
      import java.io.*;
      import java.util.*;

      public class MTSocket implements Runnable {

          Socket s;

          static void p(String s) {
      System.out.println(s);
          }

          static void pe(String s) {
      System.err.println(s);
          }

          static int SRVR_PORT = 0;

          static int nthreads = 10;

          public static void main(String[] a) throws Exception {

      ServerSocket ss = new ServerSocket(0);
      SRVR_PORT = ss.getLocalPort();

      int i;
      for (i = 0; i < nthreads; i++) {
      new Thread(new Runner(), "runner:" + i).start();
      }

      i = 0;
      while (true) {
      Socket s = ss.accept();
      new Thread(new MTSocket(s), "SRVRReader:" + (i++)).start();
      }
          }

          public MTSocket(Socket s) {
      this.s = s;
          }

          public void run() {
      try {
      run0();
      } catch (Exception e) {}
          }

          
          void run0() throws Exception {
      s.setTcpNoDelay(true);

      InputStream is = s.getInputStream();
      OutputStream os = s.getOutputStream();

      while (true) {
      int r = is.read();
      if (r == -1) {
      s.close();
      return;
      }
      os.write(r);
      }
          }

      }

      class Runner implements Runnable {

          Socket s;

          public Runner() throws IOException {
      s = new Socket("localhost", MTSocket.SRVR_PORT);
          }

          static int nt = 0;
          public void run() {
      try {
      OutputStream os = s.getOutputStream();
      InputStream is = s.getInputStream();
      /* this is crucial to reproducing the bug */
      s.setSoTimeout(10000);

      new Thread(new Closer(s), "closer:" + (nt++)).start();
      while (true) {
      try {
      os.write('A');
      if (is.read() < 0) {
      break;
      }
      } catch (Exception e) {
      break;
      }
      }
      s.close();
      } catch (Exception e) {
      }
      try {
      /* restart */
      new Thread(new Runner(), "runner:" + (nt++)).start();
      } catch (Exception e) {
      }
          }

      }

      class Closer implements Runnable {

          Socket s;

          Closer(Socket s) {
      this.s = s;
          }

          static Random rand = new Random(System.currentTimeMillis());
          public void run() {
      long nap = rand.nextLong() >>> 1;
      nap %= 1000;
      try {
      Thread.sleep(nap);
      } catch (Exception e) {}

      try {
      s.close();
      } catch (Exception e) {}
          }
      }
      (Review ID: 35693)
      ======================================================================

            busersunw Btplusnull User (Inactive)
            jdn Jeffrey Nisewanger (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: