[ASan] Add metadata to renamed instructions so ASan doesn't use the i… (#119387)

…ncorrect name

Clang needs variables to be represented with unique names. This means
that if a variable shadows another, its given a different name
internally to ensure it has a unique name. If ASan tries to use this
name when printing an error, it will print the modified unique name,
rather than the variable's source code name

Fixes #47326
This commit is contained in:
gbMattN
2025-04-03 15:27:14 +01:00
committed by GitHub
parent b61e3874fa
commit 59074a3760
4 changed files with 41 additions and 2 deletions

View File

@@ -143,6 +143,9 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
Alloca =
new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
ArraySize, Name, AllocaInsertPt->getIterator());
if (SanOpts.Mask & SanitizerKind::Address) {
Alloca->addAnnotationMetadata({"alloca_name_altered", Name.str()});
}
if (Allocas) {
Allocas->Add(Alloca);
}

View File

@@ -0,0 +1,12 @@
// RUN: %clangxx_asan -O0 %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
int main() {
int x;
{
int x;
delete &x;
}
}
// CHECK: [32, 36) 'x'

View File

@@ -27,5 +27,5 @@ int main(int argc, char *argv[]) {
// CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset [[OFFSET:[^ ]*]] in frame
// CHECK: {{.*}} in main
// CHECK: This frame has
// CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i' (line [[@LINE-15]])
// CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x' (line [[@LINE-15]])
}

View File

@@ -3437,6 +3437,29 @@ static void findStoresToUninstrumentedArgAllocas(
}
}
static StringRef getAllocaName(AllocaInst *AI) {
// Alloca could have been renamed for uniqueness. Its true name will have been
// recorded as an annotation.
if (AI->hasMetadata(LLVMContext::MD_annotation)) {
MDTuple *AllocaAnnotations =
cast<MDTuple>(AI->getMetadata(LLVMContext::MD_annotation));
for (auto &Annotation : AllocaAnnotations->operands()) {
if (!isa<MDTuple>(Annotation))
continue;
auto AnnotationTuple = cast<MDTuple>(Annotation);
for (int Index = 0; Index < AnnotationTuple->getNumOperands(); Index++) {
// All annotations are strings
auto MetadataString =
cast<MDString>(AnnotationTuple->getOperand(Index));
if (MetadataString->getString() == "alloca_name_altered")
return cast<MDString>(AnnotationTuple->getOperand(Index + 1))
->getString();
}
}
}
return AI->getName();
}
void FunctionStackPoisoner::processStaticAllocas() {
if (AllocaVec.empty()) {
assert(StaticAllocaPoisonCallVec.empty());
@@ -3477,7 +3500,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
SmallVector<ASanStackVariableDescription, 16> SVD;
SVD.reserve(AllocaVec.size());
for (AllocaInst *AI : AllocaVec) {
ASanStackVariableDescription D = {AI->getName().data(),
StringRef Name = getAllocaName(AI);
ASanStackVariableDescription D = {Name.data(),
ASan.getAllocaSizeInBytes(*AI),
0,
AI->getAlign().value(),