Guard against infinite loops

git-svn: trunk@2509
remotes/push_mirror/metadata
Nigel Horne 19 years ago
parent 05789ccd55
commit 32bca65798
  1. 6
      clamav-devel/ChangeLog
  2. 118
      clamav-devel/libclamav/jscript.c

@ -1,3 +1,9 @@
Sat Nov 18 22:44:37 GMT 2006 (njh)
----------------------------------
* libclamav: Don't implement the sleep function
Handle DoS attacks on the JS VM by adding a timeout guarding
against infinite loops
Sat Nov 18 21:46:10 CET 2006 (tk)
---------------------------------
* libclamav/matcher-ac.c: multipart signatures: give higher priority to new

@ -28,7 +28,7 @@
* TODO: Add mailfollowurls type feature
* TODO: Check for vulnerabilities, leaks etc.
*/
static char const rcsid[] = "$Id: jscript.c,v 1.5 2006/11/11 17:18:10 njh Exp $";
static char const rcsid[] = "$Id: jscript.c,v 1.6 2006/11/18 22:42:40 njh Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -70,6 +70,16 @@ static char const rcsid[] = "$Id: jscript.c,v 1.5 2006/11/11 17:18:10 njh Exp $"
# endif
#endif
#ifdef CL_THREAD_SAFE
#define VM_TIMEOUT 5 /* In seconds: FIXME should be configurable */
#endif
#if defined(VM_TIMEOUT) && (VM_TIMEOUT > 0)
#include <pthread.h>
#include <sys/time.h>
#include <signal.h>
#endif
static int run_js(const char *filename, const char *dir);
static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
@ -268,6 +278,111 @@ write_to_fout(void *context, unsigned char *buf, unsigned int len)
return (int)fwrite(buf, (size_t)len, 1, fout);
}
#if defined(VM_TIMEOUT) && (VM_TIMEOUT > 0)
struct args {
const char *filename;
const char *dir;
pthread_cond_t *cond;
int result;
};
static void
sigrecv(int sig)
{
/* pthread_cond_broadcast(&cond); */
pthread_exit(NULL); /* FIXME: interp isn't destroyed - mem leak? */
}
static void *
js_thread(void *a)
{
JSInterpPtr interp;
char *outputfilename;
struct args *args = (struct args *)a;
const char *dir = args->dir;
const char *filename = args->filename;
cli_dbgmsg("run_js(%s)\n", filename);
outputfilename = cli_gentemp(dir);
if(outputfilename == NULL) {
pthread_cond_broadcast(args->cond);
args->result = CL_ETMPFILE;
return NULL;
}
fout = fopen(outputfilename, "wb");
if(fout == NULL) {
pthread_cond_broadcast(args->cond);
cli_warnmsg("Can't create %s\n", outputfilename);
free(outputfilename);
args->result = CL_ETMPFILE;
return NULL;
}
cli_dbgmsg("Redirecting JS VM stdout to %s\n", outputfilename);
free(outputfilename);
/*
* Run NGS on the file
*/
interp = create_interp(write_to_fout);
args->result = CL_EIO; /* TODO: CL_TIMEOUT */
if(!js_eval_file(interp, filename)) {
cli_warnmsg("JS failed: %s\n", js_error_message(interp));
/*rc = CL_EIO;*/
}
if(pthread_cond_broadcast(args->cond) < 0)
perror("pthread_cond_broadcast");
js_destroy_interp(interp);
fclose(fout);
args->result = CL_SUCCESS;
return NULL;
}
static int
run_js(const char *filename, const char *dir)
{
struct args args;
pthread_t tid;
struct timespec ts;
struct timeval tp;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void (*oldkill)(int);
args.filename = filename;
args.dir = dir;
args.cond = &cond;
pthread_create(&tid, NULL, js_thread, &args);
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec + VM_TIMEOUT;
ts.tv_nsec = tp.tv_usec * 1000;
oldkill = signal(SIGUSR1, sigrecv);
pthread_mutex_lock(&mutex);
if(pthread_cond_timedwait(&cond, &mutex, &ts) == ETIMEDOUT) {
cli_warnmsg("Run away javascript stopped after %d seconds\n",
VM_TIMEOUT);
pthread_kill(tid, SIGUSR1);
}
pthread_mutex_unlock(&mutex);
pthread_join(tid, NULL);
signal(SIGUSR1, oldkill);
return args.result;
}
#else
static int
run_js(const char *filename, const char *dir)
{
@ -306,6 +421,7 @@ run_js(const char *filename, const char *dir)
return CL_SUCCESS;
}
#endif
/* Copied from pdf.c :-( */
/*

Loading…
Cancel
Save