From c7c3973e0934ea08e7415aac08a5c06249a40fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Wed, 9 May 2018 22:45:38 +0200 Subject: [PATCH] kernel: generic user_memcpy now saves the old state. fixes #14135. --- .../private/kernel/arch/generic/user_memory.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/headers/private/kernel/arch/generic/user_memory.h b/headers/private/kernel/arch/generic/user_memory.h index e356408889..83caff4b95 100644 --- a/headers/private/kernel/arch/generic/user_memory.h +++ b/headers/private/kernel/arch/generic/user_memory.h @@ -21,7 +21,12 @@ namespace { struct FaultHandlerGuard { FaultHandlerGuard() { - ASSERT(thread_get_current_thread()->fault_handler == nullptr); + old_handler = thread_get_current_thread()->fault_handler; + if (old_handler != nullptr) { + memcpy(old_handler_state, + thread_get_current_thread()->fault_handler_state, + sizeof(jmp_buf)); + } thread_get_current_thread()->fault_handler = HandleFault; std::atomic_signal_fence(std::memory_order_acq_rel); } @@ -30,7 +35,13 @@ struct FaultHandlerGuard { ~FaultHandlerGuard() { std::atomic_signal_fence(std::memory_order_acq_rel); - thread_get_current_thread()->fault_handler = nullptr; + thread_get_current_thread()->fault_handler = old_handler; + if (old_handler != nullptr) { + memcpy(thread_get_current_thread()->fault_handler_state, + old_handler_state, + sizeof(jmp_buf)); + } + } @@ -38,6 +49,9 @@ struct FaultHandlerGuard { { longjmp(thread_get_current_thread()->fault_handler_state, 1); } + + void (*old_handler)(void); + jmp_buf old_handler_state; };