diff options
author | Kurt Jaeger <pi@FreeBSD.org> | 2023-05-26 14:14:00 +0000 |
---|---|---|
committer | Kurt Jaeger <pi@FreeBSD.org> | 2023-05-26 14:14:00 +0000 |
commit | 985788b37e14798739af343e2f5a7dfdf7d59b62 (patch) | |
tree | 71256887ddc653e72e2d3e62a213679839be92ec | |
parent | 55fb38d8b98983102be699ba8a2388d6d037bc04 (diff) | |
download | ports-985788b37e14798739af343e2f5a7dfdf7d59b62.tar.gz ports-985788b37e14798739af343e2f5a7dfdf7d59b62.zip |
mail/exim: update 4.95 -> 4.96
PR: 265098
Obtained-from: https://salsa.debian.org/exim-team/exim4/-/blob/master/debian/patches/
Reported-by: vvd
Approved-by: fluffy
Reviewed-by: drs-freebsd@sieborger.nom.za
Tested-by: pi, drs-freebsd@sieborger.nom.za
Changes: https://lists.exim.org/lurker/message/20220625.141825.d6de6074.en.html
18 files changed, 53 insertions, 2274 deletions
@@ -5,6 +5,18 @@ they are unavoidable. You should get into the habit of checking this file for changes each time you update your ports collection, before attempting any port upgrades. +20230526: + AFFECTS: users of mail/exim + AUTHOR: pi@FreeBSD.org + + The port changes from USE_DB to USE_NDBM. Any existing configuration like + ${lookup{$needle}dbm{haystack.db}} + will need to change to + ${lookup{$needle}dbm{haystack}}. + + Please also rename your old DBM files while the exim daemon is stopped: + find /var/spool/exim/db/* -not -name \*.lockfile -exec mv -i {} {}.db \; + 20230513: AFFECTS: users of www/tt-rss AUTHOR: dereks@lifeofadishwasher.com diff --git a/mail/exim/Makefile b/mail/exim/Makefile index ad06672afa63..45d5209d7a2a 100644 --- a/mail/exim/Makefile +++ b/mail/exim/Makefile @@ -1,6 +1,6 @@ PORTNAME= exim PORTVERSION?= ${EXIM_VERSION} -PORTREVISION?= 7 +PORTREVISION?= 0 CATEGORIES= mail MASTER_SITES= EXIM:exim MASTER_SITE_SUBDIR= /exim4/:exim \ @@ -66,20 +66,30 @@ SQLITE_USES= pkgconfig sqlite 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}_32-Fix-PAM-auth.-Bug-2813.patch:-p1 \ - ${DEBIAN_PATCHES_PREFIX}_35-Exiqgrep-check-arg-parsing.-Bug-2821.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 \ - ${DEBIAN_PATCHES_PREFIX}_43-BSD-fix-resource-leak.patch:-p1 \ - ${DEBIAN_PATCHES_PREFIX}_45-Fix-bogus-error-message-copy.-Bug-2857.patch:-p1 \ - ${DEBIAN_PATCHES_PREFIX}_50-Fix-include_directory-in-redirect-routers.-Bug-2715.patch:-p1 \ - ${DEBIAN_PATCHES_PREFIX}_55-Specific-check-for-null-pointer.patch:-p1 - -TLS_PATCHES_PREFIX= ${FILESDIR}/tls/ -EXTRA_PATCHES+= \ - ${TLS_PATCHES_PREFIX}patch-tls1:-p1 \ - ${TLS_PATCHES_PREFIX}patch-tls2:-p1 + ${DEBIAN_PATCHES_PREFIX}_01-Fix-exit-on-attempt-to-rewrite-a-malformed-address.-.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_05-SPF-fix-memory-accounting-for-error-case.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_08-Fix-regex-n-use-after-free.-Bug-2915.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_09-Fix-non-WITH_CONTENT_SCAN-build.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_10-Fix-non-WITH_CONTENT_SCAN-build-2.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_11-Fix-non-WITH_CONTENT_SCAN-build-3.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_16-GnuTLS-fix-for-clients-offering-no-TLS-extensions.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_18-Fix-Build-with-libopendmarc-1.4.x-fixes-2728.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_19-DMARC-fix-use-after-free-in-dmarc_dns_lookup.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_22-Fix-daemon-startup.-Bug-2930.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_23-Fix-reccipients-after-run.-.-Bug-2929.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_31-Fix-regext-substring-capture-variables-for-null-matc.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_32-Fix-regex-substring-capture-variables-for-null-match.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_34-Fix-regex-substring-capture-commentary.-Bug-2933.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_37-OpenSSL-when-preloading-creds-do-the-server-certs-be.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_38-OpenSSL-fix-double-expansion-of-tls_verify_certifica.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_50-Fix-logging-of-max-size-log-line.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_55-Fix-recursion-on-dns_again_means_nonexist.-Bug-2911.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_58-Close-server-smtp-socket-explicitly-on-connect-ACL-d.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_60-OpenSSL-fix-tls_eccurve-setting-explicit-curve-group.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_62-OpenSSL-Fix-tls_eccurve-on-earlier-versions-than-3.0.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_63-OpenSSL-log-conns-rejected-for-bad-ALPN-with-the-off.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_64-DANE-do-not-check-dns_again_means_nonexist-for-TLSA-.patch:-p1 \ + ${DEBIAN_PATCHES_PREFIX}_66-Fix-crash-in-expansions.patch:-p1 .include <bsd.port.options.mk> @@ -120,7 +130,7 @@ EXTRA_PATCHES+= ${FILESDIR}/extra-patch-Local-sa-exim.c EXTRA_PATCHES+= ${FILESDIR}/extra-patch-Local-sa-exim.conf .endif -EXIM_VERSION= 4.95 +EXIM_VERSION= 4.96 SA_EXIM_VERSION=4.2.1 EXIM_INSTALL_ARG+= "-no_chown" "-no_symlink" EXTRA_PATCHES+= `${FIND} ${PATCHDIR} -name '74_*.patch'|${SORT} -h` @@ -210,7 +220,7 @@ WITH_DEFAULT_CHARSET?= ISO-8859-1 # You should not need to fiddle with anything below this point. -LIB_DEPENDS+= libpcre.so:devel/pcre +LIB_DEPENDS+= libpcre2-posix.so:devel/pcre2 .if ! ${PORT_OPTIONS:MDKIM} SEDLIST+= -e 's,^\# (DISABLE_DKIM=),\1,' @@ -601,8 +611,6 @@ do-configure: @${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: diff --git a/mail/exim/distinfo b/mail/exim/distinfo index c007834ea4bb..eb6b96ef513f 100644 --- a/mail/exim/distinfo +++ b/mail/exim/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1632918983 -SHA256 (exim/exim-4.95.tar.bz2) = 7f4716cc1b3fee66930d83b249f1c7b119fa1957f6f46e3f4372805cbc97ea63 -SIZE (exim/exim-4.95.tar.bz2) = 2035738 +TIMESTAMP = 1681024359 +SHA256 (exim/exim-4.96.tar.bz2) = c7a413fec601cc44a8f5fe9e5b64cb24a7d133f3a4a976f33741d98ff0ec6b91 +SIZE (exim/exim-4.96.tar.bz2) = 2047632 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_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 deleted file mode 100644 index ac72e532ebea..000000000000 --- a/mail/exim/files/debian/75_30-Avoid-calling-gettimeofday-select-per-char-for-cmdli.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 1843f70b733127fcba3321d9d69359e05905f8cc Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -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_32-Fix-PAM-auth.-Bug-2813.patch b/mail/exim/files/debian/75_32-Fix-PAM-auth.-Bug-2813.patch deleted file mode 100644 index 537bfed558d7..000000000000 --- a/mail/exim/files/debian/75_32-Fix-PAM-auth.-Bug-2813.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 51be321b27825c01829dffd90f11bfff256f7e42 Mon Sep 17 00:00:00 2001 -From: Adam Lackorzynski <adam@l4re.org> -Date: Sat, 16 Oct 2021 16:30:07 +0100 -Subject: [PATCH] Fix PAM auth. Bug 2813 - ---- - src/auths/call_pam.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/auths/call_pam.c b/src/auths/call_pam.c -index 80bb23ec3..03b9be1a8 100644 ---- a/src/auths/call_pam.c -+++ b/src/auths/call_pam.c -@@ -88,7 +88,7 @@ for (int i = 0; i < num_msg; i++) - arg = US""; - pam_arg_ended = TRUE; - } -- reply[i].resp = CS string_copy_malloc(arg); /* PAM frees resp */ -+ reply[i].resp = strdup(CCS arg); /* Use libc malloc, PAM frees resp directly*/ - reply[i].resp_retcode = PAM_SUCCESS; - break; - --- -2.34.1 - diff --git a/mail/exim/files/debian/75_35-Exiqgrep-check-arg-parsing.-Bug-2821.patch b/mail/exim/files/debian/75_35-Exiqgrep-check-arg-parsing.-Bug-2821.patch deleted file mode 100644 index c226354d5e8e..000000000000 --- a/mail/exim/files/debian/75_35-Exiqgrep-check-arg-parsing.-Bug-2821.patch +++ /dev/null @@ -1,42 +0,0 @@ -From df618101a5ea15dc90c4a2968798ef2be9dba16f Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Mon, 18 Oct 2021 11:01:47 +0100 -Subject: [PATCH] Exiqgrep: check arg parsing. Bug 2821 - ---- - src/exiqgrep.src | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/exiqgrep.src b/src/exiqgrep.src -index c8762df47..04602da68 100644 ---- a/src/exiqgrep.src -+++ b/src/exiqgrep.src -@@ -53,12 +53,14 @@ if ($ARGV[0] eq '--version') { - exit 0; - } - --getopts('hf:r:y:o:s:C:zxlibRcaG:',\%opt); --if ($ARGV[0]) { &help; exit;} --if ($opt{h}) { &help; exit;} -+if (!getopts('hf:r:y:o:s:C:zxlibRcaG:E:',\%opt)) { &help; exit; } -+if ($opt{h}) { &help; exit; } -+if ($ARGV[0] || !($opt{f} || $opt{r} || $opt{s} || $opt{y} || $opt{o} || $opt{z} || $opt{x} || $opt{c})) -+ { &help; exit(1); } - if ($opt{a}) { $eargs = '-bp'; } - if ($opt{C} && -e $opt{C} && -f $opt{C} && -R $opt{C}) { $eargs .= ' -C '.$opt{C}; } - if ($opt{G}) { $eargs .= ' -qG'.$opt{G}; } -+if ($opt{E}) { $exim = $opt{E}; } - - # Read message queue output into hash - &collect(); -@@ -75,6 +77,7 @@ Exim message queue display utility. - - -h This help message. - -C Specify which exim.conf to use. -+ -E Specify exim binary to use. - - Selection criteria: - -f <regexp> Match sender address sender (field is "< >" wrapped) --- -2.34.1 - 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 deleted file mode 100644 index 93c99a4ef8f2..000000000000 --- a/mail/exim/files/debian/75_38-Convert-all-uses-of-select-to-poll.-Bug-2831.patch +++ /dev/null @@ -1,931 +0,0 @@ -From dd19ce4f24eec64177cdcfcf294b8efbb631a24b Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -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 deleted file mode 100644 index b156611bd0e6..000000000000 --- a/mail/exim/files/debian/75_40-Fix-basic-memory-use-for-SPARC.-Bug-2838.patch +++ /dev/null @@ -1,140 +0,0 @@ -From d73b9f478a2a5b299634acee4e05ff8ea25375a2 Mon Sep 17 00:00:00 2001 -From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> -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/debian/75_43-BSD-fix-resource-leak.patch b/mail/exim/files/debian/75_43-BSD-fix-resource-leak.patch deleted file mode 100644 index 0a624c30875c..000000000000 --- a/mail/exim/files/debian/75_43-BSD-fix-resource-leak.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c57309a50444d858c0a2dc1581846a850d78a9ad Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Tue, 11 Jan 2022 11:21:45 +0000 -Subject: [PATCH 077/151] BSD: fix resource leak - ---- - doc/ChangeLog | 4 ++++ - src/tls.c | 9 +++++---- - -diff --git a/doc/ChangeLog b/doc/ChangeLog -index e7c7085f8..567399483 100644 ---- a/doc/ChangeLog -+++ b/doc/ChangeLog -@@ -65,6 +65,10 @@ JH/13 Bug 2845: Fix handling of tls_require_ciphers for OpenSSL when a value - - JH/14 Bug 1895: TLS: Deprecate RFC 5114 Diffie-Hellman parameters. - -+JH/15 Fix a resource leak in *BSD. An off-by-one error resulted in the daemon -+ failing to close the certificates directory, every hour or any time it -+ was touched. -+ - - Exim version 4.95 - ----------------- -diff --git a/src/tls.c b/src/tls.c -index d5d11bcea..e6b1bf7a7 100644 ---- a/src/tls.c -+++ b/src/tls.c -@@ -185,8 +185,8 @@ for (;;) - { - if ((fd1 = open(CCS filename, O_RDONLY | O_NOFOLLOW)) < 0) - { s = US"open file"; goto bad; } -- DEBUG(D_tls) debug_printf("watch file '%s'\n", filename); -- EV_SET(&kev[++kev_used], -+ DEBUG(D_tls) debug_printf("watch file '%s':\t%d\n", filename, fd1); -+ EV_SET(&kev[kev_used++], - (uintptr_t)fd1, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, -@@ -196,8 +196,8 @@ for (;;) - NULL); - cnt++; - } -- DEBUG(D_tls) debug_printf("watch dir '%s'\n", s); -- EV_SET(&kev[++kev_used], -+ DEBUG(D_tls) debug_printf("watch dir '%s':\t%d\n", s, fd2); -+ EV_SET(&kev[kev_used++], - (uintptr_t)fd2, - EVFILT_VNODE, - EV_ADD | EV_ENABLE | EV_ONESHOT, -@@ -320,6 +320,7 @@ if (tls_watch_fd < 0) return; - /* Close the files we had open for kevent */ - for (int i = 0; i < kev_used; i++) - { -+ DEBUG(D_tls) debug_printf("closing watch fd: %d\n", (int) kev[i].ident); - (void) close((int) kev[i].ident); - kev[i].ident = (uintptr_t)-1; - } --- -2.35.1 - diff --git a/mail/exim/files/debian/75_45-Fix-bogus-error-message-copy.-Bug-2857.patch b/mail/exim/files/debian/75_45-Fix-bogus-error-message-copy.-Bug-2857.patch deleted file mode 100644 index 7a582781136d..000000000000 --- a/mail/exim/files/debian/75_45-Fix-bogus-error-message-copy.-Bug-2857.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7ad863f3819407559cd654639c25dcae427c190f Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Sun, 6 Feb 2022 19:00:26 +0000 -Subject: [PATCH] Fix bogus error message copy. Bug 2857 - -Broken-by: bb43acbd98 ---- - src/parse.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/src/parse.c b/src/parse.c -index 5bf97eab9..edbee2646 100644 ---- a/src/parse.c -+++ b/src/parse.c -@@ -1354,15 +1354,16 @@ for (;;) - - if (special) - { -- uschar *ss = Ustrchr(s+1, ':') + 1; -+ uschar * ss = Ustrchr(s+1, ':') + 1; /* line after the special... */ - if ((options & specopt) == specbit) - { - *error = string_sprintf("\"%.*s\" is not permitted", len, s); - return FF_ERROR; - } -- while (*ss && isspace(*ss)) ss++; -- while (s[len] && s[len] != '\n') len++; -- *error = string_copyn(ss, s + len - ss); -+ while (*ss && isspace(*ss)) ss++; /* skip leading whitespace */ -+ if ((len = Ustrlen(ss)) > 0) /* ignore trailing newlines */ -+ for (const uschar * t = ss + len - 1; t >= ss && *t == '\n'; t--) len--; -+ *error = string_copyn(ss, len); /* becomes the error */ - return special; - } - --- -2.34.1 - diff --git a/mail/exim/files/debian/75_50-Fix-include_directory-in-redirect-routers.-Bug-2715.patch b/mail/exim/files/debian/75_50-Fix-include_directory-in-redirect-routers.-Bug-2715.patch deleted file mode 100644 index 0344630e70b3..000000000000 --- a/mail/exim/files/debian/75_50-Fix-include_directory-in-redirect-routers.-Bug-2715.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 7f8394e7c983b1c199866fc6b1c14feb857b651d Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Sun, 13 Feb 2022 12:00:55 +0000 -Subject: [PATCH] Fix include_directory in redirect routers. Bug 2715 - -Broken-by: 10c50704c1 ---- - doc/ChangeLog | 5 +++++ - src/parse.c | 9 ++++++--- - test/confs/0313 | 4 +++- - test/log/0313 | 2 ++ - test/scripts/0000-Basic/0313 | 2 ++ - 5 files changed, 18 insertions(+), 4 deletions(-) - ---- a/doc/ChangeLog -+++ b/doc/ChangeLog -@@ -23,6 +23,11 @@ JH/15 Fix a resource leak in *BSD. An off-by-one erro - failing to close the certificates directory, every hour or any time it - was touched. - -+JH/18 Bug 2751: Fix include_directory in redirect routers. Previously a -+ bad comparison between the option value and the name of the file to -+ be included was done, and a mismatch was wrongly identified. -+ 4.88 to 4.95 are affected. -+ - - Exim version 4.95 - ----------------- ---- a/src/parse.c -+++ b/src/parse.c -@@ -1422,11 +1422,13 @@ - /* Check file name if required */ - - if (directory) - { - int len = Ustrlen(directory); -- uschar *p = filename + len; -+ uschar * p; -+ while (len > 0 && directory[len-1] == '/') len--; /* ignore trailing '/' */ -+ p = filename + len; - - if (Ustrncmp(filename, directory, len) != 0 || *p != '/') - { - *error = string_sprintf("included file %s is not in directory %s", - filename, directory); -@@ -1448,13 +1450,14 @@ - } - while (*p) - { - uschar temp; - int fd2; -- uschar * q = p; -+ uschar * q = p + 1; /* skip dividing '/' */ - -- while (*++p && *p != '/') ; -+ while (*q == '/') q++; /* skip extra '/' */ -+ while (*++p && *p != '/') ; /* end of component */ - temp = *p; - *p = '\0'; - - fd2 = exim_openat(fd, CS q, O_RDONLY|O_NOFOLLOW); - close(fd); diff --git a/mail/exim/files/debian/75_55-Specific-check-for-null-pointer.patch b/mail/exim/files/debian/75_55-Specific-check-for-null-pointer.patch deleted file mode 100644 index 0d52bf5091a0..000000000000 --- a/mail/exim/files/debian/75_55-Specific-check-for-null-pointer.patch +++ /dev/null @@ -1,67 +0,0 @@ -From b249717db8ced250a586385f06e61cf7107d5222 Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Fri, 18 Feb 2022 15:45:37 +0000 -Subject: [PATCH] Specific check for null pointer - ---- - src/smtp_out.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/src/smtp_out.c b/src/smtp_out.c -index 608a781eb..fc1e6cecd 100644 ---- a/src/smtp_out.c -+++ b/src/smtp_out.c -@@ -524,13 +524,21 @@ flush_buffer(smtp_outblock * outblock, int mode) - int rc; - int n = outblock->ptr - outblock->buffer; - BOOL more = mode == SCMD_MORE; -+client_conn_ctx * cctx; - - HDEBUG(D_transport|D_acl) debug_printf_indent("cmd buf flush %d bytes%s\n", n, - more ? " (more expected)" : ""); - -+if (!(cctx = outblock->cctx)) -+ { -+ log_write(0, LOG_MAIN|LOG_PANIC, "null conn-context pointer"); -+ errno = 0; -+ return FALSE; -+ } -+ - #ifndef DISABLE_TLS --if (outblock->cctx->tls_ctx) -- rc = tls_write(outblock->cctx->tls_ctx, outblock->buffer, n, more); -+if (cctx->tls_ctx) /*XXX have seen a null cctx here, rvfy sending QUIT, hence check above */ -+ rc = tls_write(cctx->tls_ctx, outblock->buffer, n, more); - else - #endif - -@@ -544,7 +552,7 @@ else - requirement: TFO with data can, in rare cases, replay the data to the - receiver. */ - -- if ( (outblock->cctx->sock = smtp_connect(outblock->conn_args, &early_data)) -+ if ( (cctx->sock = smtp_connect(outblock->conn_args, &early_data)) - < 0) - return FALSE; - outblock->conn_args = NULL; -@@ -552,7 +560,7 @@ else - } - else - { -- rc = send(outblock->cctx->sock, outblock->buffer, n, -+ rc = send(cctx->sock, outblock->buffer, n, - #ifdef MSG_MORE - more ? MSG_MORE : 0 - #else -@@ -567,7 +575,7 @@ else - https://bugzilla.redhat.com/show_bug.cgi?id=1803806 */ - - if (!more) -- setsockopt(outblock->cctx->sock, IPPROTO_TCP, TCP_CORK, &off, sizeof(off)); -+ setsockopt(cctx->sock, IPPROTO_TCP, TCP_CORK, &off, sizeof(off)); - #endif - } - } --- -2.34.1 - diff --git a/mail/exim/files/patch-OS__Makefile-Default b/mail/exim/files/patch-OS__Makefile-Default deleted file mode 100644 index 1e639c95419a..000000000000 --- a/mail/exim/files/patch-OS__Makefile-Default +++ /dev/null @@ -1,10 +0,0 @@ ---- OS/Makefile-Default.orig 2019-01-30 14:59:52.000000000 +0100 -+++ OS/Makefile-Default 2019-02-13 00:34:40.753182000 +0100 -@@ -242,6 +242,7 @@ - # The default setting points to a template function that doesn't actually do - # any scanning, but just accepts the message. - -+# HAVE_LOCAL_SCAN=no - LOCAL_SCAN_SOURCE=src/local_scan.c - - # If you want to specify options for your local_scan() that can be set from diff --git a/mail/exim/files/patch-OS__Makefile-FreeBSD b/mail/exim/files/patch-OS__Makefile-FreeBSD index 239f5bca9637..a2608a0dcf32 100644 --- a/mail/exim/files/patch-OS__Makefile-FreeBSD +++ b/mail/exim/files/patch-OS__Makefile-FreeBSD @@ -1,11 +1,13 @@ ---- OS/Makefile-FreeBSD.orig 2009-11-14 21:13:45.000000000 +0300 -+++ OS/Makefile-FreeBSD 2009-11-14 21:15:39.000000000 +0300 -@@ -7,7 +7,7 @@ - PORTOBJFORMAT!= test -x /usr/bin/objformat && /usr/bin/objformat || echo aout +--- OS/Makefile-FreeBSD.orig 2023-04-09 09:45:04.226201000 +0200 ++++ OS/Makefile-FreeBSD 2023-04-09 09:48:01.819463000 +0200 +@@ -18,8 +18,8 @@ + # Dynamically loaded modules need to be built with -fPIC + CFLAGS_DYNAMIC=-shared -rdynamic -fPIC - CHOWN_COMMAND=/usr/sbin/chown --STRIP_COMMAND=/usr/bin/strip -+STRIP_COMMAND=XX_STRIPCMD_XX - CHMOD_COMMAND=/bin/chmod +-# FreeBSD always ships with Berkeley DB +-USE_DB=yes ++# FreeBSD ships with Berkeley DB until 13.1, but ndbm is always included ++USE_NDBM=yes - HAVE_SA_LEN=YES + # This code for building outside ports suggested by Richard Clayton + .ifdef X11BASE diff --git a/mail/exim/files/patch-OS_os.c-FreeBSD b/mail/exim/files/patch-OS_os.c-FreeBSD deleted file mode 100644 index 99e89850ed0c..000000000000 --- a/mail/exim/files/patch-OS_os.c-FreeBSD +++ /dev/null @@ -1,15 +0,0 @@ ---- 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-src-dmarc.c b/mail/exim/files/patch-src-dmarc.c deleted file mode 100644 index c0054446458c..000000000000 --- a/mail/exim/files/patch-src-dmarc.c +++ /dev/null @@ -1,19 +0,0 @@ ---- src/dmarc.c.orig 2021-04-30 12:08:21 UTC -+++ src/dmarc.c -@@ -37,6 +37,7 @@ uschar *spf_human_readable = NULL; - u_char *header_from_sender = NULL; - int history_file_status = DMARC_HIST_OK; - uschar *dkim_history_buffer= NULL; -+uschar *dkim_selector = NULL; - - typedef struct dmarc_exim_p { - uschar *name; -@@ -446,7 +447,7 @@ if (!dmarc_abort && !sender_host_authenticated) - vs == PDKIM_VERIFY_INVALID ? DMARC_POLICY_DKIM_OUTCOME_TMPFAIL : - DMARC_POLICY_DKIM_OUTCOME_NONE; - libdm_status = opendmarc_policy_store_dkim(dmarc_pctx, US sig->domain, -- dkim_result, US""); -+ dkim_selector, dkim_result, US""); - DEBUG(D_receive) - debug_printf("DMARC adding DKIM sender domain = %s\n", sig->domain); - if (libdm_status != DMARC_PARSE_OKAY) diff --git a/mail/exim/files/tls/patch-tls1 b/mail/exim/files/tls/patch-tls1 deleted file mode 100644 index d76d5589b2bb..000000000000 --- a/mail/exim/files/tls/patch-tls1 +++ /dev/null @@ -1,43 +0,0 @@ -From fc624b8cb4c3312d7450dfa86adfa3fe8dd9cbeb Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Tue, 11 Jan 2022 14:50:09 +0000 -Subject: [PATCH] Ensure server tls close alert not delayed - ---- - src/src/tls-gnu.c | 5 +++++ - src/src/tls-openssl.c | 3 +++ - 2 files changed, 8 insertions(+) - -diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c -index 53635ac..3adadb8 100644 ---- a/src/tls-gnu.c -+++ b/src/tls-gnu.c -@@ -3731,6 +3731,11 @@ if (do_shutdown) - - tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ - -+#ifdef EXIM_TCP_CORK -+ if (do_shutdown > 1) -+ (void) setsockopt(tlsp->active.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); -+#endif -+ - ALARM(2); - gnutls_bye(state->session, do_shutdown > 1 ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); - ALARM_CLR(0); -diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c -index 5130455..576f62b 100644 ---- a/src/tls-openssl.c -+++ b/src/tls-openssl.c -@@ -4516,6 +4516,9 @@ if (do_shutdown) - if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ - && do_shutdown > 1) - { -+#ifdef EXIM_TCP_CORK -+ (void) setsockopt(*fdp, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); -+#endif - ALARM(2); - rc = SSL_shutdown(*sslp); /* wait for response */ - ALARM_CLR(0); --- -1.9.1 - diff --git a/mail/exim/files/tls/patch-tls2 b/mail/exim/files/tls/patch-tls2 deleted file mode 100644 index e88c127fd374..000000000000 --- a/mail/exim/files/tls/patch-tls2 +++ /dev/null @@ -1,174 +0,0 @@ -From 2ead369f8435918f3f15408b9394e580bcaf0910 Mon Sep 17 00:00:00 2001 -From: Jeremy Harris <jgh146exb@wizmail.org> -Date: Thu, 10 Mar 2022 15:23:26 +0000 -Subject: [PATCH] OpenSSL: track shutdown calls. Bug 2864 - ---- - doc/doc-txt/ChangeLog | 5 +++++ - src/src/macros.h | 7 ++++--- - src/src/tls-gnu.c | 10 +++++++--- - src/src/tls-openssl.c | 13 ++++++++----- - src/src/transports/smtp.c | 19 +++++++++++++------ - 5 files changed, 37 insertions(+), 17 deletions(-) - -diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog -index 5ba587b..1c799b6 100644 ---- a/doc/ChangeLog -+++ b/doc/ChangeLog -@@ -95,6 +95,11 @@ JH/21 Remove the "allow_insecure_tainted_data" main config option and the - JH/22 Fix static address-list lookups to properly return the matched item. - Previously only the domain part was returned. - -+JH/23 Bug 2864: FreeBSD: fix transport hang after 4xx/5xx response. Previously -+ the call into OpenSSL to send a TLS Close was being repeated; this -+ resulted in the library waiting for the peer's Close. If that was never -+ sent we waited forever. Fix by tracking send calls. -+ - - Exim version 4.95 - ----------------- -diff --git a/src/src/macros.h b/src/src/macros.h -index 92f2cc0..659a70f 100644 ---- a/src/macros.h -+++ b/src/macros.h -@@ -1051,9 +1051,10 @@ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE }; - - - /* Options on tls_close */ --#define TLS_NO_SHUTDOWN 0 --#define TLS_SHUTDOWN_NOWAIT 1 --#define TLS_SHUTDOWN_WAIT 2 -+#define TLS_NO_SHUTDOWN 0 /* Just forget the context */ -+#define TLS_SHUTDOWN_NOWAIT 1 /* Send alert; do not wait */ -+#define TLS_SHUTDOWN_WAIT 2 /* Send alert & wait for peer's alert */ -+#define TLS_SHUTDOWN_WONLY 3 /* only wait for peer's alert */ - - - #ifdef COMPILE_UTILITY -diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c -index 1215f85..6227823 100644 ---- a/src/tls-gnu.c -+++ b/src/tls-gnu.c -@@ -3744,17 +3744,21 @@ if (!tlsp || tlsp->active.sock < 0) return; /* TLS was not active */ - if (do_shutdown) - { - DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS%s\n", -- do_shutdown > 1 ? " (with response-wait)" : ""); -+ do_shutdown > TLS_SHUTDOWN_NOWAIT ? " (with response-wait)" : ""); - - tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ - - #ifdef EXIM_TCP_CORK -- if (do_shutdown > 1) -+ if (do_shutdown == TLS_SHUTDOWN_WAIT) - (void) setsockopt(tlsp->active.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); - #endif - -+ /* The library seems to have no way to only wait for a peer's -+ shutdown, so handle the same as TLS_SHUTDOWN_WAIT */ -+ - ALARM(2); -- gnutls_bye(state->session, do_shutdown > 1 ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); -+ gnutls_bye(state->session, -+ do_shutdown > TLS_SHUTDOWN_NOWAIT ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); - ALARM_CLR(0); - } - -diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c -index d5c5778..7bf62f5 100644 ---- a/src/tls-openssl.c -+++ b/src/tls-openssl.c -@@ -4519,22 +4519,25 @@ int * fdp = o_ctx ? &tls_out.active.sock : &tls_in.active.sock; - - if (*fdp < 0) return; /* TLS was not active */ - --if (do_shutdown) -+if (do_shutdown > TLS_NO_SHUTDOWN) - { - int rc; - DEBUG(D_tls) debug_printf("tls_close(): shutting down TLS%s\n", -- do_shutdown > 1 ? " (with response-wait)" : ""); -+ do_shutdown > TLS_SHUTDOWN_NOWAIT ? " (with response-wait)" : ""); - - tls_write(ct_ctx, NULL, 0, FALSE); /* flush write buffer */ - -- if ( (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ -- && do_shutdown > 1) -+ if ( ( do_shutdown >= TLS_SHUTDOWN_WONLY -+ || (rc = SSL_shutdown(*sslp)) == 0 /* send "close notify" alert */ -+ ) -+ && do_shutdown > TLS_SHUTDOWN_NOWAIT -+ ) - { - #ifdef EXIM_TCP_CORK - (void) setsockopt(*fdp, IPPROTO_TCP, EXIM_TCP_CORK, US &off, sizeof(off)); - #endif - ALARM(2); -- rc = SSL_shutdown(*sslp); /* wait for response */ -+ rc = SSL_shutdown(*sslp); /* wait for response */ - ALARM_CLR(0); - } - -diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c -index e2c2680..524f186 100644 ---- a/src/transports/smtp.c -+++ b/src/transports/smtp.c -@@ -4085,7 +4085,7 @@ else - sx->send_quit = FALSE; /* avoid sending it later */ - - #ifndef DISABLE_TLS -- if (sx->cctx.tls_ctx) /* need to send TLS Close Notify */ -+ if (sx->cctx.tls_ctx && sx->send_tlsclose) /* need to send TLS Close Notify */ - { - # ifdef EXIM_TCP_CORK /* Use _CORK to get Close Notify in FIN segment */ - (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); -@@ -4429,7 +4429,8 @@ if (!sx->ok) - # ifndef DISABLE_TLS - if (sx->cctx.tls_ctx) - { -- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); -+ tls_close(sx->cctx.tls_ctx, -+ sx->send_tlsclose ? TLS_SHUTDOWN_WAIT : TLS_SHUTDOWN_WONLY); - sx->cctx.tls_ctx = NULL; - } - # endif -@@ -4640,7 +4641,8 @@ if (sx->completed_addr && sx->ok && sx->send_quit) - a new EHLO. If we don't get a good response, we don't attempt to pass - the socket on. */ - -- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); -+ tls_close(sx->cctx.tls_ctx, -+ sx->send_tlsclose ? TLS_SHUTDOWN_WAIT : TLS_SHUTDOWN_WONLY); - sx->send_tlsclose = FALSE; - sx->cctx.tls_ctx = NULL; - tls_out.active.sock = -1; -@@ -4742,7 +4744,7 @@ if (sx->send_quit) - { /* Use _MORE to get QUIT in FIN segment */ - (void)smtp_write_command(sx, SCMD_MORE, "QUIT\r\n"); - #ifndef DISABLE_TLS -- if (sx->cctx.tls_ctx) -+ if (sx->cctx.tls_ctx && sx->send_tlsclose) - { - # ifdef EXIM_TCP_CORK /* Use _CORK to get TLS Close Notify in FIN segment */ - (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); -@@ -4797,10 +4799,15 @@ if (sx->send_quit || tcw_done && !tcw) - while (!sigalrm_seen && n > 0); - ALARM_CLR(0); - -+ if (sx->send_tlsclose) -+ { - # ifdef EXIM_TCP_CORK -- (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); -+ (void) setsockopt(sx->cctx.sock, IPPROTO_TCP, EXIM_TCP_CORK, US &on, sizeof(on)); - # endif -- tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); -+ tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WAIT); -+ } -+ else -+ tls_close(sx->cctx.tls_ctx, TLS_SHUTDOWN_WONLY); - sx->cctx.tls_ctx = NULL; - } - #endif --- -1.9.1 - |