diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp b/compiler-rt/lib/asan/asan_fake_stack.cpp index 7443ff166984d..0f696075fb78d 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -27,6 +27,7 @@ static const u64 kAllocaRedzoneMask = 31UL; // For small size classes inline PoisonShadow for better performance. ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { + CHECK(AddrIsAlignedByGranularity(ptr + size)); u64 *shadow = reinterpret_cast(MemToShadow(ptr)); if (ASAN_SHADOW_SCALE == 3 && class_id <= 6) { // This code expects ASAN_SHADOW_SCALE=3. @@ -39,6 +40,11 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { // The size class is too big, it's cheaper to poison only size bytes. PoisonShadow(ptr, size, static_cast(magic)); } + + if (magic == 0) { + uptr redzone_size = FakeStack::BytesInSizeClass(class_id) - size; + PoisonShadow(ptr + size, redzone_size, kAsanStackRightRedzoneMagic); + } } FakeStack *FakeStack::Create(uptr stack_size_log) { diff --git a/compiler-rt/test/asan/TestCases/fakeframe-right-redzone.cpp b/compiler-rt/test/asan/TestCases/fakeframe-right-redzone.cpp new file mode 100644 index 0000000000000..da1f5f2fb9789 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/fakeframe-right-redzone.cpp @@ -0,0 +1,36 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t -fsanitize-address-use-after-return=always && not %run %t 2>&1 | FileCheck %s + +#include "defines.h" +#include +#include + +#define kFrameSize (2048) +#define KFrameSizeMask (0x07ff) + +ATTRIBUTE_NOINLINE +char *pretend_to_do_something(char *x) { + __asm__ __volatile__("" : : "r"(x) : "memory"); + return x; +} + +ATTRIBUTE_NOINLINE +char *OverwriteFakeFrameLastWord() { + char x[1024]; + memset(x, 0, sizeof(x)); + uint64_t ptr_int = (reinterpret_cast(x) & ~KFrameSizeMask) + + kFrameSize - sizeof(char **); + char **ptr = reinterpret_cast(ptr_int); + *ptr = nullptr; + return pretend_to_do_something(x); +} + +int main(int argc, char **argv) { + char *x = OverwriteFakeFrameLastWord(); + // CHECK: ERROR: AddressSanitizer: stack-buffer-overflow on address + // CHECK: is located in stack of thread T0 at offset {{2040|2044}} in frame + // CHECK: in OverwriteFakeFrameLastWord{{.*}}fakeframe-right-redzone.cpp: + // CHECK: [{{16|32}}, {{1040|1056}}) 'x' + pretend_to_do_something(x); + return 0; +} diff --git a/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c b/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c index d7e2c6dc60aa0..e15c6e6e1756a 100644 --- a/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c +++ b/compiler-rt/test/ubsan/TestCases/Integer/bit-int.c @@ -1,6 +1,6 @@ // REQUIRES: x86_64-target-arch // REQUIRES: !windows -// RUN: %clang -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -O0 -fsanitize=array-bounds,float-cast-overflow,implicit-integer-sign-change,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation,integer-divide-by-zero,pointer-overflow,shift-base,shift-exponent,signed-integer-overflow,unsigned-integer-overflow,unsigned-shift-base,vla-bound %s -o %t1 && %run %t1 2>&1 | FileCheck %s +// RUN: %clang -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -O0 -fsanitize=array-bounds,float-cast-overflow,implicit-integer-sign-change,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation,integer-divide-by-zero,pointer-overflow,shift-base,shift-exponent,signed-integer-overflow,unsigned-integer-overflow,unsigned-shift-base,vla-bound -fsanitize-address-use-after-return=never %s -o %t1 && %run %t1 2>&1 | FileCheck %s #include #include