From panama-dev:
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.
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));
}
}
This problem occurs for both memory segments AND byte buffers, since the issue is in common code used by both. Of course, since buffers can only range over int positions, you need a buffer between 2G and 4G to reproduce.
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.
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));
}
}
This problem occurs for both memory segments AND byte buffers, since the issue is in common code used by both. Of course, since buffers can only range over int positions, you need a buffer between 2G and 4G to reproduce.