clamd/others.c: handle multiple %v parameters

clamd/server-th.c: fix dbstat memleak


git-svn-id: file:///var/lib/svn/clamav-devel/branches/clamd-proto@4724 77e5149b-7576-45b1-b177-96237e5ba77b
0.95
Tomasz Kojm 17 years ago
parent c73edc125e
commit 00eab4092f
  1. 5
      ChangeLog
  2. 68
      clamd/others.c
  3. 27
      clamd/server-th.c

@ -1,3 +1,8 @@
Mon Feb 9 19:06:43 CET 2009 (tk)
---------------------------------
* clamd/others.c: handle multiple %v parameters
* clamd/server-th.c: fix dbstat memleak
Mon Feb 9 20:02:36 EET 2009 (edwin)
------------------------------------
* clamd/clamd.c, clamd/scanner.c: Reject invalid minport/maxport in

@ -80,9 +80,6 @@
#include "session.h"
#include "others.h"
#define ENV_FILE "CLAM_VIRUSEVENT_FILENAME"
#define ENV_VIRUS "CLAM_VIRUSEVENT_VIRUSNAME"
#ifdef C_WINDOWS
void virusaction(const char *filename, const char *virname, const struct optstruct *opts)
{
@ -91,14 +88,19 @@ void virusaction(const char *filename, const char *virname, const struct optstru
}
#else
#define VE_FILENAME "CLAM_VIRUSEVENT_FILENAME"
#define VE_VIRUSNAME "CLAM_VIRUSEVENT_VIRUSNAME"
static pthread_mutex_t virusaction_lock = PTHREAD_MUTEX_INITIALIZER;
void virusaction(const char *filename, const char *virname, const struct optstruct *opts)
{
pid_t pid;
const struct optstruct *opt;
char *buffer, *pt, *cmd, *buffer_file, *buffer_vir;
size_t j;
char *buffer_file, *buffer_vir, *buffer_cmd;
const char *pt;
size_t i, j, v = 0, len;
char *env[4];
if(!(opt = optget(opts, "VirusEvent"))->enabled)
@ -107,57 +109,53 @@ void virusaction(const char *filename, const char *virname, const struct optstru
env[0] = getenv("PATH");
j = env[0] ? 1 : 0;
/* Allocate env vars.. to be portable env vars should not be freed */
buffer_file = (char *) malloc(strlen(ENV_FILE) + strlen(filename) + 2);
buffer_file = (char *) malloc(strlen(VE_FILENAME) + strlen(filename) + 2);
if(buffer_file) {
sprintf(buffer_file, "%s=%s", ENV_FILE, filename);
sprintf(buffer_file, "%s=%s", VE_FILENAME, filename);
env[j++] = buffer_file;
}
buffer_vir = (char *) malloc(strlen(ENV_VIRUS) + strlen(virname) + 2);
buffer_vir = (char *) malloc(strlen(VE_VIRUSNAME) + strlen(virname) + 2);
if(buffer_vir) {
sprintf(buffer_vir, "%s=%s", ENV_VIRUS, virname);
sprintf(buffer_vir, "%s=%s", VE_VIRUSNAME, virname);
env[j++] = buffer_vir;
}
env[j++] = NULL;
cmd = strdup(opt->strarg);
if(cmd && (pt = strstr(cmd, "%v"))) {
buffer = (char *) malloc(strlen(cmd) + strlen(virname) + 10);
if(buffer) {
*pt = 0; pt += 2;
strcpy(buffer, cmd);
strcat(buffer, virname);
strcat(buffer, pt);
free(cmd);
cmd = strdup(buffer);
free(buffer);
}
pt = opt->strarg;
while((pt = strstr(pt, "%v"))) {
pt += 2;
v++;
}
if(!cmd) {
len = strlen(opt->strarg);
buffer_cmd = (char *) calloc(len + v * strlen(virname) + 1, sizeof(char));
if(!buffer_cmd) {
free(buffer_file);
free(buffer_vir);
return;
}
for(i = 0, j = 0; i < len; i++) {
if(i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'v') {
strcat(buffer_cmd, virname);
j += strlen(virname);
i++;
} else {
buffer_cmd[j++] = opt->strarg[i];
}
}
pthread_mutex_lock(&virusaction_lock);
/* We can only call async-signal-safe functions after fork(). */
pid = fork();
if ( pid == 0 ) {
/* child... */
/* WARNING: this is uninterruptable ! */
exit(execle("/bin/sh", "sh", "-c", cmd, NULL, env));
} else if (pid > 0) {
if(!pid) { /* child */
exit(execle("/bin/sh", "sh", "-c", buffer_cmd, NULL, env));
} else if(pid > 0) { /* parent */
pthread_mutex_unlock(&virusaction_lock);
/* parent */
waitpid(pid, NULL, 0);
} else {
pthread_mutex_unlock(&virusaction_lock);
/* error.. */
logg("!VirusAction: fork failed.\n");
logg("!VirusEvent: fork failed.\n");
}
free(cmd);
free(buffer_cmd);
free(buffer_file);
free(buffer_vir);
}

@ -76,7 +76,7 @@ int reload = 0;
time_t reloaded_time = 0;
pthread_mutex_t reload_mutex = PTHREAD_MUTEX_INITIALIZER;
int sighup = 0;
static struct cl_stat *dbstat = NULL;
static struct cl_stat dbstat;
static void scanner_thread(void *arg)
{
@ -168,12 +168,12 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
pua_cats[0] = 0;
*ret = 0;
if(do_check) {
if(dbstat == NULL) {
if(!dbstat.entries) {
logg("No stats for Database check - forcing reload\n");
return engine;
}
if(cl_statchkdir(dbstat) == 1) {
if(cl_statchkdir(&dbstat) == 1) {
logg("SelfCheck: Database modification detected. Forcing reload.\n");
return engine;
} else {
@ -195,19 +195,11 @@ static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dbopti
dbdir = optget(opts, "DatabaseDirectory")->strarg;
logg("Reading databases from %s\n", dbdir);
if(dbstat == NULL) {
dbstat = (struct cl_stat *) malloc(sizeof(struct cl_stat));
if(!dbstat) {
logg("!Can't allocate memory for dbstat\n");
*ret = 1;
return NULL;
}
} else {
cl_statfree(dbstat);
}
if(dbstat.entries)
cl_statfree(&dbstat);
memset(dbstat, 0, sizeof(struct cl_stat));
if((retval = cl_statinidir(dbdir, dbstat))) {
memset(&dbstat, 0, sizeof(struct cl_stat));
if((retval = cl_statinidir(dbdir, &dbstat))) {
logg("!cl_statinidir() failed: %s\n", cl_strerror(retval));
*ret = 1;
return NULL;
@ -647,6 +639,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
} else {
logg("Self checking every %u seconds.\n", selfchk);
}
memset(&dbstat, 0, sizeof(dbstat));
/* save the PID */
mainpid = getpid();
@ -1100,8 +1093,8 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
pthread_join(accept_th, NULL);
close(acceptdata.syncpipe_wake_accept[1]);
close(acceptdata.syncpipe_wake_recv[1]);
if(dbstat)
cl_statfree(dbstat);
if(dbstat.entries)
cl_statfree(&dbstat);
logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : "");
for (i = 0; i < nsockets; i++)
shutdown(socketds[i], 2);

Loading…
Cancel
Save