From 29a81842d533739990e76a90f1e26b90ff263586 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Sat, 9 Jun 2018 22:37:09 +0200 Subject: [PATCH 1/1] Sysv contexts: add Asan instrumentation. --- CMakeLists.txt | 2 -- src/kernel/context/ContextUnix.cpp | 17 +++++++++++++++++ src/kernel/context/ContextUnix.hpp | 9 ++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80ff66e1ad..c7a9f3b95d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -507,8 +507,6 @@ if(NOT HAVE_UCONTEXT_H) elseif(APPLE) message(STATUS "No ucontext factory: Apple don't want us to use them.") set(HAVE_UCONTEXT_H 0) -elseif(enable_address_sanitizer) - message(STATUS "No ucontext factory: ASan needs us to write the wrappers as explained in https://github.com/google/sanitizers/issues/189") else() try_compile(compile_makecontext ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/tools/cmake/test_prog/prog_makecontext.c OUTPUT_VARIABLE compile_makecontext_output) diff --git a/src/kernel/context/ContextUnix.cpp b/src/kernel/context/ContextUnix.cpp index dcb9088013..4c509ba425 100644 --- a/src/kernel/context/ContextUnix.cpp +++ b/src/kernel/context/ContextUnix.cpp @@ -6,6 +6,7 @@ /* \file UContext.cpp Context switching with ucontexts from System V */ #include "ContextUnix.hpp" +#include "context_private.hpp" #include "mc/mc.h" #include "src/mc/mc_ignore.hpp" @@ -85,6 +86,11 @@ UContext::UContext(std::function code, void_pfn_smxprocess_t cleanup_fun this->uc_.uc_link = nullptr; this->uc_.uc_stack.ss_sp = sg_makecontext_stack_addr(this->stack_); this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(smx_context_usable_stack_size); +#if PTH_STACKGROWTH == -1 + ASAN_EVAL(this->asan_stack_ = static_cast(this->stack_) + smx_context_usable_stack_size); +#else + ASAN_EVAL(this->asan_stack_ = this->stack_); +#endif UContext::make_ctx(&this->uc_, UContext::smx_ctx_sysv_wrapper, this); } else { if (process != nullptr && maestro_context_ == nullptr) @@ -112,12 +118,14 @@ void UContext::smx_ctx_sysv_wrapper(int i1, int i2) simgrid::kernel::context::UContext* context; memcpy(&context, ctx_addr, sizeof context); + ASAN_FINISH_SWITCH(nullptr, &context->asan_ctx_->asan_stack_, &context->asan_ctx_->asan_stack_size_); try { (*context)(); context->Context::stop(); } catch (simgrid::kernel::context::Context::StopRequest const&) { XBT_DEBUG("Caught a StopRequest"); } + ASAN_EVAL(context->asan_stop_ = true); context->suspend(); } @@ -133,6 +141,15 @@ void UContext::make_ctx(ucontext_t* ucp, void (*func)(int, int), UContext* arg) makecontext(ucp, (void (*)())func, 2, ctx_addr[0], ctx_addr[1]); } +inline void UContext::swap(UContext* from, UContext* to) +{ + void* fake_stack = nullptr; + ASAN_EVAL(to->asan_ctx_ = from); + ASAN_START_SWITCH(from->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_); + swapcontext(&from->uc_, &to->uc_); + ASAN_FINISH_SWITCH(fake_stack, &from->asan_ctx_->asan_stack_, &from->asan_ctx_->asan_stack_size_); +} + void UContext::stop() { Context::stop(); diff --git a/src/kernel/context/ContextUnix.hpp b/src/kernel/context/ContextUnix.hpp index 8bc8ce6f41..2ee74ad427 100644 --- a/src/kernel/context/ContextUnix.hpp +++ b/src/kernel/context/ContextUnix.hpp @@ -32,7 +32,7 @@ public: void stop() override; virtual void resume() = 0; - static void swap(UContext* from, UContext* to) { swapcontext(&from->uc_, &to->uc_); } + static void swap(UContext* from, UContext* to); static UContext* getMaestro() { return maestro_context_; } static void setMaestro(UContext* maestro) { maestro_context_ = maestro; } @@ -41,6 +41,13 @@ private: void* stack_ = nullptr; /* the thread stack */ ucontext_t uc_; /* the ucontext that executes the code */ +#if HAVE_SANITIZE_ADDRESS_FIBER_SUPPORT + const void* asan_stack_ = nullptr; + size_t asan_stack_size_ = 0; + UContext* asan_ctx_ = nullptr; + bool asan_stop_ = false; +#endif + static void smx_ctx_sysv_wrapper(int, int); static void make_ctx(ucontext_t* ucp, void (*func)(int, int), UContext* arg); }; -- 2.20.1