Hello!

   I think I fixed race condition in clamd. You initialized startup time of
thread after its flag set to active and after thread is created. Creation of
new thread sometimes switches timeslice to the monitor, it compares current
time with that unitialized value and sometimes kills the new thread
complaining about timeout to syslog. Try to

clamdscan bigfile & clamdscan bigfile & clamdscan bigfile & clamdscan
bigfile & clamdscan bigfile & clamdscan bigfile & clamdscan bigfile &
clamdscan bigfile & clamdscan bigfile & clamdscan bigfile & clamdscan
bigfile & clamdscan bigfile & clamdscan bigfile & clamdscan bigfile &
clamdscan bigfile & clamdscan bigfile & clamdscan bigfile & clamdscan
bigfile &

with enough big amount of maxchildren (I use 20) and look if some of them
die because of instant timeout.

   I suggest to initialize ths[i].active and ths[i].start in thread function
itself. And it is good to close descriptor if the thread did not start (due
to lack of system resources, for example).

  Another thing in clamd is it uses FILE *tmp to create temporary file for
stream, but closes only file descriptor, not whole stream.

  Clamav-milter sometimes hang on final while(recv(...)) trying to wait for
clamd to close stream.

  And thing not covered by this patch is file descriptor leakage in clamd.
Under linux go to /proc/<CLAMD-PID>/fd and compare its contents right after
startup and after several hours of milter operation. With my patch you'll be
able to see increasing filedescriptor number when accepting connection.
netstat shows hanging connections to clamd command socket.

  Following patch added some stability on my system...

misha.

diff -ru clamav-devel/clamav-milter/clamav-milter.c 
clamav-devel.misha/clamav-milter/clamav-milter.c
--- clamav-devel/clamav-milter/clamav-milter.c  Wed Oct 22 23:44:01 2003
+++ clamav-devel.misha/clamav-milter/clamav-milter.c    Wed Oct 29 19:30:39 2003
@@ -1358,8 +1365,9 @@
                        /*
                         * Flush the remote end so that clamd doesn't get a SIGPIPE
                         */
-                       while(recv(privdata->cmdSocket, buf, sizeof(buf), 0) > 0)
-                               ;
+// clamd seems to forget about this...
+//                     while(recv(privdata->cmdSocket, buf, sizeof(buf), 0) > 0)
+//                             ;
                        close(privdata->cmdSocket);
                        privdata->cmdSocket = -1;
                }
diff -ru clamav-devel/clamd/scanner.c clamav-devel.misha/clamd/scanner.c
--- clamav-devel/clamd/scanner.c        Sun Oct 26 09:00:57 2003
+++ clamav-devel.misha/clamd/scanner.c  Wed Oct 29 22:00:12 2003
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <errno.h>
 #include <clamav.h>

 #include "cfgfile.h"
@@ -180,7 +181,7 @@
        char *virname, buff[32768];
        struct sockaddr_in server;
        struct cfgstruct *cpt;
-       FILE *tmp;
+       FILE *tmp=NULL;


     while(!binded && portscan--) {
@@ -219,12 +220,13 @@
     }


-    logg("*Accepted connection on port %d\n", port);
+    logg("*Accepted connection on port %d, fd %d\n", port, acceptd);

     if(cfgopt(copt, "StreamSaveToDisk")) {
        if((tmp = tmpfile()) == NULL) {
            shutdown(sockfd, 2);
            close(sockfd);
+           close(acceptd);
            mdprintf(odesc, "Temporary file ERROR\n");
            logg("!ScanStream: Can't create temporary file.\n");
            return -1;
@@ -240,18 +242,22 @@
            if(maxsize && (size + sizeof(buff)) > maxsize) {
                shutdown(sockfd, 2);
                close(sockfd);
+               close(acceptd);
                mdprintf(odesc, "Size exceeded ERROR\n");
                logg("^ScanStream: Size exceeded (stopped at %d, max: %d)\n", size, 
maxsize);
-               close(tmpd);
+               if(tmp)
+                 fclose(tmp);
                return -1;
            }

            if(write(tmpd, buff, bread) < 0) {
                shutdown(sockfd, 2);
                close(sockfd);
+               close(acceptd);
                mdprintf(odesc, "Temporary file -> write ERROR\n");
-               logg("!ScanStream: Can't write to temporary file.\n");
-               close(tmpd);
+               logg("!ScanStream: Can't write %d bytes to temporary file: %d\n", 
bread, errno);
+               if(tmp)
+                 fclose(tmp);
                return -1;
            }

@@ -259,7 +265,8 @@

        lseek(tmpd, 0, SEEK_SET);
        ret = cl_scandesc(tmpd, &virname, scanned, root, limits, options);
-       close(tmpd);
+       if(tmp)
+         fclose(tmp);

     } else
        ret = cl_scandesc(acceptd, &virname, scanned, root, limits, 0);
diff -ru clamav-devel/clamd/server.c clamav-devel.misha/clamd/server.c
--- clamav-devel/clamd/server.c Wed Oct  8 14:40:53 2003
+++ clamav-devel.misha/clamd/server.c   Thu Oct 30 00:28:26 2003
@@ -63,6 +63,8 @@
        sigset_t sigset;
        int bread, options, maxwait = CL_DEFAULT_MAXWHILEWAIT;

+    ths[tharg->sid].start=time(NULL);
+    ths[tharg->sid].active=1;

     /* ignore all signals */
     sigfillset(&sigset);
@@ -512,6 +514,7 @@
     sigaddset(&sigact.sa_mask, SIGHUP);
     sigaction(SIGINT, &sigact, NULL);
     sigaction(SIGTERM, &sigact, NULL);
+    sigaction(SIGPIPE, &sigact, NULL);
 #ifndef CL_DEBUG
     sigaction(SIGSEGV, &sigact, NULL);
 #endif
@@ -582,9 +585,10 @@
        tharg->options = options;

        ths[i].desc = acceptd;
-       ths[i].active = 1;
-       pthread_create(&ths[i].id, &thattr, threadscanner, tharg);
-       ths[i].start = time(NULL);
+       if(pthread_create(&ths[i].id, &thattr, threadscanner, tharg)!=0) {
+           logg("Session(%d) did not start. Dropping connection.",i);
+           close(acceptd);
+       }
     }
 }

@@ -625,6 +629,9 @@
        case SIGHUP:
            sighup = 1;
            logg("SIGHUP catched: log file re-opened.\n");
+           break;
+       case SIGPIPE:
+           logg("SIGPIPE catched by pthread id %d.\n", (int)pthread_self());
            break;
     }
 }




-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?   SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/
_______________________________________________
Clamav-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/clamav-devel

Reply via email to