tags 527862 + patch security thanks The last few days I've had both clamav-milter and spamass-milter segfault on two separate servers both running Debian lenny:
Jul 13 04:59:53 canardo kernel: [9021793.803024] spamass-milter[22767]: segfault at 130 ip 7f94da384900 sp 429190e0 error 4 in libmilter.so.1.0.1[7f94da379000+f000] Jul 13 05:00:33 canardo kernel: [9021863.827618] clamav-milter[22887]: segfault at 130 ip 7f7aaa945900 sp 4234b0f0 error 4 in libmilter.so.1.0.1[7f7aaa93a000+f000] Jul 13 05:55:57 huey kernel: [4728098.560126] spamass-milter[20935]: segfault at 130 ip 7fa1b92d1900 sp 4178a0e0 error 4 in libmilter.so.1.0.1[7fa1b92c6000+f000] This might be because they are handling mail for some of the same domains, and that a single buggy mail server is bringing them both down. But I believe it is still a somewhat serious security issue, as it is obviously possible to bring down virus and spam filtering by a remote connection. I'm now testing a modified version of the patch attached to this bug, and this seems to fix the problem. Please consider adding this to Lenny as a security fix. Thanks. Note that I suspect that the patch has a bug which prevents it from working (all milters would just hang with the original patch): > - int nfd, rfd, i; > + int nfd = 0, rfd, i; I don't think setting nfd = 0 at this point makes sense. If we hit /* timeout */ if (rfd == 0) continue; then the loop will continue with rebuild_set == false and nfd == 0. I'm attaching a new patch where this is fixed. Bjørn
--- ./libmilter/worker.c.bak 2009-07-13 17:41:07.000000000 +0200 +++ ./libmilter/worker.c 2009-07-13 17:47:31.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; 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();