diff --git a/mail/exim/Makefile b/mail/exim/Makefile index 874f352e5ae3..efb374f816e3 100644 --- a/mail/exim/Makefile +++ b/mail/exim/Makefile @@ -1,672 +1,651 @@ # Created by: markm@FreeBSD.org PORTNAME= exim PORTVERSION?= ${EXIM_VERSION} -PORTREVISION?= 2 +PORTREVISION?= 0 CATEGORIES= mail MASTER_SITES= EXIM:exim MASTER_SITE_SUBDIR= /exim4/:exim \ /exim4/fixes/:exim \ /exim4/old/:exim DISTNAME= ${PORTNAME}-${EXIM_VERSION} DISTFILES= ${DISTNAME}${EXTRACT_SUFX}:exim DIST_SUBDIR= exim EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX} MAINTAINER= fluffy@FreeBSD.org COMMENT?= High performance MTA for Unix systems on the Internet LICENSE= GPLv2 USES= compiler cpe tar:bzip2 perl5 USE_CSTD= c99 USE_PERL5= run # Exim build system is job unsafe atm MAKE_JOBS_UNSAFE= yes # One can tune the following "hidden" knobs: # - EXIM_USER: user exim is running as; # - EXIM_GROUP: ditto for the group; # - LOGDIR: where Exim logs will be put; # - LOG_FILE_PATH: path where '%s' will be substituted with # the target name (main, reject, etc); # - CONFIG_FILE_PATH: path to the default configuration file; # - ALT_CONFIG_PREFIX: path to the default prefix for all # configuration files, excluding the main one; # will be effective only when WITH_ALT_CONFIG_PREFIX # will be set via OPTIONS. .if make(makesum) && !defined(FETCH_ALL) .error "You forgot to define FETCH_ALL to create the sane distinfo" .endif .include "options" OPTIONS_SUB= yes AUTH_SASL_LIB_DEPENDS= libsasl2.so:security/cyrus-sasl2 BDB_USES= bdb DMARC_LIB_DEPENDS= libopendmarc.so:mail/opendmarc EMBEDDED_PERL_USE= perl5=run,build EXIMON_USES= xorg EXIMON_USE= xorg=x11,xaw,xext,xmu,xt GNUTLS_LIB_DEPENDS= libgnutls.so:security/gnutls ICONV_USES= iconv:lib,build INTERNATIONAL_LIB_DEPENDS= libidn.so:dns/libidn LMDB_LIB_DEPENDS= liblmdb.so:databases/lmdb MYSQL_USES= mysql OPENLDAP_USE= openldap=yes PGSQL_LIB_DEPENDS= libicudata.so:devel/icu PGSQL_USES= pgsql pkgconfig REDIS_LIB_DEPENDS= libhiredis.so:databases/hiredis SASLAUTHD_RUN_DEPENDS= ${LOCALBASE}/sbin/saslauthd:security/cyrus-sasl2-saslauthd SA_EXIM_RUN_DEPENDS= ${LOCALBASE}/bin/spamc:mail/spamassassin SPF_LIB_DEPENDS= libspf2.so:mail/libspf2 SQLITE_LIB_DEPENDS= libicudata.so:devel/icu SQLITE_USES= pkgconfig sqlite -TAINTWARN_PATCHES_PREFIX= ${FILESDIR}/debian/75 -TAINTWARN_EXTRA_PATCHES= \ - ${TAINTWARN_PATCHES_PREFIX}_01-Introduce-main-config-option-allow_insecure_tainted_.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_02-search.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_03-dbstuff.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_04-acl.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_05-parse.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_06-rda.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_07-appendfile.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_08-autoreply.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_09-pipe.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_10-deliver.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_11-directory.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_12-expand.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_13-lf_sqlperform.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_14-rf_get_transport.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_15-deliver.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_16-smtp_out.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_17-smtp.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_18-update-doc.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_20-Set-mainlog_name-and-rejectlog_name-unconditionally.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_21-tidy-log.c.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_22-Silence-compiler.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_23-Do-not-close-the-main-_log-if-we-do-not-see-a-chance.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_24-Silence-the-compiler.patch:-p1 \ - ${TAINTWARN_PATCHES_PREFIX}_26-Disable-taintchecks-for-mkdir-this-isn-t-part-of-4.9.patch:-p1 +DEBIAN_PATCHES_PREFIX= ${FILESDIR}/debian/75 +EXTRA_PATCHES= \ + ${DEBIAN_PATCHES_PREFIX}_30-Avoid-calling-gettimeofday-select-per-char-for-cmdli.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_38-Convert-all-uses-of-select-to-poll.-Bug-2831.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_40-Fix-basic-memory-use-for-SPARC.-Bug-2838.patch:-p1 .include # OCSP is supported for openssl only .if ${PORT_OPTIONS:MOCSP} .if ! ${PORT_OPTIONS:MTLS} IGNORE= you cannot enable OCSP stapling without TLS support .elif ${PORT_OPTIONS:MGNUTLS} IGNORE= you cannot enable OCSP stapling with gnutls .endif .endif # DMARC implies SPF and DKIM .if ${PORT_OPTIONS:MDMARC} .if ! ${PORT_OPTIONS:MSPF} || ! ${PORT_OPTIONS:MDKIM} IGNORE= you cannot enable DMARC without SPF and DKIM support .endif .endif # ARC implies SPF and DKIM .if ${PORT_OPTIONS:MARC} .if ! ${PORT_OPTIONS:MSPF} || ! ${PORT_OPTIONS:MDKIM} IGNORE= you cannot enable ARC without SPF and DKIM support .endif .endif # DANE implies DNSSEC .if ${PORT_OPTIONS:MDANE} .if ! ${PORT_OPTIONS:MDNSSEC} || ! ${PORT_OPTIONS:MTLS} IGNORE= you cannot enable DANE without DNSSEC support or without TLS support .endif .endif .if ${PORT_OPTIONS:MSA_EXIM} || defined(FETCH_ALL) MASTER_SITES+= http://marc.merlins.org/linux/exim/files/:sa_exim \ SF/sa-exim/sa-exim/${SA_EXIM_VERSION}:sa_exim DISTFILES+= sa-exim-${SA_EXIM_VERSION}.tar.gz:sa_exim EXTRA_PATCHES+= ${FILESDIR}/extra-patch-Local-sa-exim.c EXTRA_PATCHES+= ${FILESDIR}/extra-patch-Local-sa-exim.conf .endif -EXIM_VERSION= 4.94.2 +EXIM_VERSION= 4.95 SA_EXIM_VERSION=4.2.1 EXIM_INSTALL_ARG+= "-no_chown" "-no_symlink" EXTRA_PATCHES+= `${FIND} ${PATCHDIR} -name '74_*.patch'|${SORT} -h` .if !defined(EXIMON_ONLY) PLIST_SUB+= EXIM="" .if defined(PKGNAMESUFFIX) CONFLICTS+= ${PKGNAMEPREFIX}${PORTNAME}-4.* .endif .for suffix in -ldap2 -mysql -postgresql -sa-exim -sqlite .if !defined(PKGNAMESUFFIX) || ${PKGNAMESUFFIX} != ${suffix} CONFLICTS+= ${PKGNAMEPREFIX}${PORTNAME}${suffix}-4.* .endif .endfor .if ${PORT_OPTIONS:MEXIMON} CONFLICTS+= ${PKGNAMEPREFIX}${PORTNAME}-monitor-4.* .endif PKGMESSAGE= ${WRKDIR}/POST-INSTALL-NOTES .else # !EXIMON_ONLY PLIST_SUB+= EXIM="@comment " PORT_OPTIONS+= EXIMON PKGMESSAGE= ${WRKDIR}/pkg-message EXIM_INSTALL_ARG+= "eximon" "eximon.bin" .endif # !EXIMON_ONLY PORTDOC_BASE= ACKNOWLEDGMENTS NOTICE README.UPDATING PORTDOC_FILES= ChangeLog Exim3.upgrade Exim4.upgrade NewStuff \ OptionLists.txt README README.SIEVE dbm.discuss.txt \ experimental-spec.txt filter.txt spec.txt PORT_EXAMPLES= convert4r3 convert4r4 transport-filter.pl DAILY_SCRIPTS= 150.exim-tidydb 460.exim-mail-rejects MAKE_ENV+= OSTYPE="${OPSYS}" ARCHTYPE="${ARCH}" DUMMY_LDFLAGS="${DUMMY_LDFLAGS}" STRIP_COMMAND="${STRIP_CMD}" EXIM_USER?= mailnull EXIM_GROUP?= mail # Default user/group are system ones, so we don't want to check them .if ${EXIM_USER} != "mailnull" USERS= ${EXIM_USER} .endif .if ${EXIM_GROUP} != "mail" GROUPS= ${EXIM_GROUP} .endif LOGDIR?= /var/log/exim LOG_FILE_PATH?= ${LOGDIR}/%slog CONFIG_FILE_PATH?= ${PREFIX}/etc/exim/configure ALT_CONFIG_PREFIX?= ${PREFIX}/etc/exim/ EXIM_DYNAMIC_LDFLAGS= -fPIC -rdynamic -Wl,--export-dynamic SED_SCRIPT= -e 's,%%PREFIX%%,${PREFIX},g' \ -e 's,%%DOCSDIR%%,${DOCSDIR},g' \ -e 's,%%EXAMPLESDIR%%,${EXAMPLESDIR},g' \ -e 's,%%EXIM_USER%%,${EXIM_USER},g' \ -e 's,%%EXIM_GROUP%%,${EXIM_GROUP},g' \ -e 's,%%LOGDIR%%,${LOGDIR},g' SEDLIST+= -e 's,XX_CFLAGS_XX,${CFLAGS:S/,/\\,/g},' \ -e 's,XX_PREFIX_XX,${PREFIX:S/,/\\,/g},' \ -e 's,XX_LOCALBASE_XX,${LOCALBASE:S/,/\\,/g},' \ -e 's,XX_LOG_FILE_PATH_XX,${LOG_FILE_PATH:S/,/\\,/g},' \ -e 's,XX_CONFIG_FILE_PATH_XX,${CONFIG_FILE_PATH:S/,/\\,/g},' \ -e 's,XX_ALT_CONFIG_PREFIX_XX,${ALT_CONFIG_PREFIX:S/,/\\,/g},' \ -e 's,XX_EXIM_USER_XX,${EXIM_USER:S/,/\\,/g},' \ -e 's,XX_EXIM_GROUP_XX,${EXIM_GROUP:S/,/\\,/g},' \ -e 's,XX_DEFAULT_CHARSET_XX,${WITH_DEFAULT_CHARSET:S/,/\\,/g},' \ -e 's,XX_DYNAMIC_LDFLAGS_XX,${EXIM_DYNAMIC_LDFLAGS:S/,/\\,/g},' PLIST_SUB+= EXIM_VERSION="${EXIM_VERSION}-${PORTREVISION}" \ EXIM_USER=${EXIM_USER} \ EXIM_GROUP=${EXIM_GROUP} \ LOGDIR="${LOGDIR:S/^\///}" # Exim refuses to run local deliveries as root by default. You can # add other users to this colon-separated list that cannot be # overridden at runtime below, but are advised not to remove "root". #WITH_FIXED_NEVER_USERS= root:daemon:bin # When Exim is decoding MIME "words" in header lines it converts any foreign # character sets to the one that is set in the headers_charset option. # The default setting is defined by this setting: WITH_DEFAULT_CHARSET?= ISO-8859-1 # You should not need to fiddle with anything below this point. LIB_DEPENDS+= libpcre.so:devel/pcre .if ! ${PORT_OPTIONS:MDKIM} SEDLIST+= -e 's,^\# (DISABLE_DKIM=),\1,' .endif .if ${PORT_OPTIONS:MLISTMATCH_RHS} SEDLIST+= -e 's,^\# (EXPAND_LISTMATCH_RHS=),\1,' .endif .if ${PORT_OPTIONS:MDCC} SEDLIST+= -e 's,^\# (EXPERIMENTAL_DCC=),\1,' .endif .if ${PORT_OPTIONS:MPROXY} SEDLIST+= -e 's,^\# (SUPPORT_PROXY=),\1,' .endif .if ${PORT_OPTIONS:MCERTNAMES} SEDLIST+= -e 's,^\# (EXPERIMENTAL_CERTNAMES=),\1,' .endif .if ${PORT_OPTIONS:MDSN} SEDLIST+= -e 's,^\# (EXPERIMENTAL_DSN=),\1,' .endif .if !${PORT_OPTIONS:MDANE} SEDLIST+= -e 's,^(SUPPORT_DANE=),\#\1,' .endif .if ${PORT_OPTIONS:MARC} SEDLIST+= -e 's,^\# (EXPERIMENTAL_ARC=),\1,' .endif .if !${PORT_OPTIONS:MEVENT} SEDLIST+= -e 's,^\# (DISABLE_EVENT=),\1,' .endif .if ${PORT_OPTIONS:MINTERNATIONAL} SEDLIST+= -e 's,^\# (SUPPORT_I18N=),\1,' \ -e 's,XX_IDN_LIBS_XX,-L${LOCALBASE}/lib -lidn,' .else SEDLIST+= -e 's,XX_IDN_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MSOCKS} SEDLIST+= -e 's,^\# (SUPPORT_SOCKS=),\1,' .endif .if !${PORT_OPTIONS:MPRDR} SEDLIST+= -e 's,^\# (DISABLE_PRDR=),\1,' .endif .if !${PORT_OPTIONS:MOCSP} SEDLIST+= -e 's,^\# (DISABLE_OCSP=),\1,' .endif .if !${PORT_OPTIONS:MDNSSEC} SEDLIST+= -e 's,^\# (DISABLE_DNSSEC=),\1,' .endif .if ${PORT_OPTIONS:MDMARC} SEDLIST+= -e 's,XX_DMARC_LIBS_XX,-L${LOCALBASE}/lib -lopendmarc,' \ -e 's,^\# (SUPPORT_DMARC=),\1,' .else SEDLIST+= -e 's,XX_DMARC_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MWISHLIST} EXTRA_PATCHES+= `${FIND} ${PATCHDIR} -name 'wishlist-*.patch'` .endif .if ${PORT_OPTIONS:MFIXED_NEVER_USERS} SEDLIST+= -e 's,^(FIXED_NEVER_USERS=).*,\1${WITH_FIXED_NEVER_USERS:S/,/\\,/g},' .endif .if ${PORT_OPTIONS:MEXIMON} SEDLIST+= -e 's,^\# (EXIM_MONITOR=),\1,' .endif .if ${PORT_OPTIONS:MTLS} .if ! ${PORT_OPTIONS:MGNUTLS} USES+= ssl SEDLIST+= -e 's,^\# (USE_OPENSSL=),\1,' SEDLIST+= -e 's,^\# (TLS_LIBS=.*-lssl[[:space:]]),\1,' .else SEDLIST+= -e 's,^\# (USE_GNUTLS=),\1,' SEDLIST+= -e 's,^\# (TLS_LIBS=.*-lgnutls[[:space:]]),\1,' .endif .else # TLS support SEDLIST+= -e 's,^\# (DISABLE_TLS=),\1,' .endif .if ${PORT_OPTIONS:MEMBEDDED_PERL} SEDLIST+= -e 's,^\# (EXIM_PERL=),\1,' .endif .if ${PORT_OPTIONS:MTCP_WRAPPERS} SEDLIST+= -e 's,XX_TCP_WRAPPERS_LIBS_XX,-lwrap,' \ -e 's,^\# (USE_TCP_WRAPPERS=),\1,' .else SEDLIST+= -e 's,XX_TCP_WRAPPERS_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MICONV} SEDLIST+= -e 's,XX_ICONV_LIBS_XX,-L${LOCALBASE:S/,/\\,/g}/lib ${ICONV_LIB},' \ -e 's,^\# (HAVE_ICONV=),\1,' .else SEDLIST+= -e 's,XX_ICONV_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MOPENLDAP_VER} && ${WITH_OPENLDAP_VER:tl} != "auto" WANT_OPENLDAP_VER= ${WITH_OPENLDAP_VER} .endif .if ${PORT_OPTIONS:MOPENLDAP} LDAP_LIB_TYPE= OPENLDAP2 SEDLIST+= -e 's,XX_LDAP_LIBS_XX,-L${LOCALBASE:S/,/\\,/g}/lib -llber -lldap,' \ -e 's,XX_LDAP_INCLUDE_XX,-I${LOCALBASE:S/,/\\,/g}/include,' \ -e 's,XX_LDAP_TYPE_XX,${LDAP_LIB_TYPE:S/,/\\,/g},' \ -e 's,^\# (LOOKUP_LDAP=),\1,' .else SEDLIST+= -e 's,XX_LDAP_[^ ]*_XX,,' \ -e 's,^(LDAP_LIB_TYPE=),\# \1,' .endif .if ${PORT_OPTIONS:MBDB} INVALID_BDB_VER= 2 3 DB_LIBS= -L${BDB_LIB_DIR} -l${BDB_LIB_NAME} DB_INCLUDES= -I${BDB_INCLUDE_DIR} .else DB_LIBS= DB_INCLUDES= SEDLIST+= -e 's,^(DBMLIB=),\# \1,' .endif SEDLIST+= -e 's,XX_DB_LIBS_XX,${DB_LIBS:S/,/\\,/g},' \ -e 's,XX_DB_INCLUDES_XX,${DB_INCLUDES:S/,/\\,/g},' .if ${PORT_OPTIONS:MLMDB} _LMDB_LIBS= -L${LOCALBASE}/lib -llmdb _LMDB_INCLUDES= -I${LOCALBASE}/include SEDLIST+= -e 's,^\# (EXPERIMENTAL_LMDB=),\1,' .else _LMDB_LIBS= _LMDB_INCLUDES= .endif SEDLIST+= -e 's,XX_LMDB_LIBS_XX,${_LMDB_LIBS:S/,/\\,/g},' \ -e 's,XX_LMDB_INCLUDES_XX,${_LMDB_INCLUDES:S/,/\\,/g},' .if ${PORT_OPTIONS:MMYSQL} SEDLIST+= -e 's,XX_MYSQL_LIBS_XX,-L${LOCALBASE:S/,/\\,/g}/lib/mysql -l${_MYSQL_SHLIB:S/lib//},' \ -e 's,XX_MYSQL_INCLUDE_XX,-I${LOCALBASE:S/,/\\,/g}/include/mysql,' \ -e 's,^\# (LOOKUP_MYSQL=),\1,' .else SEDLIST+= -e 's,XX_MYSQL_[^ ]*_XX,,' .endif .if ${PORT_OPTIONS:MSASLAUTHD} SASLAUTHD_SOCKET?= /var/run/saslauthd/mux SEDLIST+= -e 's,^\# (CYRUS_SASLAUTHD_SOCKET=).*,\1${SASLAUTHD_SOCKET:S/,/\\,/g},' .endif .if ${PORT_OPTIONS:MPAM} SEDLIST+= -e 's,XX_PAM_LIBS_XX,-lpam,' \ -e 's,^\# (SUPPORT_PAM=),\1,' .else SEDLIST+= -e 's,XX_PAM_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MAUTH_CRAM_MD5} SEDLIST+= -e 's,^\# (AUTH_CRAM_MD5=),\1,' .endif .if ${PORT_OPTIONS:MAUTH_PLAINTEXT} SEDLIST+= -e 's,^\# (AUTH_PLAINTEXT=),\1,' .endif .if ${PORT_OPTIONS:MAUTH_DOVECOT} SEDLIST+= -e 's,^\# (AUTH_DOVECOT=),\1,' .endif .if ${PORT_OPTIONS:MAUTH_SPA} SEDLIST+= -e 's,^\# (AUTH_SPA=),\1,' .endif .if ${PORT_OPTIONS:MAUTH_SASL} SEDLIST+= -e 's,^\# (AUTH_CYRUS_SASL=),\1,' \ -e 's,^\# (AUTH_LIBS=.*-lsasl2),\1,' .endif .if ${PORT_OPTIONS:MAUTH_RADIUS} WITH_RADIUS_TYPE?= RADLIB .if ${WITH_RADIUS_TYPE:tl} == radlib SEDLIST+= -e 's,XX_RADIUS_LIBS_XX,-lradius,' \ -e 's,^\# (RADIUS_CONFIG_FILE=).*,\1/etc/radius.conf,' \ -e 's,^\# (RADIUS_LIB_TYPE=).*,\1RADLIB,' .elif ${WITH_RADIUS_TYPE:tl} == radiusclient LIB_DEPENDS+= libfreeradius-client.so:net/freeradius-client SEDLIST+= -e 's,XX_RADIUS_LIBS_XX,-L${LOCALBASE:S/,/\\,/g}/lib -lfreeradius-client,' \ -e 's,^\# (RADIUS_CONFIG_FILE=).*,\1${LOCALBASE:S/,/\\,/g}/etc/radiusclient/radiusclient.conf,' \ -e 's,^\# (RADIUS_LIB_TYPE=).*,\1RADIUSCLIENTNEW,' .else IGNORE= the variable WITH_RADIUS_TYPE must be either RADLIB or RADIUSCLIENT .endif .else SEDLIST+= -e 's,XX_RADIUS_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MPGSQL} SEDLIST+= -e 's,XX_PGSQL_LIBS_XX,-L${LOCALBASE:S/,/\\,/g}/lib -lpq,' \ -e 's,XX_PGSQL_INCLUDE_XX,-I${LOCALBASE:S/,/\\,/g}/include/pgsql,' \ -e 's,^\# (LOOKUP_PGSQL=),\1,' .else SEDLIST+= -e 's,XX_PGSQL_[^ ]*_XX,,' .endif .if ! ${PORT_OPTIONS:MPGSQL} && ! ${PORT_OPTIONS:MMYSQL} && !defined(LDAP_LIB_TYPE) && \ ! ${PORT_OPTIONS:MBDB} && ! ${PORT_OPTIONS:MLMDB} SEDLIST+= -e 's,^(LOOKUP_LIBS=),\# \1,' \ -e 's,^(LOOKUP_INCLUDE=),\# \1,' .endif .if ! ${PORT_OPTIONS:MDNSDB} SEDLIST+= -e 's,^(LOOKUP_DNSDB=),\# \1,' .endif .if ${PORT_OPTIONS:MMAILDIR} SEDLIST+= -e 's,^\# (SUPPORT_MAILDIR=),\1,' .endif .if ${PORT_OPTIONS:MMAILSTORE} SEDLIST+= -e 's,^\# (SUPPORT_MAILSTORE=),\1,' .endif .if ${PORT_OPTIONS:MMBX} SEDLIST+= -e 's,^\# (SUPPORT_MBX=),\1,' .endif .if ${PORT_OPTIONS:MCDB} SEDLIST+= -e 's,^\# (LOOKUP_CDB=),\1,' .endif .if ${PORT_OPTIONS:MDSEARCH} SEDLIST+= -e 's,^\# (LOOKUP_DSEARCH=),\1,' .endif .if ! ${PORT_OPTIONS:MLSEARCH} SEDLIST+= -e 's,^(LOOKUP_LSEARCH=),\# \1,' .endif .if ${PORT_OPTIONS:MNIS} SEDLIST+= -e 's,^\# (LOOKUP_NIS=),\1,' .endif .if ${PORT_OPTIONS:MPASSWD} SEDLIST+= -e 's,^\# (LOOKUP_PASSWD=),\1,' .endif .if ${PORT_OPTIONS:MSQLITE} SEDLIST+= -e 's,XX_SQLITE_LIBS_XX,`pkg-config --static --libs sqlite3`,' \ -e 's,XX_SQLITE_FLAGS_XX,`pkg-config --cflags sqlite3`,' \ -e 's,^\# (LOOKUP_SQLITE=),\1,' .else SEDLIST+= -e 's,XX_SQLITE_LIBS_XX,,' \ -e 's,XX_SQLITE_FLAGS_XX,,' .endif .if ${PORT_OPTIONS:MREDIS} SEDLIST+= -e 's,XX_REDIS_LIBS_XX,-L${LOCALBASE}/lib -lhiredis,' \ -e 's,^\# (LOOKUP_REDIS=),\1,' \ -e 's,^\# (REDIS=),\1,' .else SEDLIST+= -e 's,XX_REDIS_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MLMTP} SEDLIST+= -e 's,^\# (TRANSPORT_LMTP=),\1,' .endif .if ! ${PORT_OPTIONS:MALT_CONFIG_PREFIX} SEDLIST+= -e 's,^(ALT_CONFIG_PREFIX=),\# \1,' .endif .if ${PORT_OPTIONS:MSPF} SEDLIST+= -e 's,XX_SPF_FLAGS_XX,-DSPF,' \ -e 's,XX_SPF_LIBS_XX,-L${LOCALBASE}/lib -lspf2 -lpthread,' \ -e 's,^\# (SUPPORT_SPF=),\1,' .else SEDLIST+= -e 's,XX_SPF_FLAGS_XX,,' \ -e 's,XX_SPF_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MSRS} LIB_DEPENDS+= libsrs_alt.so:mail/libsrs_alt SEDLIST+= -e 's,XX_SRS_FLAGS_XX,-DEXPERIMENTAL_SRS,' \ -e 's,XX_SRS_LIBS_XX,-L${LOCALBASE}/lib -lsrs_alt,' .else SEDLIST+= -e 's,XX_SRS_FLAGS_XX,,' \ -e 's,XX_SRS_LIBS_XX,,' .endif .if ${PORT_OPTIONS:MREADLINE} SEDLIST+= -e 's,^\# (USE_READLINE=),\1,' .endif .if ${PORT_OPTIONS:MCONTENT_SCAN} SEDLIST+= -e 's,^\# (WITH_CONTENT_SCAN=),\1,' .endif .if !defined(EXIMON_ONLY) && ${PORT_OPTIONS:MDAEMON} USE_RC_SUBR= exim PLIST_SUB+= EXIMDAEMON="" SUB_LIST+= LOGDIR="${LOGDIR}" .else PLIST_SUB+= EXIMDAEMON="@comment " .endif .if ${PORT_OPTIONS:MIPV6} SEDLIST+= -e 's,^\# (HAVE_IPV6=),\1,' .endif .if ${PORT_OPTIONS:MDISABLE_D_OPT} SEDLIST+= -e 's,^\# (DISABLE_D_OPTION=),\1,' .else .if defined(WHITELIST_D_MACROS) SEDLIST+= -e 's,^\# (WHITELIST_D_MACROS=).*$$,\1${WHITELIST_D_MACROS:S/,/\\,/g},' .endif .endif .if defined(TRUSTED_CONFIG_LIST) SEDLIST+= -e 's,^\# (TRUSTED_CONFIG_LIST=).*$$,\1${TRUSTED_CONFIG_LIST:S/,/\\,/g},' .endif .if ${PORT_OPTIONS:MQUEUEFILE} SEDLIST+= -e 's,^\# (EXPERIMENTAL_QUEUEFILE=),\1,' .endif MAKE_ENV+= INSTALL_ARG="${EXIM_INSTALL_ARG}" DUMMY_LDFLAGS!= ${ECHO_CMD} ${LDFLAGS} | ${SED} -e 's|-Wl,-rpath|-Wl,-DUMMYrpath|g; s|-rpath|-Wl,-rpath|g; s|-DUMMYrpath|-rpath|g' pre-everything:: @${ECHO} 'Exim now drops privileges when alternate configuration' @${ECHO} 'files are used. You can set make variable TRUSTED_CONFIG_LIST' @${ECHO} 'to specify the list of configuration files for which' @${ECHO} 'root privileges will be retained.' @${ECHO} '' @${ECHO} 'You can whitelist some macros using the make variable' @${ECHO} 'WHITELIST_D_MACROS. This is useful if you are running' @${ECHO} 'with DISABLE_D_OPT set, but macros whitelisting will be' @${ECHO} 'removed in some future Exim release, so it is better' @${ECHO} 'to use TRUSTED_CONFIG_LIST to set the list of trusted' @${ECHO} 'configuration files.' .if empty(.MAKEFLAGS:M-s) && ${PORT_OPTIONS:MWISHLIST} @${ECHO} '' @${ECHO} 'Included extra patches:' @${FIND} ${PATCHDIR} -name 'wishlist-*.patch' \ -exec ${SED} -ne 's,^# , ,p' {} \; @${ECHO} '' .endif post-extract: .if ${PORT_OPTIONS:MSA_EXIM} @cd ${WRKDIR} && ${TAR} ${EXTRACT_BEFORE_ARGS} ${_DISTDIR}/sa-exim-${SA_EXIM_VERSION}.tar.gz ${EXTRACT_AFTER_ARGS} @@${CP} ${WRKDIR}/sa-exim-${SA_EXIM_VERSION}/sa-exim.c ${WRKSRC}/Local @@${CP} ${WRKDIR}/sa-exim-${SA_EXIM_VERSION}/sa-exim.conf ${WRKSRC}/Local .endif do-configure: @${MKDIR} ${WRKSRC}/Local @${SED} -E ${SEDLIST} ${WRKSRC}/src/EDITME > ${WRKSRC}/Local/Makefile .if ${PORT_OPTIONS:MEXIMON} @${CP} ${WRKSRC}/exim_monitor/EDITME ${WRKSRC}/Local/eximon.conf .endif @${REINPLACE_CMD} -E ${SEDLIST} ${WRKSRC}/src/configure.default @${REINPLACE_CMD} -e 's!$$(LDFLAGS)!$$(DUMMY_LDFLAGS) -L$${LOCALBASE}/lib!' ${WRKSRC}/OS/Makefile-Base @${REINPLACE_CMD} -e 's/"(Exim $$version_number)\\n\\t"/"(Exim $$version_number (${OPSYS}))\\n\\t"/' \ ${WRKSRC}/src/globals.c @${REINPLACE_CMD} -e 's/Exim version %s \(#%s \)\{0,1\}/&(${OPSYS} ${OSREL}) /' ${WRKSRC}/src/exim.c @${REINPLACE_CMD} -e 's/^#include "cnumber\.h"$$/${PORTREVISION}/' ${WRKSRC}/src/version.c @${REINPLACE_CMD} -E -e 's/^(PERL_COMMAND=).*/\1${PERL:S,/,\/,g}/' \ -e 's/^(CC=).*/\1${CC:S,/,\/,g}/' ${WRKSRC}/OS/Makefile-Default .if ${PORT_OPTIONS:MSA_EXIM} @${REINPLACE_CMD} -E -e 's/^\# (HAVE_LOCAL_SCAN=).*/\1yes/' \ ${WRKSRC}/OS/Makefile-Default @${REINPLACE_CMD} -E -e 's/^(LOCAL_SCAN_SOURCE=).*/\1Local\/sa-exim.c/' \ ${WRKSRC}/OS/Makefile-Default @{ \ ${ECHO_CMD} "char *version=\"${SA_EXIM_VERSION}\";"; \ ${ECHO_CMD} "#define SPAMC_LOCATION \"${LOCALBASE}/bin/spamc\""; \ ${ECHO_CMD} "#define SPAMASSASSIN_CONF \"${PREFIX}/etc/exim/sa-exim.conf\""; \ } > ${WRKSRC}/Local/sa-exim.h @${REINPLACE_CMD} -e 's,/usr/bin/spamc,${LOCALBASE}/bin/spamc,' \ ${WRKSRC}/Local/sa-exim.conf .endif @${REINPLACE_CMD} -E -e 's/XX_STRIPCMD_XX/${STRIP_CMD:S,/,\/,g}/' \ ${WRKSRC}/OS/Makefile-FreeBSD @(cd ${WRKSRC}; ${SETENV} ${MAKE_ENV} ${MAKE} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} configure) post-build: .for script in ${DAILY_SCRIPTS} @${SED} ${SED_SCRIPT} ${FILESDIR}/${script}.sh > ${WRKDIR}/${script}.sh .endfor @${SED} ${SED_SCRIPT} ${FILESDIR}/POST-INSTALL-NOTES > \ ${WRKDIR}/POST-INSTALL-NOTES @${SED} ${SED_SCRIPT} ${FILESDIR}/POST-INSTALL-NOTES.clamd > ${WRKDIR}/POST-INSTALL-NOTES.clamd @${SED} ${SED_SCRIPT} ${FILESDIR}/POST-INSTALL-NOTES > ${WRKDIR}/POST-INSTALL-NOTES @[ ! -f ${PKGDIR}/pkg-message ] || ${SED} ${SED_SCRIPT} ${PKGDIR}/pkg-message > ${WRKDIR}/pkg-message .if !defined(EXIMON_ONLY) post-install: .if ${PORT_OPTIONS:MDAEMON} ${MKDIR} ${STAGEDIR}${PREFIX}/etc/periodic/daily .for script in ${DAILY_SCRIPTS} ${INSTALL_SCRIPT} ${WRKDIR}/${script}.sh ${STAGEDIR}${PREFIX}/etc/periodic/daily/${script} .endfor .endif @${MKDIR} -m 750 ${STAGEDIR}${LOGDIR} ${INSTALL_MAN} ${WRKSRC}/doc/exim.8 ${STAGEDIR}${MAN8PREFIX}/man/man8 .if ${PORT_OPTIONS:MDOCS} @${MKDIR} ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${WRKDIR}/POST-INSTALL-NOTES ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${WRKDIR}/POST-INSTALL-NOTES.clamd ${STAGEDIR}${DOCSDIR} .for docfile in ${PORTDOC_BASE} ${INSTALL_DATA} ${WRKSRC}/${docfile} ${STAGEDIR}${DOCSDIR} .endfor .for docfile in ${PORTDOC_FILES} ${INSTALL_DATA} ${WRKSRC}/doc/${docfile} ${STAGEDIR}${DOCSDIR} .endfor @${MKDIR} ${STAGEDIR}${EXAMPLESDIR} .for example in ${PORT_EXAMPLES} ${INSTALL_SCRIPT} ${WRKSRC}/build-${OPSYS}-${ARCH}/${example} ${STAGEDIR}${EXAMPLESDIR} .endfor .endif .if ${PORT_OPTIONS:MSA_EXIM} ${INSTALL_DATA} ${WRKSRC}/Local/sa-exim.conf \ ${STAGEDIR}${PREFIX}/etc/exim/sa-exim.conf.sample .endif .endif # ! defined(EXIMON_ONLY) .include # If using clang, avoid too many warnings due to Exim code style .if ${CHOSEN_COMPILER_TYPE} == "clang" EXIM_WARN_FLAGS?= -Wno-logical-op-parentheses -Wno-macro-redefined -Wno-parentheses -Wno-dangling-else .endif CFLAGS+= ${EXIM_WARN_FLAGS} .include diff --git a/mail/exim/distinfo b/mail/exim/distinfo index cf1ae320eaa8..c007834ea4bb 100644 --- a/mail/exim/distinfo +++ b/mail/exim/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1620141511 -SHA256 (exim/exim-4.94.2.tar.bz2) = 902e611486400608691dff31e1d8725eb9e23602399ad75670ec18878643bc4f -SIZE (exim/exim-4.94.2.tar.bz2) = 2007178 +TIMESTAMP = 1632918983 +SHA256 (exim/exim-4.95.tar.bz2) = 7f4716cc1b3fee66930d83b249f1c7b119fa1957f6f46e3f4372805cbc97ea63 +SIZE (exim/exim-4.95.tar.bz2) = 2035738 SHA256 (exim/sa-exim-4.2.1.tar.gz) = 24d4bf7b0fdddaea11f132981cebb6a86a4ab20ef54111a8ebd481b421c6e2c1 SIZE (exim/sa-exim-4.2.1.tar.gz) = 68933 diff --git a/mail/exim/files/debian/75_01-Introduce-main-config-option-allow_insecure_tainted_.patch b/mail/exim/files/debian/75_01-Introduce-main-config-option-allow_insecure_tainted_.patch deleted file mode 100644 index 0295ec18fa6e..000000000000 --- a/mail/exim/files/debian/75_01-Introduce-main-config-option-allow_insecure_tainted_.patch +++ /dev/null @@ -1,230 +0,0 @@ -From ec06d64532e4952fc36429f73e0222d26997ef7c Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 22:44:31 +0200 -Subject: [PATCH 01/23] Introduce main config option - allow_insecure_tainted_data - -This option is deprecated already now. ---- - src/EDITME | 7 +++++ - src/config.h.defaults | 2 ++ - src/functions.h | 54 ++++++++++++++++++++++++++++++--------- - src/globals.c | 10 ++++++++ - src/globals.h | 4 +++ - src/macros.h | 3 +++ - src/readconf.c | 3 +++ - 7 files changed, 71 insertions(+), 12 deletions(-) - -diff --git a/src/EDITME b/src/EDITME -index 8da36a353..cebb8e2ec 100644 ---- a/src/EDITME -+++ b/src/EDITME -@@ -749,6 +749,13 @@ FIXED_NEVER_USERS=root - - # WHITELIST_D_MACROS=TLS:SPOOL - -+# The next setting enables a main config option -+# "allow_insecure_tainted_data" to turn taint failures into warnings. -+# Though this option is new, it is deprecated already now, and will be -+# ignored in future releases of Exim. It is meant as mitigation for -+# upgrading old (possibly insecure) configurations to more secure ones. -+ALLOW_INSECURE_TAINTED_DATA=yes -+ - #------------------------------------------------------------------------------ - # Exim has support for the AUTH (authentication) extension of the SMTP - # protocol, as defined by RFC 2554. If you don't know what SMTP authentication -diff --git a/src/config.h.defaults b/src/config.h.defaults -index e17f015f9..4e8b18904 100644 ---- a/src/config.h.defaults -+++ b/src/config.h.defaults -@@ -17,6 +17,8 @@ Do not put spaces between # and the 'define'. - #define ALT_CONFIG_PREFIX - #define TRUSTED_CONFIG_LIST - -+#define ALLOW_INSECURE_TAINTED_DATA -+ - #define APPENDFILE_MODE 0600 - #define APPENDFILE_DIRECTORY_MODE 0700 - #define APPENDFILE_LOCKFILE_MODE 0600 -diff --git a/src/functions.h b/src/functions.h -index 51bb17a09..1e8083673 100644 ---- a/src/functions.h -+++ b/src/functions.h -@@ -1083,36 +1083,66 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec); - - /******************************************************************************/ - /* Taint-checked file opens */ -+static inline uschar * -+is_tainted2(const void *p, int lflags, const uschar* fmt, ...) -+{ -+va_list ap; -+uschar *msg; -+rmark mark; -+ -+if (!is_tainted(p)) -+ return NULL; -+ -+mark = store_mark(); -+va_start(ap, fmt); -+msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap)); -+va_end(ap); -+ -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+if (allow_insecure_tainted_data) -+ { -+ if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg); -+ store_reset(mark); -+ return NULL; -+ } -+#endif -+ -+if (lflags) log_write(0, lflags, "%s", msg); -+return msg; /* no store_reset(), as the message might be used afterwards and Exim -+ is expected to exit anyway, so we do not care about the leaked -+ storage */ -+} - - static inline int - exim_open2(const char *pathname, int flags) - { --if (!is_tainted(pathname)) return open(pathname, flags); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); -+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) -+ return open(pathname, flags); - errno = EACCES; - return -1; - } -+ - static inline int - exim_open(const char *pathname, int flags, mode_t mode) - { --if (!is_tainted(pathname)) return open(pathname, flags, mode); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); -+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) -+ return open(pathname, flags, mode); - errno = EACCES; - return -1; - } - static inline int - exim_openat(int dirfd, const char *pathname, int flags) - { --if (!is_tainted(pathname)) return openat(dirfd, pathname, flags); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); -+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) -+ return openat(dirfd, pathname, flags); - errno = EACCES; - return -1; - } - static inline int - exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode) - { --if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); -+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) -+ return openat(dirfd, pathname, flags, mode); - errno = EACCES; - return -1; - } -@@ -1120,8 +1150,8 @@ return -1; - static inline FILE * - exim_fopen(const char *pathname, const char *mode) - { --if (!is_tainted(pathname)) return fopen(pathname, mode); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); -+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) -+ return fopen(pathname, mode); - errno = EACCES; - return NULL; - } -@@ -1129,8 +1159,8 @@ return NULL; - static inline DIR * - exim_opendir(const uschar * name) - { --if (!is_tainted(name)) return opendir(CCS name); --log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name); -+if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name)) -+ return opendir(CCS name); - errno = EACCES; - return NULL; - } -diff --git a/src/globals.c b/src/globals.c -index c34ac9ddd..ff660c352 100644 ---- a/src/globals.c -+++ b/src/globals.c -@@ -98,6 +98,10 @@ int sqlite_lock_timeout = 5; - BOOL move_frozen_messages = FALSE; - #endif - -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+BOOL allow_insecure_tainted_data = FALSE; -+#endif -+ - /* These variables are outside the #ifdef because it keeps the code less - cluttered in several places (e.g. during logging) if we can always refer to - them. Also, the tls_ variables are now always visible. Note that these are -@@ -1033,6 +1037,9 @@ int log_default[] = { /* for initializing log_selector */ - Li_size_reject, - Li_skip_delivery, - Li_smtp_confirmation, -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+ Li_tainted, -+#endif - Li_tls_certificate_verified, - Li_tls_cipher, - -1 -@@ -1100,6 +1107,9 @@ bit_table log_options[] = { /* must be in alphabetical order, - BIT_TABLE(L, smtp_protocol_error), - BIT_TABLE(L, smtp_syntax_error), - BIT_TABLE(L, subject), -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+ BIT_TABLE(L, tainted), -+#endif - BIT_TABLE(L, tls_certificate_verified), - BIT_TABLE(L, tls_cipher), - BIT_TABLE(L, tls_peerdn), -diff --git a/src/globals.h b/src/globals.h -index a4c1143b7..8d72577e0 100644 ---- a/src/globals.h -+++ b/src/globals.h -@@ -77,6 +77,10 @@ extern int sqlite_lock_timeout; /* Internal lock waiting timeout */ - extern BOOL move_frozen_messages; /* Get them out of the normal directory */ - #endif - -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+extern BOOL allow_insecure_tainted_data; -+#endif -+ - /* These variables are outside the #ifdef because it keeps the code less - cluttered in several places (e.g. during logging) if we can always refer to - them. Also, the tls_ variables are now always visible. */ -diff --git a/src/macros.h b/src/macros.h -index f78ae2e3d..322ddbf56 100644 ---- a/src/macros.h -+++ b/src/macros.h -@@ -498,6 +498,9 @@ enum logbit { - Li_smtp_mailauth, - Li_smtp_no_mail, - Li_subject, -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+ Li_tainted, -+#endif - Li_tls_certificate_verified, - Li_tls_cipher, - Li_tls_peerdn, -diff --git a/src/readconf.c b/src/readconf.c -index 948fa2403..133135f8f 100644 ---- a/src/readconf.c -+++ b/src/readconf.c -@@ -68,6 +68,9 @@ static optionlist optionlist_config[] = { - { "add_environment", opt_stringptr, {&add_environment} }, - { "admin_groups", opt_gidlist, {&admin_groups} }, - { "allow_domain_literals", opt_bool, {&allow_domain_literals} }, -+#ifdef ALLOW_INSECURE_TAINTED_DATA -+ { "allow_insecure_tainted_data", opt_bool, {&allow_insecure_tainted_data} }, -+#endif - { "allow_mx_to_ip", opt_bool, {&allow_mx_to_ip} }, - { "allow_utf8_domains", opt_bool, {&allow_utf8_domains} }, - { "auth_advertise_hosts", opt_stringptr, {&auth_advertise_hosts} }, --- -2.30.2 - diff --git a/mail/exim/files/debian/75_02-search.patch b/mail/exim/files/debian/75_02-search.patch deleted file mode 100644 index 226a350af10d..000000000000 --- a/mail/exim/files/debian/75_02-search.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b71d675f695c2cf17357b190476129535d5f446c Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 22:45:03 +0200 -Subject: [PATCH 02/23] search - ---- - src/search.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/src/search.c b/src/search.c -index f8aaacb04..f6e4d1f5b 100644 ---- a/src/search.c -+++ b/src/search.c -@@ -343,12 +343,8 @@ lookup_info *lk = lookup_list[search_type]; - uschar keybuffer[256]; - int old_pool = store_pool; - --if (filename && is_tainted(filename)) -- { -- log_write(0, LOG_MAIN|LOG_PANIC, -- "Tainted filename for search: '%s'", filename); -+if (filename && is_tainted2(filename, LOG_MAIN|LOG_PANIC, "Tainted filename for search '%s'", filename)) - return NULL; -- } - - /* Change to the search store pool and remember our reset point */ - -@@ -639,7 +635,7 @@ DEBUG(D_lookup) - /* Arrange to put this database at the top of the LRU chain if it is a type - that opens real files. */ - --if ( open_top != (tree_node *)handle -+if ( open_top != (tree_node *)handle - && lookup_list[t->name[0]-'0']->type == lookup_absfile) - { - search_cache *c = (search_cache *)(t->data.ptr); --- -2.30.2 - diff --git a/mail/exim/files/debian/75_03-dbstuff.patch b/mail/exim/files/debian/75_03-dbstuff.patch deleted file mode 100644 index dc9da8e44c54..000000000000 --- a/mail/exim/files/debian/75_03-dbstuff.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 35b11dd0e52b5ac176849f807cca8898bcaf0c3d Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 10:49:49 +0200 -Subject: [PATCH 03/23] dbstuff - ---- - src/dbstuff.h | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/src/dbstuff.h b/src/dbstuff.h -index c1fb54346..dcee78696 100644 ---- a/src/dbstuff.h -+++ b/src/dbstuff.h -@@ -643,11 +643,9 @@ after reading data. */ - : (flags) == O_RDWR ? "O_RDWR" \ - : (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \ - : "??"); \ -- if (is_tainted(name) || is_tainted(dirname)) \ -- { \ -- log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \ -+ if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB file not permitted", name) \ -+ || is_tainted2(dirname, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB directory not permitted", dirname)) \ - *dbpp = NULL; \ -- } \ - else \ - { EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \ - DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \ --- -2.30.2 - diff --git a/mail/exim/files/debian/75_04-acl.patch b/mail/exim/files/debian/75_04-acl.patch deleted file mode 100644 index 810b2e591675..000000000000 --- a/mail/exim/files/debian/75_04-acl.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 44fd80ad8abcd885fc1c8dbb294fc2140e4ef481 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 10:50:14 +0200 -Subject: [PATCH 04/23] acl -Last-Update: 2021-05-01 - ---- - src/acl.c | 32 ++++++++++++++++---------------- - 1 file changed, 16 insertions(+), 16 deletions(-) - ---- a/src/acl.c -+++ b/src/acl.c -@@ -3596,24 +3596,26 @@ - rc = mime_regex(&arg); - break; - #endif - - case ACLC_QUEUE: -- if (is_tainted(arg)) - { -- *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted", -- arg); -- return ERROR; -+ uschar *m; -+ if (m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)) -+ { -+ *log_msgptr = m; -+ return ERROR; -+ } -+ if (Ustrchr(arg, '/')) -+ { -+ *log_msgptr = string_sprintf( -+ "Directory separator not permitted in queue name: '%s'", arg); -+ return ERROR; -+ } -+ queue_name = string_copy_perm(arg, FALSE); -+ break; - } -- if (Ustrchr(arg, '/')) -- { -- *log_msgptr = string_sprintf( -- "Directory separator not permitted in queue name: '%s'", arg); -- return ERROR; -- } -- queue_name = string_copy_perm(arg, FALSE); -- break; - - case ACLC_RATELIMIT: - rc = acl_ratelimit(arg, where, log_msgptr); - break; - -@@ -4005,14 +4007,12 @@ - } - - else if (*ss == '/') - { - struct stat statbuf; -- if (is_tainted(ss)) -+ if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted ACL file name '%s'", ss)) - { -- log_write(0, LOG_MAIN|LOG_PANIC, -- "attempt to open tainted ACL file name \"%s\"", ss); - /* Avoid leaking info to an attacker */ - *log_msgptr = US"internal configuration error"; - return ERROR; - } - if ((fd = Uopen(ss, O_RDONLY, 0)) < 0) diff --git a/mail/exim/files/debian/75_05-parse.patch b/mail/exim/files/debian/75_05-parse.patch deleted file mode 100644 index f9dab900f88e..000000000000 --- a/mail/exim/files/debian/75_05-parse.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7eeeb6f26af05322814ecc77c87f09c72ab2216a Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 10:58:46 +0200 -Subject: [PATCH 05/23] parse - ---- - src/parse.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/src/parse.c b/src/parse.c -index 3ea758ac9..d1bc79039 100644 ---- a/src/parse.c -+++ b/src/parse.c -@@ -1402,12 +1402,8 @@ for (;;) - return FF_ERROR; - } - -- if (is_tainted(filename)) -- { -- *error = string_sprintf("Tainted name '%s' for included file not permitted\n", -- filename); -+ if (*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)) - return FF_ERROR; -- } - - /* Check file name if required */ - --- -2.30.2 - diff --git a/mail/exim/files/debian/75_06-rda.patch b/mail/exim/files/debian/75_06-rda.patch deleted file mode 100644 index f4ca2afc13f1..000000000000 --- a/mail/exim/files/debian/75_06-rda.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a6da9c67acaee699616516be141d600cc178a633 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 10:59:46 +0200 -Subject: [PATCH 06/23] rda - ---- - src/rda.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/src/rda.c b/src/rda.c -index aed8abc24..6ad7dd8bd 100644 ---- a/src/rda.c -+++ b/src/rda.c -@@ -179,10 +179,8 @@ struct stat statbuf; - /* Reading a file is a form of expansion; we wish to deny attackers the - capability to specify the file name. */ - --if (is_tainted(filename)) -+if (*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)) - { -- *error = string_sprintf("Tainted name '%s' for file read not permitted\n", -- filename); - *yield = FF_ERROR; - return NULL; - } --- -2.30.2 - diff --git a/mail/exim/files/debian/75_07-appendfile.patch b/mail/exim/files/debian/75_07-appendfile.patch deleted file mode 100644 index 5a9e37861d7f..000000000000 --- a/mail/exim/files/debian/75_07-appendfile.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c29b50d2fe17cc108d751175ed4f4113c25c1768 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 11:00:06 +0200 -Subject: [PATCH 07/23] appendfile - ---- - src/transports/appendfile.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/transports/appendfile.c b/src/transports/appendfile.c -index 8ab8b6016..7dbbaa2f9 100644 ---- a/src/transports/appendfile.c -+++ b/src/transports/appendfile.c -@@ -1286,12 +1286,14 @@ if (!(path = expand_string(fdname))) - expand_string_message); - goto ret_panic; - } --if (is_tainted(path)) -+{ uschar *m; -+if (m = is_tainted2(path, 0, "Tainted '%s' (file or directory " -+ "name for %s transport) not permitted", path, tblock->name)) - { -- addr->message = string_sprintf("Tainted '%s' (file or directory " -- "name for %s transport) not permitted", path, tblock->name); -+ addr->message = m; - goto ret_panic; - } -+} - - if (path[0] != '/') - { --- -2.30.2 - diff --git a/mail/exim/files/debian/75_08-autoreply.patch b/mail/exim/files/debian/75_08-autoreply.patch deleted file mode 100644 index de5eb1dd3c20..000000000000 --- a/mail/exim/files/debian/75_08-autoreply.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 26de37d8960da80473866fb59b9dfd10a5761538 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 28 Mar 2021 11:06:27 +0200 -Subject: [PATCH 08/23] autoreply - ---- - src/transports/autoreply.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/src/transports/autoreply.c b/src/transports/autoreply.c -index 865abbf4f..ed99de4c6 100644 ---- a/src/transports/autoreply.c -+++ b/src/transports/autoreply.c -@@ -404,14 +404,15 @@ recipient cache. */ - - if (oncelog && *oncelog && to) - { -+ uschar *m; - time_t then = 0; - -- if (is_tainted(oncelog)) -+ if (m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" -+ " not permitted", oncelog, tblock->name)) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -- addr->message = string_sprintf("Tainted '%s' (once file for %s transport)" -- " not permitted", oncelog, tblock->name); -+ addr->message = m; - goto END_OFF; - } - -@@ -515,13 +516,14 @@ if (oncelog && *oncelog && to) - - if (then != 0 && (once_repeat_sec <= 0 || now - then < once_repeat_sec)) - { -+ uschar *m; - int log_fd; -- if (is_tainted(logfile)) -+ if (m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" -+ " not permitted", logfile, tblock->name)) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -- addr->message = string_sprintf("Tainted '%s' (logfile for %s transport)" -- " not permitted", logfile, tblock->name); -+ addr->message = m; - goto END_OFF; - } - -@@ -548,12 +550,13 @@ if (oncelog && *oncelog && to) - /* We are going to send a message. Ensure any requested file is available. */ - if (file) - { -- if (is_tainted(file)) -+ uschar *m; -+ if (m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" -+ " not permitted", file, tblock->name)) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -- addr->message = string_sprintf("Tainted '%s' (file for %s transport)" -- " not permitted", file, tblock->name); -+ addr->message = m; - return FALSE; - } - if (!(ff = Ufopen(file, "rb")) && !ob->file_optional) --- -2.30.2 - diff --git a/mail/exim/files/debian/75_09-pipe.patch b/mail/exim/files/debian/75_09-pipe.patch deleted file mode 100644 index 0ec9bcfaed19..000000000000 --- a/mail/exim/files/debian/75_09-pipe.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f9628406706112be459adb3f121db8e6cf282c2d Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Fri, 2 Apr 2021 17:30:27 +0200 -Subject: [PATCH 09/23] pipe - ---- - src/transports/pipe.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/src/transports/pipe.c b/src/transports/pipe.c -index 27422bd42..4c9e68beb 100644 ---- a/src/transports/pipe.c -+++ b/src/transports/pipe.c -@@ -599,13 +599,16 @@ if (!cmd || !*cmd) - tblock->name); - return FALSE; - } --if (is_tainted(cmd)) -+ -+{ uschar *m; -+if (m = is_tainted2(cmd, 0, "Tainted '%s' (command " -+ "for %s transport) not permitted", cmd, tblock->name)) - { -- addr->message = string_sprintf("Tainted '%s' (command " -- "for %s transport) not permitted", cmd, tblock->name); - addr->transport_return = PANIC; -+ addr->message = m; - return FALSE; - } -+} - - /* When a pipe is set up by a filter file, there may be values for $thisaddress - and numerical the variables in existence. These are passed in --- -2.30.2 - diff --git a/mail/exim/files/debian/75_10-deliver.patch b/mail/exim/files/debian/75_10-deliver.patch deleted file mode 100644 index ea4a54239e31..000000000000 --- a/mail/exim/files/debian/75_10-deliver.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2fee91ae42e974c21202e0b5e17185f6a87bf8af Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Wed, 31 Mar 2021 23:12:44 +0200 -Subject: [PATCH 10/23] deliver - ---- - src/deliver.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/src/deliver.c b/src/deliver.c -index d85edd70e..8b7998f37 100644 ---- a/src/deliver.c -+++ b/src/deliver.c -@@ -5538,10 +5538,11 @@ FILE * fp = NULL; - if (!s || !*s) - log_write(0, LOG_MAIN|LOG_PANIC, - "Failed to expand %s: '%s'\n", varname, filename); --else if (*s != '/' || is_tainted(s)) -- log_write(0, LOG_MAIN|LOG_PANIC, -- "%s is not %s after expansion: '%s'\n", -- varname, *s == '/' ? "untainted" : "absolute", s); -+else if (*s != '/') -+ log_write(0, LOG_MAIN|LOG_PANIC, "%s is not absolute after expansion: '%s'\n", -+ varname, s); -+else if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted %s after expansion: '%s'\n", varname, s)) -+ ; - else if (!(fp = Ufopen(s, "rb"))) - log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for %s " - "message texts: %s", s, reason, strerror(errno)); -@@ -6148,12 +6149,13 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) - { - uschar *tmp = expand_string(tpname); - address_file = address_pipe = NULL; -+ uschar *m; - if (!tmp) - p->message = string_sprintf("failed to expand \"%s\" as a " - "system filter transport name", tpname); -- if (is_tainted(tmp)) -- p->message = string_sprintf("attempt to used tainted value '%s' for" -- "transport '%s' as a system filter", tmp, tpname); -+ if (is_tainted2(tmp, 0, m = string_sprintf("Tainted values '%s' " -+ "for transport '%s' as a system filter", tmp, tpname))) -+ p->message = m; - tpname = tmp; - } - else --- -2.30.2 - diff --git a/mail/exim/files/debian/75_11-directory.patch b/mail/exim/files/debian/75_11-directory.patch deleted file mode 100644 index 4c3a68418c0b..000000000000 --- a/mail/exim/files/debian/75_11-directory.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5f41e800ce9cc7ad154047298914df955e905bf4 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 21:28:59 +0200 -Subject: [PATCH 11/23] directory - ---- - src/directory.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/directory.c b/src/directory.c -index 2d4d565f4..9f88f4141 100644 ---- a/src/directory.c -+++ b/src/directory.c -@@ -44,6 +44,9 @@ uschar c = 1; - struct stat statbuf; - uschar * path; - -+if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name)) -+ { p = US"create"; path = US name; errno = EACCES; goto bad; } -+ - if (parent) - { - path = string_sprintf("%s%s%s", parent, US"/", name); --- -2.30.2 - diff --git a/mail/exim/files/debian/75_12-expand.patch b/mail/exim/files/debian/75_12-expand.patch deleted file mode 100644 index ebb099d284f2..000000000000 --- a/mail/exim/files/debian/75_12-expand.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c02ea85f525ff256d78e084d6f76fe3032fd52e1 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 21:33:50 +0200 -Subject: [PATCH 12/23] expand - ---- - src/expand.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/expand.c b/src/expand.c -index 05de94c49..21b86ebf5 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -4383,13 +4383,13 @@ DEBUG(D_expand) - f.expand_string_forcedfail = FALSE; - expand_string_message = US""; - --if (is_tainted(string)) -+{ uschar *m; -+if (m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s)) - { -- expand_string_message = -- string_sprintf("attempt to expand tainted string '%s'", s); -- log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message); -+ expand_string_message = m; - goto EXPAND_FAILED; - } -+} - - while (*s != 0) - { --- -2.30.2 - diff --git a/mail/exim/files/debian/75_13-lf_sqlperform.patch b/mail/exim/files/debian/75_13-lf_sqlperform.patch deleted file mode 100644 index 67283a02676e..000000000000 --- a/mail/exim/files/debian/75_13-lf_sqlperform.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9810dfc25d8b9687b46e57963a3ac30bf5c9b2c9 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 21:36:12 +0200 -Subject: [PATCH 13/23] lf_sqlperform - ---- - src/lookups/lf_sqlperform.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/src/lookups/lf_sqlperform.c b/src/lookups/lf_sqlperform.c -index ad1df29d1..eda3089e2 100644 ---- a/src/lookups/lf_sqlperform.c -+++ b/src/lookups/lf_sqlperform.c -@@ -102,11 +102,13 @@ if (Ustrncmp(query, "servers", 7) == 0) - } - } - -- if (is_tainted(server)) -- { -- *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server); -+ { uschar *m; -+ if (m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) -+ { -+ *errmsg = m; - return DEFER; - } -+ } - - rc = (*fn)(ss+1, server, result, errmsg, &defer_break, do_cache, opts); - if (rc != DEFER || defer_break) return rc; -@@ -158,11 +160,13 @@ else - server = ele; - } - -- if (is_tainted(server)) -+ { uschar *m; -+ if (is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) - { -- *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server); -+ *errmsg = m; - return DEFER; - } -+ } - - rc = (*fn)(query, server, result, errmsg, &defer_break, do_cache, opts); - if (rc != DEFER || defer_break) return rc; --- -2.30.2 - diff --git a/mail/exim/files/debian/75_14-rf_get_transport.patch b/mail/exim/files/debian/75_14-rf_get_transport.patch deleted file mode 100644 index 9e8b69d3ad6a..000000000000 --- a/mail/exim/files/debian/75_14-rf_get_transport.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 015fff57c854184f8bce61476c46a2830a97daf8 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Fri, 2 Apr 2021 08:36:24 +0200 -Subject: [PATCH 14/23] rf_get_transport - ---- - src/routers/rf_get_transport.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/src/routers/rf_get_transport.c b/src/routers/rf_get_transport.c -index 4a43818ff..32bde9ec3 100644 ---- a/src/routers/rf_get_transport.c -+++ b/src/routers/rf_get_transport.c -@@ -66,10 +66,8 @@ if (expandable) - "\"%s\" in %s router: %s", tpname, router_name, expand_string_message); - return FALSE; - } -- if (is_tainted(ss)) -+ if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted tainted value '%s' from '%s' for transport", ss, tpname)) - { -- log_write(0, LOG_MAIN|LOG_PANIC, -- "attempt to use tainted value '%s' from '%s' for transport", ss, tpname); - addr->basic_errno = ERRNO_BADTRANSPORT; - /* Avoid leaking info to an attacker */ - addr->message = US"internal configuration error"; --- -2.30.2 - diff --git a/mail/exim/files/debian/75_15-deliver.patch b/mail/exim/files/debian/75_15-deliver.patch deleted file mode 100644 index 0c2ca2772d10..000000000000 --- a/mail/exim/files/debian/75_15-deliver.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2bafe3fc82cf62f0c21f939f5891b8d067f3abc7 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sat, 3 Apr 2021 10:54:22 +0200 -Subject: [PATCH 15/23] deliver - ---- - src/deliver.c | 5 +++-- - test/paniclog/0622 | 2 +- - test/stderr/0622 | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/src/deliver.c b/src/deliver.c -index 8b7998f37..87e944b03 100644 ---- a/src/deliver.c -+++ b/src/deliver.c -@@ -6153,9 +6153,10 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) - if (!tmp) - p->message = string_sprintf("failed to expand \"%s\" as a " - "system filter transport name", tpname); -- if (is_tainted2(tmp, 0, m = string_sprintf("Tainted values '%s' " -- "for transport '%s' as a system filter", tmp, tpname))) -+ { uschar *m; -+ if (m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname)) - p->message = m; -+ } - tpname = tmp; - } - else --- -2.30.2 - diff --git a/mail/exim/files/debian/75_16-smtp_out.patch b/mail/exim/files/debian/75_16-smtp_out.patch deleted file mode 100644 index a0280afd30a8..000000000000 --- a/mail/exim/files/debian/75_16-smtp_out.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b9b967cca71a4da51506f8ba596b9ae40cfcef57 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 21:42:38 +0200 -Subject: [PATCH 16/23] smtp_out - ---- - src/smtp_out.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/src/smtp_out.c b/src/smtp_out.c -index c4c409677..9c160e697 100644 ---- a/src/smtp_out.c -+++ b/src/smtp_out.c -@@ -53,11 +53,8 @@ if (!(expint = expand_string(istring))) - return FALSE; - } - --if (is_tainted(expint)) -+if (is_tainted2(expint, LOG_MAIN|LOG_PANIC, "Tainted value '%s' from '%s' for interface", expint, istring)) - { -- log_write(0, LOG_MAIN|LOG_PANIC, -- "attempt to use tainted value '%s' from '%s' for interface", -- expint, istring); - addr->transport_return = PANIC; - addr->message = string_sprintf("failed to expand \"interface\" " - "option for %s: configuration error", msg); -@@ -425,7 +422,7 @@ if (ob->socks_proxy) - { - int sock = socks_sock_connect(sc->host, sc->host_af, port, sc->interface, - sc->tblock, ob->connect_timeout); -- -+ - if (sock >= 0) - { - if (early_data && early_data->data && early_data->len) --- -2.30.2 - diff --git a/mail/exim/files/debian/75_17-smtp.patch b/mail/exim/files/debian/75_17-smtp.patch deleted file mode 100644 index c77a284a9ff0..000000000000 --- a/mail/exim/files/debian/75_17-smtp.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 8b7d4ba8903ace7e3e3db70343798a5a0b7cea23 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Thu, 1 Apr 2021 22:02:27 +0200 -Subject: [PATCH 17/23] smtp - ---- - src/transports/smtp.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/src/transports/smtp.c b/src/transports/smtp.c -index 6540e4d2b..8fecf7eef 100644 ---- a/src/transports/smtp.c -+++ b/src/transports/smtp.c -@@ -4715,11 +4715,8 @@ if (!hostlist || (ob->hosts_override && ob->hosts)) - else - if (ob->hosts_randomize) s = expanded_hosts = string_copy(s); - -- if (is_tainted(s)) -+ if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted host list '%s' from '%s' in transport %s", s, ob->hosts, tblock->name)) - { -- log_write(0, LOG_MAIN|LOG_PANIC, -- "attempt to use tainted host list '%s' from '%s' in transport %s", -- s, ob->hosts, tblock->name); - /* Avoid leaking info to an attacker */ - addrlist->message = US"internal configuration error"; - addrlist->transport_return = PANIC; --- -2.30.2 - diff --git a/mail/exim/files/debian/75_18-update-doc.patch b/mail/exim/files/debian/75_18-update-doc.patch deleted file mode 100644 index 2edba6916744..000000000000 --- a/mail/exim/files/debian/75_18-update-doc.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 77cc1ad3058e4ef7ae82adb914ccff0be9fe2c8b Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sat, 3 Apr 2021 09:29:13 +0200 -Subject: [PATCH 18/23] update doc - ---- - doc/doc-docbook/spec.xfpt | 45 ++++++++++++++++++++++++++++++++++++++- - doc/NewStuff | 45 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 89 insertions(+), 1 deletion(-) - ---- a/doc/NewStuff -+++ b/doc/NewStuff -@@ -4,10 +4,55 @@ - This file contains descriptions of new features that have been added to Exim. - Before a formal release, there may be quite a lot of detail so that people can - test from the snapshots or the Git before the documentation is updated. Once - the documentation is updated, this file is reduced to a short list. - -+Version 4.95 -+------------ -+ -+ 1. The fast-ramp two phase queue run support, previously experimental, is -+ now supported by default. -+ -+ 2. The native SRS support, previously experimental, is now supported. It is -+ not built unless specified in the Local/Makefile. -+ -+ 3. TLS resumption support, previously experimental, is now supported and -+ included in default builds. -+ -+ 4. Single-key LMDB lookups, previously experimental, are now supported. -+ The support is not built unless specified in the Local/Makefile. -+ -+ 5. Option "message_linelength_limit" on the smtp transport to enforce (by -+ default) the RFC 998 character limit. -+ -+ 6. An option to ignore the cache on a lookup. -+ -+ 7. Quota checking during reception (i.e. at SMTP time) for appendfile- -+ transport-managed quotas. -+ -+ 8. Sqlite lookups accept a "file=" option to specify a per-operation -+ db file, replacing the previous prefix to the SQL string (which had -+ issues when the SQL used tainted values). -+ -+ 9. Lsearch lookups accept a "ret=full" option, to return both the portion -+ of the line matching the key, and the remainder. -+ -+10. A command-line option to have a daemon not create a notifier socket. -+ -+11. Faster TLS startup. When various configuration options contain no -+ expandable elements, the information can be preloaded and cached rather -+ than the provious behaviour of always loading at startup time for every -+ connection. This helps particularly for the CA bundle. -+ -+12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout" -+ main config option. -+ -+13. Option "smtp_accept_msx_per_connection" is now expanded. -+ -+13. A main config option "allow_insecure_tainted_data" allows to turn -+ taint errors into warnings. -+ - Version 4.94 - ------------ - - 1. EXPERIMENTAL_SRS_NATIVE optional build feature. See the experimental.spec - file. ---- a/doc/spec.txt -+++ b/doc/spec.txt -@@ -8650,12 +8650,20 @@ - Whether a string is expanded depends upon the context. Usually this is solely - dependent upon the option for which a value is sought; in this documentation, - options for which string expansion is performed are marked with * after the - data type. ACL rules always expand strings. A couple of expansion conditions do - not expand some of the brace-delimited branches, for security reasons, and --expansion of data deriving from the sender ("tainted data") is not permitted. -- -+expansion of data deriving from the sender ("tainted data") is not permitted -+(including acessing a file using a tainted name). The main config -+option allow_insecure_tainted_data can be used as mitigation during -+uprades to more secure configurations. -+ -+Common ways of obtaining untainted equivalents of variables with tainted -+values come down to using the tainted value as a lookup key in a trusted -+database. This database could be the filesystem structure, or the -+password file, or accessed via a DBMS. Specific methods are indexed -+under "de-tainting". - - 11.1 Literal text in expanded strings - ------------------------------------- - - An uninterpreted dollar can be included in an expanded string by putting a -@@ -12946,10 +12954,12 @@ - - - 14.1 Miscellaneous - ------------------ - -+add_environment environment variables -+allow_insecure_tainted_data turn taint errors into warnings - bi_command to run for -bi command line option - debug_store do extra internal checks - disable_ipv6 do no IPv6 processing - keep_malformed for broken files - should not happen - localhost_number for unique message ids in clusters -@@ -13553,10 +13563,20 @@ - true, and also to add "@[]" to the list of local domains (defined in the named - domain list local_domains in the default configuration). This "magic string" - matches the domain literal form of all the local host's IP addresses. - - +-----------------------------------------------------+ -+|allow_insecure_tainted_data main boolean false | -++-----------------------------------------------------+ -+ -+The handling of tainted data may break older (pre 4.94) configurations. -+Setting this option to "true" turns taint errors (which result in a temporary -+message rejection) into warnings. This option is meant as mitigation only -+and deprecated already today. Future releases of Exim may ignore it. -+The taint log selector can be used to suppress even the warnings. -+ -++-----------------------------------------------------+ - |allow_mx_to_ip|Use: main|Type: boolean|Default: false| - +-----------------------------------------------------+ - - It appears that more and more DNS zone administrators are breaking the rules - and putting domain names that look like IP addresses on the right hand side of -@@ -35316,10 +35336,11 @@ - smtp_mailauth AUTH argument to MAIL commands - smtp_no_mail session with no MAIL commands - smtp_protocol_error SMTP protocol errors - smtp_syntax_error SMTP syntax errors - subject contents of Subject: on <= lines -+*taint taint errors or warnings - *tls_certificate_verified certificate verification status - *tls_cipher TLS cipher suite on <= and => lines - tls_peerdn TLS peer DN on <= and => lines - tls_sni TLS SNI on <= lines - unknown_in_list DNS lookup failed in list match -@@ -35604,11 +35625,13 @@ - - * tls_certificate_verified: An extra item is added to <= and => log lines - when TLS is in use. The item is "CV=yes" if the peer's certificate was - verified using a CA trust anchor, "CA=dane" if using a DNS trust anchor, - and "CV=no" if not. -- -+ * taint: Log warnings about tainted data. This selector can't be -+ turned of if allow_insecure_tainted_data is false (which is the -+ default). - * tls_cipher: When a message is sent or received over an encrypted - connection, the cipher suite used is added to the log line, preceded by X=. - - * tls_peerdn: When a message is sent or received over an encrypted - connection, and a certificate is supplied by the remote host, the peer DN diff --git a/mail/exim/files/debian/75_20-Set-mainlog_name-and-rejectlog_name-unconditionally.patch b/mail/exim/files/debian/75_20-Set-mainlog_name-and-rejectlog_name-unconditionally.patch deleted file mode 100644 index a660aeb3dd6e..000000000000 --- a/mail/exim/files/debian/75_20-Set-mainlog_name-and-rejectlog_name-unconditionally.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 41c494e2465efadc2e82002a07430e8aec85bc9b Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Mon, 12 Apr 2021 08:41:44 +0200 -Subject: [PATCH 20/23] Set mainlog_name and rejectlog_name unconditionally. - -(cherry picked from commit 3f06b9b4c7244b169d50bce216c1f54b4dfe7efb) ---- - src/log.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/src/log.c b/src/log.c -index 99eba5f90..011c4debc 100644 ---- a/src/log.c -+++ b/src/log.c -@@ -402,18 +402,20 @@ it gets statted to see if it has been cycled. With a datestamp, the datestamp - will be compared. The static slot for saving it is the same size as buffer, - and the text has been checked above to fit, so this use of strcpy() is OK. */ - --if (type == lt_main && string_datestamp_offset >= 0) -+if (type == lt_main) - { - Ustrcpy(mainlog_name, buffer); -- mainlog_datestamp = mainlog_name + string_datestamp_offset; -+ if (string_datestamp_offset > 0) -+ mainlog_datestamp = mainlog_name + string_datestamp_offset; - } - - /* Ditto for the reject log */ - --else if (type == lt_reject && string_datestamp_offset >= 0) -+else if (type == lt_reject) - { - Ustrcpy(rejectlog_name, buffer); -- rejectlog_datestamp = rejectlog_name + string_datestamp_offset; -+ if (string_datestamp_offset > 0) -+ rejectlog_datestamp = rejectlog_name + string_datestamp_offset; - } - - /* and deal with the debug log (which keeps the datestamp, but does not --- -2.30.2 - diff --git a/mail/exim/files/debian/75_21-tidy-log.c.patch b/mail/exim/files/debian/75_21-tidy-log.c.patch deleted file mode 100644 index b99f0c60988d..000000000000 --- a/mail/exim/files/debian/75_21-tidy-log.c.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 8021b95c2e266861aba29c97b4bb90dc6f7637a2 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Mon, 12 Apr 2021 09:19:21 +0200 -Subject: [PATCH 21/23] tidy log.c - -(cherry picked from commit 0327b6460eec64da6b0c1543c7e9b3d0f8cb9294) ---- - src/log.c | 97 +++++++++++++++++++++++---------------------------- - 1 file changed, 44 insertions(+), 53 deletions(-) - -diff --git a/src/log.c b/src/log.c -index 011c4debc..7ef7074ec 100644 ---- a/src/log.c -+++ b/src/log.c -@@ -397,62 +397,53 @@ people want, I hope. */ - - ok = string_format(buffer, sizeof(buffer), CS file_path, log_names[type]); - --/* Save the name of the mainlog for rollover processing. Without a datestamp, --it gets statted to see if it has been cycled. With a datestamp, the datestamp --will be compared. The static slot for saving it is the same size as buffer, --and the text has been checked above to fit, so this use of strcpy() is OK. */ -- --if (type == lt_main) -+switch (type) - { -- Ustrcpy(mainlog_name, buffer); -- if (string_datestamp_offset > 0) -- mainlog_datestamp = mainlog_name + string_datestamp_offset; -- } -- --/* Ditto for the reject log */ -- --else if (type == lt_reject) -- { -- Ustrcpy(rejectlog_name, buffer); -- if (string_datestamp_offset > 0) -- rejectlog_datestamp = rejectlog_name + string_datestamp_offset; -- } -- --/* and deal with the debug log (which keeps the datestamp, but does not --update it) */ -- --else if (type == lt_debug) -- { -- Ustrcpy(debuglog_name, buffer); -- if (tag) -- { -- /* this won't change the offset of the datestamp */ -- ok2 = string_format(buffer, sizeof(buffer), "%s%s", -- debuglog_name, tag); -- if (ok2) -- Ustrcpy(debuglog_name, buffer); -- } -- } -- --/* Remove any datestamp if this is the panic log. This is rare, so there's no --need to optimize getting the datestamp length. We remove one non-alphanumeric --char afterwards if at the start, otherwise one before. */ -- --else if (string_datestamp_offset >= 0) -- { -- uschar * from = buffer + string_datestamp_offset; -- uschar * to = from + string_datestamp_length; -+ case lt_main: -+ /* Save the name of the mainlog for rollover processing. Without a datestamp, -+ it gets statted to see if it has been cycled. With a datestamp, the datestamp -+ will be compared. The static slot for saving it is the same size as buffer, -+ and the text has been checked above to fit, so this use of strcpy() is OK. */ -+ Ustrcpy(mainlog_name, buffer); -+ if (string_datestamp_offset > 0) -+ mainlog_datestamp = mainlog_name + string_datestamp_offset; -+ case lt_reject: -+ /* Ditto for the reject log */ -+ Ustrcpy(rejectlog_name, buffer); -+ if (string_datestamp_offset > 0) -+ rejectlog_datestamp = rejectlog_name + string_datestamp_offset; -+ case lt_debug: -+ /* and deal with the debug log (which keeps the datestamp, but does not -+ update it) */ -+ Ustrcpy(debuglog_name, buffer); -+ if (tag) -+ { -+ /* this won't change the offset of the datestamp */ -+ ok2 = string_format(buffer, sizeof(buffer), "%s%s", -+ debuglog_name, tag); -+ if (ok2) -+ Ustrcpy(debuglog_name, buffer); -+ } -+ default: -+ /* Remove any datestamp if this is the panic log. This is rare, so there's no -+ need to optimize getting the datestamp length. We remove one non-alphanumeric -+ char afterwards if at the start, otherwise one before. */ -+ if (string_datestamp_offset >= 0) -+ { -+ uschar * from = buffer + string_datestamp_offset; -+ uschar * to = from + string_datestamp_length; - -- if (from == buffer || from[-1] == '/') -- { -- if (!isalnum(*to)) to++; -- } -- else -- if (!isalnum(from[-1])) from--; -+ if (from == buffer || from[-1] == '/') -+ { -+ if (!isalnum(*to)) to++; -+ } -+ else -+ if (!isalnum(from[-1])) from--; - -- /* This copy is ok, because we know that to is a substring of from. But -- due to overlap we must use memmove() not Ustrcpy(). */ -- memmove(from, to, Ustrlen(to)+1); -+ /* This copy is ok, because we know that to is a substring of from. But -+ due to overlap we must use memmove() not Ustrcpy(). */ -+ memmove(from, to, Ustrlen(to)+1); -+ } - } - - /* If the file name is too long, it is an unrecoverable disaster */ --- -2.30.2 - diff --git a/mail/exim/files/debian/75_22-Silence-compiler.patch b/mail/exim/files/debian/75_22-Silence-compiler.patch deleted file mode 100644 index ce6e89894f9a..000000000000 --- a/mail/exim/files/debian/75_22-Silence-compiler.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 2c9869d0622cc690b424cc74166d4a8393017ece Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Fri, 23 Apr 2021 17:40:40 +0200 -Subject: [PATCH 22/23] Silence compiler - ---- - src/acl.c | 2 +- - src/deliver.c | 3 +-- - src/expand.c | 6 +++++- - src/functions.h | 2 +- - src/lookups/lf_sqlperform.c | 4 ++-- - src/parse.c | 2 +- - src/rda.c | 2 +- - src/transports/appendfile.c | 4 ++-- - src/transports/autoreply.c | 12 ++++++------ - src/transports/pipe.c | 4 ++-- - 10 files changed, 22 insertions(+), 19 deletions(-) - -diff --git a/src/acl.c b/src/acl.c -index 81beab5f3..b62af5c65 100644 ---- a/src/acl.c -+++ b/src/acl.c -@@ -3600,7 +3600,7 @@ for (; cb; cb = cb->next) - case ACLC_QUEUE: - { - uschar *m; -- if (m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)) -+ if ((m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg))) - { - *log_msgptr = m; - return ERROR; -diff --git a/src/deliver.c b/src/deliver.c -index 87e944b03..b40eed4f9 100644 ---- a/src/deliver.c -+++ b/src/deliver.c -@@ -6149,12 +6149,11 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) - { - uschar *tmp = expand_string(tpname); - address_file = address_pipe = NULL; -- uschar *m; - if (!tmp) - p->message = string_sprintf("failed to expand \"%s\" as a " - "system filter transport name", tpname); - { uschar *m; -- if (m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname)) -+ if ((m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname))) - p->message = m; - } - tpname = tmp; -diff --git a/src/expand.c b/src/expand.c -index 21b86ebf5..dc4b4e102 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -4384,7 +4384,7 @@ f.expand_string_forcedfail = FALSE; - expand_string_message = US""; - - { uschar *m; --if (m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s)) -+if ((m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s))) - { - expand_string_message = m; - goto EXPAND_FAILED; -@@ -7629,10 +7629,12 @@ while (*s != 0) - /* Manually track tainting, as we deal in individual chars below */ - - if (is_tainted(sub)) -+ { - if (yield->s && yield->ptr) - gstring_rebuffer(yield); - else - yield->s = store_get(yield->size = Ustrlen(sub), TRUE); -+ } - - /* Check the UTF-8, byte-by-byte */ - -@@ -8193,6 +8195,7 @@ that is a bad idea, because expand_string_message is in dynamic store. */ - EXPAND_FAILED: - if (left) *left = s; - DEBUG(D_expand) -+ { - DEBUG(D_noutf8) - { - debug_printf_indent("|failed to expand: %s\n", string); -@@ -8212,6 +8215,7 @@ DEBUG(D_expand) - if (f.expand_string_forcedfail) - debug_printf_indent(UTF8_UP_RIGHT "failure was forced\n"); - } -+ } - if (resetok_p && !resetok) *resetok_p = FALSE; - expand_level--; - return NULL; -diff --git a/src/functions.h b/src/functions.h -index 1e8083673..b4d23c4bc 100644 ---- a/src/functions.h -+++ b/src/functions.h -@@ -1084,7 +1084,7 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec); - /******************************************************************************/ - /* Taint-checked file opens */ - static inline uschar * --is_tainted2(const void *p, int lflags, const uschar* fmt, ...) -+is_tainted2(const void *p, int lflags, const char* fmt, ...) - { - va_list ap; - uschar *msg; -diff --git a/src/lookups/lf_sqlperform.c b/src/lookups/lf_sqlperform.c -index eda3089e2..38b7c2ad3 100644 ---- a/src/lookups/lf_sqlperform.c -+++ b/src/lookups/lf_sqlperform.c -@@ -103,7 +103,7 @@ if (Ustrncmp(query, "servers", 7) == 0) - } - - { uschar *m; -- if (m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) -+ if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server))) - { - *errmsg = m; - return DEFER; -@@ -161,7 +161,7 @@ else - } - - { uschar *m; -- if (is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) -+ if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server))) - { - *errmsg = m; - return DEFER; -diff --git a/src/parse.c b/src/parse.c -index d1bc79039..0622b3127 100644 ---- a/src/parse.c -+++ b/src/parse.c -@@ -1402,7 +1402,7 @@ for (;;) - return FF_ERROR; - } - -- if (*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)) -+ if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename))) - return FF_ERROR; - - /* Check file name if required */ -diff --git a/src/rda.c b/src/rda.c -index 6ad7dd8bd..bba0b719b 100644 ---- a/src/rda.c -+++ b/src/rda.c -@@ -179,7 +179,7 @@ struct stat statbuf; - /* Reading a file is a form of expansion; we wish to deny attackers the - capability to specify the file name. */ - --if (*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)) -+if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename))) - { - *yield = FF_ERROR; - return NULL; -diff --git a/src/transports/appendfile.c b/src/transports/appendfile.c -index 7dbbaa2f9..6772b338b 100644 ---- a/src/transports/appendfile.c -+++ b/src/transports/appendfile.c -@@ -1287,8 +1287,8 @@ if (!(path = expand_string(fdname))) - goto ret_panic; - } - { uschar *m; --if (m = is_tainted2(path, 0, "Tainted '%s' (file or directory " -- "name for %s transport) not permitted", path, tblock->name)) -+if ((m = is_tainted2(path, 0, "Tainted '%s' (file or directory " -+ "name for %s transport) not permitted", path, tblock->name))) - { - addr->message = m; - goto ret_panic; -diff --git a/src/transports/autoreply.c b/src/transports/autoreply.c -index ed99de4c6..80c7c0db0 100644 ---- a/src/transports/autoreply.c -+++ b/src/transports/autoreply.c -@@ -407,8 +407,8 @@ if (oncelog && *oncelog && to) - uschar *m; - time_t then = 0; - -- if (m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" -- " not permitted", oncelog, tblock->name)) -+ if ((m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" -+ " not permitted", oncelog, tblock->name))) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -@@ -518,8 +518,8 @@ if (oncelog && *oncelog && to) - { - uschar *m; - int log_fd; -- if (m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" -- " not permitted", logfile, tblock->name)) -+ if ((m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" -+ " not permitted", logfile, tblock->name))) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -@@ -551,8 +551,8 @@ if (oncelog && *oncelog && to) - if (file) - { - uschar *m; -- if (m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" -- " not permitted", file, tblock->name)) -+ if ((m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" -+ " not permitted", file, tblock->name))) - { - addr->transport_return = DEFER; - addr->basic_errno = EACCES; -diff --git a/src/transports/pipe.c b/src/transports/pipe.c -index 4c9e68beb..fc44fa585 100644 ---- a/src/transports/pipe.c -+++ b/src/transports/pipe.c -@@ -601,8 +601,8 @@ if (!cmd || !*cmd) - } - - { uschar *m; --if (m = is_tainted2(cmd, 0, "Tainted '%s' (command " -- "for %s transport) not permitted", cmd, tblock->name)) -+if ((m = is_tainted2(cmd, 0, "Tainted '%s' (command " -+ "for %s transport) not permitted", cmd, tblock->name))) - { - addr->transport_return = PANIC; - addr->message = m; --- -2.30.2 - diff --git a/mail/exim/files/debian/75_23-Do-not-close-the-main-_log-if-we-do-not-see-a-chance.patch b/mail/exim/files/debian/75_23-Do-not-close-the-main-_log-if-we-do-not-see-a-chance.patch deleted file mode 100644 index 12d91633c4bb..000000000000 --- a/mail/exim/files/debian/75_23-Do-not-close-the-main-_log-if-we-do-not-see-a-chance.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 235c7030ee9ee1c1aad507786506a470b580bfe2 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Fri, 23 Apr 2021 22:41:57 +0200 -Subject: [PATCH 23/23] Do not close the (main)_log, if we do not see a chance - to open it again. - -The process doing local deliveries runs as an unprivileged user. If this -process needs to log failures or warnings (as caused by the -is_tainting2() function), it can't re-open the main_log and just exits. ---- - src/log.c | 84 ++++++++++++++++----------------- - src/transports/appendfile.c | 6 +++ - 2 files changed, 47 insertions(+), 43 deletions(-) - -diff --git a/src/log.c b/src/log.c -index 7ef7074ec..c2ef698e7 100644 ---- a/src/log.c -+++ b/src/log.c -@@ -646,18 +646,36 @@ return total_written; - } - - -- --static void --set_file_path(void) -+void -+set_file_path(BOOL *multiple) - { -+uschar *s; - int sep = ':'; /* Fixed separator - outside use */ --uschar *t; --const uschar *tt = US LOG_FILE_PATH; --while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE))) -+uschar *ss = *log_file_path ? log_file_path : LOG_FILE_PATH; -+ -+logging_mode = 0; -+while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) - { -- if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue; -- file_path = string_copy(t); -- break; -+ if (Ustrcmp(s, "syslog") == 0) -+ logging_mode |= LOG_MODE_SYSLOG; -+ else if (logging_mode & LOG_MODE_FILE) /* we know a file already */ -+ { -+ if (multiple) *multiple = TRUE; -+ } -+ else -+ { -+ logging_mode |= LOG_MODE_FILE; -+ -+ /* If a non-empty path is given, use it */ -+ -+ if (*s) -+ file_path = string_copy(s); -+ -+ /* If the path is empty, we want to use the first non-empty, non- -+ syslog item in LOG_FILE_PATH, if there is one, since the value of -+ log_file_path may have been set at runtime. If there is no such item, -+ use the ultimate default in the spool directory. */ -+ } - } - } - -@@ -665,7 +683,11 @@ while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE))) - void - mainlog_close(void) - { --if (mainlogfd < 0) return; -+/* avoid closing it if it is closed already or if we do not see a chance -+to open the file mainlog later again */ -+if (mainlogfd < 0 /* already closed */ -+ || !(geteuid() == 0 || geteuid() == exim_uid)) -+ return; - (void)close(mainlogfd); - mainlogfd = -1; - mainlog_inode = 0; -@@ -780,38 +802,7 @@ if (!path_inspected) - /* If nothing has been set, don't waste effort... the default values for the - statics are file_path="" and logging_mode = LOG_MODE_FILE. */ - -- if (*log_file_path) -- { -- int sep = ':'; /* Fixed separator - outside use */ -- uschar *s; -- const uschar *ss = log_file_path; -- -- logging_mode = 0; -- while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) -- { -- if (Ustrcmp(s, "syslog") == 0) -- logging_mode |= LOG_MODE_SYSLOG; -- else if (logging_mode & LOG_MODE_FILE) -- multiple = TRUE; -- else -- { -- logging_mode |= LOG_MODE_FILE; -- -- /* If a non-empty path is given, use it */ -- -- if (*s) -- file_path = string_copy(s); -- -- /* If the path is empty, we want to use the first non-empty, non- -- syslog item in LOG_FILE_PATH, if there is one, since the value of -- log_file_path may have been set at runtime. If there is no such item, -- use the ultimate default in the spool directory. */ -- -- else -- set_file_path(); /* Empty item in log_file_path */ -- } /* First non-syslog item in log_file_path */ -- } /* Scan of log_file_path */ -- } -+ if (*log_file_path) set_file_path(&multiple); - - /* If no modes have been selected, it is a major disaster */ - -@@ -1431,7 +1422,7 @@ if (opts) - resulting in certain setup not having been done. Hack this for now so we - do not segfault; note that nondefault log locations will not work */ - --if (!*file_path) set_file_path(); -+if (!*file_path) set_file_path(NULL); - - open_log(&fd, lt_debug, tag_name); - -@@ -1453,5 +1444,12 @@ debug_file = NULL; - unlink_log(lt_debug); - } - -+void -+open_logs(const char *m) -+{ -+set_file_path(NULL); -+open_log(&mainlogfd, lt_main, 0); -+open_log(&rejectlogfd, lt_reject, 0); -+} - - /* End of log.c */ -diff --git a/src/transports/appendfile.c b/src/transports/appendfile.c -index 6772b338b..706af6dde 100644 ---- a/src/transports/appendfile.c -+++ b/src/transports/appendfile.c -@@ -217,6 +217,9 @@ Arguments: - Returns: OK, FAIL, or DEFER - */ - -+void -+openlogs(); -+ - static int - appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, - transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) -@@ -231,6 +234,9 @@ dummy = dummy; - uid = uid; - gid = gid; - -+/* we can't wait until we're not privileged anymore */ -+open_logs("appendfile"); -+ - if (ob->expand_maildir_use_size_file) - ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file, - US"`maildir_use_size_file` in transport", tblock->name); --- -2.30.2 - diff --git a/mail/exim/files/debian/75_24-Silence-the-compiler.patch b/mail/exim/files/debian/75_24-Silence-the-compiler.patch deleted file mode 100644 index 14c3d5b433d2..000000000000 --- a/mail/exim/files/debian/75_24-Silence-the-compiler.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 33d5b8e8e4c2f23b4e834e3a095e3c9dd9f0686b Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 25 Apr 2021 18:58:35 +0200 -Subject: [PATCH 1/4] Silence the compiler - ---- - src/log.c | 4 ++-- - src/transports/appendfile.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/log.c b/src/log.c -index c2ef698e7..11d259197 100644 ---- a/src/log.c -+++ b/src/log.c -@@ -651,7 +651,7 @@ set_file_path(BOOL *multiple) - { - uschar *s; - int sep = ':'; /* Fixed separator - outside use */ --uschar *ss = *log_file_path ? log_file_path : LOG_FILE_PATH; -+const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH; - - logging_mode = 0; - while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) -@@ -1445,7 +1445,7 @@ unlink_log(lt_debug); - } - - void --open_logs(const char *m) -+open_logs(void) - { - set_file_path(NULL); - open_log(&mainlogfd, lt_main, 0); -diff --git a/src/transports/appendfile.c b/src/transports/appendfile.c -index 706af6dde..c0f4de4c8 100644 ---- a/src/transports/appendfile.c -+++ b/src/transports/appendfile.c -@@ -218,7 +218,7 @@ Returns: OK, FAIL, or DEFER - */ - - void --openlogs(); -+open_logs(void); - - static int - appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, -@@ -235,7 +235,7 @@ uid = uid; - gid = gid; - - /* we can't wait until we're not privileged anymore */ --open_logs("appendfile"); -+open_logs(); - - if (ob->expand_maildir_use_size_file) - ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file, --- -2.30.2 - diff --git a/mail/exim/files/debian/75_26-Disable-taintchecks-for-mkdir-this-isn-t-part-of-4.9.patch b/mail/exim/files/debian/75_26-Disable-taintchecks-for-mkdir-this-isn-t-part-of-4.9.patch deleted file mode 100644 index cee6066f9200..000000000000 --- a/mail/exim/files/debian/75_26-Disable-taintchecks-for-mkdir-this-isn-t-part-of-4.9.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 1416743e923cacf42955392e92995f5fe7e1c680 Mon Sep 17 00:00:00 2001 -From: "Heiko Schlittermann (HS12-RIPE)" -Date: Sun, 25 Apr 2021 10:19:32 +0200 -Subject: [PATCH 3/4] Disable taintchecks for mkdir, this isn't part of 4.94 - ---- - src/directory.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/directory.c b/src/directory.c -index 9f88f4141..ece1ee8f3 100644 ---- a/src/directory.c -+++ b/src/directory.c -@@ -44,8 +44,10 @@ uschar c = 1; - struct stat statbuf; - uschar * path; - -+/* does not work with 4.94 - if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name)) - { p = US"create"; path = US name; errno = EACCES; goto bad; } -+*/ - - if (parent) - { --- -2.30.2 - diff --git a/mail/exim/files/debian/75_30-Avoid-calling-gettimeofday-select-per-char-for-cmdli.patch b/mail/exim/files/debian/75_30-Avoid-calling-gettimeofday-select-per-char-for-cmdli.patch new file mode 100644 index 000000000000..ac72e532ebea --- /dev/null +++ b/mail/exim/files/debian/75_30-Avoid-calling-gettimeofday-select-per-char-for-cmdli.patch @@ -0,0 +1,616 @@ +From 1843f70b733127fcba3321d9d69359e05905f8cc Mon Sep 17 00:00:00 2001 +From: Jeremy Harris +Date: Sat, 16 Oct 2021 00:12:16 +0100 +Subject: [PATCH] Avoid calling gettimeofday(), select() per char for cmdline + message submission. Bug 2819 + +Broken-by: 3c55eef240 +--- + doc/ChangeLog | 4 ++ + src/exim.c | 7 ++- + src/filtertest.c | 16 +++---- + src/functions.h | 4 ++ + src/globals.c | 21 +++++---- + src/globals.h | 3 ++ + src/receive.c | 78 ++++++++++++++++++++++------------ + src/smtp_in.c | 24 ++++++++++- + src/tls-gnu.c | 9 ++++ + src/tls-openssl.c | 8 ++++ + src/transports/autoreply.c | 13 +++--- + 11 files changed, 133 insertions(+), 54 deletions(-) + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -1,9 +1,13 @@ + This document describes *changes* to previous versions, that might + affect Exim's operation, with an unchanged configuration file. For new + options, and new features, see the NewStuff file next to this ChangeLog. + ++JH/05 Bug 2819: speed up command-line messages being read in. Previously a ++ time check was being done for every character; replace that with one ++ per buffer. ++ + + Exim version 4.95 + ----------------- + + JH/01 Bug 1329: Fix format of Maildir-format filenames to match other mail- +--- a/src/exim.c ++++ b/src/exim.c +@@ -5382,11 +5382,11 @@ + + if (smtp_input) + { + if (!f.is_inetd) set_process_info("accepting a local %sSMTP message from <%s>", + smtp_batched_input? "batched " : "", +- (sender_address!= NULL)? sender_address : originator_login); ++ sender_address ? sender_address : originator_login); + } + else + { + int old_pool = store_pool; + store_pool = POOL_PERM; +@@ -5432,11 +5432,12 @@ + mac_smtp_fflush(); + exim_exit(EXIT_SUCCESS); + } + } + +-/* Otherwise, set up the input size limit here. */ ++/* Otherwise, set up the input size limit here and set no stdin stdio buffer ++(we handle buferring so as to have visibility of fill level). */ + + else + { + thismessage_size_limit = expand_string_integer(message_size_limit, TRUE); + if (expand_string_message) +@@ -5444,10 +5445,12 @@ + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand " + "message_size_limit: %s", expand_string_message); + else + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "invalid value for " + "message_size_limit: %s", expand_string_message); ++ ++ setvbuf(stdin, NULL, _IONBF, 0); + } + + /* Loop for several messages when reading SMTP input. If we fork any child + processes, we don't want to wait for them unless synchronous delivery is + requested, so set SIGCHLD to SIG_IGN in that case. This is not necessarily the +--- a/src/filtertest.c ++++ b/src/filtertest.c +@@ -43,15 +43,15 @@ + s = message_body_end; + body_len = 0; + body_linecount = 0; + header_size = message_size; + +-if (!dot_ended && !feof(stdin)) ++if (!dot_ended && !stdin_feof()) + { + if (!f.dot_ends) + { +- while ((ch = getc(stdin)) != EOF) ++ while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF) + { + if (ch == 0) body_zerocount++; + if (ch == '\n') body_linecount++; + if (body_len < message_body_visible) message_body[body_len++] = ch; + *s++ = ch; +@@ -60,11 +60,11 @@ + } + } + else + { + int ch_state = 1; +- while ((ch = getc(stdin)) != EOF) ++ while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF) + { + if (ch == 0) body_zerocount++; + switch (ch_state) + { + case 0: /* Normal state */ +@@ -97,10 +97,11 @@ + } + READ_END: ; + } + if (s == message_body_end || s[-1] != '\n') body_linecount++; + } ++debug_printf("%s %d\n", __FUNCTION__, __LINE__); + + message_body[body_len] = 0; + message_body_size = message_size - header_size; + + /* body_len stops at message_body_visible; it if got there, we may have +@@ -248,11 +249,11 @@ + } + + /* For a filter, set up the message_body variables and the message size if this + is the first time this function has been called. */ + +-if (message_body == NULL) read_message_body(dot_ended); ++if (!message_body) read_message_body(dot_ended); + + /* Now pass the filter file to the function that interprets it. Because + filter_test is not FILTER_NONE, the interpreter will output comments about what + it is doing. No need to clean up store. Indeed, we must not, because we may be + testing a system filter that is going to be followed by a user filter test. */ +@@ -267,14 +268,13 @@ + f.enable_dollar_recipients = FALSE; + f.system_filtering = FALSE; + } + else + { +- yield = (filter_type == FILTER_SIEVE)? +- sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error) +- : +- filter_interpret(filebuf, RDO_REWRITE, &generated, &error); ++ yield = filter_type == FILTER_SIEVE ++ ? sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, NULL, &generated, &error) ++ : filter_interpret(filebuf, RDO_REWRITE, &generated, &error); + } + + return yield != FF_ERROR; + } + +--- a/src/functions.h ++++ b/src/functions.h +@@ -66,10 +66,11 @@ + extern uschar *tls_field_from_dn(uschar *, const uschar *); + extern void tls_free_cert(void **); + extern int tls_getc(unsigned); + extern uschar *tls_getbuf(unsigned *); + extern void tls_get_cache(unsigned); ++extern BOOL tls_hasc(void); + extern BOOL tls_import_cert(const uschar *, void **); + extern BOOL tls_is_name_for_cert(const uschar *, void *); + # ifdef USE_OPENSSL + extern BOOL tls_openssl_options_parse(uschar *, long *); + # endif +@@ -148,10 +149,11 @@ + extern uschar *b64encode(const uschar *, int); + extern uschar *b64encode_taint(const uschar *, int, BOOL); + extern int b64decode(const uschar *, uschar **); + extern int bdat_getc(unsigned); + extern uschar *bdat_getbuf(unsigned *); ++extern BOOL bdat_hasc(void); + extern int bdat_ungetc(int); + extern void bdat_flush_data(void); + + extern void bits_clear(unsigned int *, size_t, int *); + extern void bits_set(unsigned int *, size_t, int *); +@@ -492,10 +494,11 @@ + uschar **, uschar *); + extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *); + extern int smtp_getc(unsigned); + extern uschar *smtp_getbuf(unsigned *); + extern void smtp_get_cache(unsigned); ++extern BOOL smtp_hasc(void); + extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); + extern void smtp_log_no_mail(void); + extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL); + extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int) NORETURN; + extern BOOL smtp_read_response(void *, uschar *, int, int, int); +@@ -521,10 +524,11 @@ + extern uschar *spool_sender_from_msgid(const uschar *); + extern int spool_write_header(uschar *, int, uschar **); + extern int stdin_getc(unsigned); + extern int stdin_feof(void); + extern int stdin_ferror(void); ++extern BOOL stdin_hasc(void); + extern int stdin_ungetc(int); + + extern void store_exit(void); + extern void store_init(void); + extern void store_writeprotect(int); +--- a/src/globals.c ++++ b/src/globals.c +@@ -169,20 +169,23 @@ + /* Input-reading functions for messages, so we can use special ones for + incoming TCP/IP. The defaults use stdin. We never need these for any + stand-alone tests. */ + + #if !defined(STAND_ALONE) && !defined(MACRO_PREDEF) +-int (*lwr_receive_getc)(unsigned) = stdin_getc; ++int (*lwr_receive_getc)(unsigned) = stdin_getc; + uschar * (*lwr_receive_getbuf)(unsigned *) = NULL; +-int (*lwr_receive_ungetc)(int) = stdin_ungetc; +-int (*receive_getc)(unsigned) = stdin_getc; +-uschar * (*receive_getbuf)(unsigned *) = NULL; +-void (*receive_get_cache)(unsigned) = NULL; +-int (*receive_ungetc)(int) = stdin_ungetc; +-int (*receive_feof)(void) = stdin_feof; +-int (*receive_ferror)(void) = stdin_ferror; +-BOOL (*receive_smtp_buffered)(void) = NULL; /* Only used for SMTP */ ++int (*lwr_receive_ungetc)(int) = stdin_ungetc; ++BOOL (*lwr_receive_hasc)(void) = stdin_hasc; ++ ++int (*receive_getc)(unsigned) = stdin_getc; ++uschar * (*receive_getbuf)(unsigned *) = NULL; ++void (*receive_get_cache)(unsigned) = NULL; ++BOOL (*receive_hasc)(void) = stdin_hasc; ++int (*receive_ungetc)(int) = stdin_ungetc; ++int (*receive_feof)(void) = stdin_feof; ++int (*receive_ferror)(void) = stdin_ferror; ++BOOL (*receive_smtp_buffered)(void) = NULL; /* Only used for SMTP */ + #endif + + + /* List of per-address expansion variables for clearing and saving/restoring + when verifying one address while routing/verifying another. We have to have +--- a/src/globals.h ++++ b/src/globals.h +@@ -159,13 +159,16 @@ + /* Input-reading functions for messages, so we can use special ones for + incoming TCP/IP. */ + + extern int (*lwr_receive_getc)(unsigned); + extern uschar * (*lwr_receive_getbuf)(unsigned *); ++extern BOOL (*lwr_receive_hasc)(void); + extern int (*lwr_receive_ungetc)(int); ++ + extern int (*receive_getc)(unsigned); + extern uschar * (*receive_getbuf)(unsigned *); ++extern BOOL (*receive_hasc)(void); + extern void (*receive_get_cache)(unsigned); + extern int (*receive_ungetc)(int); + extern int (*receive_feof)(void); + extern int (*receive_ferror)(void); + extern BOOL (*receive_smtp_buffered)(void); +--- a/src/receive.c ++++ b/src/receive.c +@@ -42,46 +42,75 @@ + /* These are the default functions that are set up in the variables such as + receive_getc initially. They just call the standard functions, passing stdin as + the file. (When SMTP input is occurring, different functions are used by + changing the pointer variables.) */ + ++uschar stdin_buf[4096]; ++uschar * stdin_inptr = stdin_buf; ++uschar * stdin_inend = stdin_buf; ++ ++static BOOL ++stdin_refill(void) ++{ ++size_t rc = fread(stdin_buf, 1, sizeof(stdin_buf), stdin); ++if (rc <= 0) ++ { ++ if (had_data_timeout) ++ { ++ fprintf(stderr, "exim: timed out while reading - message abandoned\n"); ++ log_write(L_lost_incoming_connection, ++ LOG_MAIN, "timed out while reading local message"); ++ receive_bomb_out(US"data-timeout", NULL); /* Does not return */ ++ } ++ if (had_data_sigint) ++ { ++ if (filter_test == FTEST_NONE) ++ { ++ fprintf(stderr, "\nexim: %s received - message abandoned\n", ++ had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT"); ++ log_write(0, LOG_MAIN, "%s received while reading local message", ++ had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT"); ++ } ++ receive_bomb_out(US"signal-exit", NULL); /* Does not return */ ++ } ++ return FALSE; ++ } ++stdin_inend = stdin_buf + rc; ++stdin_inptr = stdin_buf; ++return TRUE; ++} ++ + int + stdin_getc(unsigned lim) + { +-int c = getc(stdin); ++if (stdin_inptr >= stdin_inend) ++ if (!stdin_refill()) ++ return EOF; ++return *stdin_inptr++; ++} + +-if (had_data_timeout) +- { +- fprintf(stderr, "exim: timed out while reading - message abandoned\n"); +- log_write(L_lost_incoming_connection, +- LOG_MAIN, "timed out while reading local message"); +- receive_bomb_out(US"data-timeout", NULL); /* Does not return */ +- } +-if (had_data_sigint) +- { +- if (filter_test == FTEST_NONE) +- { +- fprintf(stderr, "\nexim: %s received - message abandoned\n", +- had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT"); +- log_write(0, LOG_MAIN, "%s received while reading local message", +- had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT"); +- } +- receive_bomb_out(US"signal-exit", NULL); /* Does not return */ +- } +-return c; ++ ++BOOL ++stdin_hasc(void) ++{ ++return stdin_inptr < stdin_inend; + } + + int + stdin_ungetc(int c) + { +-return ungetc(c, stdin); ++if (stdin_inptr <= stdin_buf) ++ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "buffer underflow in stdin_ungetc"); ++ ++*--stdin_inptr = c; ++return c; + } + + int + stdin_feof(void) + { +-return feof(stdin); ++return stdin_hasc() ? FALSE : feof(stdin); + } + + int + stdin_ferror(void) + { +@@ -586,11 +615,11 @@ + the file copy. */ + + static void + log_close_chk(void) + { +-if (!receive_timeout) ++if (!receive_timeout && !receive_hasc()) + { + struct timeval t; + timesince(&t, &received_time); + if (t.tv_sec > 30*60) + mainlog_close(); +@@ -652,15 +681,10 @@ + + if (!f.dot_ends) + { + int last_ch = '\n'; + +-/*XXX we do a gettimeofday before checking for every received char, +-which is hardly clever. The function-indirection doesn't help, but +-an additional function to check for nonempty read buffer would help. +-See stdin_getc() / smtp_getc() / tls_getc() / bdat_getc(). */ +- + for ( ; + log_close_chk(), (ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF; + last_ch = ch) + { + if (ch == 0) body_zerocount++; +--- a/src/smtp_in.c ++++ b/src/smtp_in.c +@@ -561,10 +561,16 @@ + if (!smtp_refill(lim)) + return EOF; + return *smtp_inptr++; + } + ++BOOL ++smtp_hasc(void) ++{ ++return smtp_inptr < smtp_inend; ++} ++ + uschar * + smtp_getbuf(unsigned * len) + { + unsigned size; + uschar * buf; +@@ -743,10 +749,18 @@ + } + } + } + } + ++BOOL ++bdat_hasc(void) ++{ ++if (chunking_data_left > 0) ++ return lwr_receive_hasc(); ++return TRUE; ++} ++ + uschar * + bdat_getbuf(unsigned * len) + { + uschar * buf; + +@@ -782,40 +796,44 @@ + bdat_push_receive_functions(void) + { + /* push the current receive_* function on the "stack", and + replace them by bdat_getc(), which in turn will use the lwr_receive_* + functions to do the dirty work. */ +-if (lwr_receive_getc == NULL) ++if (!lwr_receive_getc) + { + lwr_receive_getc = receive_getc; + lwr_receive_getbuf = receive_getbuf; ++ lwr_receive_hasc = receive_hasc; + lwr_receive_ungetc = receive_ungetc; + } + else + { + DEBUG(D_receive) debug_printf("chunking double-push receive functions\n"); + } + + receive_getc = bdat_getc; + receive_getbuf = bdat_getbuf; ++receive_hasc = bdat_hasc; + receive_ungetc = bdat_ungetc; + } + + static inline void + bdat_pop_receive_functions(void) + { +-if (lwr_receive_getc == NULL) ++if (!lwr_receive_getc) + { + DEBUG(D_receive) debug_printf("chunking double-pop receive functions\n"); + return; + } + receive_getc = lwr_receive_getc; + receive_getbuf = lwr_receive_getbuf; ++receive_hasc = lwr_receive_hasc; + receive_ungetc = lwr_receive_ungetc; + + lwr_receive_getc = NULL; + lwr_receive_getbuf = NULL; ++lwr_receive_hasc = NULL; + lwr_receive_ungetc = NULL; + } + + /************************************************* + * SMTP version of ungetc() * +@@ -2574,16 +2592,18 @@ + smtp_inbuffer[IN_BUFFER_SIZE-1] = '\0'; + + receive_getc = smtp_getc; + receive_getbuf = smtp_getbuf; + receive_get_cache = smtp_get_cache; ++receive_hasc = smtp_hasc; + receive_ungetc = smtp_ungetc; + receive_feof = smtp_feof; + receive_ferror = smtp_ferror; + receive_smtp_buffered = smtp_buffered; + lwr_receive_getc = NULL; + lwr_receive_getbuf = NULL; ++lwr_receive_hasc = NULL; + lwr_receive_ungetc = NULL; + smtp_inptr = smtp_inend = smtp_inbuffer; + smtp_had_eof = smtp_had_error = 0; + + /* Set up the message size limit; this may be host-specific */ +--- a/src/tls-gnu.c ++++ b/src/tls-gnu.c +@@ -3136,10 +3136,11 @@ + state->xfer_buffer = store_malloc(ssl_xfer_buffer_size); + + receive_getc = tls_getc; + receive_getbuf = tls_getbuf; + receive_get_cache = tls_get_cache; ++receive_hasc = tls_hasc; + receive_ungetc = tls_ungetc; + receive_feof = tls_feof; + receive_ferror = tls_ferror; + receive_smtp_buffered = tls_smtp_buffered; + +@@ -3738,10 +3739,11 @@ + if (!ct_ctx) /* server */ + { + receive_getc = smtp_getc; + receive_getbuf = smtp_getbuf; + receive_get_cache = smtp_get_cache; ++ receive_hasc = smtp_hasc; + receive_ungetc = smtp_ungetc; + receive_feof = smtp_feof; + receive_ferror = smtp_ferror; + receive_smtp_buffered = smtp_buffered; + } +@@ -3852,10 +3854,17 @@ + /* Something in the buffer; return next uschar */ + + return state->xfer_buffer[state->xfer_buffer_lwm++]; + } + ++BOOL ++tls_hasc(void) ++{ ++exim_gnutls_state_st * state = &state_server; ++return state->xfer_buffer_lwm < state->xfer_buffer_hwm; ++} ++ + uschar * + tls_getbuf(unsigned * len) + { + exim_gnutls_state_st * state = &state_server; + unsigned size; +--- a/src/tls-openssl.c ++++ b/src/tls-openssl.c +@@ -3348,10 +3348,11 @@ + ssl_xfer_eof = ssl_xfer_error = FALSE; + + receive_getc = tls_getc; + receive_getbuf = tls_getbuf; + receive_get_cache = tls_get_cache; ++receive_hasc = tls_hasc; + receive_ungetc = tls_ungetc; + receive_feof = tls_feof; + receive_ferror = tls_ferror; + receive_smtp_buffered = tls_smtp_buffered; + +@@ -4124,10 +4125,16 @@ + /* Something in the buffer; return next uschar */ + + return ssl_xfer_buffer[ssl_xfer_buffer_lwm++]; + } + ++BOOL ++tls_hasc(void) ++{ ++return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm; ++} ++ + uschar * + tls_getbuf(unsigned * len) + { + unsigned size; + uschar * buf; +@@ -4413,10 +4420,11 @@ + #endif + + receive_getc = smtp_getc; + receive_getbuf = smtp_getbuf; + receive_get_cache = smtp_get_cache; ++ receive_hasc = smtp_hasc; + receive_ungetc = smtp_ungetc; + receive_feof = smtp_feof; + receive_ferror = smtp_ferror; + receive_smtp_buffered = smtp_buffered; + tls_in.active.tls_ctx = NULL; +--- a/src/transports/autoreply.c ++++ b/src/transports/autoreply.c +@@ -644,10 +644,11 @@ + if (text[Ustrlen(text)-1] != '\n') fprintf(fp, "\n"); + } + + if (ff) + { ++debug_printf("%s %d: ff\n", __FUNCTION__, __LINE__); + while (Ufgets(big_buffer, big_buffer_size, ff) != NULL) + { + if (file_expand) + { + uschar *s = expand_string(big_buffer); +@@ -667,16 +668,16 @@ + /* Copy the original message if required, observing the return size + limit if we are returning the body. */ + + if (return_message) + { +- uschar *rubric = (tblock->headers_only)? +- US"------ This is a copy of the message's header lines.\n" +- : (tblock->body_only)? +- US"------ This is a copy of the body of the message, without the headers.\n" +- : +- US"------ This is a copy of the message, including all the headers.\n"; ++debug_printf("%s %d: ret msg\n", __FUNCTION__, __LINE__); ++ uschar *rubric = tblock->headers_only ++ ? US"------ This is a copy of the message's header lines.\n" ++ : tblock->body_only ++ ? US"------ This is a copy of the body of the message, without the headers.\n" ++ : US"------ This is a copy of the message, including all the headers.\n"; + transport_ctx tctx = { + .u = {.fd = fileno(fp)}, + .tblock = tblock, + .addr = addr, + .check_string = NULL, diff --git a/mail/exim/files/debian/75_38-Convert-all-uses-of-select-to-poll.-Bug-2831.patch b/mail/exim/files/debian/75_38-Convert-all-uses-of-select-to-poll.-Bug-2831.patch new file mode 100644 index 000000000000..93c99a4ef8f2 --- /dev/null +++ b/mail/exim/files/debian/75_38-Convert-all-uses-of-select-to-poll.-Bug-2831.patch @@ -0,0 +1,931 @@ +From dd19ce4f24eec64177cdcfcf294b8efbb631a24b Mon Sep 17 00:00:00 2001 +From: Jeremy Harris +Date: Wed, 17 Nov 2021 17:19:54 +0000 +Subject: [PATCH] select() -> poll(). Bug 2831 + +--- + doc/ChangeLog | 8 +++ + src/daemon.c | 126 +++++++++++++++++++------------------- + src/deliver.c | 54 ++++++++-------- + src/exim.c | 9 +-- + src/expand.c | 6 +- + src/functions.h | 7 +++ + src/ip.c | 12 +--- + src/malware.c | 6 +- + src/receive.c | 15 +---- + src/smtp_in.c | 18 +----- + src/spam.c | 42 ++++--------- + src/transport.c | 4 +- + src/transports/smtp.c | 37 ++++------- + 13 files changed, 142 insertions(+), 202 deletions(-) + +diff --git a/doc/ChangeLog b/doc/ChangeLog +index 7f6814d5e..58996c3f8 100644 +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -40,6 +40,14 @@ JH/09 Fix macro-definition during "-be" expansion testing. The move to + write-protected store for macros had not accounted for these runtime + additions; fix by removing this protection for "-be" mode. + ++JH/10 Convert all uses of select() to poll(). FreeBSD 12.2 was found to be ++ handing out large-numbered file descriptors, violating the usual Unix ++ assumption (and required by Posix) that the lowest possible number will be ++ allocated by the kernel when a new one is needed. In the daemon, and any ++ child procesees, values higher than 1024 (being bigger than FD_SETSIZE) ++ are not useable for FD_SET() [and hence select()] and overwrite the stack. ++ Assorted crashes happen. ++ + + Exim version 4.95 + ----------------- +diff --git a/src/daemon.c b/src/daemon.c +index 0b8d5d595..a248a4f40 100644 +--- a/src/daemon.c ++++ b/src/daemon.c +@@ -87,7 +87,7 @@ sigchld_seen = TRUE; + } + + +-/* SIGTERM handler. Try to get the damon pif file removed ++/* SIGTERM handler. Try to get the damon pid file removed + before exiting. */ + + static void +@@ -141,7 +141,7 @@ Uunlink(s); + + static void + close_daemon_sockets(int daemon_notifier_fd, +- int * listen_sockets, int listen_socket_count) ++ struct pollfd * fd_polls, int listen_socket_count) + { + if (daemon_notifier_fd >= 0) + { +@@ -152,7 +152,7 @@ if (daemon_notifier_fd >= 0) + #endif + } + +-for (int i = 0; i < listen_socket_count; i++) (void) close(listen_sockets[i]); ++for (int i = 0; i < listen_socket_count; i++) (void) close(fd_polls[i].fd); + } + + +@@ -167,7 +167,7 @@ is required so that they can be closed in the sub-process. Take care not to + leak store in this process - reset the stacking pool at the end. + + Arguments: +- listen_sockets sockets which are listening for incoming calls ++ fd_polls sockets which are listening for incoming calls + listen_socket_count count of listening sockets + accept_socket socket of the current accepted call + accepted socket information about the current call +@@ -176,7 +176,7 @@ Returns: nothing + */ + + static void +-handle_smtp_call(int *listen_sockets, int listen_socket_count, ++handle_smtp_call(struct pollfd *fd_polls, int listen_socket_count, + int accept_socket, struct sockaddr *accepted) + { + pid_t pid; +@@ -459,7 +459,7 @@ if (pid == 0) + extensive comment before the reception loop in exim.c for a fuller + explanation of this logic. */ + +- close_daemon_sockets(daemon_notifier_fd, listen_sockets, listen_socket_count); ++ close_daemon_sockets(daemon_notifier_fd, fd_polls, listen_socket_count); + + /* Set FD_CLOEXEC on the SMTP socket. We don't want any rogue child processes + to be able to communicate with them, under any circumstances. */ +@@ -1305,13 +1305,6 @@ return FALSE; + + + +-static void +-add_listener_socket(int fd, fd_set * fds, int * fd_max) +-{ +-FD_SET(fd, fds); +-if (fd > *fd_max) *fd_max = fd; +-} +- + /************************************************* + * Exim Daemon Mainline * + *************************************************/ +@@ -1339,9 +1332,8 @@ void + daemon_go(void) + { + struct passwd * pw; +-int * listen_sockets = NULL; +-int listen_socket_count = 0, listen_fd_max = 0; +-fd_set select_listen; ++struct pollfd * fd_polls, * tls_watch_poll = NULL, * dnotify_poll = NULL; ++int listen_socket_count = 0, poll_fd_count; + ip_address_item * addresses = NULL; + time_t last_connection_time = (time_t)0; + int local_queue_run_max = atoi(CS expand_string(queue_run_max)); +@@ -1353,17 +1345,21 @@ debugging lines get the pid added. */ + + DEBUG(D_any|D_v) debug_selector |= D_pid; + +-FD_ZERO(&select_listen); ++/* Allocate enough pollstructs for inetd mode plus the ancillary sockets; ++also used when there are no listen sockets. */ ++ ++fd_polls = store_get(sizeof(struct pollfd) * 3, FALSE); ++ + if (f.inetd_wait_mode) + { + listen_socket_count = 1; +- listen_sockets = store_get(sizeof(int), FALSE); + (void) close(3); + if (dup2(0, 3) == -1) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, + "failed to dup inetd socket safely away: %s", strerror(errno)); + +- listen_sockets[0] = 3; ++ fd_polls[0].fd = 3; ++ fd_polls[0].events = POLLIN; + (void) close(0); + (void) close(1); + (void) close(2); +@@ -1390,9 +1386,6 @@ if (f.inetd_wait_mode) + if (setsockopt(3, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on))) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to set socket NODELAY: %s", + strerror(errno)); +- +- FD_SET(3, &select_listen); +- listen_fd_max = 3; + } + + +@@ -1686,11 +1679,16 @@ if (f.daemon_listen && !f.inetd_wait_mode) + } + } + +- /* Get a vector to remember all the sockets in */ ++ /* Get a vector to remember all the sockets in. ++ Two extra elements for the ancillary sockets */ + + for (ipa = addresses; ipa; ipa = ipa->next) + listen_socket_count++; +- listen_sockets = store_get(sizeof(int) * listen_socket_count, FALSE); ++ fd_polls = store_get(sizeof(struct pollfd) * (listen_socket_count + 2), ++ FALSE); ++ for (struct pollfd * p = fd_polls; p < fd_polls + listen_socket_count + 2; ++ p++) ++ { p->fd = -1; p->events = POLLIN; } + + } /* daemon_listen but not inetd_wait_mode */ + +@@ -1795,7 +1793,7 @@ if (f.daemon_listen && !f.inetd_wait_mode) + wildcard = ipa->address[0] == 0; + } + +- if ((listen_sockets[sk] = fd = ip_socket(SOCK_STREAM, af)) < 0) ++ if ((fd_polls[sk].fd = fd = ip_socket(SOCK_STREAM, af)) < 0) + { + if (check_special_case(0, addresses, ipa, FALSE)) + { +@@ -1804,7 +1802,7 @@ if (f.daemon_listen && !f.inetd_wait_mode) + goto SKIP_SOCKET; + } + log_write(0, LOG_PANIC_DIE, "IPv%c socket creation failed: %s", +- (af == AF_INET6)? '6' : '4', strerror(errno)); ++ af == AF_INET6 ? '6' : '4', strerror(errno)); + } + + /* If this is an IPv6 wildcard socket, set IPV6_V6ONLY if that option is +@@ -1903,8 +1901,7 @@ if (f.daemon_listen && !f.inetd_wait_mode) + f.tcp_fastopen_ok = FALSE; + } + #endif +- +- add_listener_socket(fd, &select_listen, &listen_fd_max); ++ fd_polls[sk].fd = fd; + continue; + } + +@@ -2187,14 +2184,21 @@ tls_daemon_init(); + + /* Add ancillary sockets to the set for select */ + ++poll_fd_count = listen_socket_count; + #ifndef DISABLE_TLS + if (tls_watch_fd >= 0) +- add_listener_socket(tls_watch_fd, &select_listen, &listen_fd_max); ++ { ++ tls_watch_poll = &fd_polls[poll_fd_count++]; ++ tls_watch_poll->fd = tls_watch_fd; ++ tls_watch_poll->events = POLLIN; ++ } + #endif + if (daemon_notifier_fd >= 0) +- add_listener_socket(daemon_notifier_fd, &select_listen, &listen_fd_max); +- +-listen_fd_max++; ++ { ++ dnotify_poll = &fd_polls[poll_fd_count++]; ++ dnotify_poll->fd = daemon_notifier_fd; ++ dnotify_poll->events = POLLIN; ++ } + + /* Close the log so it can be renamed and moved. In the few cases below where + this long-running process writes to the log (always exceptional conditions), it +@@ -2293,7 +2297,7 @@ for (;;) + /* Close any open listening sockets in the child */ + + close_daemon_sockets(daemon_notifier_fd, +- listen_sockets, listen_socket_count); ++ fd_polls, listen_socket_count); + + /* Reset SIGHUP and SIGCHLD in the child in both cases. */ + +@@ -2421,9 +2425,8 @@ for (;;) + + if (f.daemon_listen) + { +- int check_lsk = 0, lcount; ++ int lcount; + BOOL select_failed = FALSE; +- fd_set fds = select_listen; + + DEBUG(D_any) debug_printf("Listening...\n"); + +@@ -2440,8 +2443,7 @@ for (;;) + errno = EINTR; + } + else +- lcount = select(listen_fd_max, (SELECT_ARG2_TYPE *)&fds, +- NULL, NULL, NULL); ++ lcount = poll(fd_polls, poll_fd_count, -1); + + if (lcount < 0) + { +@@ -2461,15 +2463,15 @@ for (;;) + handle_ending_processes(); + + #ifndef DISABLE_TLS ++ { ++ int old_tfd; + /* Create or rotate any required keys; handle (delayed) filewatch event */ +- for (int old_tfd = tls_daemon_tick(); old_tfd >= 0; ) +- { +- FD_CLR(old_tfd, &select_listen); +- if (old_tfd == listen_fd_max - 1) listen_fd_max = old_tfd; +- if (tls_watch_fd >= 0) +- add_listener_socket(tls_watch_fd, &select_listen, &listen_fd_max); +- break; +- } ++ ++ if ((old_tfd = tls_daemon_tick()) >= 0) ++ for (struct pollfd * p = &fd_polls[listen_socket_count]; ++ p < fd_polls + poll_fd_count; p++) ++ if (p->fd == old_tfd) { p->fd = tls_watch_fd ; break; } ++ } + #endif + errno = select_errno; + } +@@ -2490,22 +2492,23 @@ for (;;) + if (!select_failed) + { + #if !defined(DISABLE_TLS) && (defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT)) +- if (tls_watch_fd >= 0 && FD_ISSET(tls_watch_fd, &fds)) ++ if (tls_watch_poll && tls_watch_poll->revents & POLLIN) + { ++ tls_watch_poll->revents = 0; + tls_watch_trigger_time = time(NULL); /* Set up delayed event */ + tls_watch_discard_event(tls_watch_fd); + break; /* to top of daemon loop */ + } + #endif +- if (daemon_notifier_fd >= 0 && FD_ISSET(daemon_notifier_fd, &fds)) ++ if (dnotify_poll && dnotify_poll->revents & POLLIN) + { ++ dnotify_poll->revents = 0; + sigalrm_seen = daemon_notification(); + break; /* to top of daemon loop */ + } +- while (check_lsk < listen_socket_count) +- { +- int lfd = listen_sockets[check_lsk++]; +- if (FD_ISSET(lfd, &fds)) ++ for (struct pollfd * p = fd_polls; p < fd_polls + listen_socket_count; ++ p++) ++ if (p->revents & POLLIN) + { + EXIM_SOCKLEN_T alen = sizeof(accepted); + #ifdef TCP_INFO +@@ -2516,23 +2519,23 @@ for (;;) + + smtp_listen_backlog = 0; + if ( smtp_backlog_monitor > 0 +- && getsockopt(lfd, IPPROTO_TCP, TCP_INFO, &ti, &tlen) == 0) ++ && getsockopt(p->fd, IPPROTO_TCP, TCP_INFO, &ti, &tlen) == 0) + { + # ifdef EXIM_HAVE_TCPI_UNACKED + DEBUG(D_interface) debug_printf("listen fd %d queue max %u curr %u\n", +- lfd, ti.tcpi_sacked, ti.tcpi_unacked); ++ p->fd, ti.tcpi_sacked, ti.tcpi_unacked); + smtp_listen_backlog = ti.tcpi_unacked; + # elif defined(__FreeBSD__) /* This does not work. Investigate kernel sourcecode. */ + DEBUG(D_interface) debug_printf("listen fd %d queue max %u curr %u\n", +- lfd, ti.__tcpi_sacked, ti.__tcpi_unacked); ++ p->fd, ti.__tcpi_sacked, ti.__tcpi_unacked); + smtp_listen_backlog = ti.__tcpi_unacked; + # endif + } + #endif +- accept_socket = accept(lfd, (struct sockaddr *)&accepted, &alen); ++ p->revents = 0; ++ accept_socket = accept(p->fd, (struct sockaddr *)&accepted, &alen); + break; + } +- } + } + + /* If select or accept has failed and this was not caused by an +@@ -2591,7 +2594,7 @@ for (;;) + #endif + if (inetd_wait_timeout) + last_connection_time = time(NULL); +- handle_smtp_call(listen_sockets, listen_socket_count, accept_socket, ++ handle_smtp_call(fd_polls, listen_socket_count, accept_socket, + (struct sockaddr *)&accepted); + } + } +@@ -2606,10 +2609,8 @@ for (;;) + + else + { +- struct timeval tv; +- tv.tv_sec = queue_interval; +- tv.tv_usec = 0; +- select(0, NULL, NULL, NULL, &tv); ++ struct pollfd p; ++ poll(&p, 0, queue_interval * 1000); + handle_ending_processes(); + } + +@@ -2634,8 +2635,7 @@ for (;;) + { + log_write(0, LOG_MAIN, "pid %d: SIGHUP received: re-exec daemon", + getpid()); +- close_daemon_sockets(daemon_notifier_fd, +- listen_sockets, listen_socket_count); ++ close_daemon_sockets(daemon_notifier_fd, fd_polls, listen_socket_count); + ALARM_CLR(0); + signal(SIGHUP, SIG_IGN); + sighup_argv[0] = exim_path; +diff --git a/src/deliver.c b/src/deliver.c +index 4594c4a1d..8aad811c6 100644 +--- a/src/deliver.c ++++ b/src/deliver.c +@@ -74,6 +74,7 @@ static BOOL update_spool; + static BOOL remove_journal; + static int parcount = 0; + static pardata *parlist = NULL; ++static struct pollfd *parpoll; + static int return_count; + static uschar *frozen_info = US""; + static uschar *used_return_path = NULL; +@@ -3306,7 +3307,7 @@ BOOL done = p->done; + + /* Loop through all items, reading from the pipe when necessary. The pipe + used to be non-blocking. But I do not see a reason for using non-blocking I/O +-here, as the preceding select() tells us, if data is available for reading. ++here, as the preceding poll() tells us, if data is available for reading. + + A read() on a "selected" handle should never block, but(!) it may return + less data then we expected. (The buffer size we pass to read() shouldn't be +@@ -3840,7 +3841,7 @@ static address_item * + par_wait(void) + { + int poffset, status; +-address_item *addr, *addrlist; ++address_item * addr, * addrlist; + pid_t pid; + + set_process_info("delivering %s: waiting for a remote delivery subprocess " +@@ -3850,18 +3851,18 @@ set_process_info("delivering %s: waiting for a remote delivery subprocess " + existence - in which case give an error return. We cannot proceed just by + waiting for a completion, because a subprocess may have filled up its pipe, and + be waiting for it to be emptied. Therefore, if no processes have finished, we +-wait for one of the pipes to acquire some data by calling select(), with a ++wait for one of the pipes to acquire some data by calling poll(), with a + timeout just in case. + + The simple approach is just to iterate after reading data from a ready pipe. + This leads to non-ideal behaviour when the subprocess has written its final Z + item, closed the pipe, and is in the process of exiting (the common case). A +-call to waitpid() yields nothing completed, but select() shows the pipe ready - ++call to waitpid() yields nothing completed, but poll() shows the pipe ready - + reading it yields EOF, so you end up with busy-waiting until the subprocess has + actually finished. + + To avoid this, if all the data that is needed has been read from a subprocess +-after select(), an explicit wait() for it is done. We know that all it is doing ++after poll(), an explicit wait() for it is done. We know that all it is doing + is writing to the pipe and then exiting, so the wait should not be long. + + The non-blocking waitpid() is to some extent just insurance; if we could +@@ -3881,9 +3882,7 @@ for (;;) /* Normally we do not repeat this loop */ + { + while ((pid = waitpid(-1, &status, WNOHANG)) <= 0) + { +- struct timeval tv; +- fd_set select_pipes; +- int maxpipe, readycount; ++ int readycount; + + /* A return value of -1 can mean several things. If errno != ECHILD, it + either means invalid options (which we discount), or that this process was +@@ -3907,7 +3906,7 @@ for (;;) /* Normally we do not repeat this loop */ + subprocesses are still in existence. If kill() gives an OK return, we know + it must be for one of our processes - it can't be for a re-use of the pid, + because if our process had finished, waitpid() would have found it. If any +- of our subprocesses are in existence, we proceed to use select() as if ++ of our subprocesses are in existence, we proceed to use poll() as if + waitpid() had returned zero. I think this is safe. */ + + if (pid < 0) +@@ -3931,7 +3930,7 @@ for (;;) /* Normally we do not repeat this loop */ + if (poffset >= remote_max_parallel) + { + DEBUG(D_deliver) debug_printf("*** no delivery children found\n"); +- return NULL; /* This is the error return */ ++ return NULL; /* This is the error return */ + } + } + +@@ -3940,28 +3939,23 @@ for (;;) /* Normally we do not repeat this loop */ + subprocess, but there are no completed subprocesses. See if any pipes are + ready with any data for reading. */ + +- DEBUG(D_deliver) debug_printf("selecting on subprocess pipes\n"); ++ DEBUG(D_deliver) debug_printf("polling subprocess pipes\n"); + +- maxpipe = 0; +- FD_ZERO(&select_pipes); + for (poffset = 0; poffset < remote_max_parallel; poffset++) + if (parlist[poffset].pid != 0) +- { +- int fd = parlist[poffset].fd; +- FD_SET(fd, &select_pipes); +- if (fd > maxpipe) maxpipe = fd; +- } ++ { ++ parpoll[poffset].fd = parlist[poffset].fd; ++ parpoll[poffset].events = POLLIN; ++ } ++ else ++ parpoll[poffset].fd = -1; + + /* Stick in a 60-second timeout, just in case. */ + +- tv.tv_sec = 60; +- tv.tv_usec = 0; +- +- readycount = select(maxpipe + 1, (SELECT_ARG2_TYPE *)&select_pipes, +- NULL, NULL, &tv); ++ readycount = poll(parpoll, remote_max_parallel, 60 * 1000); + + /* Scan through the pipes and read any that are ready; use the count +- returned by select() to stop when there are no more. Select() can return ++ returned by poll() to stop when there are no more. Select() can return + with no processes (e.g. if interrupted). This shouldn't matter. + + If par_read_pipe() returns TRUE, it means that either the terminating Z was +@@ -3978,7 +3972,7 @@ for (;;) /* Normally we do not repeat this loop */ + poffset++) + { + if ( (pid = parlist[poffset].pid) != 0 +- && FD_ISSET(parlist[poffset].fd, &select_pipes) ++ && parpoll[poffset].revents + ) + { + readycount--; +@@ -4016,7 +4010,7 @@ for (;;) /* Normally we do not repeat this loop */ + "transport process list", pid); + } /* End of the "for" loop */ + +-/* Come here when all the data was completely read after a select(), and ++/* Come here when all the data was completely read after a poll(), and + the process in pid has been wait()ed for. */ + + PROCESS_DONE: +@@ -4051,7 +4045,7 @@ if ((status & 0xffff) != 0) + "%s %d", + addrlist->transport->driver_name, + status, +- (msb == 0)? "terminated by signal" : "exit code", ++ msb == 0 ? "terminated by signal" : "exit code", + code); + + if (msb != 0 || (code != SIGTERM && code != SIGKILL && code != SIGQUIT)) +@@ -4069,7 +4063,8 @@ if ((status & 0xffff) != 0) + /* Else complete reading the pipe to get the result of the delivery, if all + the data has not yet been obtained. */ + +-else if (!parlist[poffset].done) (void)par_read_pipe(poffset, TRUE); ++else if (!parlist[poffset].done) ++ (void) par_read_pipe(poffset, TRUE); + + /* Put the data count and return path into globals, mark the data slot unused, + decrement the count of subprocesses, and return the address chain. */ +@@ -4218,6 +4213,7 @@ if (!parlist) + parlist = store_get(remote_max_parallel * sizeof(pardata), FALSE); + for (poffset = 0; poffset < remote_max_parallel; poffset++) + parlist[poffset].pid = 0; ++ parpoll = store_get(remote_max_parallel * sizeof(struct pollfd), FALSE); + } + + /* Now loop for each remote delivery */ +@@ -4613,7 +4609,7 @@ nonmatch domains + that it can use either of them, though it prefers O_NONBLOCK, which + distinguishes between EOF and no-more-data. */ + +-/* The data appears in a timely manner and we already did a select on ++/* The data appears in a timely manner and we already did a poll on + all pipes, so I do not see a reason to use non-blocking IO here + + #ifdef O_NONBLOCK +diff --git a/src/exim.c b/src/exim.c +index 133761de9..42db457c0 100644 +--- a/src/exim.c ++++ b/src/exim.c +@@ -5735,13 +5735,8 @@ for (BOOL more = TRUE; more; ) + the file copy. */ + + if (!receive_timeout) +- { +- struct timeval t = { .tv_sec = 30*60, .tv_usec = 0 }; /* 30 minutes */ +- fd_set r; +- +- FD_ZERO(&r); FD_SET(0, &r); +- if (select(1, &r, NULL, NULL, &t) == 0) mainlog_close(); +- } ++ if (poll_one_fd(0, POLLIN, 30*60*1000) == 0) /* 30 minutes */ ++ mainlog_close(); + + /* Read the data for the message. If filter_test is not FTEST_NONE, this + will just read the headers for the message, and not write anything onto the +diff --git a/src/expand.c b/src/expand.c +index 59554840e..bfae2a3c0 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -1760,8 +1760,6 @@ const uschar * where; + #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS + uschar * sname; + #endif +-fd_set fds; +-struct timeval tv; + + if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) + { +@@ -1805,9 +1803,7 @@ if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0) + buf[0] = NOTIFY_QUEUE_SIZE_REQ; + if (send(fd, buf, 1, 0) < 0) { where = US"send"; goto bad; } + +-FD_ZERO(&fds); FD_SET(fd, &fds); +-tv.tv_sec = 2; tv.tv_usec = 0; +-if (select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tv) != 1) ++if (poll_one_fd(fd, POLLIN, 2 * 1000) != 1) + { + DEBUG(D_expand) debug_printf("no daemon response; using local evaluation\n"); + len = snprintf(CS buf, sizeof(buf), "%u", queue_count_cached()); +diff --git a/src/functions.h b/src/functions.h +index 3dd890a00..0cf80dfbb 100644 +--- a/src/functions.h ++++ b/src/functions.h +@@ -1255,6 +1255,13 @@ child_open(uschar **argv, uschar **envp, int newumask, int *infdptr, + outfdptr, make_leader, purpose); + } + ++static inline int ++poll_one_fd(int fd, short pollbits, int tmo_millisec) ++{ ++struct pollfd p = {.fd = fd, .events = pollbits}; ++return poll(&p, 1, tmo_millisec); ++} ++ + # endif /* !COMPILE_UTILITY */ + + /******************************************************************************/ +diff --git a/src/ip.c b/src/ip.c +index d83d6f910..aa42343fb 100644 +--- a/src/ip.c ++++ b/src/ip.c +@@ -589,9 +589,7 @@ Returns: TRUE => ready for i/o + BOOL + fd_ready(int fd, time_t timelimit) + { +-fd_set select_inset; +-int time_left = timelimit - time(NULL); +-int rc; ++int rc, time_left = timelimit - time(NULL); + + if (time_left <= 0) + { +@@ -602,12 +600,8 @@ if (time_left <= 0) + + do + { +- struct timeval tv = { .tv_sec = time_left, .tv_usec = 0 }; +- FD_ZERO (&select_inset); +- FD_SET (fd, &select_inset); +- + /*DEBUG(D_transport) debug_printf("waiting for data on fd\n");*/ +- rc = select(fd + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv); ++ rc = poll_one_fd(fd, POLLIN, time_left * 1000); + + /* If some interrupt arrived, just retry. We presume this to be rare, + but it can happen (e.g. the SIGUSR1 signal sent by exiwhat causes +@@ -636,7 +630,7 @@ do + /* Checking the FD_ISSET is not enough, if we're interrupted, the + select_inset may still contain the 'input'. */ + } +-while (rc < 0 || !FD_ISSET(fd, &select_inset)); ++while (rc < 0); + return TRUE; + } + +diff --git a/src/malware.c b/src/malware.c +index 10a390dfa..d9ab3b9dd 100644 +--- a/src/malware.c ++++ b/src/malware.c +@@ -277,11 +277,7 @@ int fd = ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5, + /* Under some fault conditions, FreeBSD 12.2 seen to send a (non-TFO) SYN + and, getting no response, wait for a long time. Impose a 5s max. */ + if (fd >= 0) +- { +- struct timeval tv = {.tv_sec = 5}; +- fd_set fds; +- FD_ZERO(&fds); FD_SET(fd, &fds); (void) select(fd+1, NULL, &fds, NULL, &tv); +- } ++ (void) poll_one_fd(fd, POLLOUT, 5 * 1000); + #endif + return fd; + } +diff --git a/src/receive.c b/src/receive.c +index fab0f00c4..3adcbbd88 100644 +--- a/src/receive.c ++++ b/src/receive.c +@@ -624,12 +624,8 @@ if (!receive_timeout && !receive_hasc()) + if (t.tv_sec > 30*60) + mainlog_close(); + else +- { +- fd_set r; +- FD_ZERO(&r); FD_SET(0, &r); +- t.tv_sec = 30*60 - t.tv_sec; t.tv_usec = 0; +- if (select(1, &r, NULL, NULL, &t) == 0) mainlog_close(); +- } ++ if (poll_one_fd(0, POLLIN, (30*60 - t.tv_sec) * 1000) == 0) ++ mainlog_close(); + } + } + +@@ -4234,12 +4230,7 @@ response, but the chance of this happening should be small. */ + if (smtp_input && sender_host_address && !f.sender_host_notsocket && + !receive_smtp_buffered()) + { +- struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; +- fd_set select_check; +- FD_ZERO(&select_check); +- FD_SET(fileno(smtp_in), &select_check); +- +- if (select(fileno(smtp_in) + 1, &select_check, NULL, NULL, &tv) != 0) ++ if (poll_one_fd(fileno(smtp_in), POLLIN, 0) != 0) + { + int c = (receive_getc)(GETC_BUFFER_UNLIMITED); + if (c != EOF) (receive_ungetc)(c); else +diff --git a/src/smtp_in.c b/src/smtp_in.c +index 824178e4d..7cb966f24 100644 +--- a/src/smtp_in.c ++++ b/src/smtp_in.c +@@ -346,8 +346,6 @@ static BOOL + wouldblock_reading(void) + { + int fd, rc; +-fd_set fds; +-struct timeval tzero = {.tv_sec = 0, .tv_usec = 0}; + + #ifndef DISABLE_TLS + if (tls_in.active.sock >= 0) +@@ -358,9 +356,7 @@ if (smtp_inptr < smtp_inend) + return FALSE; + + fd = fileno(smtp_in); +-FD_ZERO(&fds); +-FD_SET(fd, &fds); +-rc = select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tzero); ++rc = poll_one_fd(fd, POLLIN, 0); + + if (rc <= 0) return TRUE; /* Not ready to read */ + rc = smtp_getc(GETC_BUFFER_UNLIMITED); +@@ -3942,16 +3938,8 @@ log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", + /* Pause, hoping client will FIN first so that they get the TIME_WAIT. + The socket should become readble (though with no data) */ + +- { +- int fd = fileno(smtp_in); +- fd_set fds; +- struct timeval t_limit = {.tv_sec = 0, .tv_usec = 200*1000}; +- +- FD_ZERO(&fds); +- FD_SET(fd, &fds); +- (void) select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &t_limit); +- } +-#endif /*!DAEMON_CLOSE_NOWAIT*/ ++(void) poll_one_fd(fileno(smtp_in), POLLIN, 200); ++#endif /*!SERVERSIDE_CLOSE_NOWAIT*/ + } + + +diff --git a/src/spam.c b/src/spam.c +index 470e5fae7..e3316ed96 100644 +--- a/src/spam.c ++++ b/src/spam.c +@@ -194,12 +194,6 @@ uschar *p,*q; + int override = 0; + time_t start; + size_t read, wrote; +-#ifndef NO_POLL_H +-struct pollfd pollfd; +-#else /* Patch posted by Erik ? for OS X */ +-struct timeval select_tv; /* and applied by PH */ +-fd_set select_fd; +-#endif + uschar *spamd_address_work; + spamd_address_container * sd; + +@@ -395,19 +389,19 @@ if (wrote == -1) + } + + /* now send the file */ +-/* spamd sometimes accepts connections but doesn't read data off +- * the connection. We make the file descriptor non-blocking so +- * that the write will only write sufficient data without blocking +- * and we poll the descriptor to make sure that we can write without +- * blocking. Short writes are gracefully handled and if the whole +- * transaction takes too long it is aborted. +- * Note: poll() is not supported in OSX 10.2 and is reported to be +- * broken in more recent versions (up to 10.4). ++/* spamd sometimes accepts connections but doesn't read data off the connection. ++We make the file descriptor non-blocking so that the write will only write ++sufficient data without blocking and we poll the descriptor to make sure that we ++can write without blocking. Short writes are gracefully handled and if the ++whole transaction takes too long it is aborted. ++ ++Note: poll() is not supported in OSX 10.2 and is reported to be broken in more ++ recent versions (up to 10.4). Workaround using select() removed 2021/11 (jgh). + */ +-#ifndef NO_POLL_H +-pollfd.fd = spamd_cctx.sock; +-pollfd.events = POLLOUT; ++#ifdef NO_POLL_H ++# error Need poll(2) support + #endif ++ + (void)fcntl(spamd_cctx.sock, F_SETFL, O_NONBLOCK); + do + { +@@ -416,19 +410,7 @@ do + { + offset = 0; + again: +-#ifndef NO_POLL_H +- result = poll(&pollfd, 1, 1000); +- +-/* Patch posted by Erik ? for OS X and applied by PH */ +-#else +- select_tv.tv_sec = 1; +- select_tv.tv_usec = 0; +- FD_ZERO(&select_fd); +- FD_SET(spamd_cctx.sock, &select_fd); +- result = select(spamd_cctx.sock+1, NULL, &select_fd, NULL, &select_tv); +-#endif +-/* End Erik's patch */ +- ++ result = poll_one_fd(spamd_cctx.sock, POLLOUT, 1000); + if (result == -1 && errno == EINTR) + goto again; + else if (result < 1) +diff --git a/src/transport.c b/src/transport.c +index 8c74030f0..ef523657e 100644 +--- a/src/transport.c ++++ b/src/transport.c +@@ -253,7 +253,6 @@ for (int i = 0; i < 100; i++) + + for(;;) + { +- fd_set fds; + /* This code makes use of alarm() in order to implement the timeout. This + isn't a very tidy way of doing things. Using non-blocking I/O with select() + provides a neater approach. However, I don't know how to do this when TLS is +@@ -281,8 +280,7 @@ for (int i = 0; i < 100; i++) + if (rc >= 0 || errno != ENOTCONN || connretry <= 0) + break; + +- FD_ZERO(&fds); FD_SET(fd, &fds); +- select(fd+1, NULL, &fds, NULL, NULL); /* could set timout? */ ++ poll_one_fd(fd, POLLOUT, -1); /* could set timeout? retval check? */ + connretry--; + } + +diff --git a/src/transports/smtp.c b/src/transports/smtp.c +index d321bd69e..c64bb7010 100644 +--- a/src/transports/smtp.c ++++ b/src/transports/smtp.c +@@ -3550,8 +3550,8 @@ void + smtp_proxy_tls(void * ct_ctx, uschar * buf, size_t bsize, int * pfd, + int timeout) + { +-fd_set rfds, efds; +-int max_fd = MAX(pfd[0], tls_out.active.sock) + 1; ++struct pollfd p[2] = {{.fd = tls_out.active.sock, .events = POLLIN}, ++ {.fd = pfd[0], .events = POLLIN}}; + int rc, i; + BOOL send_tls_shutdown = TRUE; + +@@ -3560,23 +3560,16 @@ if ((rc = exim_fork(US"tls-proxy"))) + _exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS); + + set_process_info("proxying TLS connection for continued transport"); +-FD_ZERO(&rfds); +-FD_SET(tls_out.active.sock, &rfds); +-FD_SET(pfd[0], &rfds); + +-for (int fd_bits = 3; fd_bits; ) ++do + { + time_t time_left = timeout; + time_t time_start = time(NULL); + + /* wait for data */ +- efds = rfds; + do + { +- struct timeval tv = { time_left, 0 }; +- +- rc = select(max_fd, +- (SELECT_ARG2_TYPE *)&rfds, NULL, (SELECT_ARG2_TYPE *)&efds, &tv); ++ rc = poll(p, 2, time_left * 1000); + + if (rc < 0 && errno == EINTR) + if ((time_left -= time(NULL) - time_start) > 0) continue; +@@ -3589,23 +3582,22 @@ for (int fd_bits = 3; fd_bits; ) + + /* For errors where not readable, bomb out */ + +- if (FD_ISSET(tls_out.active.sock, &efds) || FD_ISSET(pfd[0], &efds)) ++ if (p[0].revents & POLLERR || p[1].revents & POLLERR) + { + DEBUG(D_transport) debug_printf("select: exceptional cond on %s fd\n", +- FD_ISSET(pfd[0], &efds) ? "proxy" : "tls"); +- if (!(FD_ISSET(tls_out.active.sock, &rfds) || FD_ISSET(pfd[0], &rfds))) ++ p[0].revents & POLLERR ? "tls" : "proxy"); ++ if (!(p[0].revents & POLLIN || p[1].events & POLLIN)) + goto done; + DEBUG(D_transport) debug_printf("- but also readable; no exit yet\n"); + } + } +- while (rc < 0 || !(FD_ISSET(tls_out.active.sock, &rfds) || FD_ISSET(pfd[0], &rfds))); ++ while (rc < 0 || !(p[0].revents & POLLIN || p[1].revents & POLLIN)); + + /* handle inbound data */ +- if (FD_ISSET(tls_out.active.sock, &rfds)) ++ if (p[0].revents & POLLIN) + if ((rc = tls_read(ct_ctx, buf, bsize)) <= 0) /* Expect -1 for EOF; */ + { /* that reaps the TLS Close Notify record */ +- fd_bits &= ~1; +- FD_CLR(tls_out.active.sock, &rfds); ++ p[0].fd = -1; + shutdown(pfd[0], SHUT_WR); + timeout = 5; + } +@@ -3616,11 +3608,10 @@ for (int fd_bits = 3; fd_bits; ) + /* Handle outbound data. We cannot combine payload and the TLS-close + due to the limitations of the (pipe) channel feeding us. Maybe use a unix-domain + socket? */ +- if (FD_ISSET(pfd[0], &rfds)) ++ if (p[1].revents & POLLIN) + if ((rc = read(pfd[0], buf, bsize)) <= 0) + { +- fd_bits &= ~2; +- FD_CLR(pfd[0], &rfds); ++ p[1].fd = -1; + + # ifdef EXIM_TCP_CORK /* Use _CORK to get TLS Close Notify in FIN segment */ + (void) setsockopt(tls_out.active.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); +@@ -3633,10 +3624,8 @@ for (int fd_bits = 3; fd_bits; ) + for (int nbytes = 0; rc - nbytes > 0; nbytes += i) + if ((i = tls_write(ct_ctx, buf + nbytes, rc - nbytes, FALSE)) < 0) + goto done; +- +- if (fd_bits & 1) FD_SET(tls_out.active.sock, &rfds); +- if (fd_bits & 2) FD_SET(pfd[0], &rfds); + } ++while (p[0].fd >= 0 || p[1].fd >= 0); + + done: + if (send_tls_shutdown) tls_close(ct_ctx, TLS_SHUTDOWN_NOWAIT); diff --git a/mail/exim/files/debian/75_40-Fix-basic-memory-use-for-SPARC.-Bug-2838.patch b/mail/exim/files/debian/75_40-Fix-basic-memory-use-for-SPARC.-Bug-2838.patch new file mode 100644 index 000000000000..b156611bd0e6 --- /dev/null +++ b/mail/exim/files/debian/75_40-Fix-basic-memory-use-for-SPARC.-Bug-2838.patch @@ -0,0 +1,140 @@ +From d73b9f478a2a5b299634acee4e05ff8ea25375a2 Mon Sep 17 00:00:00 2001 +From: John Paul Adrian Glaubitz +Date: Sun, 28 Nov 2021 17:26:40 +0000 +Subject: [PATCH] Fix basic memory use for SPARC. Bug 2838 + +--- + doc/ChangeLog | 5 +++++ + src/store.c | 34 +++++++++++++++++++--------------- + src/store.h | 2 +- + 3 files changed, 25 insertions(+), 16 deletions(-) + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -14,6 +14,11 @@ + are not useable for FD_SET() [and hence select()] and overwrite the stack. + Assorted crashes happen. + ++JH/12 Bug 2838: Fix for i32lp64 hard-align platforms. Found for SPARC Linux, ++ though only once PCRE2 was introduced: the memory accounting used under ++ debug offset allocations by an int, giving a hard trap in early startup. ++ Change to using a size_t. Debug and fix by John Paul Adrian Glaubitz. ++ + + Exim version 4.95 + ----------------- +--- a/src/store.c ++++ b/src/store.c +@@ -190,11 +190,11 @@ + [POOL_TAINT_MESSAGE] = US"tainted", + }; + #endif + + +-static void * internal_store_malloc(int, const char *, int); ++static void * internal_store_malloc(size_t, const char *, int); + static void internal_store_free(void *, const char *, int linenumber); + + /******************************************************************************/ + /* Initialisation, for things fragile with parameter channges when using + static initialisers. */ +@@ -859,30 +859,33 @@ + + Returns: pointer to gotten store (panic on failure) + */ + + static void * +-internal_store_malloc(int size, const char *func, int line) ++internal_store_malloc(size_t size, const char *func, int line) + { + void * yield; + +-if (size < 0 || size >= INT_MAX/2) ++/* Check specifically for a possibly result of conversion from ++a negative int, to the (unsigned, wider) size_t */ ++ ++if (size >= INT_MAX/2) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, +- "bad memory allocation requested (%d bytes) at %s %d", +- size, func, line); ++ "bad memory allocation requested (%lld bytes) at %s %d", ++ (unsigned long long)size, func, line); + +-size += sizeof(int); /* space to store the size, used under debug */ ++size += sizeof(size_t); /* space to store the size, used under debug */ + if (size < 16) size = 16; + +-if (!(yield = malloc((size_t)size))) ++if (!(yield = malloc(size))) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to malloc %d bytes of memory: " + "called from line %d in %s", size, line, func); + + #ifndef COMPILE_UTILITY +-DEBUG(D_any) *(int *)yield = size; ++DEBUG(D_any) *(size_t *)yield = size; + #endif +-yield = US yield + sizeof(int); ++yield = US yield + sizeof(size_t); + + if ((nonpool_malloc += size) > max_nonpool_malloc) + max_nonpool_malloc = nonpool_malloc; + + /* Cut out the debugging stuff for utilities, but stop picky compilers from +@@ -891,20 +894,20 @@ + #ifndef COMPILE_UTILITY + /* If running in test harness, spend time making sure all the new store + is not filled with zeros so as to catch problems. */ + + if (f.running_in_test_harness) +- memset(yield, 0xF0, (size_t)size - sizeof(int)); +-DEBUG(D_memory) debug_printf("--Malloc %6p %5d bytes\t%-20s %4d\tpool %5d nonpool %5d\n", ++ memset(yield, 0xF0, size - sizeof(size_t)); ++DEBUG(D_memory) debug_printf("--Malloc %6p %5lld bytes\t%-20s %4d\tpool %5d nonpool %5d\n", + yield, size, func, line, pool_malloc, nonpool_malloc); + #endif /* COMPILE_UTILITY */ + + return yield; + } + + void * +-store_malloc_3(int size, const char *func, int linenumber) ++store_malloc_3(size_t size, const char *func, int linenumber) + { + if (n_nonpool_blocks++ > max_nonpool_blocks) + max_nonpool_blocks = n_nonpool_blocks; + return internal_store_malloc(size, func, linenumber); + } +@@ -925,14 +928,15 @@ + */ + + static void + internal_store_free(void * block, const char * func, int linenumber) + { +-uschar * p = US block - sizeof(int); ++uschar * p = US block - sizeof(size_t); + #ifndef COMPILE_UTILITY +-DEBUG(D_any) nonpool_malloc -= *(int *)p; +-DEBUG(D_memory) debug_printf("----Free %6p %5d bytes\t%-20s %4d\n", block, *(int *)p, func, linenumber); ++DEBUG(D_any) nonpool_malloc -= *(size_t *)p; ++DEBUG(D_memory) debug_printf("----Free %6p %5lld bytes\t%-20s %4d\n", ++ block, (unsigned long long) *(size_t *)p, func, linenumber); + #endif + free(p); + } + + void +--- a/src/store.h ++++ b/src/store.h +@@ -63,11 +63,11 @@ + typedef void ** rmark; + + extern BOOL store_extend_3(void *, BOOL, int, int, const char *, int); + extern void store_free_3(void *, const char *, int); + /* store_get_3 & store_get_perm_3 are in local_scan.h */ +-extern void *store_malloc_3(int, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; ++extern void *store_malloc_3(size_t, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; + extern rmark store_mark_3(const char *, int); + extern void *store_newblock_3(void *, BOOL, int, int, const char *, int); + extern void store_release_above_3(void *, const char *, int); + extern rmark store_reset_3(rmark, const char *, int); + diff --git a/mail/exim/files/patch-OS_os.c-FreeBSD b/mail/exim/files/patch-OS_os.c-FreeBSD new file mode 100644 index 000000000000..99e89850ed0c --- /dev/null +++ b/mail/exim/files/patch-OS_os.c-FreeBSD @@ -0,0 +1,15 @@ +--- OS/os.c-FreeBSD.orig 2021-10-11 17:03:56.119681000 +0200 ++++ OS/os.c-FreeBSD 2021-10-11 17:04:27.802597000 +0200 +@@ -16,10 +16,11 @@ + ssize_t + os_sendfile(int out, int in, off_t * offp, size_t cnt) + { +-off_t loff = *offp, written; ++off_t loff = offp ? *offp : 0; ++off_t written; + + if (sendfile(in, out, loff, cnt, NULL, &written, 0) < 0) return (ssize_t)-1; +-*offp = loff + written; ++if (offp) *offp = loff + written; + return (ssize_t)written; + } diff --git a/mail/exim/files/patch-OS_os.h-FreeBSD b/mail/exim/files/patch-OS_os.h-FreeBSD deleted file mode 100644 index 0113c0c1ebb1..000000000000 --- a/mail/exim/files/patch-OS_os.h-FreeBSD +++ /dev/null @@ -1,17 +0,0 @@ ---- OS/os.h-FreeBSD.orig 2018-04-14 23:18:10 UTC -+++ OS/os.h-FreeBSD -@@ -12,6 +12,14 @@ - #define SIOCGIFCONF_GIVES_ADDR - #define HAVE_SRANDOMDEV - #define HAVE_ARC4RANDOM -+/* Applications should not call arc4random_stir() explicitly after -+ FreeBSD r227520 (approximately 1000002). -+ Set NOT_HAVE_ARC4RANDOM_STIR if the version released is past -+ that point. */ -+#include -+#if __FreeBSD_version >= 1000002 -+# define NOT_HAVE_ARC4RANDOM_STIR -+#endif - - typedef struct flock flock_t; - diff --git a/mail/exim/files/patch-src__EDITME b/mail/exim/files/patch-src__EDITME index cdbc576fda1d..ea4c1303bca9 100644 --- a/mail/exim/files/patch-src__EDITME +++ b/mail/exim/files/patch-src__EDITME @@ -1,144 +1,146 @@ ---- src/EDITME.orig 2012-05-31 04:40:15.000000000 +0400 -+++ src/EDITME 2012-06-28 18:43:50.000000000 +0400 -@@ -98,7 +98,7 @@ +--- src/EDITME.orig 2021-09-28 10:24:46.000000000 +0200 ++++ src/EDITME 2021-09-29 19:38:22.776161000 +0200 +@@ -99,7 +99,7 @@ # /usr/local/sbin. The installation script will try to create this directory, # and any superior directories, if they do not exist. -BIN_DIRECTORY=/usr/exim/bin +BIN_DIRECTORY=XX_PREFIX_XX/sbin #------------------------------------------------------------------------------ -@@ -114,7 +114,7 @@ +@@ -115,7 +115,7 @@ # don't exist. It will also install a default runtime configuration if this # file does not exist. -CONFIGURE_FILE=/usr/exim/configure +CONFIGURE_FILE=XX_CONFIG_FILE_PATH_XX # It is possible to specify a colon-separated list of files for CONFIGURE_FILE. # In this case, Exim will use the first of them that exists when it is run. -@@ -131,7 +131,7 @@ +@@ -132,7 +132,7 @@ # deliveries. (Local deliveries run as various non-root users, typically as the # owner of a local mailbox.) Specifying these values as root is not supported. -EXIM_USER= +EXIM_USER=ref:XX_EXIM_USER_XX # If you specify EXIM_USER as a name, this is looked up at build time, and the # uid number is built into the binary. However, you can specify that this -@@ -152,7 +152,7 @@ +@@ -153,7 +153,7 @@ # for EXIM_USER (e.g. EXIM_USER=exim), you don't need to set EXIM_GROUP unless # you want to use a group other than the default group for the given user. -# EXIM_GROUP= +EXIM_GROUP=ref:XX_EXIM_GROUP_XX # Many sites define a user called "exim", with an appropriate default group, # and use -@@ -330,6 +330,7 @@ +@@ -451,6 +451,7 @@ # LDAP_LIB_TYPE=OPENLDAP2 # LDAP_LIB_TYPE=NETSCAPE # LDAP_LIB_TYPE=SOLARIS +LDAP_LIB_TYPE=XX_LDAP_TYPE_XX # If you don't set any of these, Exim assumes the original University of # Michigan (OpenLDAP 1) library. -@@ -361,8 +362,10 @@ +@@ -491,9 +492,10 @@ # # You do not need to use this for any lookup information added via pkg-config. -# LOOKUP_INCLUDE=-I /usr/local/ldap/include -I /usr/local/mysql/include -I /usr/local/pgsql/include --# LOOKUP_LIBS=-L/usr/local/lib -lldap -llber -lmysqlclient -lpq -lgds -lsqlite3 +-# LOOKUP_INCLUDE +=-I /usr/local/include +-# LOOKUP_LIBS=-L/usr/local/lib -lldap -llber -lmysqlclient -lpq -lgds -lsqlite3 -llmdb +INCLUDE=-IXX_LOCALBASE_XX/include XX_DB_INCLUDES_XX XX_LMDB_INCLUDES_XX +LOOKUP_INCLUDE=XX_MYSQL_INCLUDE_XX XX_PGSQL_INCLUDE_XX XX_LDAP_INCLUDE_XX +LOOKUP_LIBS=XX_MYSQL_LIBS_XX XX_PGSQL_LIBS_XX XX_LDAP_LIBS_XX XX_LMDB_LIBS_XX +DBMLIB=XX_DB_LIBS_XX #------------------------------------------------------------------------------ -@@ -454,6 +457,7 @@ - - +@@ -633,6 +635,7 @@ + # Uncomment the following line to add queuefile transport support + # EXPERIMENTAL_QUEUEFILE=yes +# EXPERIMENTAL_DCC=yes ############################################################################### # THESE ARE THINGS YOU MIGHT WANT TO SPECIFY # ############################################################################### -@@ -521,6 +525,7 @@ +@@ -700,6 +703,7 @@ # ALT_CONFIG_PREFIX=/some/directory/ # ALT_CONFIG_PREFIX=/some/directory/exim.conf- +ALT_CONFIG_PREFIX=XX_ALT_CONFIG_PREFIX_XX #------------------------------------------------------------------------------ -@@ -607,7 +612,7 @@ +@@ -802,7 +806,7 @@ # one that is set in the headers_charset option. The default setting is # defined by this setting: -HEADERS_CHARSET="ISO-8859-1" +HEADERS_CHARSET="XX_DEFAULT_CHARSET_XX" # If you are going to make use of $header_xxx expansions in your configuration # file, or if your users are going to use them in filter files, and the normal -@@ -751,7 +756,7 @@ +@@ -898,7 +902,7 @@ # Once you have done this, "make install" will build the info files and # install them in the directory you have defined. -# INFO_DIRECTORY=/usr/share/info +INFO_DIRECTORY=XX_PREFIX_XX/share/info #------------------------------------------------------------------------------ -@@ -764,7 +769,7 @@ +@@ -911,7 +915,7 @@ # %s. This will be replaced by one of the strings "main", "panic", or "reject" # to form the final file names. Some installations may want something like this: -# LOG_FILE_PATH=/var/log/exim_%slog +LOG_FILE_PATH=XX_LOG_FILE_PATH_XX # which results in files with names /var/log/exim_mainlog, etc. The directory # in which the log files are placed must exist; Exim does not try to create -@@ -840,7 +845,7 @@ +@@ -993,7 +997,7 @@ # that the local_scan API is made available by the linker. You may also need # to add -ldl to EXTRALIBS so that dlopen() is available to Exim. -# EXPAND_DLFUNC=yes +EXPAND_DLFUNC=yes #------------------------------------------------------------------------------ -@@ -937,6 +942,8 @@ +@@ -1130,6 +1134,8 @@ # # but of course there may need to be other things in CFLAGS and EXTRALIBS_EXIM # as well. +CFLAGS=XX_CFLAGS_XX XX_SPF_FLAGS_XX XX_SRS_FLAGS_XX XX_SQLITE_FLAGS_XX +EXTRALIBS=XX_TCP_WRAPPERS_LIBS_XX XX_PAM_LIBS_XX XX_ICONV_LIBS_XX XX_SPF_LIBS_XX XX_SRS_LIBS_XX XX_RADIUS_LIBS_XX XX_SQLITE_LIBS_XX XX_DMARC_LIBS_XX XX_REDIS_LIBS_XX XX_DYNAMIC_LDFLAGS_XX XX_IDN_LIBS_XX # # To use a name other than exim in the tcpwrappers config file, # e.g. if you're running multiple daemons with different access lists, -@@ -945,6 +952,14 @@ +@@ -1138,7 +1144,15 @@ # # TCP_WRAPPERS_DAEMON_NAME="exim" +# IPv6 is coming. Exim has experimental support that has been tried out on +# one or two OS. See the file README.IPV6 for the current status of this +# support. Do not set this option unless you are working on IPv6 and know +# what you are doing. -+ + +# HAVE_IPV6=YES + + - ++ #------------------------------------------------------------------------------ # The default action of the exim_install script (which is run by "make -@@ -1222,7 +1237,7 @@ + # install") is to install the Exim binary with a unique name such as +@@ -1424,7 +1438,7 @@ # (process id) to a file so that it can easily be identified. The path of the # file can be specified here. Some installations may want something like this: -# PID_FILE_PATH=/var/lock/exim.pid +PID_FILE_PATH=/var/run/exim.pid # If PID_FILE_PATH is not defined, Exim writes a file in its spool directory # using the name "exim-daemon.pid". diff --git a/mail/exim/options b/mail/exim/options index 56d828faa1c3..b36b0cd9c411 100644 --- a/mail/exim/options +++ b/mail/exim/options @@ -1,132 +1,131 @@ OPTIONS_DEFINE+= ALT_CONFIG_PREFIX \ CONTENT_SCAN \ DAEMON \ DANE \ DEBUG \ DISABLE_D_OPT \ DKIM \ SPF \ DNSSEC \ DOCS \ EMBEDDED_PERL \ EXIMON \ ICONV \ IPV6 \ LISTMATCH_RHS \ LMTP \ OCSP \ PRDR \ READLINE \ SUID \ - TAINTWARN \ TCP_WRAPPERS \ WISHLIST \ EVENT \ PROXY \ SOCKS \ INTERNATIONAL OPTIONS_DEFAULT+= AUTH_CRAM_MD5 \ AUTH_DOVECOT \ AUTH_PLAINTEXT \ AUTH_SPA \ CDB \ CONTENT_SCAN \ DAEMON \ DISABLE_D_OPT \ DKIM \ DNSDB \ DNSSEC \ DSEARCH \ EMBEDDED_PERL \ EVENT \ ICONV \ INTERNATIONAL \ LMTP \ LSEARCH \ MAILDIR \ MAILSTORE \ MBX \ OCSP \ PAM \ PASSWD \ PRDR \ SPF \ SUID \ TLS OPTIONS_RADIO_TLS= TLS GNUTLS TLS_DESC= TLS support OPTIONS_RADIO_LS= SA_EXIM LS_DESC= Local scan patch OPTIONS_RADIO_SRSR= SRS SRSR_DESC= Sender Rewriting Scheme OPTIONS_RADIO= TLS LS SRSR OPTIONS_GROUP_AUTH= AUTH_CRAM_MD5 AUTH_DOVECOT AUTH_PLAINTEXT AUTH_RADIUS AUTH_SASL AUTH_SPA SASLAUTHD PAM PASSWD AUTH_DESC= SMTP Authorization OPTIONS_GROUP_LOOKUP= CDB BDB DNSDB DSEARCH LSEARCH MYSQL NIS OPENLDAP PGSQL REDIS SQLITE LOOKUP_DESC= Lookup support OPTIONS_GROUP_STORAGE= MAILDIR MAILSTORE MBX STORAGE_DESC= Supported storage formats OPTIONS_GROUP_EXPERIMENTAL= CERTNAMES DCC DMARC DSN ARC LMDB QUEUEFILE EXPERIMENTAL_DESC= Experimental options OPTIONS_GROUP= AUTH LOOKUP STORAGE EXPERIMENTAL ALT_CONFIG_PREFIX_DESC= Restrict the set of configuration files ARC_DESC= Enable experimental ARC support AUTH_CRAM_MD5_DESC= Enable CRAM-MD5 authentication mechanisms AUTH_DOVECOT_DESC= Enable Dovecot authentication mechanisms AUTH_PLAINTEXT_DESC= Enable plaintext authentication AUTH_RADIUS_DESC= Enable radius (RFC 2865) authentication AUTH_SASL_DESC= Enable use of Cyrus SASL auth library AUTH_SPA_DESC= Enable Secure Password Authentication CERTNAMES_DESC= Check certiticates ownership BDB_DESC= Enable Berkeley DB lookups CDB_DESC= Enable CDB-style lookups CONTENT_SCAN_DESC= Enable exiscan email content scanner DAEMON_DESC= Install scripts to run as a daemon DANE_DESC= Enable experimental DANE support DCC_DESC= Enable DCC at ACL support via dccifd DISABLE_D_OPT_DESC= Disable macros overrides using option -D DKIM_DESC= Enable support for DKIM DMARC_DESC= Enable DMARC support DNSDB_DESC= Enable DNS-style lookups DNSSEC_DESC= Enable DNSSEC validation DSEARCH_DESC= Enable directory-list lookups DSN_DESC= Enable Delivery Status Notifications EMBEDDED_PERL_DESC= Enable embedded Perl interpreter EVENT_DESC= Messages events support (TPDA namely) EXIMON_DESC= Build eximon monitor (requires X libraries) ICONV_DESC= Enable header charset conversion INTERNATIONAL_DESC= Enable support for the transmission of UTF-8 envelope addresses LISTMATCH_RHS_DESC= Enable pre-4.77 behaviour for match_* LMDB_DESC= Enable LMDB lookups LMTP_DESC= RFC2033 SMTP over command pipe transport LSEARCH_DESC= Enable wildcarded-file lookups MAILDIR_DESC= Enable Maildir mailbox format MAILSTORE_DESC= Enable Mailstore mailbox format MBX_DESC= Enable MBX mailbox format MYSQL_DESC= Enable mysql lookups NIS_DESC= Enable NIS-style lookups OPENLDAP_DESC= Enable LDAP lookups OCSP_DESC= Enable OCSP stapling QUEUEFILE_DESC= Enable queuefile transport PAM_DESC= Enable PAM authentication mechanisms PASSWD_DESC= Enable /etc/passwd lookups PGSQL_DESC= Enable postgresql lookups PRDR_DESC= Enable Per-Recipient-Data-Response support PROXY_DESC= Enable Experimental Proxy Protocol READLINE_DESC= Enable readline(3) library REDIS_DESC= Enable redis lookups SASLAUTHD_DESC= Enable use of Cyrus SASL auth daemon SA_EXIM_DESC= Build with Spamassassin local scan SOCKS_DESC= Enable smtp transport via socks5 proxies SPF_DESC= Enable Sender Policy Framework checking SQLITE_DESC= Enable SQLite lookups SRS_DESC= Enable Sender Rewriting Scheme SUID_DESC= Install the exim binary suid root TAINTWARN_DESC= Allow insecure tainted data (pre-4.93 config style, deprecated) TCP_WRAPPERS_DESC= Enable /etc/hosts.allow access control GNUTLS_DESC= Use GnuTLS instead of OpenSSL for TLS WISHLIST_DESC= Include the unsupported patches