[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