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();