Skip to content

Commit 47eaebb

Browse files
committed
Change klee_get_taint_rule to klee_get_taint_hits, fix memory and some Pointer creations
1 parent 82252b5 commit 47eaebb

File tree

16 files changed

+161
-115
lines changed

16 files changed

+161
-115
lines changed

configs/annotations.json

+11
Original file line numberDiff line numberDiff line change
@@ -2326,5 +2326,16 @@
23262326
[]
23272327
],
23282328
"properties": []
2329+
},
2330+
"printf": {
2331+
"name": "printf",
2332+
"annotation": [
2333+
[],
2334+
[
2335+
"TaintSink::FormatString",
2336+
"TaintSink::SensitiveDataLeak"
2337+
]
2338+
],
2339+
"properties": []
23292340
}
23302341
}

include/klee/Core/MockBuilder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class MockBuilder {
5353
llvm::CallInst *buildCallKleeTaintFunction(const std::string &functionName,
5454
llvm::Value *source, size_t taint,
5555
llvm::Type *returnType);
56-
void buildCallKleeTaintHit(llvm::Value *taintRule);
56+
void buildCallKleeTaintHit(llvm::Value *taintHits, size_t taintSink);
5757

5858
void buildAnnotationTaintOutput(llvm::Value *elem,
5959
const Statement::Ptr &statement);

include/klee/Expr/Expr.h

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ class Expr {
396396
ref<ReadExpr> hasOrderedReads(bool stride) const;
397397
ref<ReadExpr> hasOrderedReads() const;
398398
ref<Expr> getValue() const;
399+
ref<Expr> getTaint() const;
399400

400401
/* Static utility methods */
401402

include/klee/klee.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,20 @@ void klee_clear_taint(void *array, size_t taint_source);
6161
*/
6262
bool klee_check_taint_source(void *array, size_t taint_source);
6363

64-
/* klee_get_taint_rule - Return taint rule id +1 if contents of the object pointer
65-
* to \arg addr causes a taint sink \arg taint_sink hit, else return 0.
64+
/* klee_get_taint_hits - Return taint hits if contents of the object pointer
65+
* to \arg addr causes a taint sink \arg taint_sink hit.
6666
*
6767
* \arg addr - The start of the object.
6868
* \arg taint_sink - Taint sink.
6969
*/
70-
uint64_t klee_get_taint_rule(void *array, size_t taint_sink);
70+
uint64_t klee_get_taint_hits(void *array, size_t taint_sink);
7171

72-
/* klee_taint_hit - Execute taint hit with rule.
72+
/* klee_taint_hit - Execute taint hits.
7373
*
74-
* \arg rule - Taint rule id.
74+
* \arg taint_hits - Actual taint hits.
75+
* \arg taint_sink - Taint sink.
7576
*/
76-
void klee_taint_hit(size_t rule);
77+
void klee_taint_hit(uint64_t taint_hits, size_t taint_sink);
7778

7879
/* klee_range - Construct a symbolic value in the signed interval
7980
* [begin,end).

lib/Core/Executor.cpp

+26-36
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,9 @@ Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
509509
annotationsData(opts.AnnotationsFile, opts.TaintAnnotationsFile),
510510
interpreterHandler(ih), searcher(nullptr),
511511
externalDispatcher(new ExternalDispatcher(ctx)), statsTracker(0),
512-
pathWriter(0), symPathWriter(0),
513-
specialFunctionHandler(0), timers{time::Span(TimerInterval)},
514-
guidanceKind(opts.Guidance), codeGraphInfo(new CodeGraphInfo()),
512+
pathWriter(0), symPathWriter(0), specialFunctionHandler(0),
513+
timers{time::Span(TimerInterval)}, guidanceKind(opts.Guidance),
514+
codeGraphInfo(new CodeGraphInfo()),
515515
distanceCalculator(new DistanceCalculator(*codeGraphInfo)),
516516
targetCalculator(new TargetCalculator(*codeGraphInfo)),
517517
targetManager(new TargetManager(guidanceKind, *distanceCalculator,
@@ -5028,17 +5028,21 @@ void Executor::terminateStateOnTargetError(ExecutionState &state,
50285028
}
50295029

50305030
void Executor::terminateStateOnTargetTaintError(ExecutionState &state,
5031-
uint64_t rule) {
5032-
if (rule >= annotationsData.taintAnnotation.rules.size()) {
5033-
terminateStateOnUserError(state, "Incorrect rule id");
5031+
uint64_t hits, size_t sink) {
5032+
std::string error = "Taint error:";
5033+
const auto &sinkData = annotationsData.taintAnnotation.hits.at(sink);
5034+
for (size_t source = 0; source < annotationsData.taintAnnotation.sources.size(); source++) {
5035+
if ((hits >> source) & 1u) {
5036+
error += " " + annotationsData.taintAnnotation.rules[sinkData.at(source)];
5037+
}
50345038
}
50355039

5036-
const std::string &ruleStr = annotationsData.taintAnnotation.rules[rule];
50375040
reportStateOnTargetError(
5038-
state, ReachWithError(ReachWithErrorType::MaybeTaint, ruleStr));
5041+
state, ReachWithError(ReachWithErrorType::MaybeTaint, error));
50395042

5040-
terminateStateOnProgramError(state, ruleStr + " taint error",
5041-
StateTerminationType::Taint);
5043+
terminateStateOnProgramError(
5044+
state, new ErrorEvent(locationOf(state), StateTerminationType::Taint,
5045+
error));
50425046
}
50435047

50445048
void Executor::terminateStateOnError(ExecutionState &state,
@@ -5569,9 +5573,10 @@ void Executor::executeChangeTaintSource(ExecutionState &state,
55695573

55705574
ObjectState *wos = it->second->addressSpace.getWriteable(mo, os.get());
55715575
if (wos->readOnly) {
5572-
terminateStateOnProgramError(*(it->second),
5573-
"memory error: object read only",
5574-
StateTerminationType::ReadOnly);
5576+
terminateStateOnProgramError(
5577+
*(it->second), new ErrorEvent(locationOf(*(it->second)),
5578+
StateTerminationType::ReadOnly,
5579+
"memory error: object read only"));
55755580
} else {
55765581
wos->updateTaint(Expr::createTaintBySource(source), isAdd);
55775582
}
@@ -5613,11 +5618,11 @@ void Executor::executeCheckTaintSource(ExecutionState &state,
56135618
}
56145619
}
56155620

5616-
void Executor::executeGetTaintRule(ExecutionState &state,
5621+
void Executor::executeGetTaintHits(ExecutionState &state,
56175622
klee::KInstruction *target,
56185623
ref<PointerExpr> address, uint64_t sink) {
56195624
const auto &hitsBySink = annotationsData.taintAnnotation.hits[sink];
5620-
ref<Expr> hitsBySinkTaint = Expr::createEmptyTaint();
5625+
ref<ConstantExpr> hitsBySinkTaint = Expr::createEmptyTaint();
56215626
for (const auto [source, rule] : hitsBySink) {
56225627
hitsBySinkTaint =
56235628
OrExpr::create(hitsBySinkTaint, Expr::createTaintBySource(source));
@@ -5637,7 +5642,7 @@ void Executor::executeGetTaintRule(ExecutionState &state,
56375642
if (zeroPointer.second) {
56385643
ExactResolutionList rl;
56395644
resolveExact(*zeroPointer.second, address,
5640-
typeSystemManager->getUnknownType(), rl, "getTaintRule");
5645+
typeSystemManager->getUnknownType(), rl, "getTaintHits");
56415646

56425647
for (Executor::ExactResolutionList::iterator it = rl.begin(), ie = rl.end();
56435648
it != ie; ++it) {
@@ -5647,35 +5652,20 @@ void Executor::executeGetTaintRule(ExecutionState &state,
56475652
ref<const ObjectState> os = op.second;
56485653

56495654
ref<Expr> hits = AndExpr::create(os->readTaint(), hitsBySinkTaint);
5650-
5651-
auto curState = it->second;
5652-
for (size_t source = 0;
5653-
source < annotationsData.taintAnnotation.sources.size(); source++) {
5654-
ref<Expr> taintSource = ExtractExpr::create(hits, source, Expr::Bool);
5655-
StatePair taintSourceStates =
5656-
forkInternal(*curState, taintSource, BranchType::Taint);
5657-
if (taintSourceStates.first) {
5658-
bindLocal(target, *taintSourceStates.first,
5659-
ConstantExpr::create(hitsBySink.at(source) + 1,
5660-
Expr::Int64)); // return (rule + 1)
5661-
}
5662-
if (taintSourceStates.second) {
5663-
curState = taintSourceStates.second;
5664-
}
5665-
}
5666-
bindLocal(target, *curState, ConstantExpr::create(0, Expr::Int64));
5655+
bindLocal(target, *it->second, hits);
56675656
}
56685657
}
56695658
}
56705659

56715660
bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
56725661
KType *type, ExactResolutionList &results,
56735662
const std::string &name) {
5674-
ref<PointerExpr> pointer =
5675-
PointerExpr::create(address->getValue(), address->getValue());
5663+
ref<PointerExpr> pointer = PointerExpr::create(
5664+
address->getValue(), address->getValue(), address->getTaint());
56765665
address = pointer->getValue();
56775666
ref<Expr> base = pointer->getBase();
5678-
ref<PointerExpr> basePointer = PointerExpr::create(base, base);
5667+
ref<PointerExpr> basePointer =
5668+
PointerExpr::create(base, base, address->getTaint());
56795669
ref<Expr> zeroPointer = PointerExpr::create(Expr::createPointer(0));
56805670

56815671
if (SimplifySymIndices) {

lib/Core/Executor.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class Executor : public Interpreter {
370370
klee::KInstruction *target,
371371
ref<PointerExpr> address, uint64_t source);
372372

373-
void executeGetTaintRule(ExecutionState &state, klee::KInstruction *target,
373+
void executeGetTaintHits(ExecutionState &state, klee::KInstruction *target,
374374
ref<PointerExpr> address, uint64_t sink);
375375

376376
/// Serialize a landingpad instruction so it can be handled by the
@@ -646,7 +646,8 @@ class Executor : public Interpreter {
646646
/// Then just call `terminateStateOnError`
647647
void terminateStateOnTargetError(ExecutionState &state, ReachWithError error);
648648

649-
void terminateStateOnTargetTaintError(ExecutionState &state, uint64_t rule);
649+
void terminateStateOnTargetTaintError(ExecutionState &state, uint64_t hits,
650+
size_t sink);
650651

651652
/// Call error handler and terminate state in case of program errors
652653
/// (e.g. free()ing globals, out-of-bound accesses)

lib/Core/Memory.cpp

+49-16
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ DISABLE_WARNING_POP
4141
#include <cstddef>
4242
#include <functional>
4343
#include <sstream>
44+
#include <utility>
4445

4546
namespace klee {
4647
llvm::cl::opt<MemoryType> MemoryBackend(
@@ -111,11 +112,10 @@ ObjectState::ObjectState(const MemoryObject *mo, const Array *array, KType *dt,
111112
: copyOnWriteOwner(0), object(mo), valueOS(ObjectStage(array, nullptr)),
112113
baseOS(ObjectStage(array->size, Expr::createPointer(0), false,
113114
Context::get().getPointerWidth())),
114-
taintOS(
115-
ObjectStage(array->size, defaultTaintValue, false, Expr::TaintWidth)),
115+
taintOS(ObjectStage(array->size, std::move(defaultTaintValue), false,
116+
Expr::TaintWidth)),
116117
lastUpdate(nullptr), size(array->size), dynamicType(dt), readOnly(false) {
117118
baseOS.initializeToZero();
118-
taintOS.initializeToZero();
119119
}
120120

121121
ObjectState::ObjectState(const MemoryObject *mo, KType *dt,
@@ -124,12 +124,11 @@ ObjectState::ObjectState(const MemoryObject *mo, KType *dt,
124124
valueOS(ObjectStage(mo->getSizeExpr(), nullptr)),
125125
baseOS(ObjectStage(mo->getSizeExpr(), Expr::createPointer(0), false,
126126
Context::get().getPointerWidth())),
127-
taintOS(ObjectStage(mo->getSizeExpr(), defaultTaintValue, false,
128-
Expr::TaintWidth)),
127+
taintOS(ObjectStage(mo->getSizeExpr(), std::move(defaultTaintValue),
128+
false, Expr::TaintWidth)),
129129
lastUpdate(nullptr), size(mo->getSizeExpr()), dynamicType(dt),
130130
readOnly(false) {
131131
baseOS.initializeToZero();
132-
taintOS.initializeToZero();
133132
}
134133

135134
ObjectState::ObjectState(const ObjectState &os)
@@ -254,8 +253,7 @@ ref<Expr> ObjectState::readTaint8(ref<Expr> offset) const {
254253
dyn_cast<ConstantExpr>(object->getSizeExpr())) {
255254
auto moSize = sizeExpr->getZExtValue();
256255
if (object && moSize > 4096) {
257-
std::string allocInfo;
258-
object->getAllocInfo(allocInfo);
256+
std::string allocInfo = object->getAllocInfo();
259257
klee_warning_once(nullptr,
260258
"Symbolic memory access will send the following "
261259
"array of %lu bytes to "
@@ -832,17 +830,29 @@ void ObjectStage::reset(ref<Expr> updateForDefault, bool isAdd) {
832830
}
833831

834832
ref<Expr> ObjectStage::combineAll() const {
835-
ref<Expr> result = knownSymbolics->defaultV();
833+
ref<Expr> result = Expr::createEmptyTaint();
834+
if (knownSymbolics->defaultV()) {
835+
result = knownSymbolics->defaultV();
836+
}
836837
for (auto [index, value] : knownSymbolics->storage()) {
837838
result = OrExpr::create(result, value);
838839
}
840+
if (updates.root) {
841+
if (ref<ConstantSource> constantSource =
842+
cast<ConstantSource>(updates.root->source)) {
843+
for (const auto &[index, value] :
844+
constantSource->constantValues->storage()) {
845+
result = OrExpr::create(result, value);
846+
}
847+
}
848+
}
839849
for (const auto *un = updates.head.get(); un; un = un->next.get()) {
840850
result = OrExpr::create(result, un->value);
841851
}
842852
return result;
843853
}
844854

845-
void ObjectStage::updateAll(ref<Expr> updateExpr, bool isAdd) {
855+
void ObjectStage::updateAll(const ref<ConstantExpr> &updateExpr, bool isAdd) {
846856
std::vector<std::pair<size_t, ref<Expr>>> newKnownSymbolics;
847857
for (auto [index, value] : knownSymbolics->storage()) {
848858
ref<Expr> newValue =
@@ -851,11 +861,13 @@ void ObjectStage::updateAll(ref<Expr> updateExpr, bool isAdd) {
851861
newKnownSymbolics.emplace_back(index, value);
852862
}
853863

854-
ref<Expr> oldDefault = knownSymbolics->defaultV();
855-
ref<Expr> newDefault =
856-
isAdd ? OrExpr::create(oldDefault, updateExpr)
857-
: AndExpr::create(oldDefault, NotExpr::create(updateExpr));
858-
knownSymbolics->reset(std::move(newDefault));
864+
if (knownSymbolics->defaultV()) {
865+
ref<Expr> oldDefault = knownSymbolics->defaultV();
866+
ref<Expr> newDefault =
867+
isAdd ? OrExpr::create(oldDefault, updateExpr)
868+
: AndExpr::create(oldDefault, NotExpr::create(updateExpr));
869+
knownSymbolics->reset(std::move(newDefault));
870+
}
859871

860872
for (auto [index, value] : newKnownSymbolics) {
861873
knownSymbolics->store(index, value);
@@ -868,7 +880,28 @@ void ObjectStage::updateAll(ref<Expr> updateExpr, bool isAdd) {
868880
: AndExpr::create(un->value, NotExpr::create(updateExpr));
869881
newUpdates.emplace_back(un->index, newValue);
870882
}
871-
updates = UpdateList(nullptr, nullptr);
883+
884+
const Array *array = nullptr;
885+
if (updates.root) {
886+
if (ref<ConstantSource> constantSource =
887+
cast<ConstantSource>(updates.root->source)) {
888+
SparseStorage<ref<ConstantExpr>> *newStorage = constructStorage(
889+
size, ConstantExpr::create(0, width), MaxFixedSizeStructureSize);
890+
891+
for (const auto &[index, value] :
892+
constantSource->constantValues->storage()) {
893+
ref<ConstantExpr> newValue =
894+
isAdd ? OrExpr::create(value, updateExpr)
895+
: AndExpr::create(value, NotExpr::create(updateExpr));
896+
newStorage->store(index, newValue);
897+
}
898+
899+
array = Array::create(size, SourceBuilder::constant(newStorage),
900+
Expr::Int32, width);
901+
}
902+
}
903+
904+
updates = UpdateList(array, nullptr);
872905
for (auto [index, value] : newUpdates) {
873906
updates.extend(index, value);
874907
}

lib/Core/Memory.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class ObjectStage {
271271
void reset(ref<Expr> updateForDefault, bool isAdd);
272272

273273
ref<Expr> combineAll() const;
274-
void updateAll(ref<Expr> updateExpr, bool isAdd);
274+
void updateAll(const ref<ConstantExpr> &updateExpr, bool isAdd);
275275

276276
private:
277277
const UpdateList &getUpdates() const;
@@ -361,8 +361,7 @@ class ObjectState {
361361
KType *getDynamicType() const;
362362

363363
ref<Expr> readTaint() const { return taintOS.combineAll(); }
364-
void updateTaint(ref<Expr> updateForTaint, bool isAdd) {
365-
// resetTaint(updateForTaint, isAdd);
364+
void updateTaint(const ref<ConstantExpr> &updateForTaint, bool isAdd) {
366365
taintOS.updateAll(updateForTaint, isAdd);
367366
}
368367

0 commit comments

Comments
 (0)