From ab03c1cdce90660dcb75d000ebda817ae589aaec Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Sat, 5 May 2018 00:04:13 +0100 Subject: Fix handling of errno if external functions are invoked If an external function in KLEE is invoked, it might update errno. Previously, the errno specific variable in a state was only updated if it was part of the executed instructions. That opened up a timeframe that increased the likelihood of errno being overwritten by another method call. This patch fixes two issues: * the errno of the KLEE process state is updated before the external function call allowing to detect changes to it later on * after the external call, the memory object of errno is directly updated with its new value, reducing the likelihood to be overwritten by another call Additional features: * Add support for `errno()` for Darwin as well. * Simplified errno handling in POSIX layer --- lib/Core/ExternalDispatcher.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'lib/Core/ExternalDispatcher.cpp') diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp index 6c54d34b..70c14050 100644 --- a/lib/Core/ExternalDispatcher.cpp +++ b/lib/Core/ExternalDispatcher.cpp @@ -65,6 +65,7 @@ private: llvm::Module *singleDispatchModule; std::vector moduleIDs; std::string &getFreshModuleID(); + int lastErrno; public: ExternalDispatcherImpl(llvm::LLVMContext &ctx); @@ -72,6 +73,8 @@ public: bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args); void *resolveSymbol(const std::string &name); + int getLastErrno(); + void setLastErrno(int newErrno); }; std::string &ExternalDispatcherImpl::getFreshModuleID() { @@ -114,7 +117,8 @@ void *ExternalDispatcherImpl::resolveSymbol(const std::string &name) { return addr; } -ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx) : ctx(ctx) { +ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx) + : ctx(ctx), lastErrno(0) { std::string error; singleDispatchModule = new Module(getFreshModuleID(), ctx); #if LLVM_VERSION_CODE < LLVM_VERSION(3, 6) @@ -252,7 +256,10 @@ bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) { if (setjmp(escapeCallJmpBuf)) { res = false; } else { + errno = lastErrno; executionEngine->runFunction(f, gvArgs); + // Explicitly acquire errno information + lastErrno = errno; res = true; } @@ -346,6 +353,11 @@ Function *ExternalDispatcherImpl::createDispatcher(Function *target, return dispatcher; } +int ExternalDispatcherImpl::getLastErrno() { return lastErrno; } +void ExternalDispatcherImpl::setLastErrno(int newErrno) { + lastErrno = newErrno; +} + ExternalDispatcher::ExternalDispatcher(llvm::LLVMContext &ctx) : impl(new ExternalDispatcherImpl(ctx)) {} @@ -359,4 +371,9 @@ bool ExternalDispatcher::executeCall(llvm::Function *function, void *ExternalDispatcher::resolveSymbol(const std::string &name) { return impl->resolveSymbol(name); } + +int ExternalDispatcher::getLastErrno() { return impl->getLastErrno(); } +void ExternalDispatcher::setLastErrno(int newErrno) { + impl->setLastErrno(newErrno); +} } -- cgit 1.4.1