RFR: 8371918: aarch64: Incorrect pointer dereference in TemplateInterpreterGenerator::generate_native_entry

Aleksey Shipilev shade at openjdk.org
Wed Nov 19 12:14:48 UTC 2025


On Sat, 15 Nov 2025 02:33:46 GMT, Dean Long <dlong at openjdk.org> wrote:

>> …rGenerator::generate_native_entry
>> 
>> 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.
>> 
>> This change removes the errant aarch64 hotspot assembly instruction that was reading from libjvm.so .text segment.
>> 
>> Updated comment with markdown for code.
>
> According to InterpreterRuntime::prepare_native_call(), if there is a signal handler, which is checked first, then there should be a native function.  So I wonder if we can remove the check for the native function from all CPU ports.

I did also wonder how it is not breaking now with uninitialized native entries. But I see we are doing this init as part of signature handler resolution: https://github.com/openjdk/jdk/blob/54893dc5c2a4702896029b1844bc9496325c8f26/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp#L1323-L1334 -- before we hit this block. So, as @dean-long says, maybe we do not need this native method entry check at all. But this fix is fine to unbreak BSD/AArch64 alone.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/28327#issuecomment-3552366023


More information about the hotspot-dev mailing list