[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
Török Edvin
edwin at clamav.net
Sun Apr 4 01:24:13 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 884a0b8f8d3477aadb3a4668e21a1f0f2da9171f
Author: Török Edvin <edwin at clamav.net>
Date: Mon Mar 22 16:57:27 2010 +0200
Support for timeouts.
diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
index 7334cac..31bdfcf 100644
--- a/libclamav/c++/bytecode2llvm.cpp
+++ b/libclamav/c++/bytecode2llvm.cpp
@@ -20,6 +20,10 @@
* MA 02110-1301, USA.
*/
#define DEBUG_TYPE "clamavjit"
+#include <pthread.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
#include "ClamBCModule.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
@@ -60,6 +64,7 @@
#include <cstdlib>
#include <csetjmp>
#include <new>
+#include <cerrno>
#include "llvm/Config/config.h"
#if !ENABLE_THREADS
@@ -1303,20 +1308,17 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
}
-int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
- const struct cli_bc_func *func)
+struct bc_thread {
+ void *code;
+ struct cli_bc_ctx *ctx;
+ int finished;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+static int bytecode_thread_execute(intptr_t code, struct cli_bc_ctx *ctx)
{
- // no locks needed here, since LLVM automatically acquires a JIT lock
- // if needed.
jmp_buf env;
- void *code = bcs->engine->compiledFunctions[func];
- if (!code) {
- errs() << MODULE << "Unable to find compiled function\n";
- if (func->numArgs)
- errs() << MODULE << "Function has "
- << (unsigned)func->numArgs << " arguments, it must have 0 to be called as entrypoint\n";
- return CL_EBYTECODE;
- }
// execute;
if (setjmp(env) == 0) {
// setup exception handler to longjmp back here
@@ -1329,7 +1331,86 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
errs().changeColor(raw_ostream::RED, true) << MODULE
<< "*** JITed code intercepted runtime error!\n";
errs().resetColor();
- return CL_EBYTECODE;
+ return 1;
+}
+
+static void* bytecode_thread(void* dummy)
+{
+ int ret;
+ struct bc_thread *thr = (struct bc_thread*)dummy;
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ ret = bytecode_thread_execute((intptr_t)thr->code, thr->ctx);
+ pthread_mutex_lock(&thr->mutex);
+ thr->finished = 1;
+ pthread_cond_signal(&thr->cond);
+ pthread_mutex_unlock(&thr->mutex);
+ return ret ? dummy : NULL;
+}
+extern "C" const char *cli_strerror(int errnum, char* buf, size_t len);
+int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
+ const struct cli_bc_func *func)
+{
+ char buf[1024];
+ int ret;
+ void *threadret;
+ pthread_t thread;
+ struct timeval tv0, tv1;
+ struct timespec abstimeout;
+ int timedout = 0;
+ // no locks needed here, since LLVM automatically acquires a JIT lock
+ // if needed.
+ void *code = bcs->engine->compiledFunctions[func];
+ if (!code) {
+ errs() << MODULE << "Unable to find compiled function\n";
+ if (func->numArgs)
+ errs() << MODULE << "Function has "
+ << (unsigned)func->numArgs << " arguments, it must have 0 to be called as entrypoint\n";
+ return CL_EBYTECODE;
+ }
+ struct bc_thread bcthr = {
+ code, ctx, 0,
+ PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER
+ };
+ gettimeofday(&tv0, NULL);
+ pthread_mutex_lock(&bcthr.mutex);
+ ret = pthread_create(&thread, NULL, bytecode_thread, &bcthr);
+ if (ret) {
+ errs() << "Bytecode: failed to create new thread!";
+ errs() << cli_strerror(ret, buf, sizeof(buf));
+ errs() << "\n";
+ return CL_EBYTECODE;
+ }
+
+ abstimeout.tv_sec = tv0.tv_sec + 5;
+ abstimeout.tv_nsec = tv0.tv_usec*1000;
+ do {
+ ret = pthread_cond_timedwait(&bcthr.cond, &bcthr.mutex, &abstimeout);
+ } while (!bcthr.finished && ret != ETIMEDOUT);
+ pthread_mutex_unlock(&bcthr.mutex);
+ if (ret == ETIMEDOUT) {
+ errs() << "Bytecode run timed out, canceling thread\n";
+ timedout = 1;
+ ret = pthread_cancel(thread);
+ if (ret) {
+ errs() << "Bytecode: failed to create new thread!";
+ errs() << cli_strerror(ret, buf, sizeof(buf));
+ errs() << "\n";
+ }
+ }
+ ret = pthread_join(thread, &threadret);
+ if (ret) {
+ errs() << "Bytecode: failed to create new thread!";
+ errs() << cli_strerror(ret, buf, sizeof(buf));
+ errs() << "\n";
+ }
+ if (cli_debug_flag) {
+ gettimeofday(&tv1, NULL);
+ tv1.tv_sec -= tv0.tv_sec;
+ tv1.tv_usec -= tv0.tv_usec;
+ errs() << "bytecode finished in " << (tv1.tv_sec*1000000 + tv1.tv_usec) << "us\n";
+ }
+ return timedout ? CL_ETIMEOUT : (threadret ? CL_EBYTECODE : CL_SUCCESS);
}
static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list