Skip to content

Commit e8b23d5

Browse files
committed
[asan][x86] Abort instrumenting memintrinsics that target fs, gs to prevent miscompilation (#124238)
1 parent db4dd33 commit e8b23d5

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ struct AddressSanitizer {
797797
bool IsWrite, size_t AccessSizeIndex,
798798
Value *SizeArgument, uint32_t Exp,
799799
RuntimeCallInserter &RTCI);
800+
bool maybeIgnoreMemIntrinsic (MemIntrinsic *MI, const Triple &TargetTriple);
800801
void instrumentMemIntrinsic(MemIntrinsic *MI, RuntimeCallInserter &RTCI);
801802
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
802803
bool suppressInstrumentationSiteForDebug(int &Instrumented);
@@ -1340,10 +1341,21 @@ Value *AddressSanitizer::memToShadow(Value *Shadow, IRBuilder<> &IRB) {
13401341
return IRB.CreateAdd(Shadow, ShadowBase);
13411342
}
13421343

1344+
bool AddressSanitizer::maybeIgnoreMemIntrinsic (MemIntrinsic *MI, const Triple &TargetTriple)
1345+
{
1346+
// Ignore FS and GS registers to prevent miscompilation
1347+
if (MI->getDestAddressSpace() >= 256
1348+
&& TargetTriple.getArch() == Triple::x86_64)
1349+
return true;
1350+
return false;
1351+
}
1352+
13431353
// Instrument memset/memmove/memcpy
13441354
void AddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI,
13451355
RuntimeCallInserter &RTCI) {
13461356
InstrumentationIRBuilder IRB(MI);
1357+
if (maybeIgnoreMemIntrinsic(MI, TargetTriple))
1358+
return;
13471359
if (isa<MemTransferInst>(MI)) {
13481360
RTCI.createRuntimeCall(
13491361
IRB, isa<MemMoveInst>(MI) ? AsanMemmove : AsanMemcpy,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; RUN: opt -passes=asan %s -S | FileCheck %s
2+
3+
;; Punt AddressSanitizer::instrumentMemIntrinsics out for MemIntrinsics
4+
;; that need write to unsupported registers on X86
5+
;; PR124238: https://www.github.com/llvm/llvm-project/issues/124238
6+
7+
target triple = "x86_64-unknown-linux-gnu"
8+
9+
$.str.658906a285b7a0f82dabd9915e07848c = comdat any
10+
@.str = internal constant { [2 x i8], [30 x i8] } { [2 x i8] c"x\00", [30 x i8] zeroinitializer }, comdat($.str.658906a285b7a0f82dabd9915e07848c), align 32
11+
@0 = private alias { [2 x i8], [30 x i8] }, ptr @.str
12+
13+
define void @test_memcpy(i64 noundef %addr) sanitize_address #0 {
14+
entry:
15+
%addr.addr = alloca i64, align 8
16+
store i64 %addr, ptr %addr.addr, align 8
17+
%0 = load i64, ptr %addr.addr, align 8
18+
%1 = inttoptr i64 %0 to ptr addrspace(257)
19+
call void @llvm.memcpy.p257.p0.i64(ptr addrspace(257) align 1 %1, ptr align 1 @.str, i64 1, i1 false)
20+
; CHECK: llvm.memcpy
21+
%2 = load i64, ptr %addr.addr, align 8
22+
%3 = inttoptr i64 %2 to ptr addrspace(256)
23+
call void @llvm.memcpy.p256.p0.i64(ptr addrspace(256) align 1 %3, ptr align 1 @.str, i64 1, i1 false)
24+
; CHECK: llvm.memcpy
25+
ret void
26+
}
27+
28+
define void @test_memset(i64 noundef %addr) sanitize_address #0 {
29+
entry:
30+
%addr.addr = alloca i64, align 8
31+
store i64 %addr, ptr %addr.addr, align 8
32+
%0 = load i64, ptr %addr.addr, align 8
33+
%1 = inttoptr i64 %0 to ptr addrspace(257)
34+
call void @llvm.memset.p257.i64(ptr addrspace(257) align 1 %1, i8 0, i64 1, i1 false)
35+
; CHECK: llvm.memset
36+
%2 = load i64, ptr %addr.addr, align 8
37+
%3 = inttoptr i64 %2 to ptr addrspace(256)
38+
call void @llvm.memset.p256.i64(ptr addrspace(256) align 1 %3, i8 0, i64 1, i1 false)
39+
; CHECK: llvm.memset
40+
ret void
41+
}
42+
43+
define void @test_memmove(i64 noundef %addr) sanitize_address #0 {
44+
entry:
45+
%addr.addr = alloca i64, align 8
46+
store i64 %addr, ptr %addr.addr, align 8
47+
%0 = load i64, ptr %addr.addr, align 8
48+
%1 = inttoptr i64 %0 to ptr addrspace(257)
49+
%2 = load i64, ptr %addr.addr, align 8
50+
%3 = inttoptr i64 %2 to ptr
51+
call void @llvm.memmove.p257.p0.i64(ptr addrspace(257) align 1 %1, ptr align 1 %3, i64 1, i1 false)
52+
; CHECK: llvm.memmove
53+
%4 = load i64, ptr %addr.addr, align 8
54+
%5 = inttoptr i64 %4 to ptr addrspace(256)
55+
%6 = load i64, ptr %addr.addr, align 8
56+
%7 = inttoptr i64 %6 to ptr
57+
call void @llvm.memmove.p256.p0.i64(ptr addrspace(256) align 1 %5, ptr align 1 %7, i64 1, i1 false)
58+
; CHECK: llvm.memmove
59+
ret void
60+
}

0 commit comments

Comments
 (0)