RFR (S) JDK-7107135 - Stack guard pages becomes writable
Ioi Lam
ioi.lam at oracle.com
Wed Feb 27 13:41:45 PST 2013
Thanks to everyone for the reviews. I just came back from two days of
vacation and two days of flu ....
Please see my comments in-line:
On 02/20/2013 10:07 PM, David Holmes wrote:
> On 21/02/2013 4:40 AM, Ioi Lam wrote:
>> [Moving the discussion to hotspot-runtime-dev at openjdk.java.net]
>> Please review:
>> http://javaweb.us.oracle.com/~iklam/webrev/7107135/stack_guard_001/
>>
>> Bug: Stack guard pages are no more protected after loading a shared
>> library with executable stack
>> https://jbs.oracle.com/bugs/browse/JDK-7107135
>
> This seems somewhat more complex than necessary.
>
> First dll_open_inner should only ever be called via the VMOperation
> and that will only happen if:
> - LoadExecStackDllInVMThread == true
> - os::uses_stack_guard_pages() == true
> - is_init_completed() == true
>
> so there is no need to check any of these inside dll_open_inner.
>
That's right. I will fix it.
> Related to that back in dll_load I don't understand why we don't
> simply have:
>
> if (!LoadExecStackDllInVMThread) {
> result = ::dl_open(..)
> else {
> // use Vm op
> }
>
The VM op is used for both loading the DLL (in case of
LoadExecStackDllInVMThread==true) and for fixing the stack after loading
a "bad" DLL.
> Also I think you will find that Java threads (reference-processor and
> finalizer threads) have been created before init_completed is set.
>
I found that when (is_init_completed() == false), all the DLLs are
loaded before any Java threads are created. I will try to fix the
comments and put an assert() to that effect.
- Ioi
> David
> -----
>
>
>> Background:
>>
>> Recent versions of Linux support Non-Executable Stack
>> protection -- by default, the stack is made non-executable to
>> prevent code injection via overflowing on-stack buffers.
>>
>> However, some old Linux DLLs require the stack to be
>> executable. For backwards compatibility, after loading such
>> DLLs, the Linux dynamic loader makes the stack executable.
>>
>> Due to a limitation of the Linux system call API, the Linux
>> dynamic loader makes the stack readable/writable as well. This
>> disables Java's stack guard.
>>
>> Summary of fix:
>>
>> 1. Check if DLL requires executable stack by inspecting ELF header.
>> 2. Enter a Safepoint and load such DLLs in the VM thread.
>> - immediately after loading, change all Java stack guards
>> back to PROT_NONE.
>> 3. Leave Safepoint to resume Java execution.
>>
>> I also added a global flag LoadExecStackDllInVMThread to load
>> such "bad" DLLs outside of the safepoint (in case the DLL
>> invokes JNI functions inside static constructors, which are
>> executed before dlopen() returns).
>>
>> Note:
>>
>> I got this code from an outside contributor and I don't really
>> understand what this block does. Please comment if it's
>> correct:
>>
>> 1877: ThreadInVMfromNative tiv(JavaThread::current());
>> 1878: debug_only(VMNativeEntryWrapper vew;)
>>
>> Tests executed:
>>
>> * JPRT
>> * UTE (vm.quick.testlist)
>> * JTREG (hotspot/tests/runtime, hotspot/tests/closed/runtime)
>>
>> Thanks,
>> Ioi
>>
More information about the hotspot-runtime-dev
mailing list