Skip to content

Commit 4dcf58b

Browse files
committed
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
1 parent 0fefa56 commit 4dcf58b

File tree

3 files changed

+75
-14
lines changed

3 files changed

+75
-14
lines changed

clang/docs/AddressSanitizer.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,23 @@ To summarize: ``-fsanitize-address-use-after-return=<mode>``
164164
* ``always``: Enables detection of UAR errors in all cases. (reduces code
165165
size, but not as much as ``never``).
166166

167+
Container Overflow Detection
168+
----------------------------
169+
170+
AddressSanitizer can detect overflows in containers with custom allocators
171+
(such as std::vector) where the Library developers have added calls into the
172+
AddressSanitizer runtime to indicate which memory is poisoned etc.
173+
174+
In environments where not all the process binaries can be recompiled with
175+
AddressSanitizer enabled, these checks can cause false positives.
176+
177+
These checks can be disabled at runtime using
178+
``ASAN_OPTIONS=detect_container_overflow=0``
179+
180+
``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__`` can be used at compile time to
181+
disable container overflow checks if the container library has added support
182+
for this define.
183+
167184
Memory leak detection
168185
---------------------
169186

@@ -242,6 +259,29 @@ AddressSanitizer also supports
242259
works similar to ``__attribute__((no_sanitize("address")))``, but it also
243260
prevents instrumentation performed by other sanitizers.
244261

262+
Disabling container overflow checks with ``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__``
263+
----------------------------------------------------------------------------------
264+
265+
To support a standard way to disable container overflow checks at compile time,
266+
Library developers should use this definition in conjunction with the
267+
AddressSanitizer feature test to conditionally include container overflow
268+
related code compiled into user code:
269+
270+
The recommended form is
271+
272+
.. code-block:: c
273+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
274+
// Container overflow detection enabled - include annotations
275+
__sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid);
276+
#endif
277+
278+
This pattern ensures that:
279+
280+
* Container overflow annotations are only included when AddressSanitizer is
281+
enabled
282+
* Container overflow detection can be disabled by passing
283+
``-D__ASAN_DISABLE_CONTAINER_OVERFLOW__`` to the compiler
284+
245285
Suppressing Errors in Recompiled Code (Ignorelist)
246286
--------------------------------------------------
247287

compiler-rt/lib/asan/asan_errors.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,11 +514,15 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
514514
}
515515

516516
static void PrintContainerOverflowHint() {
517-
Printf("HINT: if you don't care about these errors you may set "
518-
"ASAN_OPTIONS=detect_container_overflow=0.\n"
519-
"If you suspect a false positive see also: "
520-
"https://github.com/google/sanitizers/wiki/"
521-
"AddressSanitizerContainerOverflow.\n");
517+
Printf(
518+
"HINT: if you don't care about these errors you may set "
519+
"ASAN_OPTIONS=detect_container_overflow=0.\n"
520+
"If supported by the container library pass "
521+
"-D__ASAN_DISABLE_CONTAINER_OVERFLOW__ to the compiler to disable "
522+
" instrumentation.\n"
523+
"If you suspect a false positive see also: "
524+
"https://github.com/google/sanitizers/wiki/"
525+
"AddressSanitizerContainerOverflow.\n");
522526
}
523527

524528
static void PrintShadowByte(InternalScopedString *str, const char *before,

compiler-rt/test/asan/TestCases/contiguous_container_crash.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,55 +7,72 @@
77
// RUN: %env_asan_opts=detect_container_overflow=0 %run %t crash
88
//
99
// Test crash due to __sanitizer_annotate_contiguous_container.
10+
//
11+
// Test with -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ flag - should not crash
12+
// RUN: %clangxx_asan -D__ASAN_DISABLE_CONTAINER_OVERFLOW__ -O %s -o %t-no-overflow
13+
// RUN: %run %t-no-overflow crash
14+
// RUN: %run %t-no-overflow bad-bounds
15+
// RUN: %run %t-no-overflow unaligned-bad-bounds
16+
// RUN: %run %t-no-overflow odd-alignment
17+
// RUN: %run %t-no-overflow odd-alignment-end
18+
//
19+
// Test overflow checks can be disabled
1020

1121
#include <assert.h>
1222
#include <string.h>
1323

14-
extern "C" {
15-
void __sanitizer_annotate_contiguous_container(const void *beg, const void *end,
16-
const void *old_mid,
17-
const void *new_mid);
18-
} // extern "C"
24+
// public definition of __sanitizer_annotate_contiguous_container
25+
#include "sanitizer/common_interface_defs.h"
1926

2027
static volatile int one = 1;
2128

2229
int TestCrash() {
2330
long t[100];
2431
t[60] = 0;
32+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
2533
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 100,
2634
&t[0] + 50);
27-
// CHECK-CRASH: AddressSanitizer: container-overflow
28-
// CHECK-CRASH: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0
29-
return (int)t[60 * one]; // Touches the poisoned memory.
35+
#endif
36+
// CHECK-CRASH: AddressSanitizer: container-overflow
37+
// CHECK-CRASH: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0
38+
return (int)t[60 * one]; // Touches the poisoned memory.
3039
}
3140

3241
void BadBounds() {
3342
long t[100];
34-
// CHECK-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
43+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
44+
// CHECK-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
3545
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 101,
3646
&t[0] + 50);
47+
#endif
3748
}
3849

3950
void UnalignedBadBounds() {
4051
char t[100];
52+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
4153
// CHECK-UNALIGNED-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container
4254
__sanitizer_annotate_contiguous_container(&t[1], &t[0] + 100, &t[0] + 101,
4355
&t[0] + 50);
56+
#endif
4457
}
4558

4659
int OddAlignment() {
4760
int t[100];
4861
t[60] = 0;
62+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
4963
__sanitizer_annotate_contiguous_container(&t[1], &t[0] + 100, &t[0] + 100,
5064
&t[1] + 50);
65+
#endif
5166
return (int)t[60 * one]; // Touches the poisoned memory.
5267
}
5368

5469
int OddAlignmentEnd() {
5570
int t[99];
5671
t[60] = 0;
72+
#if __has_feature(address_sanitizer) && !__ASAN_DISABLE_CONTAINER_OVERFLOW__
5773
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 98, &t[0] + 98,
5874
&t[0] + 50);
75+
#endif
5976
return (int)t[60 * one]; // Touches the poisoned memory.
6077
}
6178

0 commit comments

Comments
 (0)