On Fri, 18 Mar 2005, Tomasz Kojm wrote:
I've looked at your patch and it's definitely too complicated. Moreover it's not portable (free_env_var - although it _should_ work on most systems) as the old UNIX rule says: "_never_ free variable passed to putenv()".
Hi, I implemented your suggestions into my patch. Please find it attached.
It is indeed much simpler now..
This is the fifth revision of this patch. Please use it!! :)
diff -ur clamav-devel/clamd/clamuko.c clamav-devel-modified/clamd/clamuko.c --- clamav-devel/clamd/clamuko.c 2005-03-09 12:32:41.000000000 -0500 +++ clamav-devel-modified/clamd/clamuko.c 2005-03-14 10:08:30.000000000 -0500 @@ -173,7 +173,7 @@ if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->root, tharg->limits, tharg->options) == CL_VIRUS) { logg("Clamuko: %s: %s FOUND\n", acc->filename, virname); - virusaction(virname, tharg->copt); + virusaction(acc->filename, virname, tharg->copt); acc->deny = 1; } else acc->deny = 0; diff -ur clamav-devel/clamd/others.c clamav-devel-modified/clamd/others.c --- clamav-devel/clamd/others.c 2005-03-09 12:32:41.000000000 -0500 +++ clamav-devel-modified/clamd/others.c 2005-03-19 14:23:34.000000000 -0500 @@ -69,32 +69,61 @@ #include "cfgparser.h" #include "session.h" -void virusaction(const char *virname, const struct cfgstruct *copt) +#define ENV_FILE "CLAM_VIRUSEVENT_FILENAME" +#define ENV_VIRUS "CLAM_VIRUSEVENT_VIRUSNAME" + +void virusaction(const char *filename, const char *virname, const struct cfgstruct *copt) { - char *buffer, *pt, *cmd; + pid_t pid; struct cfgstruct *cpt; - if(!(cpt = cfgopt(copt, "VirusEvent"))) return; - cmd = strdup(cpt->strarg); + /* NB: we need to fork here since this function modifies the environment. + (Modifications to the env. are not reentrant, but we need to be.) */ + pid = fork(); - if((pt = strstr(cmd, "%v"))) { - buffer = (char *) mcalloc(strlen(cmd) + strlen(virname) + 10, sizeof(char)); - *pt = 0; pt += 2; - strcpy(buffer, cmd); - strcat(buffer, virname); - strcat(buffer, pt); - free(cmd); - cmd = strdup(buffer); - free(buffer); - } + if ( pid == 0 ) { + /* child... */ + char *buffer, *pt, *cmd; - /* WARNING: this is uninterruptable ! */ - system(cmd); + cmd = strdup(cpt->strarg); - free(cmd); + if((pt = strstr(cmd, "%v"))) { + buffer = (char *) mcalloc(strlen(cmd) + strlen(virname) + 10, sizeof(char)); + *pt = 0; pt += 2; + strcpy(buffer, cmd); + strcat(buffer, virname); + strcat(buffer, pt); + free(cmd); + cmd = strdup(buffer); + free(buffer); + } + + /* Allocate env vars.. to be portable env vars should not be freed */ + buffer = (char *) mcalloc(strlen(ENV_FILE) + strlen(filename) + 2, sizeof(char)); + sprintf(buffer, "%s=%s", ENV_FILE, filename); + putenv(buffer); + + buffer = (char *) mcalloc(strlen(ENV_VIRUS) + strlen(virname) + 2, sizeof(char)); + sprintf(buffer, "%s=%s", ENV_VIRUS, virname); + putenv(buffer); + + + /* WARNING: this is uninterruptable ! */ + exit(system(cmd)); + + /* The below is not reached but is here for completeness to remind + maintainers that this buffer is still allocated.. */ + free(cmd); + } else if (pid > 0) { + /* parent */ + waitpid(pid, NULL, 0); + } else { + /* error.. */ + logg("!VirusAction: fork failed.\n"); + } } int poll_fd(int fd, int timeout_sec) diff -ur clamav-devel/clamd/others.h clamav-devel-modified/clamd/others.h --- clamav-devel/clamd/others.h 2005-03-09 12:32:41.000000000 -0500 +++ clamav-devel-modified/clamd/others.h 2005-03-14 10:08:30.000000000 -0500 @@ -28,7 +28,7 @@ int poll_fd(int fd, int timeout_sec); int is_fd_connected(int fd); -void virusaction(const char *virname, const struct cfgstruct *copt); +void virusaction(const char *filename, const char *virname, const struct cfgstruct *copt); int writen(int fd, void *buff, unsigned int count); #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) && !defined(C_CYGWIN) && !defined(C_OS2) diff -ur clamav-devel/clamd/scanner.c clamav-devel-modified/clamd/scanner.c --- clamav-devel/clamd/scanner.c 2005-03-19 14:21:10.000000000 -0500 +++ clamav-devel-modified/clamd/scanner.c 2005-03-19 14:20:45.000000000 -0500 @@ -159,7 +159,7 @@ mdprintf(odesc, "%s: %s FOUND\n", fname, *virname); logg("%s: %s FOUND\n", fname, *virname); - virusaction(*virname, copt); + virusaction(fname, *virname, copt); if(!contscan) { closedir(dd); free(fname); @@ -237,7 +237,7 @@ if(ret == CL_VIRUS) { mdprintf(odesc, "%s: %s FOUND\n", filename, virname); logg("%s: %s FOUND\n", filename, virname); - virusaction(virname, copt); + virusaction(filename, virname, copt); } else if(ret != CL_CLEAN) { mdprintf(odesc, "%s: %s ERROR\n", filename, cl_strerror(ret)); logg("%s: %s ERROR\n", filename, cl_strerror(ret)); @@ -266,6 +266,7 @@ int ret; const char *virname; struct stat statbuf; + char fdstr[32]; if(fstat(fd, &statbuf) == -1) @@ -274,19 +275,21 @@ if(!S_ISREG(statbuf.st_mode)) return -1; + snprintf(fdstr, sizeof(fdstr), "fd[%d]", fd); + ret = cl_scandesc(fd, &virname, scanned, root, limits, options); if(ret == CL_VIRUS) { - mdprintf(odesc, "fd[%d]: %s FOUND\n", fd, virname); - logg("fd[%d]: %s FOUND\n", fd, virname); - virusaction(virname, copt); + mdprintf(odesc, "%s: %s FOUND\n", fdstr, virname); + logg("%s: %s FOUND\n", fdstr, virname); + virusaction(fdstr, virname, copt); } else if(ret != CL_CLEAN) { - mdprintf(odesc, "fd[%d]: %s ERROR\n", fd, cl_strerror(ret)); - logg("fd[%d]: %s ERROR\n", fd, cl_strerror(ret)); + mdprintf(odesc, "%s: %s ERROR\n", fdstr, cl_strerror(ret)); + logg("%s: %s ERROR\n", fdstr, cl_strerror(ret)); } else { - mdprintf(odesc, "fd[%d]: OK\n", fd); + mdprintf(odesc, "%s: OK\n", fdstr); if(logok) - logg("fd[%d]: OK\n", fd); + logg("%s: OK\n", fdstr); } return ret; @@ -467,7 +470,7 @@ if(ret == CL_VIRUS) { mdprintf(odesc, "stream: %s FOUND\n", virname); logg("stream: %s FOUND\n", virname); - virusaction(virname, copt); + virusaction("stream", virname, copt); } else if(ret != CL_CLEAN) { mdprintf(odesc, "stream: %s ERROR\n", cl_strerror(ret)); logg("stream: %s ERROR\n", cl_strerror(ret));
_______________________________________________ http://lurker.clamav.net/list/clamav-devel.html