Skip to content

Commit

Permalink
[TA] Handle global variables as Src operand (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
niktesic authored Feb 10, 2023
1 parent 93a431b commit 3c54c76
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class TaintAnalysis {
void resetTaintList(SmallVectorImpl<TaintInfo> &TL);
void mergeTaintList(SmallVectorImpl<TaintInfo> &Dest_TL,
SmallVectorImpl<TaintInfo> &Src_TL);
bool handleGlobalVar(TaintInfo &Ti);
bool propagateTaint(DestSourcePair &DS, SmallVectorImpl<TaintInfo> &TL,
const MachineInstr &MI, TaintDataFlowGraph &TaintDFG,
RegisterEquivalence &REAnalysis,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class Decompiler {
SmallVector<long, 8> FunctionsThatAreNotInBT;

lldb::SBTarget *DecTarget = nullptr;
lldb::SBModule *DecModule = nullptr;

// Store debug info compile units for coresponding files.
std::unordered_map<std::string, std::pair<DIFile *, DICompileUnit *>> CUs;
Expand Down Expand Up @@ -148,6 +149,9 @@ class Decompiler {
void setTarget(lldb::SBTarget *T) { DecTarget = T; }
lldb::SBTarget *getTarget() { return DecTarget; }

void setSBModule(lldb::SBModule *M) { DecModule = M; }
lldb::SBModule *getSBModule() { return DecModule; }

class Module &getModule() {
return *Module.get();
}
Expand Down
62 changes: 62 additions & 0 deletions llvm-15.0.3/llvm-crash-analyzer/lib/Analysis/TaintAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,62 @@ void crash_analyzer::TaintAnalysis::insertTaint(
printTaintList(TL);
}

// Check if Ti represents a global variable and convert Ti into expected form.
// Expected form is $noreg plus offset, which is the global variable symbol
// address.
bool crash_analyzer::TaintAnalysis::handleGlobalVar(TaintInfo &Ti) {

if (!Dec)
return false;

auto LLDBModule = Dec->getSBModule();
if (!LLDBModule)
return false;

if (!Ti.Op)
return false;

Optional<int64_t> ImmVal = llvm::None;
// Get symbol address from Ti ({reg:$noreg; off:ADDR}).
if (Ti.Op->isReg() && Ti.Op->getReg() == 0 && Ti.Offset)
ImmVal = *Ti.Offset;

// Get symbol address from Ti ({imm:ADDR}).
if (Ti.Op->isImm())
ImmVal = Ti.Op->getImm();

if (!ImmVal)
return false;

if (*ImmVal < 0)
return false;

uint64_t VarAddr = static_cast<uint64_t>(*ImmVal);

// Search symbols for global var with the matching address.
int NumSym = static_cast<int>(LLDBModule->GetNumSymbols());
for (int i = 0; i < NumSym; i++) {
auto SBSym = LLDBModule->GetSymbolAtIndex(i);
auto SymAddr = SBSym.GetStartAddress().GetLoadAddress(*Dec->getTarget());
// Check symbol address and if it is a global variable.
if (SymAddr == VarAddr &&
Dec->getTarget()->FindFirstGlobalVariable(SBSym.GetName())) {
LLVM_DEBUG(dbgs() << "Handle global variable \"" << SBSym.GetName()
<< "\"\n");
// Convert Ti from {imm:ADDR} to {reg:$noreg; off:ADDR}.
if (Ti.Op->isImm()) {
Ti.Offset = VarAddr;
MachineOperand *MO2 = new MachineOperand(*Ti.Op);
MO2->ChangeToRegister(0, false);
Ti.Op = MO2;
LLVM_DEBUG(dbgs() << "Update Taint Info to " << Ti << "\n");
}
return true;
}
}
return false;
}

void crash_analyzer::TaintAnalysis::startTaint(
DestSourcePair &DS, SmallVectorImpl<TaintInfo> &TL, const MachineInstr &MI,
TaintDataFlowGraph &TaintDFG, RegisterEquivalence &REAnalysis) {
Expand Down Expand Up @@ -687,6 +743,8 @@ bool llvm::crash_analyzer::TaintAnalysis::propagateTaint(
if (SrcTi.Offset)
calculateMemAddr(SrcTi);

bool SrcGlobalVar = handleGlobalVar(SrcTi);

Src2Ti.Op = DS.Source2;
Src2Ti.Offset = DS.Src2Offset;
if (Src2Ti.Offset)
Expand Down Expand Up @@ -750,6 +808,10 @@ bool llvm::crash_analyzer::TaintAnalysis::propagateTaint(
SrcTi = ZeroTi;
ConstantFound = true;
}
// Immediate operand, which is a symbol address for the global variable,
// should not be treated as a constant.
if (SrcGlobalVar)
ConstantFound = false;

// FIXME: Since now we have corefile content we can check if this constant
// is the same from the crash point, and by doing that we avoid FALSE
Expand Down
6 changes: 6 additions & 0 deletions llvm-15.0.3/llvm-crash-analyzer/llvm-crash-analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ int main(int argc, char **argv) {
crash_analyzer::TaintAnalysis TA(TaintDotFileName, MirDotFileName,
PrintPotentialCrashCauseLocation);
Dec->setTarget(&coreFile.getTarget());

// Set SBModule for Decompiler, so we can access the symbol table.
auto FileSpec = lldb::SBFileSpec(InputFilename.c_str());
auto LLDBModule = coreFile.getTarget().FindModule(FileSpec);
Dec->setSBModule(new lldb::SBModule(LLDBModule));

TA.setDecompiler(Dec);
TA.runOnBlameModule(BlameTrace);

Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
##include <stdio.h>
## typedef struct node {
## int *fn;
## } T;
##
## T p;
## T q2;
## void h(int *r) {
## *r = 0; // crash
## }
##
## void g (T*q) {
## int *t = q->fn;
## h(t);
## }
##
## void f() {
## p.fn = NULL; // blame point - line 18
## q2.fn = NULL;
## g(&p);
## }
##
## int main() {
## f();
## return 0;
## }


# RUN: %llvm-crash-analyzer --core-file=%S/Inputs/core.global-var-immediate \
# RUN: %S/Inputs/global-var-immediate.out --print-potential-crash-cause-loc < %s 2>&1 | FileCheck %s

# CHECK: Blame Function is f
# CHECK-NOT: From File {{.*}}/m.c:18:8

0 comments on commit 3c54c76

Please sign in to comment.