From 55478f7725bd999ecca6d094a203ba0e65e64fc2 Mon Sep 17 00:00:00 2001 From: yinchuang Date: Tue, 14 Nov 2023 19:01:04 +0800 Subject: [PATCH] [Gwp-Asan] Export c interface from gwp_asan Issue:I8GFJL Signed-off-by: yinchuang --- compiler-rt/cmake/config-ix.cmake | 4 +- compiler-rt/lib/gwp_asan/CMakeLists.txt | 23 ++++- .../lib/gwp_asan/guarded_pool_allocator.cpp | 15 +++ .../lib/gwp_asan/guarded_pool_allocator.h | 3 + .../lib/gwp_asan/gwp_asan_c_interface.cpp | 99 +++++++++++++++++++ .../lib/gwp_asan/optional/backtrace_ohos.cpp | 20 ++++ .../lib/gwp_asan/optional/segv_handler.h | 8 ++ .../gwp_asan/optional/segv_handler_posix.cpp | 48 +++++++++ .../guarded_pool_allocator_posix.cpp | 10 +- .../gwp_asan/platform_specific/mutex_posix.h | 6 ++ 10 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 compiler-rt/lib/gwp_asan/gwp_asan_c_interface.cpp create mode 100644 compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index a631ae4e86c3..a549732afea0 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -860,10 +860,12 @@ endif() # calling malloc on first use. # TODO(hctim): Enable this on Android again. Looks like it's causing a SIGSEGV # for Scudo and GWP-ASan, further testing needed. +# OHOS_LOCAL begin if (GWP_ASAN_SUPPORTED_ARCH AND COMPILER_RT_BUILD_GWP_ASAN AND - OS_NAME MATCHES "Linux") + OS_NAME MATCHES "Linux|OHOS") set(COMPILER_RT_HAS_GWP_ASAN TRUE) else() set(COMPILER_RT_HAS_GWP_ASAN FALSE) endif() +# OHOS_LOCAL end pythonize_bool(COMPILER_RT_HAS_GWP_ASAN) diff --git a/compiler-rt/lib/gwp_asan/CMakeLists.txt b/compiler-rt/lib/gwp_asan/CMakeLists.txt index bb5b2902f99d..27d67036ed56 100644 --- a/compiler-rt/lib/gwp_asan/CMakeLists.txt +++ b/compiler-rt/lib/gwp_asan/CMakeLists.txt @@ -12,6 +12,11 @@ set(GWP_ASAN_SOURCES guarded_pool_allocator.cpp stack_trace_compressor.cpp ) +# OHOS_LOCAL begin +if(OHOS) +list(APPEND GWP_ASAN_SOURCES gwp_asan_c_interface.cpp) +endif() +# OHOS_LOCAL end set(GWP_ASAN_HEADERS common.h @@ -58,6 +63,19 @@ set(GWP_ASAN_BACKTRACE_HEADERS options.h options.inc ) +# OHOS_LOCAL begin +if(OHOS) + set(GWP_ASAN_BACKTRACE_SOURCES + optional/backtrace_ohos.cpp) + set(GWP_ASAN_OBJECT_LIBS + RTGwpAsanSegvHandler) +else() + set(GWP_ASAN_BACKTRACE_SOURCES + optional/backtrace_linux_libc.cpp) + set(GWP_ASAN_OBJECT_LIBS) +endif() +# OHOS_LOCAL end + set(GWP_ASAN_SEGV_HANDLER_HEADERS optional/segv_handler.h options.h) @@ -74,6 +92,7 @@ if (COMPILER_RT_HAS_GWP_ASAN) SOURCES ${GWP_ASAN_SOURCES} ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS} CFLAGS ${GWP_ASAN_CFLAGS} + OBJECT_LIBS ${GWP_ASAN_OBJECT_LIBS} PARENT_TARGET gwp_asan ) endforeach() @@ -83,7 +102,6 @@ if (COMPILER_RT_HAS_GWP_ASAN) SOURCES ${GWP_ASAN_SOURCES} ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS} CFLAGS ${GWP_ASAN_CFLAGS}) - add_compiler_rt_object_libraries(RTGwpAsanOptionsParser ARCHS ${GWP_ASAN_SUPPORTED_ARCH} SOURCES ${GWP_ASAN_OPTIONS_PARSER_SOURCES} @@ -93,9 +111,10 @@ if (COMPILER_RT_HAS_GWP_ASAN) # As above, build the pre-implemented optional backtrace support libraries. add_compiler_rt_object_libraries(RTGwpAsanBacktraceLibc ARCHS ${GWP_ASAN_SUPPORTED_ARCH} - SOURCES optional/backtrace_linux_libc.cpp + SOURCES ${GWP_ASAN_BACKTRACE_SOURCES} ADDITIONAL_HEADERS ${GWP_ASAN_BACKTRACE_HEADERS} CFLAGS ${GWP_ASAN_CFLAGS}) + add_compiler_rt_object_libraries(RTGwpAsanSegvHandler ARCHS ${GWP_ASAN_SUPPORTED_ARCH} SOURCES optional/segv_handler_posix.cpp diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp index 7096b428764c..5bf1284e1f89 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp @@ -131,6 +131,21 @@ void GuardedPoolAllocator::iterate(void *Base, size_t Size, iterate_callback Cb, } } +// OHOS_LOCAL begin +bool GuardedPoolAllocator::hasFreeMem() +{ + if (NumSampledAllocations < State.MaxSimultaneousAllocations) { + return true; + } + + if (FreeSlotsLength > 0) { + return true; + } + + return false; +} +// OHOS_LOCAL end + void GuardedPoolAllocator::uninitTestOnly() { if (State.GuardedPagePool) { unreserveGuardedPool(); diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h index 6d2ce2576c13..152028acd822 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @@ -54,6 +54,9 @@ public: // options. void init(const options::Options &Opts); void uninitTestOnly(); + // OHOS_LOCAL begin + bool hasFreeMem(); + // OHOS_LOCAL end // Functions exported for libmemunreachable's use on Android. disable() // installs a lock in the allocator that prevents any thread from being able diff --git a/compiler-rt/lib/gwp_asan/gwp_asan_c_interface.cpp b/compiler-rt/lib/gwp_asan/gwp_asan_c_interface.cpp new file mode 100644 index 000000000000..e0bbfde90950 --- /dev/null +++ b/compiler-rt/lib/gwp_asan/gwp_asan_c_interface.cpp @@ -0,0 +1,99 @@ +//===-- gwp_asan_c_interface.cpp ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gwp_asan/guarded_pool_allocator.h" +#include "gwp_asan/optional/segv_handler.h" + +#include +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +static gwp_asan::GuardedPoolAllocator guarded_poll_alloctor; + +typedef struct gwp_asan_option { + bool help; + bool enable; + bool install_signal_handlers; + bool install_fork_handlers; + int sample_rate; + int max_simultaneous_allocations; + gwp_asan::options::Backtrace_t backtrace; + gwp_asan::Printf_t gwp_asan_printf; + gwp_asan::backtrace::PrintBacktrace_t printf_backtrace; + gwp_asan::backtrace::SegvBacktrace_t segv_backtrace; +} gwp_asan_option; + +void init_gwp_asan(void *init_options) +{ + gwp_asan::options::Options opts; + gwp_asan_option *input_opts = reinterpret_cast(init_options); + opts.help = input_opts->help; + opts.Enabled = input_opts->enable; + opts.MaxSimultaneousAllocations = input_opts->max_simultaneous_allocations; + opts.SampleRate = input_opts->sample_rate; + opts.InstallSignalHandlers = input_opts->install_signal_handlers; + opts.InstallForkHandlers = input_opts->install_fork_handlers; + opts.Backtrace = input_opts->backtrace; + guarded_poll_alloctor.init(opts); + if (input_opts->install_signal_handlers) { + gwp_asan::segv_handler::installSignalHandlersOhos(&guarded_poll_alloctor, input_opts->gwp_asan_printf, + input_opts->printf_backtrace, input_opts->segv_backtrace); + } +} + +void* gwp_asan_malloc(size_t bytes) +{ + return guarded_poll_alloctor.allocate(bytes); +} + +void gwp_asan_free(void *mem) +{ + return guarded_poll_alloctor.deallocate(mem); +} + +size_t gwp_asan_get_size(void *mem) +{ + return guarded_poll_alloctor.getSize(mem); +} + +bool gwp_asan_should_sample() +{ + return guarded_poll_alloctor.shouldSample(); +} + +bool gwp_asan_pointer_is_mine(void *mem) +{ + return guarded_poll_alloctor.pointerIsMine(mem); +} + +bool gwp_asan_has_free_mem() +{ + return guarded_poll_alloctor.hasFreeMem(); +} + +void gwp_asan_disable() +{ + return guarded_poll_alloctor.disable(); +} + +void gwp_asan_enable() +{ + return guarded_poll_alloctor.enable(); +} + +void gwp_asan_iterate(void *base, size_t size, gwp_asan::GuardedPoolAllocator::iterate_callback cb, void *arg) +{ + return guarded_poll_alloctor.iterate(base, size, cb, arg); +} + +#ifdef __cplusplus +} +#endif diff --git a/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp new file mode 100644 index 000000000000..442ba653303a --- /dev/null +++ b/compiler-rt/lib/gwp_asan/optional/backtrace_ohos.cpp @@ -0,0 +1,20 @@ +//===-- backtrace_ohos.cpp -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gwp_asan/optional/backtrace.h" + +namespace gwp_asan { +namespace backtrace { + +// These interfaces are implemented by OHOS musl which is registered with gwp_asan. +options::Backtrace_t getBacktraceFunction() { return nullptr; } +PrintBacktrace_t getPrintBacktraceFunction() { return nullptr; } +SegvBacktrace_t getSegvBacktraceFunction() { return nullptr; } + +} // namespace backtrace +} // namespace gwp_asan diff --git a/compiler-rt/lib/gwp_asan/optional/segv_handler.h b/compiler-rt/lib/gwp_asan/optional/segv_handler.h index 87d9fe1dff17..9173ca80e176 100644 --- a/compiler-rt/lib/gwp_asan/optional/segv_handler.h +++ b/compiler-rt/lib/gwp_asan/optional/segv_handler.h @@ -24,7 +24,15 @@ namespace segv_handler { void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf, gwp_asan::backtrace::PrintBacktrace_t PrintBacktrace, gwp_asan::backtrace::SegvBacktrace_t SegvBacktrace); +// OHOS_LOCAL begin +#if defined(__OHOS__) +void installSignalHandlersOhos(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf, + gwp_asan::backtrace::PrintBacktrace_t PrintBacktrace, + gwp_asan::backtrace::SegvBacktrace_t SegvBacktrace); +#endif + +// OHOS_LOCAL end // Uninistall the signal handlers, test-only. void uninstallSignalHandlers(); } // namespace segv_handler diff --git a/compiler-rt/lib/gwp_asan/optional/segv_handler_posix.cpp b/compiler-rt/lib/gwp_asan/optional/segv_handler_posix.cpp index 5c9bb9f3a2e7..c55175fca11f 100644 --- a/compiler-rt/lib/gwp_asan/optional/segv_handler_posix.cpp +++ b/compiler-rt/lib/gwp_asan/optional/segv_handler_posix.cpp @@ -22,6 +22,11 @@ #include #include #include +// OHOS_LOCAL begin +#if defined(__OHOS__) +#include +#endif +// OHOS_LOCAL end using gwp_asan::AllocationMetadata; using gwp_asan::Error; @@ -159,6 +164,22 @@ Printf_t PrintfForSignalHandler; PrintBacktrace_t PrintBacktraceForSignalHandler; SegvBacktrace_t BacktraceForSignalHandler; +// OHOS_LOCAL begin +#if defined(__OHOS__) +static bool sigSegvHandlerOhos(int sig, siginfo_t *info, void *ucontext) { + if (GPAForSignalHandler) { + GPAForSignalHandler->stop(); + dumpReport(reinterpret_cast(info->si_addr), + GPAForSignalHandler->getAllocatorState(), + GPAForSignalHandler->getMetadataRegion(), + BacktraceForSignalHandler, PrintfForSignalHandler, + PrintBacktraceForSignalHandler, ucontext); + } + return false; +} +#endif +// OHOS_LOCAL end + static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) { if (GPAForSignalHandler) { GPAForSignalHandler->stop(); @@ -194,6 +215,33 @@ static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) { namespace gwp_asan { namespace segv_handler { +// OHOS_LOCAL begin +#if defined(__OHOS__) +void installSignalHandlersOhos(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf, + PrintBacktrace_t PrintBacktrace, + SegvBacktrace_t SegvBacktrace) { + assert(GPA && "GPA wasn't provided to installSignalHandlers."); + assert(Printf && "Printf wasn't provided to installSignalHandlers."); + assert(PrintBacktrace && + "PrintBacktrace wasn't provided to installSignalHandlers."); + assert(SegvBacktrace && + "SegvBacktrace wasn't provided to installSignalHandlers."); + GPAForSignalHandler = GPA; + PrintfForSignalHandler = Printf; + PrintBacktraceForSignalHandler = PrintBacktrace; + BacktraceForSignalHandler = SegvBacktrace; + + struct signal_chain_action Action = { + .sca_sigaction = sigSegvHandlerOhos, + .sca_mask = {}, + .sca_flags = SA_SIGINFO | SA_RESTART, + }; + add_special_signal_handler(SIGSEGV, &Action); + SignalHandlerInstalled = true; +} +#endif +// OHOS_LOCAL end + void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf, PrintBacktrace_t PrintBacktrace, SegvBacktrace_t SegvBacktrace) { diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp index adb7330a431e..149b74238f0d 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp @@ -19,17 +19,19 @@ #include #include -#ifdef ANDROID +// OHOS_LOCAL begin +#if defined(ANDROID) || defined(__OHOS__) #include #define PR_SET_VMA 0x53564d41 #define PR_SET_VMA_ANON_NAME 0 -#endif // ANDROID +#endif // ANDROID || __OHOS__ +// OHOS_LOCAL end namespace { void MaybeSetMappingName(void *Mapping, size_t Size, const char *Name) { -#ifdef ANDROID +#if defined(ANDROID) || defined(__OHOS__) prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, Mapping, Size, Name); -#endif // ANDROID +#endif // ANDROID || __OHOS__ // Anonymous mapping names are only supported on Android. return; } diff --git a/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.h b/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.h index 7f0239198f56..57b981c6e1b0 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.h +++ b/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.h @@ -15,7 +15,13 @@ namespace gwp_asan { class PlatformMutex { protected: +// OHOS_LOCAL begin +#if defined(__OHOS__) + pthread_mutex_t Mu = {{{PTHREAD_MUTEX_RECURSIVE}}}; +#else pthread_mutex_t Mu = PTHREAD_MUTEX_INITIALIZER; +#endif +// OHOS_LOCAL end }; } // namespace gwp_asan -- Gitee