diff options
author | John Beck <John.Beck@Sun.COM> | 2010-01-06 13:22:51 -0800 |
---|---|---|
committer | John Beck <John.Beck@Sun.COM> | 2010-01-06 13:22:51 -0800 |
commit | e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9be (patch) | |
tree | 6a7ad97561f2580625546f56c063c89ebb3b92dd /usr/src/cmd/sendmail/libmilter | |
parent | 5f8171005a0c33f3c67f7da52d41c2362c3fd891 (diff) | |
download | illumos-joyent-e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9be.tar.gz |
6913961 upgrade sendmail to 8.14.4
6790772 Array overrun in sendmail
Diffstat (limited to 'usr/src/cmd/sendmail/libmilter')
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/comm.c | 21 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/engine.c | 145 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/example.c | 6 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/handler.c | 23 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/libmilter.h | 5 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/listener.c | 9 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/main.c | 7 | ||||
-rw-r--r-- | usr/src/cmd/sendmail/libmilter/worker.c | 49 |
8 files changed, 177 insertions, 88 deletions
diff --git a/usr/src/cmd/sendmail/libmilter/comm.c b/usr/src/cmd/sendmail/libmilter/comm.c index fd64922d37..e04681c8d0 100644 --- a/usr/src/cmd/sendmail/libmilter/comm.c +++ b/usr/src/cmd/sendmail/libmilter/comm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,10 +8,8 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: comm.c,v 8.66 2004/08/20 20:38:35 ca Exp $") +SM_RCSID("@(#)$Id: comm.c,v 8.70 2009/12/16 16:33:48 ca Exp $") #include "libmilter.h" #include <sm/errstring.h> @@ -20,7 +18,6 @@ SM_RCSID("@(#)$Id: comm.c,v 8.66 2004/08/20 20:38:35 ca Exp $") static ssize_t retry_writev __P((socket_t, struct iovec *, int, struct timeval *)); static size_t Maxdatasize = MILTER_MAX_DATA_SIZE; -#if _FFR_MAXDATASIZE /* ** SMFI_SETMAXDATASIZE -- set limit for milter data read/write. ** @@ -41,7 +38,6 @@ smfi_setmaxdatasize(sz) Maxdatasize = sz; return old; } -#endif /* _FFR_MAXDATASIZE */ /* ** MI_RD_CMD -- read a command @@ -124,8 +120,8 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) else if (ret < 0) { smi_log(SMI_LOG_ERR, - "%s: mi_rd_cmd: select returned %d: %s", - name, ret, sm_errstring(errno)); + "%s: mi_rd_cmd: %s() returned %d: %s", + name, MI_POLLSELECT, ret, sm_errstring(errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -216,8 +212,8 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) if (ret < 0) { smi_log(SMI_LOG_ERR, - "%s: mi_rd_cmd: select returned %d: %s", - name, ret, sm_errstring(save_errno)); + "%s: mi_rd_cmd: %s() returned %d: %s", + name, MI_POLLSELECT, ret, sm_errstring(save_errno)); *cmd = SMFIC_RECVERR; return NULL; } @@ -328,7 +324,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) char *buf; size_t len; { - size_t sl, i; + size_t sl; ssize_t l; mi_int32 nl; int iovcnt; @@ -341,7 +337,6 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) nl = htonl(len + 1); /* add 1 for the cmd char */ (void) memcpy(data, (void *) &nl, MILTER_LEN_BYTES); data[MILTER_LEN_BYTES] = (char) cmd; - i = 0; sl = MILTER_LEN_BYTES + 1; /* set up the vector for the size / command */ @@ -354,7 +349,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) iov[1].iov_len = len; iovcnt = 2; } - + l = retry_writev(sd, iov, iovcnt, timeout); if (l == MI_FAILURE) return MI_FAILURE; diff --git a/usr/src/cmd/sendmail/libmilter/engine.c b/usr/src/cmd/sendmail/libmilter/engine.c index b10a926dd3..a2d3e1e3f3 100644 --- a/usr/src/cmd/sendmail/libmilter/engine.c +++ b/usr/src/cmd/sendmail/libmilter/engine.c @@ -8,10 +8,8 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: engine.c,v 8.162 2008/02/27 01:34:14 ca Exp $") +SM_RCSID("@(#)$Id: engine.c,v 8.166 2009/11/06 00:57:07 ca Exp $") #include "libmilter.h" @@ -115,6 +113,7 @@ static void fix_stm __P((SMFICTX_PTR)); static bool trans_ok __P((int, int)); static char **dec_argv __P((char *, size_t)); static int dec_arg2 __P((char *, size_t, char **, char **)); +static void mi_clr_symlist __P((SMFICTX_PTR)); #if _FFR_WORKERS_POOL static bool mi_rd_socket_ready __P((int)); @@ -760,6 +759,69 @@ mi_clr_macros(ctx, m) } /* +** MI_CLR_SYMLIST -- clear list of macros +** +** Parameters: +** ctx -- context structure +** +** Returns: +** None. +*/ + +static void +mi_clr_symlist(ctx) + SMFICTX *ctx; +{ + int i; + + SM_ASSERT(ctx != NULL); + for (i = SMFIM_FIRST; i <= SMFIM_LAST; i++) + { + if (ctx->ctx_mac_list[i] != NULL) + { + free(ctx->ctx_mac_list[i]); + ctx->ctx_mac_list[i] = NULL; + } + } +} + +/* +** MI_CLR_CTX -- clear context +** +** Parameters: +** ctx -- context structure +** +** Returns: +** None. +*/ + +void +mi_clr_ctx(ctx) + SMFICTX *ctx; +{ + SM_ASSERT(ctx != NULL); + if (ValidSocket(ctx->ctx_sd)) + { + (void) closesocket(ctx->ctx_sd); + ctx->ctx_sd = INVALID_SOCKET; + } + if (ctx->ctx_reply != NULL) + { + free(ctx->ctx_reply); + ctx->ctx_reply = NULL; + } + if (ctx->ctx_privdata != NULL) + { + smi_log(SMI_LOG_WARN, + "%s: private data not NULL", + ctx->ctx_smfi->xxfi_name); + } + mi_clr_macros(ctx, 0); + mi_clr_symlist(ctx); + free(ctx); +} + +/* ** ST_OPTIONNEG -- negotiate options ** ** Parameters: @@ -773,8 +835,11 @@ static int st_optionneg(g) genarg *g; { - mi_int32 i, v, fake_pflags; + mi_int32 i, v, fake_pflags, internal_pflags; SMFICTX_PTR ctx; +#if _FFR_MILTER_CHECK + bool testmode = false; +#endif /* _FFR_MILTER_CHECK */ int (*fi_negotiate) __P((SMFICTX *, unsigned long, unsigned long, unsigned long, unsigned long, @@ -828,6 +893,7 @@ st_optionneg(g) v = SMFI_V1_ACTS; ctx->ctx_mta_aflags = v; /* MTA action flags */ + internal_pflags = 0; (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES * 2]), MILTER_LEN_BYTES); v = ntohl(i); @@ -835,7 +901,51 @@ st_optionneg(g) /* no flags? set to default value for V1 protocol */ if (v == 0) v = SMFI_V1_PROT; - ctx->ctx_mta_pflags = v; /* MTA protocol flags */ +#if _FFR_MDS_NEGOTIATE + else if (ctx->ctx_smfi->xxfi_version >= SMFI_VERSION_MDS) + { + /* + ** Allow changing the size only if milter is compiled + ** against a version that supports this. + ** If a milter is dynamically linked against a newer + ** libmilter version, we don't want to "surprise" + ** it with a larger buffer as it may rely on it + ** even though it is not documented as a limit. + */ + + if (bitset(SMFIP_MDS_1M, v)) + { + internal_pflags |= SMFIP_MDS_1M; + (void) smfi_setmaxdatasize(MILTER_MDS_1M); + } + else if (bitset(SMFIP_MDS_256K, v)) + { + internal_pflags |= SMFIP_MDS_256K; + (void) smfi_setmaxdatasize(MILTER_MDS_256K); + } + } +# if 0 + /* don't log this for now... */ + else if (ctx->ctx_smfi->xxfi_version < SMFI_VERSION_MDS && + bitset(SMFIP_MDS_1M|SMFIP_MDS_256K, v)) + { + smi_log(SMI_LOG_WARN, + "%s: st_optionneg[%ld]: milter version=%X, trying flags=%X", + ctx->ctx_smfi->xxfi_name, + (long) ctx->ctx_id, ctx->ctx_smfi->xxfi_version, v); + } +# endif /* 0 */ +#endif /* _FFR_MDS_NEGOTIATE */ + + /* + ** MTA protocol flags. + ** We pass the internal flags to the milter as "read only", + ** i.e., a milter can read them so it knows which size + ** will be used, but any changes by a milter will be ignored + ** (see below, search for SMFI_INTERNAL). + */ + + ctx->ctx_mta_pflags = (v & ~SMFI_INTERNAL) | internal_pflags; /* ** Copy flags from milter struct into libmilter context; @@ -882,6 +992,12 @@ st_optionneg(g) 0, 0, &m_aflags, &m_pflags, &m_f2, &m_f3); +#if _FFR_MILTER_CHECK + testmode = bitset(SMFIP_TEST, m_pflags); + if (testmode) + m_pflags &= ~SMFIP_TEST; +#endif /* _FFR_MILTER_CHECK */ + /* ** Types of protocol flags (pflags): ** 1. do NOT send protocol step X @@ -1013,6 +1129,25 @@ st_optionneg(g) , ctx->ctx_mta_aflags, ctx->ctx_mta_pflags , ctx->ctx_aflags, ctx->ctx_pflags); +#if _FFR_MILTER_CHECK + if (ctx->ctx_dbg > 3) + sm_dprintf("[%ld] milter_negotiate:" + " testmode=%d, pflags2mta=%X, internal_pflags=%X\n" + , (long) ctx->ctx_id, testmode + , ctx->ctx_pflags2mta, internal_pflags); + + /* in test mode: take flags without further modifications */ + if (!testmode) + /* Warning: check statement below! */ +#endif /* _FFR_MILTER_CHECK */ + + /* + ** Remove the internal flags that might have been set by a milter + ** and set only those determined above. + */ + + ctx->ctx_pflags2mta = (ctx->ctx_pflags2mta & ~SMFI_INTERNAL) + | internal_pflags; return _SMFIS_OPTIONS; } diff --git a/usr/src/cmd/sendmail/libmilter/example.c b/usr/src/cmd/sendmail/libmilter/example.c index 8d9b057e45..cef4b0f33a 100644 --- a/usr/src/cmd/sendmail/libmilter/example.c +++ b/usr/src/cmd/sendmail/libmilter/example.c @@ -6,11 +6,9 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: example.c,v 8.3 2006/12/20 21:22:34 ca Exp $ + * $Id: example.c,v 8.4 2008/07/22 15:12:47 ca Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* ** A trivial example filter that logs all email to a file. ** This milter also has some callbacks which it does not really use, @@ -254,7 +252,7 @@ struct smfiDesc smfilter = mlfi_close, /* connection cleanup */ mlfi_unknown, /* unknown/unimplemented SMTP commands */ mlfi_data, /* DATA command filter */ - mlfi_negotiate /* option negotation at connection startup */ + mlfi_negotiate /* option negotiation at connection startup */ }; int diff --git a/usr/src/cmd/sendmail/libmilter/handler.c b/usr/src/cmd/sendmail/libmilter/handler.c index faca90460a..2c34f1f05d 100644 --- a/usr/src/cmd/sendmail/libmilter/handler.c +++ b/usr/src/cmd/sendmail/libmilter/handler.c @@ -8,10 +8,8 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: handler.c,v 8.38 2006/11/02 02:38:22 ca Exp $") +SM_RCSID("@(#)$Id: handler.c,v 8.39 2008/11/25 01:14:16 ca Exp $") #include "libmilter.h" @@ -45,24 +43,7 @@ mi_handle_session(ctx) ret = MI_FAILURE; else ret = mi_engine(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(ctx->ctx_sd); - ctx->ctx_sd = INVALID_SOCKET; - } - if (ctx->ctx_reply != NULL) - { - free(ctx->ctx_reply); - ctx->ctx_reply = NULL; - } - if (ctx->ctx_privdata != NULL) - { - smi_log(SMI_LOG_WARN, - "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); + mi_clr_ctx(ctx); ctx = NULL; return ret; } diff --git a/usr/src/cmd/sendmail/libmilter/libmilter.h b/usr/src/cmd/sendmail/libmilter/libmilter.h index 93e0b088de..5824151da3 100644 --- a/usr/src/cmd/sendmail/libmilter/libmilter.h +++ b/usr/src/cmd/sendmail/libmilter/libmilter.h @@ -14,14 +14,12 @@ #ifndef _LIBMILTER_H # define _LIBMILTER_H 1 -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> #ifdef _DEFINE # define EXTERN # define INIT(x) = x -SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.74 2006/12/19 18:19:52 ca Exp $") +SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.77 2008/11/25 18:28:18 ca Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -284,6 +282,7 @@ extern int mi_handle_session __P((SMFICTX_PTR)); extern int mi_engine __P((SMFICTX_PTR)); extern int mi_listener __P((char *, int, smfiDesc_ptr, time_t, int)); extern void mi_clr_macros __P((SMFICTX_PTR, int)); +extern void mi_clr_ctx __P((SMFICTX_PTR)); extern int mi_stop __P((void)); extern int mi_control_startup __P((char *)); extern void mi_stop_milters __P((int)); diff --git a/usr/src/cmd/sendmail/libmilter/listener.c b/usr/src/cmd/sendmail/libmilter/listener.c index e9f62f2e7b..48c552fddd 100644 --- a/usr/src/cmd/sendmail/libmilter/listener.c +++ b/usr/src/cmd/sendmail/libmilter/listener.c @@ -8,10 +8,8 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: listener.c,v 8.124 2007/04/23 22:22:50 ca Exp $") +SM_RCSID("@(#)$Id: listener.c,v 8.126 2009/12/16 16:40:23 ca Exp $") /* ** listener.c -- threaded network listener @@ -779,8 +777,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog) continue; scnt++; smi_log(SMI_LOG_ERR, - "%s: select() failed (%s), %s", - smfi->xxfi_name, sm_errstring(save_errno), + "%s: %s() failed (%s), %s", + smfi->xxfi_name, MI_POLLSELECT, + sm_errstring(save_errno), scnt >= MAX_FAILS_S ? "abort" : "try again"); MI_SLEEP(scnt); if (scnt >= MAX_FAILS_S) diff --git a/usr/src/cmd/sendmail/libmilter/main.c b/usr/src/cmd/sendmail/libmilter/main.c index b8609cd785..d6e727959d 100644 --- a/usr/src/cmd/sendmail/libmilter/main.c +++ b/usr/src/cmd/sendmail/libmilter/main.c @@ -8,10 +8,8 @@ * */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: main.c,v 8.83 2007/04/23 22:22:50 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.84 2008/09/02 05:37:06 ca Exp $") #define _DEFINE 1 #include "libmilter.h" @@ -54,7 +52,8 @@ smfi_register(smfilter) (void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len); /* compare milter version with hard coded version */ - if (smfi->xxfi_version != SMFI_VERSION && + if ((SM_LM_VRS_MAJOR(smfi->xxfi_version) != SM_LM_VRS_MAJOR(SMFI_VERSION) || + SM_LM_VRS_MINOR(smfi->xxfi_version) != SM_LM_VRS_MINOR(SMFI_VERSION)) && smfi->xxfi_version != 2 && smfi->xxfi_version != 3 && smfi->xxfi_version != 4) diff --git a/usr/src/cmd/sendmail/libmilter/worker.c b/usr/src/cmd/sendmail/libmilter/worker.c index 929c94ca92..28d404fa3a 100644 --- a/usr/src/cmd/sendmail/libmilter/worker.c +++ b/usr/src/cmd/sendmail/libmilter/worker.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004, 2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 2003-2004, 2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,10 +10,8 @@ * Jose-Marcio.Martins@ensmp.fr */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sm/gen.h> -SM_RCSID("@(#)$Id: worker.c,v 8.10 2007/12/03 22:06:05 ca Exp $") +SM_RCSID("@(#)$Id: worker.c,v 8.17 2009/06/15 15:34:54 ca Exp $") #include "libmilter.h" @@ -212,23 +210,7 @@ mi_close_session(ctx) SM_ASSERT(ctx != NULL); (void) mi_list_del_ctx(ctx); - if (ValidSocket(ctx->ctx_sd)) - { - (void) closesocket(ctx->ctx_sd); - ctx->ctx_sd = INVALID_SOCKET; - } - if (ctx->ctx_reply != NULL) - { - free(ctx->ctx_reply); - ctx->ctx_reply = NULL; - } - if (ctx->ctx_privdata != NULL) - { - smi_log(SMI_LOG_WARN, "%s: private data not NULL", - ctx->ctx_smfi->xxfi_name); - } - mi_clr_macros(ctx, 0); - free(ctx); + mi_clr_ctx(ctx); return MI_SUCCESS; } @@ -261,7 +243,7 @@ mi_pool_controller_init() if (pipe(Tskmgr.tm_p) != 0) { smi_log(SMI_LOG_ERR, "can't create event pipe: %s", - sm_errstring(r)); + sm_errstring(errno)); return MI_FAILURE; } @@ -330,6 +312,7 @@ mi_pool_controller(arg) 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) @@ -347,12 +330,12 @@ mi_pool_controller(arg) } 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)); @@ -366,20 +349,20 @@ mi_pool_controller(arg) /* 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, @@ -391,10 +374,9 @@ mi_pool_controller(arg) (void) (*fi_close)(ctx); mi_close_session(ctx); - ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD); - continue; } } + ctx = ctx_nxt; } lastcheck = now; } @@ -467,6 +449,7 @@ mi_pool_controller(arg) } } } + rebuild_set = false; } TASKMGR_UNLOCK(); |