-
Bug
-
Resolution: Fixed
-
P3
-
21
-
b26
-
Verified
It seems that the linker does not verify the size of the provided captured call segment:
jshell> MethodHandle strlen = linker.downcallHandle(linker.defaultLookup().find("strlen").get(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS), Linker.Option.captureCallState("errno"));
jshell> var segment = arena.allocateUtf8String("Hello!");
segment ==> MemorySegment{ heapBase: Optional.empty address:139746963920864 limit: 7 }
strlen ==> MethodHandle(MemorySegment,MemorySegment)long
jshell> var cap = arena.allocate(1);
cap ==> MemorySegment{ heapBase: Optional.empty address:139746963913392 limit: 1 }
jshell> strlen.invoke(cap, segment);
$19 ==> 6
I believe this works because the state is saved in the assembly stub, which ignores any limits of the provided memory segment. As such, we should verify compatibility of these limits before going in native code. More specifically, we should check that the provided segment is compatible with the capture state layout size and alignment.
jshell> MethodHandle strlen = linker.downcallHandle(linker.defaultLookup().find("strlen").get(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS), Linker.Option.captureCallState("errno"));
jshell> var segment = arena.allocateUtf8String("Hello!");
segment ==> MemorySegment{ heapBase: Optional.empty address:139746963920864 limit: 7 }
strlen ==> MethodHandle(MemorySegment,MemorySegment)long
jshell> var cap = arena.allocate(1);
cap ==> MemorySegment{ heapBase: Optional.empty address:139746963913392 limit: 1 }
jshell> strlen.invoke(cap, segment);
$19 ==> 6
I believe this works because the state is saved in the assembly stub, which ignores any limits of the provided memory segment. As such, we should verify compatibility of these limits before going in native code. More specifically, we should check that the provided segment is compatible with the capture state layout size and alignment.