diff --git a/libmilter/listener.c b/libmilter/listener.c index cd3f6e8..c45683c 100644 --- a/libmilter/listener.c +++ b/libmilter/listener.c @@ -728,6 +728,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) int acnt = 0; /* error count for accept() failures */ int scnt = 0; /* error count for select() failures */ int save_errno = 0; + int fdflags; #if !_FFR_WORKERS_POOL sthread_t thread_id; #endif /* !_FFR_WORKERS_POOL */ @@ -808,6 +809,19 @@ mi_listener(conn, dbg, smfi, timeout, backlog) (void) smutex_unlock(&L_Mutex); /* + ** Need to set close-on-exec for connfd in case a user's + ** filter starts other applications + */ + if ((fdflags = fcntl(connfd, F_GETFD, 0)) == -1 || + fcntl(connfd, F_SETFD, fdflags | FD_CLOEXEC) == -1) + { + smi_log(SMI_LOG_WARN, + "%s: Unable to set close-on-exec on connfd (%s)", + smfi->xxfi_name, sm_errstring(errno)); + /* XXX: continue? */ + } + + /* ** If remote side closes before accept() finishes, ** sockaddr might not be fully filled in. */ diff --git a/sendmail/milter.c b/sendmail/milter.c index 88f8b60..f9de6b1 100644 --- a/sendmail/milter.c +++ b/sendmail/milter.c @@ -30,6 +30,9 @@ SM_RCSID("@(#)$Id: milter.c,v 8.281 2013/11/22 20:51:56 ca Exp $") # include +# include +# include + static void milter_connect_timeout __P((int)); static void milter_error __P((struct milter *, ENVELOPE *)); static int milter_open __P((struct milter *, bool, ENVELOPE *)); @@ -655,6 +658,7 @@ milter_open(m, parseonly, e) SOCKADDR_LEN_T addrlen = 0; int addrno = 0; int save_errno; + int fdflags; char *p; char *colon; char *at; @@ -1191,6 +1195,21 @@ milter_open(m, parseonly, e) (char *)&nodelay, sizeof(nodelay)); } # endif /* MILTER_NO_NAGLE && !defined(TCP_CORK) */ + + /* + ** Need to set close-on-exec for sock to prevent it + ** leaking to the local delivery process + */ + if ((fdflags = fcntl(sock, F_GETFD, 0)) == -1 || + fcntl(sock, F_SETFD, fdflags | FD_CLOEXEC) == -1) + { + save_errno = errno; + if (MilterLogLevel > 0) + sm_syslog(LOG_WARNING, e->e_id, + "Milter (%s): Unable to set close-on-exec on sock (%s)", + m->mf_name, sm_errstring(save_errno = errno)); + } + return sock; }