Skip to content

Commit ace1d6d

Browse files
Roy Sundahlthetruestblue
authored andcommitted
[ASAN] Don't inline when -asan-max-inline-poisoning-size=0
When -asan-max-inline-poisoning-size=0, all shadow memory access should be outlined (through asan calls). This was not occuring when partial poisoning was required on the right side of a variable's redzone. This diff contains the changes necessary to implement and utilize __asan_set_shadow_01() through __asan_set_shadow_07(). The change is necessary for the full abstraction of the asan implementation and will enable experimentation with alternate strategies. Differential Revision: https://reviews.llvm.org/D136197
1 parent e39533e commit ace1d6d

File tree

8 files changed

+183
-6
lines changed

8 files changed

+183
-6
lines changed

compiler-rt/lib/asan/asan_interface.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ INTERFACE_FUNCTION(__asan_report_store_n_noabort)
108108
INTERFACE_FUNCTION(__asan_set_death_callback)
109109
INTERFACE_FUNCTION(__asan_set_error_report_callback)
110110
INTERFACE_FUNCTION(__asan_set_shadow_00)
111+
INTERFACE_FUNCTION(__asan_set_shadow_01)
112+
INTERFACE_FUNCTION(__asan_set_shadow_02)
113+
INTERFACE_FUNCTION(__asan_set_shadow_03)
114+
INTERFACE_FUNCTION(__asan_set_shadow_04)
115+
INTERFACE_FUNCTION(__asan_set_shadow_05)
116+
INTERFACE_FUNCTION(__asan_set_shadow_06)
117+
INTERFACE_FUNCTION(__asan_set_shadow_07)
111118
INTERFACE_FUNCTION(__asan_set_shadow_f1)
112119
INTERFACE_FUNCTION(__asan_set_shadow_f2)
113120
INTERFACE_FUNCTION(__asan_set_shadow_f3)

compiler-rt/lib/asan/asan_interface_internal.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ extern "C" {
9090
SANITIZER_INTERFACE_ATTRIBUTE
9191
void __asan_set_shadow_00(uptr addr, uptr size);
9292
SANITIZER_INTERFACE_ATTRIBUTE
93+
void __asan_set_shadow_01(uptr addr, uptr size);
94+
SANITIZER_INTERFACE_ATTRIBUTE
95+
void __asan_set_shadow_02(uptr addr, uptr size);
96+
SANITIZER_INTERFACE_ATTRIBUTE
97+
void __asan_set_shadow_03(uptr addr, uptr size);
98+
SANITIZER_INTERFACE_ATTRIBUTE
99+
void __asan_set_shadow_04(uptr addr, uptr size);
100+
SANITIZER_INTERFACE_ATTRIBUTE
101+
void __asan_set_shadow_05(uptr addr, uptr size);
102+
SANITIZER_INTERFACE_ATTRIBUTE
103+
void __asan_set_shadow_06(uptr addr, uptr size);
104+
SANITIZER_INTERFACE_ATTRIBUTE
105+
void __asan_set_shadow_07(uptr addr, uptr size);
106+
SANITIZER_INTERFACE_ATTRIBUTE
93107
void __asan_set_shadow_f1(uptr addr, uptr size);
94108
SANITIZER_INTERFACE_ATTRIBUTE
95109
void __asan_set_shadow_f2(uptr addr, uptr size);

compiler-rt/lib/asan/asan_poisoning.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#include "asan_poisoning.h"
1515

16+
#include <assert.h>
17+
1618
#include "asan_report.h"
1719
#include "asan_stack.h"
1820
#include "sanitizer_common/sanitizer_atomic.h"
@@ -312,6 +314,41 @@ void __asan_set_shadow_00(uptr addr, uptr size) {
312314
REAL(memset)((void *)addr, 0, size);
313315
}
314316

317+
void __asan_set_shadow_01(uptr addr, uptr size) {
318+
assert(size == 1);
319+
REAL(memset)((void *)addr, 0x01, size);
320+
}
321+
322+
void __asan_set_shadow_02(uptr addr, uptr size) {
323+
assert(size == 1);
324+
REAL(memset)((void *)addr, 0x02, size);
325+
}
326+
327+
void __asan_set_shadow_03(uptr addr, uptr size) {
328+
assert(size == 1);
329+
REAL(memset)((void *)addr, 0x03, size);
330+
}
331+
332+
void __asan_set_shadow_04(uptr addr, uptr size) {
333+
assert(size == 1);
334+
REAL(memset)((void *)addr, 0x04, size);
335+
}
336+
337+
void __asan_set_shadow_05(uptr addr, uptr size) {
338+
assert(size == 1);
339+
REAL(memset)((void *)addr, 0x05, size);
340+
}
341+
342+
void __asan_set_shadow_06(uptr addr, uptr size) {
343+
assert(size == 1);
344+
REAL(memset)((void *)addr, 0x06, size);
345+
}
346+
347+
void __asan_set_shadow_07(uptr addr, uptr size) {
348+
assert(size == 1);
349+
REAL(memset)((void *)addr, 0x07, size);
350+
}
351+
315352
void __asan_set_shadow_f1(uptr addr, uptr size) {
316353
REAL(memset)((void *)addr, 0xf1, size);
317354
}

compiler-rt/lib/asan/asan_rtl.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,18 @@ static NOINLINE void force_interface_symbols() {
288288
case 38: __asan_region_is_poisoned(0, 0); break;
289289
case 39: __asan_describe_address(0); break;
290290
case 40: __asan_set_shadow_00(0, 0); break;
291-
case 41: __asan_set_shadow_f1(0, 0); break;
292-
case 42: __asan_set_shadow_f2(0, 0); break;
293-
case 43: __asan_set_shadow_f3(0, 0); break;
294-
case 44: __asan_set_shadow_f5(0, 0); break;
295-
case 45: __asan_set_shadow_f8(0, 0); break;
291+
case 41: __asan_set_shadow_01(0, 0); break;
292+
case 42: __asan_set_shadow_02(0, 0); break;
293+
case 43: __asan_set_shadow_03(0, 0); break;
294+
case 44: __asan_set_shadow_04(0, 0); break;
295+
case 45: __asan_set_shadow_05(0, 0); break;
296+
case 46: __asan_set_shadow_06(0, 0); break;
297+
case 47: __asan_set_shadow_07(0, 0); break;
298+
case 48: __asan_set_shadow_f1(0, 0); break;
299+
case 49: __asan_set_shadow_f2(0, 0); break;
300+
case 50: __asan_set_shadow_f3(0, 0); break;
301+
case 51: __asan_set_shadow_f5(0, 0); break;
302+
case 52: __asan_set_shadow_f8(0, 0); break;
296303
}
297304
// clang-format on
298305
}

