Browse code

Fix hung clamd on FreeBSD (bb #2235).

bytecode selfcheck running under JIT ran too early, and spawned a thread.
Then clamd forked. threads + fork = bad idea.
So prevent the thread from being spawned in selfcheck mode.
So at the time of fork clamd will still be single threaded as in 0.96.1.

Török Edvin authored on 2010/09/03 03:22:31
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Sep  2 21:21:58 EEST 2010 (edwin)
2
+-------------------------------------
3
+ * libclamav/c++/bytecode2llvm.cpp: fix hung clamd on FreeBSD (bb #2235)
4
+
1 5
 Thu Sep  2 15:38:22 EEST 2010 (edwin)
2 6
 -------------------------------------
3 7
  * libclamav/pe.c: add BC_PE_ALL hook (bb #2237)
... ...
@@ -2107,6 +2107,7 @@ static int run_selfcheck(struct cli_all_bc *bcs)
2107 2107
     cli_bytecode_context_setfuncid(ctx, bc, 0);
2108 2108
 
2109 2109
     cli_dbgmsg("bytecode self test running\n");
2110
+    ctx->bytecode_timeout = 0;
2110 2111
     rc = cli_bytecode_run(bcs, bc, ctx);
2111 2112
     cli_bytecode_context_destroy(ctx);
2112 2113
     if (rc != CL_SUCCESS) {
... ...
@@ -1637,11 +1637,15 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
1637 1637
 	0
1638 1638
     };
1639 1639
 
1640
-    if ((ret = pthread_create(&thread, NULL, bytecode_watchdog, &w))) {
1641
-	errs() << "Bytecode: failed to create new thread!";
1642
-	errs() << cli_strerror(ret, buf, sizeof(buf));
1643
-	errs() << "\n";
1644
-	return CL_EBYTECODE;
1640
+    if (ctx->bytecode_timeout) {
1641
+	/* only spawn if timeout is set.
1642
+	 * we don't set timeout for selfcheck (see bb #2235) */
1643
+	if ((ret = pthread_create(&thread, NULL, bytecode_watchdog, &w))) {
1644
+	    errs() << "Bytecode: failed to create new thread!";
1645
+	    errs() << cli_strerror(ret, buf, sizeof(buf));
1646
+	    errs() << "\n";
1647
+	    return CL_EBYTECODE;
1648
+	}
1645 1649
     }
1646 1650
 
1647 1651
     ret = bytecode_execute((intptr_t)code, ctx);
... ...
@@ -1649,7 +1653,9 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
1649 1649
     w.finished = 1;
1650 1650
     pthread_cond_signal(&w.cond);
1651 1651
     pthread_mutex_unlock(&w.mutex);
1652
-    pthread_join(thread, NULL);
1652
+    if (ctx->bytecode_timeout) {
1653
+	pthread_join(thread, NULL);
1654
+    }
1653 1655
 
1654 1656
     if (cli_debug_flag) {
1655 1657
 	gettimeofday(&tv1, NULL);