MappedMemorySegments.isLoaded() can crash the JVM with large mapped files on Linux

Marcel Käufler marcel.kaeufler at hhu.de
Tue Apr 6 21:25:53 UTC 2021


Hi,

I've found a bug when calling `MappedMemorySegments::isLoaded`. With a 
large segment size this causes malloc in the native isLoaded0 method 
being called with an invalid size, crashing the JVM.

Any size below 2GB - 4KB works fine. Above that it first gives an 
OutOfMemoryError. Even larger sizes (e.g. 4GB) then crash the JVM.
It's actually not only related to the foreign memory access api but also 
applies to MappedByteBuffers in existing release builds. As the 
ByteBuffers max. size is limited to Integer.MAX_VALUE it won't crash the 
JVM and "only" give an OOM between 2G - 4K and 2G.

It's caused by a miss-scoped cast in java.nio.Bits::pageCount:

     static int pageCount(long size) {
         return (int)(size + (long)pageSize() - 1L) / pageSize();
     }

There should be parentheses around the whole statement before the (int) 
cast.


To reproduce:

     import jdk.incubator.foreign.MappedMemorySegments;
     import jdk.incubator.foreign.MemorySegment;

     import java.io.File;
     import java.io.IOException;
     import java.nio.channels.FileChannel;

     public class Main {

         public static final long SIZE_OK = 1024L * 1024 * 1024 * 2 - 4096;
         public static final long SIZE_OOM = SIZE_OK + 1;
         public static final long SIZE_CRASH = SIZE_OK * 2;

         public static void main(String[] args) throws IOException {
             File f = new File("/tmp/is_loaded_test_file");
             f.createNewFile();
             MemorySegment memorySegment = 
MemorySegment.mapFile(f.toPath(), 0,
                     SIZE_CRASH, FileChannel.MapMode.READ_WRITE);
System.out.println(MappedMemorySegments.isLoaded(memorySegment));
         }
     }


Best Regards
Marcel


More information about the panama-dev mailing list