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

(bf) MappedByteBuffer.load can SIGBUS if file is truncated

XMLWordPrintable

    • b105
    • x86
    • linux
    • Verified

      OPERATING SYSTEM
      ----------------
      Linux

      LICENSEE PROBLEM DESCRIPTION
      -------------------
      The problem described by CR 6244515 ("Unsafe operations that access invalid memory are not handled gracefully") is not resolved on Linux, contrary to the information in that CR.

      A simple testcase is provided below, which does the following:

      1. Create a test file
      2. Open a FileChannel to the test file
      3. Create a MappedByteBuffer from the FileChannel
      4. Attempt to truncate the file via FileChannel.truncate()
      5. Attempt to call load() on the MappedByteBuffer created in step 3

      The situation presented by the testcase is handled gracefully on Solaris and Windows, but causes a crash on Linux (which is very similar to the crash observed on Solaris
      with the 5.0 JDK).

      Note that this does not appear to be a regression, as the problem is reproducible on Linux with ALL Java 6 SDKs. In fact it seems that the issue was never fixed properly. The problem is also seen with Java 7 (tested b69).

      Here are the results on Windows, Solaris and Linux, all with 1.6.0_16:

      Windows
      -------
      Creating test file...done
      Creating mapped buffer from test file...done
      Attempting to truncate the file...Exception in thread "main" java.io.IOException: The requested operation cannot be performed on a file with a user-mapped section open
              at sun.nio.ch.FileChannelImpl.truncate0(Native Method)
              at sun.nio.ch.FileChannelImpl.truncate(FileChannelImpl.java:338)
              at TruncateTest.main(TruncateTest.java:22)

      Solaris
      -------
      Creating test file...done
      Creating mapped buffer from test file...done
      Attempting to truncate the file...done
      Attempting to load mapped buffer...Exception in thread "main" java.io.IOException: Bad address
              at java.nio.MappedByteBuffer.load0(Native Method)
              at java.nio.MappedByteBuffer.load(MappedByteBuffer.java:127)
              at TruncateTest.main(TruncateTest.java:26)

      Linux
      -----
      Creating test file...done
      Creating mapped buffer from test file...done
      Attempting to truncate the file...done
      Attempting to load mapped buffer...
      #
      # A fatal error has been detected by the Java Runtime Environment:
      #
      # SIGBUS (0x7) at pc=0xb53257f0, pid=13023, tid=3075017616
      #
      # JRE version: 6.0_16-b01
      # Java VM: Java HotSpot(TM) Client VM (14.2-b01 mixed mode linux-x86 )
      # Problematic frame:
      # C [libnio.so+0x47f0] Java_java_nio_MappedByteBuffer_load0+0x70
      #
      # An error report file with more information is saved as:
      # /home/xxxxxxxx/test/hs_err_pid13023.log
      #
      # If you would like to submit a bug report, please visit:
      # http://java.sun.com/webapps/bugreport/crash.jsp
      # The crash happened outside the Java Virtual Machine in native code.
      # See problematic frame for where to report the bug.
      #
      Aborted

      TESTCASE SOURCE
      ---------------
      import java.nio.*;
      import java.io.*;
      import java.nio.channels.*;

      public class TruncateTest {
          public static void main(String args[]) throws IOException {

              // Write a test file
              System.out.print("Creating test file...");
              BufferedWriter out = new BufferedWriter(new FileWriter("testfile"));
              for (int i=0; i<1000; i++) {
                 out.write("This is a test file. ");
              }
              System.out.println("done");

              // Map the file
              System.out.print("Creating mapped buffer from test file...");
              FileChannel fc = new java.io.RandomAccessFile("testfile", "rw").getChannel();
              MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_WRITE, 0L, fc.size());
              System.out.println("done");

              // Truncate the file
              System.out.print("Attempting to truncate the file...");
              fc.truncate(512);
              System.out.println("done");

              // Now try to load from the MappedByteBuffer
              System.out.println("Attempting to load mapped buffer...");
              buf.load();
              System.out.println("done");
          }
      }

            alanb Alan Bateman
            dkorbel David Korbel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: