Skip to content

Commit 0eb3ce6

Browse files
committed
Add klee_mock without chaking size before add_taint
1 parent 238fa5e commit 0eb3ce6

File tree

6 files changed

+133
-65
lines changed

6 files changed

+133
-65
lines changed

include/klee/Core/MockBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class MockBuilder {
4848
buildCallKleeMakeSymbolic(const std::string &kleeMakeSymbolicFunctionName,
4949
llvm::Value *source, llvm::Type *type,
5050
const std::string &symbolicName);
51+
void buildCallKleeMakeMockAll(llvm::Value *source,
52+
const std::string &symbolicName);
5153
llvm::CallInst *buildCallKleeTaintFunction(const std::string &functionName,
5254
llvm::Value *source, size_t taint,
5355
llvm::Type *returnType);

lib/Core/MockBuilder.cpp

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ void MockBuilder::buildCallKleeMakeSymbolic(
5555
{bitCastInst, llvm::ConstantInt::get(ctx, sz), gep});
5656
}
5757

58+
void MockBuilder::buildCallKleeMakeMockAll(llvm::Value *source,
59+
const std::string &symbolicName) {
60+
auto *kleeMakeSymbolicName = llvm::FunctionType::get(
61+
llvm::Type::getVoidTy(ctx),
62+
{llvm::Type::getInt8PtrTy(ctx), llvm::Type::getInt8PtrTy(ctx)}, false);
63+
auto kleeMakeSymbolicCallee = mockModule->getOrInsertFunction(
64+
"klee_make_mock_all", kleeMakeSymbolicName);
65+
auto bitCastInst =
66+
builder->CreateBitCast(source, llvm::Type::getInt8PtrTy(ctx));
67+
auto globalSymbolicName = builder->CreateGlobalString("@" + symbolicName);
68+
auto gep = builder->CreateConstInBoundsGEP2_64(
69+
globalSymbolicName->getValueType(), globalSymbolicName, 0, 0);
70+
builder->CreateCall(kleeMakeSymbolicCallee, {bitCastInst, gep});
71+
}
72+
5873
std::map<std::string, llvm::FunctionType *>
5974
MockBuilder::getExternalFunctions() {
6075
std::map<std::string, llvm::FunctionType *> externals;
@@ -544,44 +559,6 @@ MockBuilder::buildCallKleeTaintFunction(const std::string &functionName,
544559
false);
545560
auto kleeTaintFunctionCallee =
546561
mockModule->getOrInsertFunction(functionName, kleeTaintFunctionType);
547-
548-
// //TODO: that's not all:
549-
// // - add var arg list (now it is not even considered
550-
// // when passing through the function
551-
// // parameters and never gets here)
552-
// // - think about **
553-
// // - add going by pointers
554-
// llvm::Value *beginPtr;
555-
// llvm::Value *countBytes;
556-
// if (!source->getType()->isPointerTy() && !source->getType()->isArrayTy())
557-
// {
558-
// beginPtr = builder->CreateAlloca(source->getType());
559-
// builder->CreateStore(source, beginPtr);
560-
//
561-
// const size_t bytes = mockModule->getDataLayout().getTypeStoreSize(
562-
// source->getType()->getPointerElementType());
563-
// countBytes = llvm::ConstantInt::get(
564-
// mockModule->getContext(),
565-
// llvm::APInt(64, bytes, false));
566-
// } else if (source->getType()->isPointerTy()) {
567-
// beginPtr = builder->CreateBitCast(
568-
// source, llvm::Type::getInt8PtrTy(mockModule->getContext()));
569-
//
570-
// if (source->getType()->getPointerElementType()->isIntegerTy(8)) {
571-
// auto *TLI = new
572-
// llvm::TargetLibraryInfo(llvm::TargetLibraryInfoImpl()); countBytes =
573-
// llvm::emitStrLen(source, *builder,
574-
// mockModule->getDataLayout(),TLI);
575-
// }
576-
// else {
577-
// const size_t bytes = mockModule->getDataLayout().getTypeStoreSize(
578-
// source->getType()->getPointerElementType());
579-
// countBytes = llvm::ConstantInt::get(
580-
// mockModule->getContext(),
581-
// llvm::APInt(64, bytes, false));
582-
// }
583-
// }
584-
585562
llvm::Value *beginPtr;
586563
if (!source->getType()->isPointerTy() && !source->getType()->isArrayTy()) {
587564
beginPtr = builder->CreateAlloca(source->getType());
@@ -624,6 +601,7 @@ void MockBuilder::buildAnnotationForExternalFunctionArgs(
624601
#else
625602
const auto arg = &func->arg_begin()[i];
626603
#endif
604+
size_t offsetIndex = 0;
627605
auto statementsMap = unifyByOffset(statements[i]);
628606
for (const auto &[offset, statementsOffset] : statementsMap) {
629607
auto [prev, elem] = goByOffset(arg, offset);
@@ -632,6 +610,11 @@ void MockBuilder::buildAnnotationForExternalFunctionArgs(
632610
Statement::Free *freePtr = nullptr;
633611
Statement::InitNull *initNullPtr = nullptr;
634612

613+
bool isMocked = false;
614+
std::string mockName = "klee_mock" + func->getName().str() + "_arg_" +
615+
std::to_string(i) + "_" +
616+
std::to_string(offsetIndex);
617+
635618
for (const auto &statement : statementsOffset) {
636619
switch (statement->getKind()) {
637620
case Statement::Kind::Deref: {
@@ -697,13 +680,23 @@ void MockBuilder::buildAnnotationForExternalFunctionArgs(
697680
if (!elem->getType()->isPointerTy()) {
698681
klee_error("Annotation: TaintOutput arg is not pointer");
699682
}
683+
684+
if (!isMocked) {
685+
buildCallKleeMakeMockAll(elem, mockName);
686+
isMocked = true;
687+
}
700688
buildAnnotationTaintOutput(elem, statement);
701689
break;
702690
}
703691
case Statement::Kind::TaintPropagation: {
704692
if (!elem->getType()->isPointerTy()) {
705693
klee_error("Annotation: TaintPropagation arg is not pointer");
706694
}
695+
696+
if (!isMocked) {
697+
buildCallKleeMakeMockAll(elem, mockName);
698+
isMocked = true;
699+
}
707700
buildAnnotationTaintPropagation(elem, statement, func,
708701
"_arg_" + std::to_string(i) + "_");
709702
break;
@@ -724,6 +717,7 @@ void MockBuilder::buildAnnotationForExternalFunctionArgs(
724717
buildFree(elem, freePtr);
725718
}
726719
processingValue(prev, elem->getType(), allocSourcePtr, initNullPtr);
720+
offsetIndex++;
727721
}
728722
}
729723
}
@@ -852,14 +846,6 @@ void MockBuilder::buildAnnotationForExternalFunctionReturn(
852846
std::string retName = "ret_" + func->getName().str();
853847
llvm::Value *retValuePtr = builder->CreateAlloca(returnType, nullptr);
854848

855-
// TODO: fix strange type ("fopen" mock, store instruction)
856-
// if (func->getName() == "fopen") {
857-
// buildCallKleeMakeSymbolic("klee_make_mock", retValuePtr, returnType,
858-
// func->getName().str());
859-
// llvm::Value *retValue = builder->CreateLoad(returnType, retValuePtr,
860-
// retName); builder->CreateRet(retValue); return;
861-
// }
862-
863849
if (returnType->isPointerTy() && (allocSourcePtr || mustInitNull)) {
864850
processingValue(retValuePtr, returnType, allocSourcePtr,
865851
mustInitNull || maybeInitNull);

lib/Core/SpecialFunctionHandler.cpp

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static SpecialFunctionHandler::HandlerInfo handlerInfo[] = {
116116
add("klee_is_symbolic", handleIsSymbolic, true),
117117
add("klee_make_symbolic", handleMakeSymbolic, false),
118118
add("klee_make_mock", handleMakeMock, false),
119+
add("klee_make_mock_all", handleMakeMockAll, false),
119120
add("klee_mark_global", handleMarkGlobal, false),
120121
add("klee_prefer_cex", handlePreferCex, false),
121122
add("klee_posix_prefer_cex", handlePosixPreferCex, false),
@@ -1077,6 +1078,71 @@ void SpecialFunctionHandler::handleMakeMock(ExecutionState &state,
10771078
}
10781079
}
10791080

1081+
void SpecialFunctionHandler::handleMakeMockAll(
1082+
ExecutionState &state, KInstruction *target,
1083+
std::vector<ref<Expr>> &arguments) {
1084+
std::string name;
1085+
1086+
if (arguments.size() != 2) {
1087+
executor.terminateStateOnUserError(state,
1088+
"Incorrect number of arguments to "
1089+
"klee_make_mock_all(void*, char*)");
1090+
return;
1091+
}
1092+
1093+
name = arguments[1]->isZero()
1094+
? ""
1095+
: readStringAtAddress(state, executor.makePointer(arguments[1]));
1096+
1097+
if (name.empty()) {
1098+
executor.terminateStateOnUserError(
1099+
state, "Empty name of function in klee_make_mock_all");
1100+
return;
1101+
}
1102+
1103+
KFunction *kf = target->parent->parent;
1104+
1105+
Executor::ExactResolutionList rl;
1106+
executor.resolveExact(state, arguments[0],
1107+
executor.typeSystemManager->getUnknownType(), rl,
1108+
"make_symbolic");
1109+
1110+
for (auto &it : rl) {
1111+
ObjectPair op = it.second->addressSpace.findObject(it.first);
1112+
const MemoryObject *mo = op.first;
1113+
mo->setName(name);
1114+
mo->updateTimestamp();
1115+
1116+
const ObjectState *old = op.second;
1117+
ExecutionState *s = it.second;
1118+
1119+
if (old->readOnly) {
1120+
executor.terminateStateOnUserError(
1121+
*s, "cannot make readonly object symbolic");
1122+
return;
1123+
}
1124+
1125+
ref<SymbolicSource> source;
1126+
switch (executor.interpreterOpts.MockStrategy) {
1127+
case MockStrategyKind::Naive:
1128+
source =
1129+
SourceBuilder::mockNaive(executor.kmodule.get(), *kf->function(),
1130+
executor.updateNameVersion(state, name));
1131+
break;
1132+
case MockStrategyKind::Deterministic:
1133+
std::vector<ref<Expr>> args(kf->getNumArgs());
1134+
for (size_t i = 0; i < kf->getNumArgs(); i++) {
1135+
args[i] = executor.getArgumentCell(state, kf, i).value;
1136+
}
1137+
source = SourceBuilder::mockDeterministic(executor.kmodule.get(),
1138+
*kf->function(), args);
1139+
break;
1140+
}
1141+
executor.executeMakeSymbolic(state, mo, old->getDynamicType(), source,
1142+
false);
1143+
}
1144+
}
1145+
10801146
void SpecialFunctionHandler::handleMarkGlobal(
10811147
ExecutionState &state, KInstruction *target,
10821148
std::vector<ref<Expr>> &arguments) {
@@ -1231,6 +1297,11 @@ void SpecialFunctionHandler::handleAddTaint(klee::ExecutionState &state,
12311297
"klee_add_taint(void*, size_t)");
12321298
return;
12331299
}
1300+
1301+
// uint64_t taintSource = dyn_cast<ConstantExpr>(arguments[1])->getZExtValue();
1302+
// printf("klee_add_taint source: %zu\n", taintSource);
1303+
// executor.executeChangeTaintSource(
1304+
// state, target, executor.makePointer(arguments[0]), taintSource, true);
12341305
}
12351306

12361307
void SpecialFunctionHandler::handleClearTaint(
@@ -1242,6 +1313,11 @@ void SpecialFunctionHandler::handleClearTaint(
12421313
"klee_clear_taint(void*, size_t)");
12431314
return;
12441315
}
1316+
1317+
// uint64_t taintSource = dyn_cast<ConstantExpr>(arguments[1])->getZExtValue();
1318+
// printf("klee_clear_taint source: %zu\n", taintSource);
1319+
// executor.executeChangeTaintSource(
1320+
// state, target, executor.makePointer(arguments[0]), taintSource, false);
12451321
}
12461322

12471323
void SpecialFunctionHandler::handleCheckTaintSource(
@@ -1255,8 +1331,9 @@ void SpecialFunctionHandler::handleCheckTaintSource(
12551331
}
12561332

12571333
// uint64_t taintSource = dyn_cast<ConstantExpr>(arguments[1])->getZExtValue();
1258-
// executor.executeCheckTaintSource(state, target,
1259-
// executor.makePointer(arguments[0]), taintSource);
1334+
// printf("klee_check_taint_source source: %zu\n", taintSource);
1335+
// executor.executeCheckTaintSource(
1336+
// state, target, executor.makePointer(arguments[0]), taintSource);
12601337
}
12611338

12621339
void SpecialFunctionHandler::handleGetTaintRule(
@@ -1269,11 +1346,12 @@ void SpecialFunctionHandler::handleGetTaintRule(
12691346
return;
12701347
}
12711348

1272-
// // TODO: now mock
1273-
ref<Expr> result = ConstantExpr::create(1, Expr::Int64);
1274-
executor.bindLocal(target, state, result);
1349+
// // TODO: now mock
1350+
ref<Expr> result = ConstantExpr::create(1, Expr::Int64);
1351+
executor.bindLocal(target, state, result);
12751352

12761353
// uint64_t taintSink = dyn_cast<ConstantExpr>(arguments[1])->getZExtValue();
1354+
// printf("klee_get_taint_rule source: %zu\n", taintSink);
12771355
// executor.executeGetTaintRule(state, target,
12781356
// executor.makePointer(arguments[0]), taintSink);
12791357
}
@@ -1287,7 +1365,7 @@ void SpecialFunctionHandler::handleTaintHit(klee::ExecutionState &state,
12871365
return;
12881366
}
12891367

1290-
uint64_t ruleId = dyn_cast<ConstantExpr>(arguments[0])->getZExtValue();
1291-
// printf("klee_taint_hit for rule: %zu\n", ruleId);
1292-
executor.terminateStateOnTargetTaintError(state, ruleId);
1368+
uint64_t taintRule = dyn_cast<ConstantExpr>(arguments[0])->getZExtValue();
1369+
printf("klee_taint_hit rule: %zu\n", taintRule);
1370+
executor.terminateStateOnTargetTaintError(state, taintRule);
12931371
}

lib/Core/SpecialFunctionHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class SpecialFunctionHandler {
130130
HANDLER(handleIsSymbolic);
131131
HANDLER(handleMakeSymbolic);
132132
HANDLER(handleMakeMock);
133+
HANDLER(handleMakeMockAll);
133134
HANDLER(handleMalloc);
134135
HANDLER(handleMemalign);
135136
HANDLER(handleMarkGlobal);

runtime/Runtest/intrinsics.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,12 @@ void klee_make_mock(void *ret_array, size_t ret_nbytes, const char *fname) {
165165
}
166166

167167
// TODO: add for tests
168-
void klee_add_taint(void *array, size_t taint_source) {}
169-
void klee_clear_taint(void *array, size_t taint_source) {}
170-
bool klee_check_taint_source(void *array, size_t taint_source) {}
171-
bool klee_check_taint_sink(void *array, size_t taint_sink) {}
172-
void klee_taint_sink_hit(size_t taint_sink) {}
168+
//void klee_make_mock_all(void *ret_array, const char *fname);
169+
//void klee_add_taint(void *array, size_t taint_source) {}
170+
//void klee_clear_taint(void *array, size_t taint_source) {}
171+
//bool klee_check_taint_source(void *array, size_t taint_source) {}
172+
//size_t klee_get_taint_rule(void *array, size_t taint_sink) {}
173+
//void klee_taint_hit(size_t rule) {}
173174

174175
void klee_silent_exit(int x) { exit(x); }
175176

tools/klee/main.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,12 +1087,12 @@ static const char *modelledExternals[] = {
10871087
"klee_get_valuef", "klee_get_valued", "klee_get_valuel", "klee_get_valuell",
10881088
"klee_get_value_i32", "klee_get_value_i64", "klee_get_obj_size",
10891089
"klee_is_symbolic", "klee_make_symbolic", "klee_make_mock",
1090-
"klee_add_taint", "klee_clear_taint", "klee_check_taint_source",
1091-
"klee_get_taint_rule", "klee_taint_hit", "klee_mark_global",
1092-
"klee_open_merge", "klee_close_merge", "klee_prefer_cex",
1093-
"klee_posix_prefer_cex", "klee_print_expr", "klee_print_range",
1094-
"klee_report_error", "klee_set_forking", "klee_silent_exit", "klee_warning",
1095-
"klee_warning_once", "klee_stack_trace",
1090+
"klee_make_mock_all", "klee_add_taint", "klee_clear_taint",
1091+
"klee_check_taint_source", "klee_get_taint_rule", "klee_taint_hit",
1092+
"klee_mark_global", "klee_open_merge", "klee_close_merge",
1093+
"klee_prefer_cex", "klee_posix_prefer_cex", "klee_print_expr",
1094+
"klee_print_range", "klee_report_error", "klee_set_forking",
1095+
"klee_silent_exit", "klee_warning", "klee_warning_once", "klee_stack_trace",
10961096
#ifdef SUPPORT_KLEE_EH_CXX
10971097
"_klee_eh_Unwind_RaiseException_impl", "klee_eh_typeid_for",
10981098
#endif

0 commit comments

Comments
 (0)