compiler-rt/lib/asan/tests/asan_internal_interface_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,27 @@ TEST(AddressSanitizerInternalInterface, SetShadow) {
1919
__asan_set_shadow_00((uptr)buffer.data(), buffer.size());
2020
EXPECT_EQ(std::vector<char>(buffer.size(), 0x00), buffer);
2121

22+
__asan_set_shadow_01((uptr)buffer.data(), buffer.size());
23+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x01), buffer);
24+
25+
__asan_set_shadow_02((uptr)buffer.data(), buffer.size());
26+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x02), buffer);
27+
28+
__asan_set_shadow_03((uptr)buffer.data(), buffer.size());
29+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x03), buffer);
30+
31+
__asan_set_shadow_04((uptr)buffer.data(), buffer.size());
32+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x04), buffer);
33+
34+
__asan_set_shadow_05((uptr)buffer.data(), buffer.size());
35+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x05), buffer);
36+
37+
__asan_set_shadow_06((uptr)buffer.data(), buffer.size());
38+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x06), buffer);
39+
40+
__asan_set_shadow_07((uptr)buffer.data(), buffer.size());
41+
EXPECT_EQ(std::vector<char>(buffer.size(), 0x07), buffer);
42+
2243
__asan_set_shadow_f1((uptr)buffer.data(), buffer.size());
2344
EXPECT_EQ(std::vector<char>(buffer.size(), 0xf1), buffer);
2445

compiler-rt/test/asan/TestCases/set_shadow_test.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
#include <stdlib.h>
1414

1515
void __asan_set_shadow_00(size_t addr, size_t size);
16+
void __asan_set_shadow_01(size_t addr, size_t size);
17+
void __asan_set_shadow_02(size_t addr, size_t size);
18+
void __asan_set_shadow_03(size_t addr, size_t size);
19+
void __asan_set_shadow_04(size_t addr, size_t size);
20+
void __asan_set_shadow_05(size_t addr, size_t size);
21+
void __asan_set_shadow_06(size_t addr, size_t size);
22+
void __asan_set_shadow_07(size_t addr, size_t size);
1623
void __asan_set_shadow_f1(size_t addr, size_t size);
1724
void __asan_set_shadow_f2(size_t addr, size_t size);
1825
void __asan_set_shadow_f3(size_t addr, size_t size);
@@ -32,6 +39,34 @@ void f(long arg) {
3239
// X00: PASS
3340
case 0x00:
3441
return __asan_set_shadow_00(addr, 1);
42+
// X01: AddressSanitizer: stack-buffer-overflow
43+
// X01: [01]
44+
case 0x01:
45+
return __asan_set_shadow_01(addr, 1);
46+
// X02: AddressSanitizer: stack-buffer-overflow
47+
// X02: [02]
48+
case 0x02:
49+
return __asan_set_shadow_02(addr, 1);
50+
// X03: AddressSanitizer: stack-buffer-overflow
51+
// X03: [03]
52+
case 0x03:
53+
return __asan_set_shadow_03(addr, 1);
54+
// X04: AddressSanitizer: stack-buffer-overflow
55+
// X04: [04]
56+
case 0x04:
57+
return __asan_set_shadow_04(addr, 1);
58+
// X05: AddressSanitizer: stack-buffer-overflow
59+
// X05: [05]
60+
case 0x05:
61+
return __asan_set_shadow_05(addr, 1);
62+
// X06: AddressSanitizer: stack-buffer-overflow
63+
// X06: [06]
64+
case 0x06:
65+
return __asan_set_shadow_06(addr, 1);
66+
// X07: AddressSanitizer: stack-buffer-overflow
67+
// X07: [07]
68+
case 0x07:
69+
return __asan_set_shadow_07(addr, 1);
3570
// XF1: AddressSanitizer: stack-buffer-underflow
3671
// XF1: [f1]
3772
case 0xf1:

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2838,7 +2838,8 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) {
28382838
kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy);
28392839
}
28402840

