Skip to content

Commit deef649

Browse files
authored
Poison unused tail of FakeFrame (#133689)
Fix [issue#133640](#133640)
1 parent 8ebc98c commit deef649

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

compiler-rt/lib/asan/asan_fake_stack.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static const u64 kAllocaRedzoneMask = 31UL;
2727

2828
// For small size classes inline PoisonShadow for better performance.
2929
ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
30+
CHECK(AddrIsAlignedByGranularity(ptr + size));
3031
u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
3132
if (ASAN_SHADOW_SCALE == 3 && class_id <= 6) {
3233
// This code expects ASAN_SHADOW_SCALE=3.
@@ -39,6 +40,11 @@ ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
3940
// The size class is too big, it's cheaper to poison only size bytes.
4041
PoisonShadow(ptr, size, static_cast<u8>(magic));
4142
}
43+
44+
if (magic == 0) {
45+
uptr redzone_size = FakeStack::BytesInSizeClass(class_id) - size;
46+
PoisonShadow(ptr + size, redzone_size, kAsanStackRightRedzoneMagic);
47+
}
4248
}
4349

4450
FakeStack *FakeStack::Create(uptr stack_size_log) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
2+
// RUN: %clangxx_asan -O0 %s -o %t -fsanitize-address-use-after-return=always && not %run %t 2>&1 | FileCheck %s
3+
4+
#include "defines.h"
5+
#include <stdint.h>
6+
#include <string.h>
7+
8+
#define kFrameSize (2048)
9+
#define KFrameSizeMask (0x07ff)
10+
11+
ATTRIBUTE_NOINLINE
12+
char *pretend_to_do_something(char *x) {
13+
__asm__ __volatile__("" : : "r"(x) : "memory");
14+
return x;
15+
}
16+
17+
ATTRIBUTE_NOINLINE
18+
char *OverwriteFakeFrameLastWord() {
19+
char x[1024];
20+
memset(x, 0, sizeof(x));
21+
uint64_t ptr_int = (reinterpret_cast<uint64_t>(x) & ~KFrameSizeMask) +
22+
kFrameSize - sizeof(char **);
23+
char **ptr = reinterpret_cast<char **>(ptr_int);
24+
*ptr = nullptr;
25+
return pretend_to_do_something(x);
26+
}
27+
28+
int main(int argc, char **argv) {
29+
char *x = OverwriteFakeFrameLastWord();
30+
// CHECK: ERROR: AddressSanitizer: stack-buffer-overflow on address
31+
// CHECK: is located in stack of thread T0 at offset {{2040|2044}} in frame
32+
// CHECK: in OverwriteFakeFrameLastWord{{.*}}fakeframe-right-redzone.cpp:
33+
// CHECK: [{{16|32}}, {{1040|1056}}) 'x'
34+
pretend_to_do_something(x);
35+
return 0;
36+
}

compiler-rt/test/ubsan/TestCases/Integer/bit-int.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// REQUIRES: x86_64-target-arch
22
// REQUIRES: !windows
3-
// 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
3+
// 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
44

55
#include <stdint.h>
66
#include <stdio.h>

0 commit comments

Comments
 (0)