From 389f08367f819a9c28c87c4736acd4245e0f2c65 Mon Sep 17 00:00:00 2001 From: Pavel Afremov Date: Thu, 27 Sep 2007 20:06:37 +0400 Subject: [PATCH] Fix bug in stack check function. Function check_stack_size_enough_for_exception_catch(void * sp) returns true instead false in the case when sp is smaller guard page address. Source of the bug was in incorrect signed / usigned transforms. This patch fixes it. --- vm/vmcore/src/exception/exceptions_jit.cpp | 9 +++++++++ vm/vmcore/src/util/linux/signals_em64t.cpp | 11 ++++------- vm/vmcore/src/util/linux/signals_ia32.cpp | 9 +++------ vm/vmcore/src/util/linux/signals_ipf.cpp | 9 +++------ .../win/ia32_em64t/nt_exception_filter_common.cpp | 9 +++------ 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/vm/vmcore/src/exception/exceptions_jit.cpp b/vm/vmcore/src/exception/exceptions_jit.cpp index 8d74899..f705528 100644 --- a/vm/vmcore/src/exception/exceptions_jit.cpp +++ b/vm/vmcore/src/exception/exceptions_jit.cpp @@ -394,6 +394,15 @@ #endif // VM_STATS // Exception propagates to the native code assert(si_is_native(si)); + if (restore_guard_page) { + bool res = check_stack_size_enough_for_exception_catch(((char*)si_get_sp(si))); + //must always be enough. otherwise program behavior is unspecified: finally blocks, monitor exits are not executed + assert(res); + if (!res) { + p_TLS_vmthread->restore_guard_page = false; + } + } + // The current thread exception is set to the exception and we return 0/NULL to the native code if (*exn_obj == NULL) { *exn_obj = create_lazy_exception(exn_class, exn_constr, diff --git a/vm/vmcore/src/util/linux/signals_em64t.cpp b/vm/vmcore/src/util/linux/signals_em64t.cpp index e8144d2..82c8d59 100644 --- a/vm/vmcore/src/util/linux/signals_em64t.cpp +++ b/vm/vmcore/src/util/linux/signals_em64t.cpp @@ -404,16 +404,13 @@ bool check_available_stack_size(size_t r } size_t get_restore_stack_size() { - return 0x0800; + return 0x1000; } bool check_stack_size_enough_for_exception_catch(void* sp) { - char* stack_adrr = (char*) get_stack_addr(); - size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); - size_t available_stack_size = - get_stack_size() - used_stack_size - - 2 * get_guard_page_size() - get_guard_stack_size(); - return get_restore_stack_size() < available_stack_size; + char* stack_addr = (char*) get_stack_addr(); + return ((size_t)sp) > ((size_t)((char*)stack_addr - get_stack_size() + + get_guard_stack_size() + 2 * get_guard_page_size())); } void remove_guard_stack() { diff --git a/vm/vmcore/src/util/linux/signals_ia32.cpp b/vm/vmcore/src/util/linux/signals_ia32.cpp index e09f406..554f753 100644 --- a/vm/vmcore/src/util/linux/signals_ia32.cpp +++ b/vm/vmcore/src/util/linux/signals_ia32.cpp @@ -455,12 +455,9 @@ size_t get_restore_stack_size() { } bool check_stack_size_enough_for_exception_catch(void* sp) { - char* stack_adrr = (char*) get_stack_addr(); - size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); - size_t available_stack_size = - get_stack_size() - used_stack_size - - 2 * get_guard_page_size() - get_guard_stack_size(); - return get_restore_stack_size() < available_stack_size; + char* stack_addr = (char*) get_stack_addr(); + return ((size_t)sp) > ((size_t)((char*)stack_addr - get_stack_size() + + get_guard_stack_size() + 2 * get_guard_page_size())); } void remove_guard_stack() { diff --git a/vm/vmcore/src/util/linux/signals_ipf.cpp b/vm/vmcore/src/util/linux/signals_ipf.cpp index b2eb8a3..0841083 100644 --- a/vm/vmcore/src/util/linux/signals_ipf.cpp +++ b/vm/vmcore/src/util/linux/signals_ipf.cpp @@ -350,12 +350,9 @@ size_t get_restore_stack_size() { } bool check_stack_size_enough_for_exception_catch(void* sp) { - char* stack_adrr = (char*) get_stack_addr(); - size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); - size_t available_stack_size = - get_stack_size() - used_stack_size - - 2 * get_guard_page_size() - get_guard_stack_size(); - return get_restore_stack_size() < available_stack_size; + char* stack_addr = (char*) get_stack_addr(); + return ((size_t)sp) > ((size_t)((char*)stack_addr - get_stack_size() + + get_guard_stack_size() + 2 * get_guard_page_size())); } diff --git a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp index df3e8f0..7be9089 100644 --- a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp +++ b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp @@ -256,12 +256,9 @@ size_t get_restore_stack_size() { } bool check_stack_size_enough_for_exception_catch(void* sp) { - char* stack_adrr = (char*) get_stack_addr(); - size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); - size_t available_stack_size = - get_stack_size() - used_stack_size - - 2 * get_guard_page_size() - get_guard_stack_size(); - return get_restore_stack_size() < available_stack_size; + char* stack_addr = (char*) get_stack_addr(); + return ((size_t)sp) > ((size_t)((char*)stack_addr - get_stack_size() + + get_guard_stack_size() + 2 * get_guard_page_size())); } -- 1.4.1