-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
P4
-
None
-
Affects Version/s: None
-
Component/s: hotspot
-
None
-
Environment:
OpenBSD 7.8/aarch64
-
aarch64
-
other
I believe there's a incorrect pointer deference in TemplateInterpreterGenerator::generate_native_entry() in this part of the code:
// get native function entry point in r10
{
Label L;
__ ldr(r10, Address(rmethod, Method::native_function_offset()));
ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
__ lea(rscratch2, unsatisfied);
__ ldr(rscratch2, rscratch2);
__ cmp(r10, rscratch2);
__ br(Assembler::NE, L);
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::prepare_native_call),
rmethod);
__ get_method(rmethod);
__ ldr(r10, Address(rmethod, Method::native_function_offset()));
__ bind(L);
}
If I understand this correctly, the entry point for unsatisfied link error is loaded into rscratch2. The next instruction, ldr(rscratch2, rscratch2), dereferences that pointer and reads from the text segment the initial instructions at the entry point into rscratch2. It then compares the native method entry point in r10 with the initial instructions loaded into rscratch2 which will never match. I believe the intent here was to compare the native method entry point with the unsatisfied link error entry point and the ldr(rscratch2, rscratch2) instruction should be removed.
This was found on OpenBSD/aarch64. OpenBSD has a security feature where the text segments are marked execute only and do not allow reads independent of execution. the ldr(rscratch2, rscratch2) instruction causes a segfault because it is reading the text segment. While this bug was found on OpenBSD I believe it applies to all OS on aaarch64.
// get native function entry point in r10
{
Label L;
__ ldr(r10, Address(rmethod, Method::native_function_offset()));
ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
__ lea(rscratch2, unsatisfied);
__ ldr(rscratch2, rscratch2);
__ cmp(r10, rscratch2);
__ br(Assembler::NE, L);
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::prepare_native_call),
rmethod);
__ get_method(rmethod);
__ ldr(r10, Address(rmethod, Method::native_function_offset()));
__ bind(L);
}
If I understand this correctly, the entry point for unsatisfied link error is loaded into rscratch2. The next instruction, ldr(rscratch2, rscratch2), dereferences that pointer and reads from the text segment the initial instructions at the entry point into rscratch2. It then compares the native method entry point in r10 with the initial instructions loaded into rscratch2 which will never match. I believe the intent here was to compare the native method entry point with the unsatisfied link error entry point and the ldr(rscratch2, rscratch2) instruction should be removed.
This was found on OpenBSD/aarch64. OpenBSD has a security feature where the text segments are marked execute only and do not allow reads independent of execution. the ldr(rscratch2, rscratch2) instruction causes a segfault because it is reading the text segment. While this bug was found on OpenBSD I believe it applies to all OS on aaarch64.
- links to
-
Review(master)
openjdk/jdk/28327