2841-
for (size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) {
2841+
for (size_t Val : {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xf1, 0xf2,
2842+
0xf3, 0xf5, 0xf8}) {
28422843
std::ostringstream Name;
28432844
Name << kAsanSetShadowPrefix;
28442845
Name << std::setw(2) << std::setfill('0') << std::hex << Val;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
; RUN: opt < %s -passes=asan -asan-max-inline-poisoning-size=0 -asan-stack-dynamic-alloca=0 -S | FileCheck --check-prefix=OUTLINE %s
2+
; RUN: opt < %s -passes=asan -asan-max-inline-poisoning-size=999 -asan-stack-dynamic-alloca=0 -S | FileCheck --check-prefix=INLINE %s
3+
4+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5+
target triple = "arm64-apple-macosx13.0.0"
6+
7+
; Function Attrs: noinline nounwind optnone sanitize_address ssp uwtable(sync)
8+
define void @foo() #0 {
9+
entry:
10+
%array01 = alloca [1 x i8], align 1
11+
%array02 = alloca [2 x i8], align 1
12+
%array03 = alloca [3 x i8], align 1
13+
%array04 = alloca [4 x i8], align 1
14+
%array05 = alloca [5 x i8], align 1
15+
%array06 = alloca [6 x i8], align 1
16+
%array07 = alloca [7 x i8], align 1
17+
; OUTLINE: call void @__asan_set_shadow_f1(i64 %33, i64 4)
18+
; OUTLINE: call void @__asan_set_shadow_01(i64 %34, i64 1)
19+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %35, i64 1)
20+
; OUTLINE: call void @__asan_set_shadow_02(i64 %36, i64 1)
21+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %37, i64 1)
22+
; OUTLINE: call void @__asan_set_shadow_03(i64 %38, i64 1)
23+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %39, i64 1)
24+
; OUTLINE: call void @__asan_set_shadow_04(i64 %40, i64 1)
25+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %41, i64 1)
26+
; OUTLINE: call void @__asan_set_shadow_05(i64 %42, i64 1)
27+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %43, i64 3)
28+
; OUTLINE: call void @__asan_set_shadow_06(i64 %44, i64 1)
29+
; OUTLINE: call void @__asan_set_shadow_f2(i64 %45, i64 3)
30+
; OUTLINE: call void @__asan_set_shadow_07(i64 %46, i64 1)
31+
; OUTLINE: call void @__asan_set_shadow_f3(i64 %47, i64 3)
32+
; OUTLINE: call void @__asan_set_shadow_f5(i64 %134, i64 32)
33+
; OUTLINE: call void @__asan_set_shadow_00(i64 %140, i64 24)
34+
; INLINE: store i64 -1007977276409515535, ptr %34, align 1
35+
; INLINE: store i64 -940423264817843709, ptr %36, align 1
36+
; INLINE: store i64 -868083087686045178, ptr %38, align 1
37+
%arrayidx = getelementptr inbounds [1 x i8], ptr %array01, i64 0, i64 1
38+
store i8 1, ptr %arrayidx, align 1
39+
%arrayidx1 = getelementptr inbounds [2 x i8], ptr %array02, i64 0, i64 2
40+
store i8 2, ptr %arrayidx1, align 1
41+
%arrayidx2 = getelementptr inbounds [3 x i8], ptr %array03, i64 0, i64 3
42+
store i8 3, ptr %arrayidx2, align 1
43+
%arrayidx3 = getelementptr inbounds [4 x i8], ptr %array04, i64 0, i64 4
44+
store i8 4, ptr %arrayidx3, align 1
45+
%arrayidx4 = getelementptr inbounds [5 x i8], ptr %array05, i64 0, i64 5
46+
store i8 5, ptr %arrayidx4, align 1
47+
%arrayidx5 = getelementptr inbounds [6 x i8], ptr %array06, i64 0, i64 6
48+
store i8 6, ptr %arrayidx5, align 1
49+
%arrayidx6 = getelementptr inbounds [7 x i8], ptr %array07, i64 0, i64 7
50+
store i8 7, ptr %arrayidx6, align 1
51+
; CHECK-NOT: store i64 -723401728380766731, ptr %126, align 1
52+
ret void
53+
}
54+
attributes #0 = { noinline nounwind optnone sanitize_address ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
55+

0 commit comments

Comments
 (0)