Skip to content

Commit e0eee84

Browse files
TeemperorAlviseDeFaveri
authored andcommitted
[hw-fuzzing] Turn MSan into bit-precise DFSan
1 parent d3e1fef commit e0eee84

File tree

5 files changed

+89
-50
lines changed

5 files changed

+89
-50
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,24 @@ static void addSanitizers(const Triple &TargetTriple,
696696

697697
if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
698698
MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
699+
700+
// PHANTOM_TRAILS
701+
if (Level != OptimizationLevel::O0) {
702+
FunctionPassManager FPM = PB.buildFunctionSimplificationPipeline(Level,
703+
ThinOrFullLTOPhase::FullLTOPreLink);
704+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
705+
}
706+
// END PHANTOM_TRAILS
707+
}
708+
709+
if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
710+
// PHANTOM_TRAILS
711+
if (Level != OptimizationLevel::O0) {
712+
FunctionPassManager FPM = PB.buildFunctionSimplificationPipeline(Level,
713+
ThinOrFullLTOPhase::FullLTOPreLink);
714+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
715+
}
716+
// END
699717
}
700718
});
701719
}

compiler-rt/include/tainting.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef TAINTING_H
2+
#define TAINTING_H
3+
4+
#include <cstdint>
5+
#include <cstdio>
6+
#include <cstring>
7+
8+
class Tainting {
9+
__attribute__((no_sanitize("memory", "dataflow")))
10+
static char *toShadowAddr(void *ptr) {
11+
return (char *)((intptr_t)(ptr) ^ 0x500000000000);
12+
}
13+
14+
public:
15+
__attribute__((no_sanitize("memory", "dataflow")))
16+
static void taintPtr(void *ptr, unsigned size) {
17+
memset(toShadowAddr(ptr), 0xff, size);
18+
}
19+
20+
__attribute__((no_sanitize("memory", "dataflow")))
21+
static void untaintPtr(void *ptr, unsigned size) {
22+
memset(toShadowAddr(ptr), 0x0, size);
23+
}
24+
25+
__attribute__((no_sanitize("memory", "dataflow")))
26+
static void taintBits(uint8_t *byte, uint8_t lbl) {
27+
memset(toShadowAddr(byte), lbl, 1);
28+
}
29+
30+
[[nodiscard]]
31+
__attribute__((no_sanitize("memory", "dataflow")))
32+
static bool check(void *ptr, unsigned size) {
33+
char *addr = toShadowAddr(ptr);
34+
char *end = addr + size;
35+
for (; addr < end; ++addr) {
36+
if (*addr != 0)
37+
return true;
38+
}
39+
return false;
40+
}
41+
};
42+
43+
#endif // TAINTING_H

compiler-rt/lib/msan/msan_flags.inc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@
1818

