RFR (S) JDK-7107135 - Stack guard pages becomes writable
Ioi Lam
ioi.lam at oracle.com
Thu Feb 21 10:28:35 PST 2013
Hi Vokler & Goetz,
I have posted the review at:
http://cr.openjdk.java.net/~iklam/7107135/stack_guard_001/
The bug should be
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7107135
However, for some reason it's not visible to outside. Could someone at
Oracle tell me how to fix this?
Also, as in the webview, I have removed the SAP copyright notice
(sorry!) as somewhere in the Oracle header it says "DO NOT ALTER ....
THIS FILE HEADER". What should we do with code contributed from outside
of Oracle.
Thanks
- Ioi
On 02/21/2013 01:03 AM, Volker Simonis wrote:
> Hi Ioi,
>
> could you please always post webrev and bug URLs which are visible
> from non-Oracle employees as well.
>
> I think the original bug together with a fix was submitted by a
> colleague, but with the information you give it is hard to verify
> this.
>
> Regards,
> Volker
>
> On Wed, Feb 20, 2013 at 7:40 PM, Ioi Lam <ioi.lam at oracle.com> wrote:
>> [Moving the discussion to hotspot-runtime-dev at openjdk.java.net]
>>
>> The original request for review is cut-and-pasted atthe end of this message.
>>
>> Thanks
>> - Ioi
>>
>>
>> On 02/20/2013 08:25 AM, Dean Long wrote:
>>> On 2/20/2013 3:01 AM, David Holmes wrote:
>>>> On 20/02/2013 6:32 PM, Dean Long wrote:
>>>>> On 2/20/2013 12:12 AM, David Holmes wrote:
>>>>>> On 20/02/2013 3:29 PM, Dean Long wrote:
>>>>>>> On 2/19/2013 6:48 PM, David Holmes wrote:
>>>>>>>> On 20/02/2013 11:39 AM, Dean Long wrote:
>>>>>>>>> On 2/19/2013 5:35 PM, David Holmes wrote:
>>>>>>>>>> On 20/02/2013 11:24 AM, Dean Long wrote:
>>>>>>>>>>>>
>>>>>>>>>>> If os::Linux::default_guard_size() returns non-zero, we set an
>>>>>>>>>>> attribute
>>>>>>>>>>> for pthread_create telling it to create guard pages for us.
>>>>>>>>>>> These guard pages aren't set to rwx by the dynamic linker because
>>>>>>>>>>> pthreads knows about them.
>>>>>>>>>>
>>>>>>>>>> Are you saying that these guard pages don't get reset when the
>>>>>>>>>> library
>>>>>>>>>> is loaded (or that they will at least get repaired afterwards) ?
>>>>>>>>>
>>>>>>>>> They will not be reset.
>>>>>>>>
>>>>>>>> Can you point me to any docs or the source code that demonstrates
>>>>>>>> this? From previous discussions the OS only allowed you to set page
>>>>>>>> bits not read them, and hence not add them. So I'd like to see how
>>>>>>>> they are achieving this.
>>>>>>>>
>>>>>>> The magic happens here in change_stack_perm():
>>>>>>>
>>>>>>>
>>>>>>> http://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/allocatestack.c#l314
>>>>>>>
>>>>>> But that simply makes the stack readable, writable and executable but
>>>>>> skipping over the guard pages. The initial protection of the guard
>>>>>> pages happens here:
>>>>>>
>>>>>> 634 if (mprotect (guard, guardsize, PROT_NONE) != 0)
>>>>>>
>>>>>> but I don't see anything in this code that prevents the guard pages
>>>>>> from being modified when a library with executable stack is loaded?
>>>>>>
>>>>> The code path that does the modifying looks like: dlopen --> ... -->
>>>>> __make_stacks_executable --> change_stack_perm.
>>>>
>>>> Ah I see. The above is what causes the problem, but it skips the built-in
>>>> guard pages.
>>>>
>>>> I'm sure someone thought this made sense at some point. :( But it sure
>>>> seems like a bug to me.
>>>>
>>> Which part seems buggy, changing the permissions? It seems necessary as
>>> long as executable stacks is
>>> a supported feature. It would be nice if dlopen() would just fail to load
>>> these libraries based on some flag
>>> in the executable's ELF file. I think the existing flag means "no
>>> executable stacks used by this module",
>>> but "no executable stacks used by this process" would make more sense for
>>> Java.
>>>
>>> dl
>>>
>>>> Thanks,
>>>> David
>>>>
>>>>>> Also note that for user supplied stack memory there are no guard pages
>>>>>> added.
>>>>>>
>>>>> OK.
>>>>>
>>>>> dl
>>>>>
>>>>>> David
>>>>>> -----
>>>>>>
>>>>>>> I wish there was a way to change the guardsize after the thread is
>>>>>>> created.
>>>>>>>
>>>>>>> dl
>>>>>>>
>> 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
>>
>> 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