On 6/29/11 3:36 AM, Ralf Hildebrandt wrote:
but, if clamav hung on the primary (like it has done twice since
upgrading to 0.97.1),
Ah, it's happening to you as well? Happened here twice or three times
already :(
I have attached a patch, for freebsd, cd ../ports/security/clamav/files
put this attached patch there (its against clamav 0.97.1)
it should remove this:
<http://git.clamav.net/gitweb?p=clamav-devel.git;a=commitdiff;h=bbfe830c935837cfc357541cb307a7b863394abb;hp=d9ff9e65080d7c70de722e174d365d3b2cb312d3>
see if that helps.
amavisd just seems to sit there till I totally kill clamd with a
sigsegv.
Yeah, same here.
--
Michael Scheidell, CTO
o: 561-999-5000
d: 561-948-2259
>*| *SECNAP Network Security Corporation
* Best Mobile Solutions Product of 2011
* Best Intrusion Prevention Product
* Hot Company Finalist 2011
* Best Email Security Product
* Certified SNORT Integrator
______________________________________________________________________
This email has been scanned and certified safe by SpammerTrap(r).
For Information please see http://www.secnap.com/products/spammertrap/
______________________________________________________________________
--- libclamav/c++/bytecode2llvm.cpp.orig 2011-05-13 07:25:31.000000000
-0400
+++ libclamav/c++/bytecode2llvm.cpp 2011-06-29 09:32:09.000000000 -0400
@@ -1874,119 +1874,30 @@
INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
#endif
-static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER;
-static int watchdog_running = 0;
-
-struct watchdog_item {
+struct bc_watchdog {
volatile uint8_t* timeout;
- struct timespec abstimeout;
- struct watchdog_item *next;
+ struct timespec * abstimeout;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int finished;
};
-static struct watchdog_item* watchdog_head = NULL;
-static struct watchdog_item* watchdog_tail = NULL;
-
-#define WATCHDOG_IDLE 10
static void *bytecode_watchdog(void *arg)
{
- struct timeval tv;
- struct timespec out;
-
- pthread_mutex_lock(&watchdog_mutex);
- watchdog_running = 1;
- if (cli_debug_flag)
- cli_dbgmsg_internal("bytecode watchdog is running\n");
- do {
- struct watchdog_item *item;
- gettimeofday(&tv, NULL);
- out.tv_sec = tv.tv_sec + WATCHDOG_IDLE;
- out.tv_nsec = tv.tv_usec*1000;
- /* wait for some work, up to WATCHDOG_IDLE time */
- while (watchdog_head == NULL &&
- pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
- &out) != ETIMEDOUT) {}
- if (watchdog_head == NULL)
- break;
- /* wait till timeout is reached on this item */
- item = watchdog_head;
- while (item == watchdog_head &&
- pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
- &item->abstimeout) != ETIMEDOUT) {}
- if (item != watchdog_head)
- continue;/* got removed meanwhile */
- /* timeout reached, signal it to bytecode */
- *item->timeout = 1;
+ int ret = 0;
+ struct bc_watchdog *w = (struct bc_watchdog*)arg;
+ pthread_mutex_lock(&w->mutex);
+ while (!w->finished && ret != ETIMEDOUT) {
+ ret = pthread_cond_timedwait(&w->cond, &w->mutex, w->abstimeout);
+ }
+ pthread_mutex_unlock(&w->mutex);
+ if (ret == ETIMEDOUT) {
+ *w->timeout = 1;
cli_warnmsg("[Bytecode JIT]: Bytecode run timed out, timeout flag
set\n");
- watchdog_head = item->next;
- if (!watchdog_head)
- watchdog_tail = NULL;
- } while (1);
- watchdog_running = 0;
- if (cli_debug_flag)
- cli_dbgmsg_internal("bytecode watchdog quiting\n");
- pthread_mutex_unlock(&watchdog_mutex);
+ }
return NULL;
}
-extern "C" const char *cli_strerror(int errnum, char* buf, size_t len);
-static void watchdog_disarm(struct watchdog_item *item)
-{
- struct watchdog_item *q, *p = NULL;
- if (!item)
- return;
- pthread_mutex_lock(&watchdog_mutex);
- for (q=watchdog_head;q && q != item;p = q, q = q->next) {}
- if (q == item) {
- if (p)
- p->next = q->next;
- if (q == watchdog_head)
- watchdog_head = q->next;
- if (q == watchdog_tail)
- watchdog_tail = p;
- }
- pthread_mutex_unlock(&watchdog_mutex);
-}
-
-static int watchdog_arm(struct watchdog_item *item, int ms, volatile uint8_t
*timeout)
-{
- int rc = 0;
- struct timeval tv0;
-
- *timeout = 0;
- item->timeout = timeout;
- item->next = NULL;
-
- gettimeofday(&tv0, NULL);
- tv0.tv_usec += ms * 1000;
- item->abstimeout.tv_sec = tv0.tv_sec + tv0.tv_usec/1000000;
- item->abstimeout.tv_nsec = (tv0.tv_usec%1000000)*1000;
-
- pthread_mutex_lock(&watchdog_mutex);
- if (!watchdog_running) {
- pthread_t thread;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- if ((rc = pthread_create(&thread, &attr, bytecode_watchdog, NULL))) {
- char buf[256];
- cli_errmsg("(watchdog) pthread_create failed: %s\n",
cli_strerror(rc, buf, sizeof(buf)));
- }
- pthread_attr_destroy(&attr);
- }
- if (!rc) {
- if (watchdog_tail)
- watchdog_tail->next = item;
- watchdog_tail = item;
- if (!watchdog_head)
- watchdog_head = item;
- }
- pthread_cond_signal(&watchdog_cond);
- pthread_mutex_unlock(&watchdog_mutex);
- return rc;
-}
-
static int bytecode_execute(intptr_t code, struct cli_bc_ctx *ctx)
{
ScopedExceptionHandler handler;
@@ -2002,12 +1913,15 @@
return CL_EBYTECODE;
}
+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;
+ pthread_t thread;
struct timeval tv0, tv1;
- struct watchdog_item witem;
+ uint32_t timeoutus;
// no locks needed here, since LLVM automatically acquires a JIT lock
// if needed.
void *code = bcs->engine->compiledFunctions[func];
@@ -2018,20 +1932,40 @@
func->numArgs);
return CL_EBYTECODE;
}
- if (cli_debug_flag)
gettimeofday(&tv0, NULL);
+ struct timespec abstime;
+
+ timeoutus = (ctx->bytecode_timeout%1000)*1000 + tv0.tv_usec;
+ abstime.tv_sec = tv0.tv_sec + ctx->bytecode_timeout/1000 +
timeoutus/1000000;
+ abstime.tv_nsec = 1000*(timeoutus%1000000);
+ ctx->timeout = 0;
+
+ struct bc_watchdog w = {
+ &ctx->timeout,
+ &abstime,
+ PTHREAD_MUTEX_INITIALIZER,
+ PTHREAD_COND_INITIALIZER,
+ 0
+ };
if (ctx->bytecode_timeout) {
/* only spawn if timeout is set.
* we don't set timeout for selfcheck (see bb #2235) */
- if (watchdog_arm(&witem, ctx->bytecode_timeout, &ctx->timeout))
+ if ((ret = pthread_create(&thread, NULL, bytecode_watchdog, &w))) {
+ cli_warnmsg("[Bytecode JIT]: Bytecode: failed to create new thread
:%s!\n",
+ cli_strerror(ret, buf, sizeof(buf)));
return CL_EBYTECODE;
}
+ }
ret = bytecode_execute((intptr_t)code, ctx);
-
- if (ctx->bytecode_timeout)
- watchdog_disarm(&witem);
+ pthread_mutex_lock(&w.mutex);
+ w.finished = 1;
+ pthread_cond_signal(&w.cond);
+ pthread_mutex_unlock(&w.mutex);
+ if (ctx->bytecode_timeout) {
+ pthread_join(thread, NULL);
+ }
if (cli_debug_flag) {
long diff;