Merge "Update Android.bp to point to fuzz target."
diff --git a/gwp_asan/optional/backtrace.h b/gwp_asan/optional/backtrace.h
index 3aad9ea..6c9ee9f 100644
--- a/gwp_asan/optional/backtrace.h
+++ b/gwp_asan/optional/backtrace.h
@@ -17,7 +17,9 @@
// and backtrace printing functions when RTGwpAsanBacktraceLibc or
// RTGwpAsanBacktraceSanitizerCommon are linked. Use these functions to get the
// backtrace function for populating the Options::Backtrace and
-// Options::PrintBacktrace when initialising the GuardedPoolAllocator.
+// Options::PrintBacktrace when initialising the GuardedPoolAllocator. Please
+// note any thread-safety descriptions for the implementation of these functions
+// that you use.
Backtrace_t getBacktraceFunction();
PrintBacktrace_t getPrintBacktraceFunction();
} // namespace options
diff --git a/gwp_asan/optional/backtrace_sanitizer_common.cpp b/gwp_asan/optional/backtrace_sanitizer_common.cpp
index 427ac77..5e07fd6 100644
--- a/gwp_asan/optional/backtrace_sanitizer_common.cpp
+++ b/gwp_asan/optional/backtrace_sanitizer_common.cpp
@@ -13,6 +13,9 @@
#include "gwp_asan/optional/backtrace.h"
#include "gwp_asan/options.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
void __sanitizer::BufferedStackTrace::UnwindImpl(uptr pc, uptr bp,
@@ -58,7 +61,18 @@
namespace gwp_asan {
namespace options {
-Backtrace_t getBacktraceFunction() { return Backtrace; }
+// This function is thread-compatible. It must be synchronised in respect to any
+// other calls to getBacktraceFunction(), calls to getPrintBacktraceFunction(),
+// and calls to either of the functions that they return. Furthermore, this may
+// require synchronisation with any calls to sanitizer_common that use flags.
+// Generally, this function will be called during the initialisation of the
+// allocator, which is done in a thread-compatible manner.
+Backtrace_t getBacktraceFunction() {
+ // The unwinder requires the default flags to be set.
+ __sanitizer::SetCommonFlagsDefaults();
+ __sanitizer::InitializeCommonFlags();
+ return Backtrace;
+}
PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; }
} // namespace options
} // namespace gwp_asan
diff --git a/gwp_asan/options.h b/gwp_asan/options.h
index 67a6129..ae3f3d4 100644
--- a/gwp_asan/options.h
+++ b/gwp_asan/options.h
@@ -25,6 +25,7 @@
// 2. pointers: "%p"
// 3. strings: "%[-]([0-9]*)?(\\.\\*)?s"
// 4. chars: "%c"
+// This function must be implemented in a signal-safe manner.
// =================================== Notes ===================================
// This function has a slightly different signature than the C standard
// library's printf(). Notably, it returns 'void' rather than 'int'.
diff --git a/gwp_asan/options.inc b/gwp_asan/options.inc
index 9042b11..df6c46e 100644
--- a/gwp_asan/options.inc
+++ b/gwp_asan/options.inc
@@ -21,9 +21,9 @@
"byte buffer-overflows for multibyte allocations at the cost of "
"performance, and may be incompatible with some architectures.")
-GWP_ASAN_OPTION(
- int, MaxSimultaneousAllocations, 16,
- "Number of usable guarded slots in the allocation pool. Defaults to 16.")
+GWP_ASAN_OPTION(int, MaxSimultaneousAllocations, 16,
+ "Number of simultaneously-guarded allocations available in the "
+ "pool. Defaults to 16.")
GWP_ASAN_OPTION(int, SampleRate, 5000,
"The probability (1 / SampleRate) that an allocation is "
diff --git a/gwp_asan/scripts/symbolize.sh b/gwp_asan/scripts/symbolize.sh
new file mode 100755
index 0000000..fad9620
--- /dev/null
+++ b/gwp_asan/scripts/symbolize.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# The lines that we're looking to symbolize look like this:
+ #0 ./a.out(_foo+0x3e6) [0x55a52e64c696]
+# ... which come from the backtrace_symbols() symbolisation function used by
+# default in Scudo's implementation of GWP-ASan.
+
+while read -r line; do
+ # Check that this line needs symbolization.
+ should_symbolize="$(echo $line |\
+ grep -E '^[ ]*\#.*\(.*\+0x[0-9a-f]+\) \[0x[0-9a-f]+\]$')"
+
+ if [ -z "$should_symbolize" ]; then
+ echo "$line"
+ continue
+ fi
+
+ # Carve up the input line into sections.
+ binary_name="$(echo $line | grep -oE ' .*\(' | rev | cut -c2- | rev |\
+ cut -c2-)"
+ function_name="$(echo $line | grep -oE '\([^+]*' | cut -c2-)"
+ function_offset="$(echo $line | grep -oE '\(.*\)' | grep -oE '\+.*\)' |\
+ cut -c2- | rev | cut -c2- | rev)"
+ frame_number="$(echo $line | grep -oE '\#[0-9]+ ')"
+
+ if [ -z "$function_name" ]; then
+ # If the offset is binary-relative, just resolve that.
+ symbolized="$(echo $function_offset | addr2line -e $binary_name)"
+ else
+ # Otherwise, the offset is function-relative. Get the address of the
+ # function, and add it to the offset, then symbolize.
+ function_addr="0x$(echo $function_offset |\
+ nm --defined-only $binary_name 2> /dev/null |\
+ grep -E " $function_name$" | cut -d' ' -f1)"
+
+ # Check that we could get the function address from nm.
+ if [ -z "$function_addr" ]; then
+ echo "$line"
+ continue
+ fi
+
+ # Add the function address and offset to get the offset into the binary.
+ binary_offset="$(printf "0x%X" "$((function_addr+function_offset))")"
+ symbolized="$(echo $binary_offset | addr2line -e $binary_name)"
+ fi
+
+ # Check that it symbolized properly. If it didn't, output the old line.
+ echo $symbolized | grep -E ".*\?.*:" > /dev/null
+ if [ "$?" -eq "0" ]; then
+ echo "$line"
+ continue
+ else
+ echo "${frame_number}${symbolized}"
+ fi
+done
diff --git a/gwp_asan/tests/harness.h b/gwp_asan/tests/harness.h
index 136e566..77f7b51 100644
--- a/gwp_asan/tests/harness.h
+++ b/gwp_asan/tests/harness.h
@@ -9,18 +9,24 @@
#ifndef GWP_ASAN_TESTS_HARNESS_H_
#define GWP_ASAN_TESTS_HARNESS_H_
-#include "gtest/gtest.h"
+#include <stdarg.h>
-// Include sanitizer_common first as gwp_asan/guarded_pool_allocator.h
-// transiently includes definitions.h, which overwrites some of the definitions
-// in sanitizer_common.
-#include "sanitizer_common/sanitizer_common.h"
+#include "gtest/gtest.h"
#include "gwp_asan/guarded_pool_allocator.h"
#include "gwp_asan/optional/backtrace.h"
-#include "gwp_asan/optional/options_parser.h"
#include "gwp_asan/options.h"
+namespace gwp_asan {
+namespace test {
+// This printf-function getter allows other platforms (e.g. Android) to define
+// their own signal-safe Printf function. In LLVM, we use
+// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
+// for this purpose.
+options::Printf_t getPrintfFunction();
+}; // namespace test
+}; // namespace gwp_asan
+
class DefaultGuardedPoolAllocator : public ::testing::Test {
public:
DefaultGuardedPoolAllocator() {
@@ -28,7 +34,7 @@
Opts.setDefaults();
MaxSimultaneousAllocations = Opts.MaxSimultaneousAllocations;
- Opts.Printf = __sanitizer::Printf;
+ Opts.Printf = gwp_asan::test::getPrintfFunction();
GPA.init(Opts);
}
@@ -49,7 +55,7 @@
Opts.MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
MaxSimultaneousAllocations = MaxSimultaneousAllocationsArg;
- Opts.Printf = __sanitizer::Printf;
+ Opts.Printf = gwp_asan::test::getPrintfFunction();
GPA.init(Opts);
}
@@ -62,15 +68,10 @@
class BacktraceGuardedPoolAllocator : public ::testing::Test {
public:
BacktraceGuardedPoolAllocator() {
- // Call initOptions to initialise the internal sanitizer_common flags. These
- // flags are referenced by the sanitizer_common unwinder, and if left
- // uninitialised, they'll unintentionally crash the program.
- gwp_asan::options::initOptions();
-
gwp_asan::options::Options Opts;
Opts.setDefaults();
- Opts.Printf = __sanitizer::Printf;
+ Opts.Printf = gwp_asan::test::getPrintfFunction();
Opts.Backtrace = gwp_asan::options::getBacktraceFunction();
Opts.PrintBacktrace = gwp_asan::options::getPrintBacktraceFunction();
GPA.init(Opts);
diff --git a/gwp_asan/tests/optional/printf_sanitizer_common.cpp b/gwp_asan/tests/optional/printf_sanitizer_common.cpp
new file mode 100644
index 0000000..e823aeb
--- /dev/null
+++ b/gwp_asan/tests/optional/printf_sanitizer_common.cpp
@@ -0,0 +1,22 @@
+//===-- printf_sanitizer_common.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 "sanitizer_common/sanitizer_common.h"
+#include "gwp_asan/options.h"
+
+namespace gwp_asan {
+namespace test {
+// This printf-function getter allows other platforms (e.g. Android) to define
+// their own signal-safe Printf function. In LLVM, we use
+// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
+// for this purpose.
+options::Printf_t getPrintfFunction() {
+ return __sanitizer::Printf;
+}
+}; // namespace test
+}; // namespace gwp_asan
diff --git a/gwp_asan/stack_trace_compressor_fuzzer.cpp b/tools/stack_trace_compressor_fuzzer.cpp
similarity index 100%
rename from gwp_asan/stack_trace_compressor_fuzzer.cpp
rename to tools/stack_trace_compressor_fuzzer.cpp