[clang] [compiler-rt] [ASan] Document define to disable container overflow checks at compile time. (PR #163468)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 14 15:44:48 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Paddy McDonald (padriff)
<details>
<summary>Changes</summary>
Document a define to allow library developers to support disabling
AddressSanitizer's container overflow detection in template code at
compile time.
The primary motivation is to reduce false positives in environments where
libraries and frameworks that cannot be recompiled with sanitizers enabled
are called from application code. This supports disabling checks when the
runtime environment cannot be reliably controlled to use ASAN_OPTIONS.
Key changes:
- Update documentation in AddressSanitizer.rst to suggest and illustrate use of the define
- Add details of the define in PrintContainerOverflowHint()
- Update contiguous_container_crash.cpp to illustrate the usage and test it works
The recommended pattern is:
This requires no compiler changes and should be supportable cross compiler toolchains.
An RFC has been opened to discuss: https://discourse.llvm.org/t/rfc-add-fsanitize-address-disable-container-overflow-flag-to-addresssanitizer/88349
---
Full diff: https://github.com/llvm/llvm-project/pull/163468.diff
3 Files Affected:
- (modified) clang/docs/AddressSanitizer.rst (+40)
- (modified) compiler-rt/lib/asan/asan_errors.cpp (+9-5)
- (modified) compiler-rt/test/asan/TestCases/contiguous_container_crash.cpp (+26-9)
``````````diff
diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst
index 21e1a3652192e..2fb4d7056296b 100644
--- a/clang/docs/AddressSanitizer.rst
+++ b/clang/docs/AddressSanitizer.rst
@@ -164,6 +164,23 @@ To summarize: ``-fsanitize-address-use-after-return=<mode>``
* ``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.
+
+These checks can be disabled at runtime using
+``ASAN_OPTIONS=detect_container_overflow=0``
+
+``-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.
+
Memory leak detection
---------------------
@@ -242,6 +259,29 @@ AddressSanitizer also supports
works similar to ``__attribute__((no_sanitize("address")))``, but it also
prevents instrumentation performed by other sanitizers.
+Disabling container overflow checks with ``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__``
+----------------------------------------------------------------------------------
+
+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..5b3d479fbbcd4 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"
+ "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/contiguous_container_crash.cpp b/compiler-rt/test/asan/TestCases/contiguous_container_crash.cpp
index b88e02b84ad67..4661c20d3d792 100644
--- a/compiler-rt/test/asan/TestCases/contiguous_container_crash.cpp
+++ b/compiler-rt/test/asan/TestCases/contiguous_container_crash.cpp
@@ -7,55 +7,72 @@
// RUN: %env_asan_opts=detect_container_overflow=0 %run %t crash
//
// Test crash due to __sanitizer_annotate_contiguous_container.
+//
+// Test with -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ flag - should not crash
+// RUN: %clangxx_asan -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ -O %s -o %t-no-overflow
+// RUN: %run %t-no-overflow crash
+// RUN: %run %t-no-overflow bad-bounds
+// RUN: %run %t-no-overflow unaligned-bad-bounds
+// RUN: %run %t-no-overflow odd-alignment
+// RUN: %run %t-no-overflow odd-alignment-end
+//
+// Test overflow checks can be disabled
#include <assert.h>
#include <string.h>
-extern "C" {
-void __sanitizer_annotate_contiguous_container(const void *beg, const void *end,
- const void *old_mid,
- const void *new_mid);
-} // extern "C"
+// 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);
-// CHECK-CRASH: AddressSanitizer: container-overflow
-// CHECK-CRASH: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0
- return (int)t[60 * one]; // Touches the poisoned memory.
+#endif
+ // CHECK-CRASH: AddressSanitizer: container-overflow
+ // CHECK-CRASH: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0
+ return (int)t[60 * one]; // Touches the poisoned memory.
}
void BadBounds() {
long t[100];
-// CHECK-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
+#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
+ // CHECK-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 101,
&t[0] + 50);
+#endif
}
void UnalignedBadBounds() {
char t[100];
+#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
// CHECK-UNALIGNED-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
__sanitizer_annotate_contiguous_container(&t[1], &t[0] + 100, &t[0] + 101,
&t[0] + 50);
+#endif
}
int OddAlignment() {
int t[100];
t[60] = 0;
+#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
__sanitizer_annotate_contiguous_container(&t[1], &t[0] + 100, &t[0] + 100,
&t[1] + 50);
+#endif
return (int)t[60 * one]; // Touches the poisoned memory.
}
int OddAlignmentEnd() {
int t[99];
t[60] = 0;
+#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 98, &t[0] + 98,
&t[0] + 50);
+#endif
return (int)t[60 * one]; // Touches the poisoned memory.
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/163468
More information about the cfe-commits
mailing list