[GWP-ASan] Integrate GWP-ASan into bionc's malloc() (using hooks).
This patch introduces GWP-ASan - a sampled allocator framework that
finds use-after-free and heap-buffer-overflow bugs in production
environments.
GWP-ASan is being introduced in an always-disabled mode. This means that
GWP-ASan will be permanently disabled until a further patch turns on
support. As such, there should be no visible functional change for the
time being.
GWP-ASan requires -fno-emulated-tls wherever it's linked from. We
intentionally link GWP-ASan into libc so that it's part of the initial
set of libraries, and thus has static TLS storage (so we can use
Initial-Exec TLS instead of Global-Dynamic). As a benefit, this reduces
overhead for a sampled process.
GWP-ASan is always initialised via. a call to
mallopt(M_INITIALIZE_GWP_ASAN, which must be done before a process is
multithreaded).
More information about GWP-ASan can be found in the upstream
documentation: http://llvm.org/docs/GwpAsan.html
Bug: 135634846
Test: atest bionic
Change-Id: Ib9bd33337d17dab39ac32f4536bff71bd23498b0
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index e08083f..da68c80 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -41,6 +41,7 @@
#include <private/bionic_config.h>
#include <platform/bionic/malloc.h>
+#include "gwp_asan_wrappers.h"
#include "heap_tagging.h"
#include "malloc_common.h"
#include "malloc_limit.h"
@@ -316,8 +317,42 @@
if (opcode == M_SET_HEAP_TAGGING_LEVEL) {
return SetHeapTaggingLevel(arg, arg_size);
}
+ if (opcode == M_INITIALIZE_GWP_ASAN) {
+ if (arg == nullptr || arg_size != sizeof(bool)) {
+ errno = EINVAL;
+ return false;
+ }
+ return MaybeInitGwpAsan(*reinterpret_cast<bool*>(arg));
+ }
errno = ENOTSUP;
return false;
}
#endif
// =============================================================================
+
+static constexpr MallocDispatch __libc_malloc_default_dispatch __attribute__((unused)) = {
+ Malloc(calloc),
+ Malloc(free),
+ Malloc(mallinfo),
+ Malloc(malloc),
+ Malloc(malloc_usable_size),
+ Malloc(memalign),
+ Malloc(posix_memalign),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ Malloc(pvalloc),
+#endif
+ Malloc(realloc),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+ Malloc(valloc),
+#endif
+ Malloc(malloc_iterate),
+ Malloc(malloc_disable),
+ Malloc(malloc_enable),
+ Malloc(mallopt),
+ Malloc(aligned_alloc),
+ Malloc(malloc_info),
+};
+
+const MallocDispatch* NativeAllocatorDispatch() {
+ return &__libc_malloc_default_dispatch;
+}