diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 21e1a3652192e..40e876a02d4ea 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -164,6 +164,18 @@ To summarize: ``-fsanitize-address-use-after-return=`` * ``always``: Enables detection of UAR errors in all cases. (reduces code size, but not as much as ``never``). +Container Overflow Detection +---------------------------- + +AddressSanitizer can detect overflows in containers with custom allocators +(such as std::vector) where the library developers have added calls into the +AddressSanitizer runtime to indicate which memory is poisoned etc. + +In environments where not all the process binaries can be recompiled with +AddressSanitizer enabled, these checks can cause false positives. + +See `Disabling container overflow checks`_ for details on suppressing checks. + Memory leak detection --------------------- @@ -242,6 +254,43 @@ AddressSanitizer also supports works similar to ``__attribute__((no_sanitize("address")))``, but it also prevents instrumentation performed by other sanitizers. +Disabling container overflow checks +----------------------------------- + +Runtime suppression +^^^^^^^^^^^^^^^^^^^ + +Container overflow checks can be disabled at runtime using the +``ASAN_OPTIONS=detect_container_overflow=0`` environment variable. + +Compile time suppression +^^^^^^^^^^^^^^^^^^^^^^^^ + +``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__`` can be used at compile time to +disable container overflow checks if the container library has added support +for this define. + +To support a standard way to disable container overflow checks at compile time, +library developers should use this definition in conjunction with the +AddressSanitizer feature test to conditionally include container overflow +related code compiled into user code: + +The recommended form is + +.. code-block:: c + + #if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__ + // Container overflow detection enabled - include annotations + __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid); + #endif + +This pattern ensures that: + +* Container overflow annotations are only included when AddressSanitizer is + enabled +* Container overflow detection can be disabled by passing + ``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__`` to the compiler + Suppressing Errors in Recompiled Code (Ignorelist) -------------------------------------------------- diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp index 2a207cd06ccac..567a295d861ac 100644 --- a/compiler-rt/lib/asan/asan_errors.cpp +++ b/compiler-rt/lib/asan/asan_errors.cpp @@ -514,11 +514,15 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, } static void PrintContainerOverflowHint() { - Printf("HINT: if you don't care about these errors you may set " - "ASAN_OPTIONS=detect_container_overflow=0.\n" - "If you suspect a false positive see also: " - "https://github.com/google/sanitizers/wiki/" - "AddressSanitizerContainerOverflow.\n"); + Printf( + "HINT: if you don't care about these errors you may set " + "ASAN_OPTIONS=detect_container_overflow=0.\n" + "Or if supported by the container library, pass " + "-D__ASAN_DISABLE_CONTAINER_OVERFLOW__ to the compiler to disable " + " instrumentation.\n" + "If you suspect a false positive see also: " + "https://github.com/google/sanitizers/wiki/" + "AddressSanitizerContainerOverflow.\n"); } static void PrintShadowByte(InternalScopedString *str, const char *before, diff --git a/compiler-rt/test/asan/TestCases/disable_container_overflow_checks.cpp b/compiler-rt/test/asan/TestCases/disable_container_overflow_checks.cpp new file mode 100644 index 0000000000000..294ade20c0dd3 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/disable_container_overflow_checks.cpp @@ -0,0 +1,50 @@ +// Test crash gives guidance on -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ and +// ASAN_OPTIONS=detect_container_overflow=0 +// RUN: %clangxx_asan -O %s -o %t +// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s +// +// Test overflow checks can be disabled at runtime with +// ASAN_OPTIONS=detect_container_overflow=0 +// RUN: %env_asan_opts=detect_container_overflow=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-NOCRASH %s +// +// Illustrate use of -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ flag to suppress +// overflow checks at compile time. +// RUN: %clangxx_asan -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ -O %s -o %t-no-overflow +// RUN: %run %t-no-overflow 2>&1 | FileCheck --check-prefix=CHECK-NOCRASH %s +// + +#include +#include +#include + +// public definition of __sanitizer_annotate_contiguous_container +#include "sanitizer/common_interface_defs.h" + +static volatile int one = 1; + +int TestCrash() { + long t[100]; + t[60] = 0; +#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__ + __sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 100, + &t[0] + 50); +#endif + // CHECK-CRASH: AddressSanitizer: container-overflow + // CHECK-CRASH: ASAN_OPTIONS=detect_container_overflow=0 + // CHECK-CRASH: __ASAN_DISABLE_CONTAINER_OVERFLOW__ + // CHECK-NOCRASH-NOT: AddressSanitizer: container-overflow + // CHECK-NOCRASH-NOT: ASAN_OPTIONS=detect_container_overflow=0 + // CHECK-NOCRASH-NOT: __ASAN_DISABLE_CONTAINER_OVERFLOW__ + return (int)t[60 * one]; // Touches the poisoned memory. +} + +int main(int argc, char **argv) { + + int retval = 0; + + retval = TestCrash(); + + printf("Exiting main\n"); + + return retval; +}