1919
MSAN_FLAG(int, exit_code, -1,
2020
"DEPRECATED. Use exitcode from common flags instead.")
21-
MSAN_FLAG(int, origin_history_size, Origin::kMaxDepth, "")
22-
MSAN_FLAG(int, origin_history_per_stack_limit, 20000, "")
21+
MSAN_FLAG(int, origin_history_size, 0, "")
22+
MSAN_FLAG(int, origin_history_per_stack_limit, 0, "")
2323
MSAN_FLAG(bool, poison_heap_with_zeroes, false, "")
2424
MSAN_FLAG(bool, poison_stack_with_zeroes, false, "")
25-
MSAN_FLAG(bool, poison_in_malloc, true, "")
26-
MSAN_FLAG(bool, poison_in_free, true, "")
27-
MSAN_FLAG(bool, poison_in_dtor, true, "")
28-
MSAN_FLAG(bool, report_umrs, true, "")
25+
MSAN_FLAG(bool, poison_in_malloc, false, "")
26+
MSAN_FLAG(bool, poison_in_free, false, "")
27+
MSAN_FLAG(bool, poison_in_dtor, false, "")
28+
MSAN_FLAG(bool, report_umrs, false, "")
2929
MSAN_FLAG(bool, wrap_signals, true, "")
3030
MSAN_FLAG(bool, print_stats, false, "")
31-
MSAN_FLAG(bool, halt_on_error, !&__msan_keep_going, "")
32-
MSAN_FLAG(bool, atexit, false, "")
33-
MSAN_FLAG(int, store_context_size, 20,
31+
MSAN_FLAG(bool, halt_on_error, false, "")
32+
MSAN_FLAG(bool, atexit, true, "")
33+
MSAN_FLAG(int, store_context_size, 0,
3434
"Like malloc_context_size, but for uninit stores.")

llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1541,7 +1541,9 @@ bool DataFlowSanitizer::runImpl(Module &M) {
15411541
// DFSanVisitor may delete Inst, so keep track of whether it was a
15421542
// terminator.
15431543
bool IsTerminator = Inst->isTerminator();
1544-
if (!DFSF.SkipInsts.count(Inst))
1544+
1545+
if (!DFSF.SkipInsts.count(Inst) &&
1546+
!Inst->hasMetadata(LLVMContext::MD_nosanitize))
15451547
DFSanVisitor(DFSF).visit(Inst);
15461548
if (IsTerminator)
15471549
break;

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ static cl::opt<bool> ClKeepGoing("msan-keep-going",
227227

228228
static cl::opt<bool> ClPoisonStack("msan-poison-stack",
229229
cl::desc("poison uninitialized stack variables"),
230-
cl::Hidden, cl::init(true));
230+
cl::Hidden, cl::init(false));
231231

232232
static cl::opt<bool> ClPoisonStackWithCall("msan-poison-stack-with-call",
233233
cl::desc("poison uninitialized stack variables with a call"),
@@ -239,7 +239,7 @@ static cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern",
239239

240240
static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
241241
cl::desc("poison undef temps"),
242-
cl::Hidden, cl::init(true));
242+
cl::Hidden, cl::init(false));
243243

244244
static cl::opt<bool> ClHandleICmp("msan-handle-icmp",
245245
cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
@@ -279,7 +279,7 @@ static cl::opt<bool> ClHandleAsmConservative(
279279
// be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
280280
static cl::opt<bool> ClCheckAccessAddress("msan-check-access-address",
281281
cl::desc("report accesses through a pointer which has poisoned shadow"),
282-
cl::Hidden, cl::init(true));
282+
cl::Hidden, cl::init(false));
283283

284284
static cl::opt<bool> ClEagerChecks(
285285
"msan-eager-checks",
@@ -650,10 +650,10 @@ template <class T> T getOptOrDefault(const cl::opt<T> &Opt, T Default) {
650650

651651
MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K,
652652
bool EagerChecks)
653-
: Kernel(getOptOrDefault(ClEnableKmsan, K)),
654-
TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)),
655-
Recover(getOptOrDefault(ClKeepGoing, Kernel || R)),
656-
EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {}
653+
: Kernel(false), // BFSAN: Overwrite defaults.
654+
TrackOrigins(false),
655+
Recover(true),
656+
EagerChecks(false) {}
657657

658658
PreservedAnalyses MemorySanitizerPass::run(Function &F,
659659
FunctionAnalysisManager &FAM) {
@@ -1208,6 +1208,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
12081208

12091209
/// Helper function to insert a warning at IRB's current insert point.
12101210
void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1211+
return; // BFSAN: Ignore taint checks.
1212+
12111213
if (!Origin)
12121214
Origin = (Value *)IRB.getInt32(0);
12131215
assert(Origin->getType()->isIntegerTy());
@@ -1791,6 +1793,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
17911793
/// This location will be later instrumented with a check that will print a
17921794
/// UMR warning in runtime if the value is not fully defined.
17931795
void insertShadowCheck(Value *Val, Instruction *OrigIns) {
1796+
return; // BFSAN: Disable checks
1797+
17941798
assert(Val);
17951799
Value *Shadow, *Origin;
17961800
if (ClCheckConstantShadow) {
@@ -2323,37 +2327,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
23232327
/// Sometimes the comparison result is known even if some of the bits of the
23242328
/// arguments are not.
23252329
void handleEqualityComparison(ICmpInst &I) {
2326-
IRBuilder<> IRB(&I);
2327-
Value *A = I.getOperand(0);
2328-
Value *B = I.getOperand(1);
2329-
Value *Sa = getShadow(A);
2330-
Value *Sb = getShadow(B);
2331-
2332-
// Get rid of pointers and vectors of pointers.
2333-
// For ints (and vectors of ints), types of A and Sa match,
2334-
// and this is a no-op.
2335-
A = IRB.CreatePointerCast(A, Sa->getType());
2336-
B = IRB.CreatePointerCast(B, Sb->getType());
2337-
2338-
// A == B <==> (C = A^B) == 0
2339-
// A != B <==> (C = A^B) != 0
2340-
// Sc = Sa | Sb
2341-
Value *C = IRB.CreateXor(A, B);
2342-
Value *Sc = IRB.CreateOr(Sa, Sb);
2343-
// Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2344-
// Result is defined if one of the following is true
2345-
// * there is a defined 1 bit in C
2346-
// * C is fully defined
2347-
// Si = !(C & ~Sc) && Sc
2348-
Value *Zero = Constant::getNullValue(Sc->getType());
2349-
Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2350-
Value *Si =
2351-
IRB.CreateAnd(IRB.CreateICmpNE(Sc, Zero),
2352-
IRB.CreateICmpEQ(
2353-
IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero));
2354-
Si->setName("_msprop_icmp");
2355-
setShadow(&I, Si);
2356-
setOriginForNaryOp(I);
2330+
setShadow(&I, getCleanShadow(&I));
2331+
setOrigin(&I, getCleanOrigin());
23572332
}
23582333

23592334
/// Build the lowest possible value of V, taking into account V's
@@ -3970,7 +3945,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
39703945
Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
39713946
}
39723947
Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
3973-
setShadow(&I, Sa);
3948+
setShadow(&I, Sa0); // BFSAN: Avoid checking condition taint.
39743949
if (MS.TrackOrigins) {
39753950
// Origins are always i32, so any vector conditions must be flattened.
39763951
// FIXME: consider tracking vector origins for app vectors?
@@ -4008,7 +3983,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
40083983
}
40093984

40103985
void visitGetElementPtrInst(GetElementPtrInst &I) {
4011-
handleShadowOr(I);
3986+
setShadow(&I, getCleanShadow(&I));
3987+
setOrigin(&I, getCleanOrigin());
40123988
}
40133989

40143990
void visitExtractValueInst(ExtractValueInst &I) {

0 commit comments

Comments
 (0)