In debian 5.0, _FFR_WORKERS_POOL is enabled by default. I'm running this for many years on some OSs, including Debian Etch and Lenny. There is a bug in the WORKERS_POOL feature which can segfaults and kill the filter when old staled connections are closed.

I'm attaching a patch which corrects this bug and also some other minor 
harmless bugs.

This patch will be included in the next release of sendmail.



--- worker.c.org        2007-12-03 23:06:05.000000000 +0100
+++ worker.c    2009-06-12 19:46:17.000000000 +0200
@@ -328,6 +328,7 @@
        int dim_pfd = 0;
        bool rebuild_set = true;
        int pcnt = 0; /* error count for poll() failures */
+       time_t lastcheck;
 
        Tskmgr.tm_tid = sthread_get_id();
        if (pthread_detach(Tskmgr.tm_tid) != 0)
@@ -345,12 +346,12 @@
        }
        dim_pfd = PFD_STEP;
 
+       lastcheck = time(NULL);
        for (;;)
        {
                SMFICTX_PTR ctx;
-               int nfd, rfd, i;
+               int nfd = 0, rfd, i;
                time_t now;
-               time_t lastcheck;
 
                POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
 
@@ -364,20 +365,20 @@
                /* check for timed out sessions? */
                if (lastcheck + DT_CHECK_OLD_SESSIONS < now)
                {
-                       SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
+                       ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
+                       while (ctx != SM_TAILQ_END(&WRK_CTX_HEAD))
                        {
+                               SMFICTX_PTR ctx_nxt;
+
+                               ctx_nxt = SM_TAILQ_NEXT(ctx, ctx_link);
                                if (ctx->ctx_wstate == WKST_WAITING)
                                {
                                        if (ctx->ctx_wait == 0)
-                                       {
                                                ctx->ctx_wait = now;
-                                               continue;
-                                       }
-
-                                       /* if session timed out, close it */
-                                       if (ctx->ctx_wait + OLD_SESSION_TIMEOUT
-                                           < now)
+                                       else if (ctx->ctx_wait + 
OLD_SESSION_TIMEOUT
+                                                < now)
                                        {
+                                               /* if session timed out, close 
it */
                                                sfsistat (*fi_close) 
__P((SMFICTX *));
 
                                                POOL_LEV_DPRINTF(4,
@@ -389,10 +390,9 @@
                                                        (void) (*fi_close)(ctx);
 
                                                mi_close_session(ctx);
-                                               ctx = 
SM_TAILQ_FIRST(&WRK_CTX_HEAD);
-                                               continue;
                                        }
                                }
+                               ctx = ctx_nxt;
                        }
                        lastcheck = now;
                }
@@ -465,6 +465,7 @@
                                        }
                                }
                        }
+                       rebuild_set = false;
                }
 
                TASKMGR_UNLOCK();

Reply via email to