Skip to content

Commit 3016056

Browse files
committed
[asan] Change the way we report the alloca frame on stack-buff-overflow.
Before: the function name was stored by the compiler as a constant string and the run-time was printing it. Now: the PC is stored instead and the run-time prints the full symbolized frame. This adds a couple of instructions into every function with non-empty stack frame, but also reduces the binary size because we store less strings (I saw 2% size reduction). This change bumps the asan ABI version to v3. llvm part. Example of report (now): ==31711==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffa77cf1c5 at pc 0x41feb0 bp 0x7fffa77cefb0 sp 0x7fffa77cefa8 READ of size 1 at 0x7fffa77cf1c5 thread T0 #0 0x41feaf in Frame0(int, char*, char*, char*) stack-oob-frames.cc:20 #1 0x41f7ff in Frame1(int, char*, char*) stack-oob-frames.cc:24 #2 0x41f477 in Frame2(int, char*) stack-oob-frames.cc:28 #3 0x41f194 in Frame3(int) stack-oob-frames.cc:32 #4 0x41eee0 in main stack-oob-frames.cc:38 #5 0x7f0c5566f76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c) #6 0x41eb1c (/usr/local/google/kcc/llvm_cmake/a.out+0x41eb1c) Address 0x7fffa77cf1c5 is located in stack of thread T0 at offset 293 in frame #0 0x41f87f in Frame0(int, char*, char*, char*) stack-oob-frames.cc:12 <<<<<<<<<<<<<< this is new This frame has 6 object(s): [32, 36) 'frame.addr' [96, 104) 'a.addr' [160, 168) 'b.addr' [224, 232) 'c.addr' [288, 292) 's' [352, 360) 'd' git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177724 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent aa2bece commit 3016056

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static const char *kAsanRegisterGlobalsName = "__asan_register_globals";
7171
static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals";
7272
static const char *kAsanPoisonGlobalsName = "__asan_before_dynamic_init";
7373
static const char *kAsanUnpoisonGlobalsName = "__asan_after_dynamic_init";
74-
static const char *kAsanInitName = "__asan_init_v2";
74+
static const char *kAsanInitName = "__asan_init_v3";
7575
static const char *kAsanHandleNoReturnName = "__asan_handle_no_return";
7676
static const char *kAsanMappingOffsetName = "__asan_mapping_offset";
7777
static const char *kAsanMappingScaleName = "__asan_mapping_scale";
@@ -1317,10 +1317,10 @@ void FunctionStackPoisoner::poisonStack() {
13171317
ConstantInt::get(IntptrTy, LocalStackSize), OrigStackBase);
13181318
}
13191319

1320-
// This string will be parsed by the run-time (DescribeStackAddress).
1320+
// This string will be parsed by the run-time (DescribeAddressIfStack).
13211321
SmallString<2048> StackDescriptionStorage;
13221322
raw_svector_ostream StackDescription(StackDescriptionStorage);
1323-
StackDescription << F.getName() << " " << AllocaVec.size() << " ";
1323+
StackDescription << AllocaVec.size() << " ";
13241324

13251325
// Insert poison calls for lifetime intrinsics for alloca.
13261326
bool HavePoisonedAllocas = false;
@@ -1353,19 +1353,26 @@ void FunctionStackPoisoner::poisonStack() {
13531353
}
13541354
assert(Pos == LocalStackSize);
13551355

1356-
// Write the Magic value and the frame description constant to the redzone.
1356+
// The left-most redzone has enough space for at least 4 pointers.
1357+
// Write the Magic value to redzone[0].
13571358
Value *BasePlus0 = IRB.CreateIntToPtr(LocalStackBase, IntptrPtrTy);
13581359
IRB.CreateStore(ConstantInt::get(IntptrTy, kCurrentStackFrameMagic),
13591360
BasePlus0);
1360-
Value *BasePlus1 = IRB.CreateAdd(LocalStackBase,
1361-
ConstantInt::get(IntptrTy,
1362-
ASan.LongSize/8));
1363-
BasePlus1 = IRB.CreateIntToPtr(BasePlus1, IntptrPtrTy);
1361+
// Write the frame description constant to redzone[1].
1362+
Value *BasePlus1 = IRB.CreateIntToPtr(
1363+
IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, ASan.LongSize/8)),
1364+
IntptrPtrTy);
13641365
GlobalVariable *StackDescriptionGlobal =
13651366
createPrivateGlobalForString(*F.getParent(), StackDescription.str());
13661367
Value *Description = IRB.CreatePointerCast(StackDescriptionGlobal,
13671368
IntptrTy);
13681369
IRB.CreateStore(Description, BasePlus1);
1370+
// Write the PC to redzone[2].
1371+
Value *BasePlus2 = IRB.CreateIntToPtr(
1372+
IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy,
1373+
2 * ASan.LongSize/8)),
1374+
IntptrPtrTy);
1375+
IRB.CreateStore(IRB.CreatePointerCast(&F, IntptrTy), BasePlus2);
13691376

13701377
// Poison the stack redzones at the entry.
13711378
Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB);

0 commit comments

Comments
 (0)