Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
java-1_6_0-openjdk
openjdk-6-src-b17-stack-protector.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openjdk-6-src-b17-stack-protector.patch of Package java-1_6_0-openjdk
Index: icedtea6-1.7/openjdk/hotspot/src/os/linux/vm/os_linux.cpp =================================================================== --- icedtea6-1.7.orig/openjdk/hotspot/src/os/linux/vm/os_linux.cpp +++ icedtea6-1.7/openjdk/hotspot/src/os/linux/vm/os_linux.cpp @@ -22,6 +22,8 @@ * */ +# define __STDC_FORMAT_MACROS + // do not include precompiled header file # include "incls/_os_linux.cpp.incl" @@ -53,6 +55,8 @@ # include <sys/ipc.h> # include <sys/shm.h> # include <link.h> +# include <stdint.h> +# include <inttypes.h> #define MAX_PATH (2 * K) @@ -2519,6 +2523,91 @@ bool os::uncommit_memory(char* addr, siz != MAP_FAILED; } +// Linux uses a growable mapping for the stack, and if the mapping for +// the stack guard pages is not removed when we detach a thread the +// stack cannot grow beyond the pages where the stack guard was +// mapped. If at some point later in the process the stack expands to +// that point, the Linux kernel cannot expand the stack any further +// because the guard pages are in the way, and a segfault occurs. +// +// However, it's essential not to split the stack region by unmapping +// a region (leaving a hole) that's already part of the stack mapping, +// so if the stack mapping has already grown beyond the guard pages at +// the time we create them, we have to truncate the stack mapping. +// So, we need to know the extent of the stack mapping when +// create_stack_guard_pages() is called. + +// Find the bounds of the stack mapping. Return true for success. +// +// We only need this for stacks that are growable: at the time of +// writing thread stacks don't use growable mappings (i.e. those +// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this +// only applies to the main thread. +static bool +get_stack_bounds(uintptr_t *bottom, uintptr_t *top) +{ + FILE *f = fopen("/proc/self/maps", "r"); + if (f == NULL) + return false; + + while (!feof(f)) { + size_t dummy; + char *str = NULL; + ssize_t len = getline(&str, &dummy, f); + if (len == -1) { + return false; + } + + if (len > 0 && str[len-1] == '\n') { + str[len-1] = 0; + len--; + } + + static const char *stack_str = "[stack]"; + if (len > (ssize_t)strlen(stack_str) + && (strcmp(str + len - strlen(stack_str), stack_str) + == 0)) { + if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) { + uintptr_t sp = (uintptr_t)__builtin_frame_address(0); + if (sp >= *bottom && sp <= *top) { + free(str); + return true; + } + } + } + + free(str); + } + + return false; +} + +// If the (growable) stack mapping already extends beyond the point +// where we're going to put our guard pages, truncate the mapping at +// that point by munmap()ping it. This ensures that when we later +// munmap() the guard pages we don't leave a hole in the stack +// mapping. +bool os::create_stack_guard_pages(char* addr, size_t size) { + uintptr_t stack_extent, stack_base; + if (get_stack_bounds(&stack_extent, &stack_base)) { + if (stack_extent < (uintptr_t)addr) + ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); + } + + return os::commit_memory(addr, size); +} + +// If this is a growable mapping, remove the guard pages entirely by +// munmap()ping them. If not, just call uncommit_memory(). +bool os::remove_stack_guard_pages(char* addr, size_t size) { + uintptr_t stack_extent, stack_base; + if (get_stack_bounds(&stack_extent, &stack_base)) { + return ::munmap(addr, size) == 0; + } + + return os::uncommit_memory(addr, size); +} + static address _highest_vm_reserved_address = NULL; // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory Index: icedtea6-1.7/openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp =================================================================== --- icedtea6-1.7.orig/openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp +++ icedtea6-1.7/openjdk/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -2696,6 +2696,14 @@ void os::free_memory(char* addr, size_t } } +bool os::create_stack_guard_pages(char* addr, size_t size) { + return os::commit_memory(addr, size); +} + +bool os::remove_stack_guard_pages(char* addr, size_t size) { + return os::uncommit_memory(addr, size); +} + // Change the page size in a given range. void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); Index: icedtea6-1.7/openjdk/hotspot/src/os/windows/vm/os_windows.cpp =================================================================== --- icedtea6-1.7.orig/openjdk/hotspot/src/os/windows/vm/os_windows.cpp +++ icedtea6-1.7/openjdk/hotspot/src/os/windows/vm/os_windows.cpp @@ -2778,6 +2778,14 @@ bool os::release_memory(char* addr, size return VirtualFree(addr, 0, MEM_RELEASE) != 0; } +bool os::create_stack_guard_pages(char* addr, size_t size) { + return os::commit_memory(addr, size); +} + +bool os::remove_stack_guard_pages(char* addr, size_t size) { + return os::uncommit_memory(addr, size); +} + // Set protections specified bool os::protect_memory(char* addr, size_t bytes, ProtType prot, bool is_committed) { Index: icedtea6-1.7/openjdk/hotspot/src/share/vm/runtime/os.hpp =================================================================== --- icedtea6-1.7.orig/openjdk/hotspot/src/share/vm/runtime/os.hpp +++ icedtea6-1.7/openjdk/hotspot/src/share/vm/runtime/os.hpp @@ -213,6 +213,9 @@ class os: AllStatic { static bool guard_memory(char* addr, size_t bytes); static bool unguard_memory(char* addr, size_t bytes); + static bool create_stack_guard_pages(char* addr, size_t bytes); + static bool remove_stack_guard_pages(char* addr, size_t bytes); + static char* map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only = false, bool allow_exec = false); Index: icedtea6-1.7/openjdk/hotspot/src/share/vm/runtime/thread.cpp =================================================================== --- icedtea6-1.7.orig/openjdk/hotspot/src/share/vm/runtime/thread.cpp +++ icedtea6-1.7/openjdk/hotspot/src/share/vm/runtime/thread.cpp @@ -2114,7 +2114,7 @@ void JavaThread::create_stack_guard_page int allocate = os::allocate_stack_guard_pages(); // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len); - if (allocate && !os::commit_memory((char *) low_addr, len)) { + if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) { warning("Attempt to allocate stack guard pages failed."); return; } @@ -2135,7 +2135,7 @@ void JavaThread::remove_stack_guard_page size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size(); if (os::allocate_stack_guard_pages()) { - if (os::uncommit_memory((char *) low_addr, len)) { + if (os::remove_stack_guard_pages((char *) low_addr, len)) { _stack_guard_state = stack_guard_unused; } else { warning("Attempt to deallocate stack guard pages failed.");
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor