Merge "benchmarks: add 16 and 32 bytes to common sizes"
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 1feb871..d3e6a14 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -26,7 +26,10 @@
* SUCH DAMAGE.
*/
+#include <platform/bionic/android_unsafe_frame_pointer_chase.h>
#include <platform/bionic/malloc.h>
+#include <private/bionic_arc4random.h>
+#include <private/bionic_globals.h>
#include <private/bionic_malloc_dispatch.h>
#include <stddef.h>
#include <stdint.h>
@@ -64,9 +67,15 @@
Opts.SampleRate = 2500;
Opts.InstallSignalHandlers = false;
Opts.InstallForkHandlers = true;
+ Opts.Backtrace = android_unsafe_frame_pointer_chase;
GuardedAlloc.init(Opts);
- info_log("GWP-ASan has been enabled.");
+ // TODO(b/149790891): The log line below causes ART tests to fail as they're
+ // not expecting any output. Disable the output for now.
+ // info_log("GWP-ASan has been enabled.");
+
+ __libc_shared_globals()->gwp_asan_state = GuardedAlloc.getAllocatorState();
+ __libc_shared_globals()->gwp_asan_metadata = GuardedAlloc.getMetadataRegion();
return true;
}
@@ -190,9 +199,15 @@
Malloc(malloc_info),
};
-// TODO(mitchp): Turn on GWP-ASan here probabilistically.
+// The probability (1 / kProcessSampleRate) that a process will be ranodmly
+// selected for sampling. kProcessSampleRate should always be a power of two to
+// avoid modulo bias.
+static constexpr uint8_t kProcessSampleRate = 128;
+
bool ShouldGwpAsanSampleProcess() {
- return false;
+ uint8_t random_number;
+ __libc_safe_arc4random_buf(&random_number, sizeof(random_number));
+ return random_number % kProcessSampleRate == 0;
}
bool MaybeInitGwpAsanFromLibc(libc_globals* globals) {
@@ -259,3 +274,7 @@
return true;
}
+
+bool DispatchIsGwpAsan(const MallocDispatch* dispatch) {
+ return dispatch == &gwp_asan_dispatch;
+}
diff --git a/libc/bionic/gwp_asan_wrappers.h b/libc/bionic/gwp_asan_wrappers.h
index fd9c547..a39d50b 100644
--- a/libc/bionic/gwp_asan_wrappers.h
+++ b/libc/bionic/gwp_asan_wrappers.h
@@ -37,3 +37,8 @@
// Maybe initialize GWP-ASan. Set force_init to true to bypass process sampling.
bool MaybeInitGwpAsan(libc_globals* globals, bool force_init = false);
+
+// Returns whether GWP-ASan is the provided dispatch table pointer. Used in
+// heapprofd's signal-initialization sequence to determine the intermediate
+// dispatch pointer to use when initing.
+bool DispatchIsGwpAsan(const MallocDispatch* dispatch);
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index bf4c63a..198d2f0 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -42,6 +42,7 @@
#include <private/bionic_malloc_dispatch.h>
#include <sys/system_properties.h>
+#include "gwp_asan_wrappers.h"
#include "malloc_common.h"
#include "malloc_common_dynamic.h"
#include "malloc_heapprofd.h"
@@ -86,30 +87,6 @@
extern "C" void* MallocInitHeapprofdHook(size_t);
-static constexpr MallocDispatch __heapprofd_init_dispatch
- __attribute__((unused)) = {
- Malloc(calloc),
- Malloc(free),
- Malloc(mallinfo),
- MallocInitHeapprofdHook, // malloc replacement
- 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),
- };
-
constexpr char kHeapprofdProgramPropertyPrefix[] = "heapprofd.enable.";
constexpr size_t kHeapprofdProgramPropertyPrefixSize = sizeof(kHeapprofdProgramPropertyPrefix) - 1;
constexpr size_t kMaxCmdlineSize = 512;
@@ -176,6 +153,15 @@
// is loaded synchronously).
// In both cases, the caller is responsible for verifying that the process is
// considered profileable.
+
+// Previously installed default dispatch table, if it exists. This is used to
+// load heapprofd properly when GWP-ASan was already installed. If GWP-ASan was
+// already installed, heapprofd will take over the dispatch table, but will use
+// GWP-ASan as the backing dispatch. This variable is atomically protected by
+// gHeapprofdInitInProgress.
+static const MallocDispatch* gPreviousDefaultDispatchTable = nullptr;
+static MallocDispatch gEphemeralDispatch;
+
void HandleHeapprofdSignal() {
if (atomic_load_explicit(&gHeapprofdIncompatibleHooks, memory_order_acquire)) {
error_log("%s: not enabling heapprofd, malloc_debug/malloc_hooks are enabled.", getprogname());
@@ -187,11 +173,29 @@
// not ever have a conflict modifying the globals.
if (!atomic_exchange(&gGlobalsMutating, true)) {
if (!atomic_exchange(&gHeapprofdInitInProgress, true)) {
+ // If the backing dispatch is GWP-ASan, we should use GWP-ASan as the
+ // intermediate dispatch table during initialisation. It may be possible
+ // at this point in time that heapprofd is *already* the default dispatch,
+ // and as such we don't want to use heapprofd as the backing store
+ // (otherwise infinite recursion occurs).
+ gPreviousDefaultDispatchTable = nullptr;
+ const MallocDispatch* default_dispatch = GetDefaultDispatchTable();
+ if (DispatchIsGwpAsan(default_dispatch)) {
+ gPreviousDefaultDispatchTable = default_dispatch;
+ }
+
__libc_globals.mutate([](libc_globals* globals) {
- atomic_store(&globals->default_dispatch_table, &__heapprofd_init_dispatch);
- auto dispatch_table = GetDispatchTable();
- if (!MallocLimitInstalled() || dispatch_table == &globals->malloc_dispatch_table) {
- atomic_store(&globals->current_dispatch_table, &__heapprofd_init_dispatch);
+ // Wholesale copy the malloc dispatch table here. If the current/default
+ // dispatch table is pointing to the malloc_dispatch_table, we can't
+ // modify it as it may be racy. This dispatch table copy is ephemeral,
+ // and the dispatch tables will be resolved back to the global
+ // malloc_dispatch_table after initialization finishes.
+ gEphemeralDispatch = globals->malloc_dispatch_table;
+ gEphemeralDispatch.malloc = MallocInitHeapprofdHook;
+
+ atomic_store(&globals->default_dispatch_table, &gEphemeralDispatch);
+ if (!MallocLimitInstalled()) {
+ atomic_store(&globals->current_dispatch_table, &gEphemeralDispatch);
}
});
}
@@ -241,6 +245,12 @@
return;
}
+ // Before we set the new default_dispatch_table in FinishInstallHooks, save
+ // the previous dispatch table. If DispatchReset() gets called later, we want
+ // to be able to restore the dispatch. We're still under
+ // gHeapprofdInitInProgress locks at this point.
+ gPreviousDefaultDispatchTable = GetDefaultDispatchTable();
+
if (FinishInstallHooks(globals, nullptr, kHeapprofdPrefix)) {
atomic_store(&gHeapprofdHandle, impl_handle);
} else if (!reusing_handle) {
@@ -274,10 +284,9 @@
if (!atomic_exchange(&gHeapprofdInitHookInstalled, true)) {
pthread_mutex_lock(&gGlobalsMutateLock);
__libc_globals.mutate([](libc_globals* globals) {
- auto old_dispatch = GetDefaultDispatchTable();
- atomic_store(&globals->default_dispatch_table, nullptr);
- if (GetDispatchTable() == old_dispatch) {
- atomic_store(&globals->current_dispatch_table, nullptr);
+ atomic_store(&globals->default_dispatch_table, gPreviousDefaultDispatchTable);
+ if (!MallocLimitInstalled()) {
+ atomic_store(&globals->current_dispatch_table, gPreviousDefaultDispatchTable);
}
});
pthread_mutex_unlock(&gGlobalsMutateLock);
@@ -292,7 +301,10 @@
error_log("%s: heapprod: failed to pthread_setname_np", getprogname());
}
}
- return Malloc(malloc)(bytes);
+ // Get an allocation from libc malloc. If we had a previous dispatch table,
+ // this will come from it - otherwise, we'll get it from the system
+ // allocator.
+ return malloc(bytes);
}
bool HeapprofdInitZygoteChildProfiling() {
@@ -309,10 +321,9 @@
if (!atomic_exchange(&gHeapprofdInitInProgress, true)) {
pthread_mutex_lock(&gGlobalsMutateLock);
__libc_globals.mutate([](libc_globals* globals) {
- auto old_dispatch = GetDefaultDispatchTable();
- atomic_store(&globals->default_dispatch_table, nullptr);
- if (GetDispatchTable() == old_dispatch) {
- atomic_store(&globals->current_dispatch_table, nullptr);
+ atomic_store(&globals->default_dispatch_table, gPreviousDefaultDispatchTable);
+ if (!MallocLimitInstalled()) {
+ atomic_store(&globals->current_dispatch_table, gPreviousDefaultDispatchTable);
}
});
pthread_mutex_unlock(&gGlobalsMutateLock);
diff --git a/libc/include/bits/elf_mips.h b/libc/include/bits/elf_mips.h
deleted file mode 100644
index e29c481..0000000
--- a/libc/include/bits/elf_mips.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $NetBSD: elf_machdep.h,v 1.15 2011/03/15 07:39:22 matt Exp $ */
-
-#ifndef _MIPS_ELF_MACHDEP_H_
-#define _MIPS_ELF_MACHDEP_H_
-
-/* mips relocs. */
-
-#define R_MIPS_NONE 0
-#define R_MIPS_16 1
-#define R_MIPS_32 2
-#define R_MIPS_REL32 3
-#define R_MIPS_REL R_MIPS_REL32
-#define R_MIPS_26 4
-#define R_MIPS_HI16 5 /* high 16 bits of symbol value */
-#define R_MIPS_LO16 6 /* low 16 bits of symbol value */
-#define R_MIPS_GPREL16 7 /* GP-relative reference */
-#define R_MIPS_LITERAL 8 /* Reference to literal section */
-#define R_MIPS_GOT16 9 /* Reference to global offset table */
-#define R_MIPS_GOT R_MIPS_GOT16
-#define R_MIPS_PC16 10 /* 16 bit PC relative reference */
-#define R_MIPS_CALL16 11 /* 16 bit call thru glbl offset tbl */
-#define R_MIPS_CALL R_MIPS_CALL16
-#define R_MIPS_GPREL32 12
-
-/* 13, 14, 15 are not defined at this point. */
-#define R_MIPS_UNUSED1 13
-#define R_MIPS_UNUSED2 14
-#define R_MIPS_UNUSED3 15
-
-/*
- * The remaining relocs are apparently part of the 64-bit Irix ELF ABI.
- */
-#define R_MIPS_SHIFT5 16
-#define R_MIPS_SHIFT6 17
-
-#define R_MIPS_64 18
-#define R_MIPS_GOT_DISP 19
-#define R_MIPS_GOT_PAGE 20
-#define R_MIPS_GOT_OFST 21
-#define R_MIPS_GOT_HI16 22
-#define R_MIPS_GOT_LO16 23
-#define R_MIPS_SUB 24
-#define R_MIPS_INSERT_A 25
-#define R_MIPS_INSERT_B 26
-#define R_MIPS_DELETE 27
-#define R_MIPS_HIGHER 28
-#define R_MIPS_HIGHEST 29
-#define R_MIPS_CALL_HI16 30
-#define R_MIPS_CALL_LO16 31
-#define R_MIPS_SCN_DISP 32
-#define R_MIPS_REL16 33
-#define R_MIPS_ADD_IMMEDIATE 34
-#define R_MIPS_PJUMP 35
-#define R_MIPS_RELGOT 36
-#define R_MIPS_JALR 37
-/* TLS relocations */
-
-#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
-#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
-#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
-#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
-#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
-#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
-#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
-#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
-#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
-#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
-#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
-#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
-#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
-
-#define R_MIPS_max 51
-
-#define R_MIPS16_min 100
-#define R_MIPS16_26 100
-#define R_MIPS16_GPREL 101
-#define R_MIPS16_GOT16 102
-#define R_MIPS16_CALL16 103
-#define R_MIPS16_HI16 104
-#define R_MIPS16_LO16 105
-#define R_MIPS16_max 106
-
-
-/* mips dynamic tags */
-
-#define DT_MIPS_RLD_VERSION 0x70000001
-#define DT_MIPS_TIME_STAMP 0x70000002
-#define DT_MIPS_ICHECKSUM 0x70000003
-#define DT_MIPS_IVERSION 0x70000004
-#define DT_MIPS_FLAGS 0x70000005
-#define DT_MIPS_BASE_ADDRESS 0x70000006
-#define DT_MIPS_CONFLICT 0x70000008
-#define DT_MIPS_LIBLIST 0x70000009
-#define DT_MIPS_CONFLICTNO 0x7000000b
-#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* number of local got ents */
-#define DT_MIPS_LIBLISTNO 0x70000010
-#define DT_MIPS_SYMTABNO 0x70000011 /* number of .dynsym entries */
-#define DT_MIPS_UNREFEXTNO 0x70000012
-#define DT_MIPS_GOTSYM 0x70000013 /* first dynamic sym in got */
-#define DT_MIPS_HIPAGENO 0x70000014
-#define DT_MIPS_RLD_MAP 0x70000016 /* address of loader map */
-#define DT_MIPS_RLD_MAP_REL 0x70000035 /* offset of loader map, used for PIE */
-
-/*
- * ELF Flags
- */
-#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
-#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
-#define EF_MIPS_ABI2 0x00000020 /* N32 */
-
-#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural extensions */
-#define EF_MIPS_ARCH_MDMX 0x08000000 /* MDMX multimedia extension */
-#define EF_MIPS_ARCH_M16 0x04000000 /* MIPS-16 ISA extensions */
-
-#define EF_MIPS_ARCH 0xf0000000 /* Architecture field */
-#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code */
-#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code */
-#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code */
-#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code */
-#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code */
-#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code */
-#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code */
-#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code */
-#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code */
-
-#define EF_MIPS_ABI 0x0000f000
-#define EF_MIPS_ABI_O32 0x00001000
-#define EF_MIPS_ABI_O64 0x00002000
-#define EF_MIPS_ABI_EABI32 0x00003000
-#define EF_MIPS_ABI_EABI64 0x00004000
-
-#endif /* _MIPS_ELF_MACHDEP_H_ */
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 4a7ed12..beb5ff5 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -204,21 +204,17 @@
"'strlcat' called with size bigger than buffer") {
#if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
return __strlcat_chk(dst, src, size, __bos(dst));
-#endif
+#else
return __call_bypassing_fortify(strlcat)(dst, src, size);
+#endif
}
+#if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
__BIONIC_FORTIFY_INLINE
size_t strlen(const char* const s __pass_object_size0) __overloadable {
-#if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
- size_t bos = __bos0(s);
-
- if (!__bos_trivially_gt(bos, __builtin_strlen(s))) {
- return __strlen_chk(s, bos);
- }
-#endif
- return __builtin_strlen(s);
+ return __strlen_chk(s, __bos0(s));
}
+#endif
__BIONIC_FORTIFY_INLINE
char* strchr(const char* const s __pass_object_size, int c) __overloadable {
diff --git a/libc/include/elf.h b/libc/include/elf.h
index a319abb..4739bbd 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -33,7 +33,6 @@
#include <bits/auxvec.h>
#include <bits/elf_arm.h>
#include <bits/elf_arm64.h>
-#include <bits/elf_mips.h>
#include <bits/elf_x86.h>
#include <bits/elf_x86_64.h>
#include <linux/elf.h>
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index 661664a..fbf3895 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -42,20 +42,26 @@
}
#endif
-struct ScopedDisableMTE {
- ScopedDisableMTE() {
#ifdef __aarch64__
+class ScopedDisableMTE {
+ size_t prev_tco_;
+
+ public:
+ ScopedDisableMTE() {
if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; msr tco, #1");
+ __asm__ __volatile__(".arch_extension mte; mrs %0, tco; msr tco, #1" : "=r"(prev_tco_));
}
-#endif
}
~ScopedDisableMTE() {
-#ifdef __aarch64__
if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; msr tco, #0");
+ __asm__ __volatile__(".arch_extension mte; msr tco, %0" : : "r"(prev_tco_));
}
-#endif
}
};
+#else
+struct ScopedDisableMTE {
+ // Silence unused variable warnings in non-aarch64 builds.
+ ScopedDisableMTE() {}
+};
+#endif
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 4cc9bbe..6e7eb76 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -65,6 +65,10 @@
__LIBC_HIDDEN__ extern WriteProtected<libc_globals> __libc_globals;
struct abort_msg_t;
+namespace gwp_asan {
+struct AllocatorState;
+struct AllocationMetadata;
+}; // namespace gwp_asan
// Globals shared between the dynamic linker and libc.so.
struct libc_shared_globals {
@@ -96,6 +100,9 @@
// Values passed from the linker to libc.so.
const char* init_progname = nullptr;
char** init_environ = nullptr;
+
+ const gwp_asan::AllocatorState *gwp_asan_state = nullptr;
+ const gwp_asan::AllocationMetadata *gwp_asan_metadata = nullptr;
};
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 03b08b6..15b6a40 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3448,16 +3448,12 @@
return path;
}
- // Use generated linker config if flag is set
- // TODO(b/138920271) Do not check property once it is confirmed as stable
- if (android::base::GetBoolProperty("sys.linker.use_generated_config", true)) {
- if (file_exists(kLdGeneratedConfigFilePath)) {
- return kLdGeneratedConfigFilePath;
- } else {
- // TODO(b/146386369) : Adjust log level and add more condition to log only when necessary
- INFO("Warning: failed to find generated linker configuration from \"%s\"",
- kLdGeneratedConfigFilePath);
- }
+ if (file_exists(kLdGeneratedConfigFilePath)) {
+ return kLdGeneratedConfigFilePath;
+ } else {
+ // TODO(b/146386369) : Adjust log level and add more condition to log only when necessary
+ INFO("Warning: failed to find generated linker configuration from \"%s\"",
+ kLdGeneratedConfigFilePath);
}
path = get_ld_config_file_vndk_path();
diff --git a/linker/linker_debuggerd_android.cpp b/linker/linker_debuggerd_android.cpp
index b8c82f9..42ea2b7 100644
--- a/linker/linker_debuggerd_android.cpp
+++ b/linker/linker_debuggerd_android.cpp
@@ -39,6 +39,12 @@
return __libc_shared_globals()->abort_msg;
},
.post_dump = ¬ify_gdb_of_libraries,
+ .get_gwp_asan_state = []() {
+ return __libc_shared_globals()->gwp_asan_state;
+ },
+ .get_gwp_asan_metadata = []() {
+ return __libc_shared_globals()->gwp_asan_metadata;
+ },
};
debuggerd_init(&callbacks);
}
diff --git a/tests/mte_test.cpp b/tests/mte_test.cpp
index 2f922a2..8928805 100644
--- a/tests/mte_test.cpp
+++ b/tests/mte_test.cpp
@@ -16,17 +16,30 @@
#include <gtest/gtest.h>
+#include <android-base/macros.h>
#include <bionic/mte.h>
__attribute__((no_sanitize("hwaddress")))
static void test_tag_mismatch() {
- ScopedDisableMTE x;
-#if defined(__aarch64__)
std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
p[0] = 1;
- int* mistagged_p = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p.get()) + (1ULL << 56));
- volatile int load = *mistagged_p;
- (void)load;
+ int* mistagged_p ATTRIBUTE_UNUSED =
+ reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p.get()) + (1ULL << 56));
+ {
+ ScopedDisableMTE x;
+ { ScopedDisableMTE y; }
+#if defined(__aarch64__)
+ volatile int load ATTRIBUTE_UNUSED = *mistagged_p;
+#endif
+ }
+#if defined(__aarch64__)
+ if (mte_supported()) {
+ EXPECT_DEATH(
+ {
+ volatile int load ATTRIBUTE_UNUSED = *mistagged_p;
+ },
+ "");
+ }
#endif
}