On 2023-08-16 Andreas Metzler <[email protected]> wrote: [...] > I would like to push another round of cherry-picked upstream fixes to > bookworm. They have been part of the uploads to sid up to and including > 4.96-19. [...]
Hello, I had to update the update since 75_78-Fix-free-of-value-after-run.patch broke a specific expansion. While at it I also pulled the CI related changes from -21. cu Andreas
diff -Nru exim4-4.96/debian/changelog exim4-4.96/debian/changelog
--- exim4-4.96/debian/changelog 2023-07-02 14:56:17.000000000 +0200
+++ exim4-4.96/debian/changelog 2023-09-03 13:34:15.000000000 +0200
@@ -1,3 +1,22 @@
+exim4 (4.96-15+deb12u2) bookworm; urgency=medium
+
+ * Multiple bugfixes from upstream GIT master:
+ + 75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch
+ + 75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch
+ (Upstream bug 2998)
+ + 75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch
+ + 75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch
+ (Upstream bug 3013)
+ + 75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch: Fix on-demand
+ TLS cert expiry date. Closes: #1043233
+ (Upstream bug 3014)
+ + 75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch
+ * tests/basic: Add isolation-container restriction (needs a running
+ exim daemon).
+ * Add ${run } expansion test to tests/basic.
+
+ -- Andreas Metzler <[email protected]> Sun, 03 Sep 2023 13:34:15 +0200
+
exim4 (4.96-15+deb12u1) bookworm; urgency=medium
* 75_42-Fix-run-arg-parsing.patch (From upstream GIT master, backported by
diff -Nru exim4-4.96/debian/patches/75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch exim4-4.96/debian/patches/75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch
--- exim4-4.96/debian/patches/75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch 2023-08-16 17:44:32.000000000 +0200
@@ -0,0 +1,35 @@
+From 4d108e7777e9b8e5fb212c31812fef61529cd414 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <[email protected]>
+Date: Mon, 12 Jun 2023 22:13:46 +0100
+Subject: [PATCH] Cancel early-pipe on an observed advertising change
+
+---
+ src/transports/smtp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/transports/smtp.c b/src/transports/smtp.c
+index c72028ce9..24ee577a2 100644
+--- a/src/transports/smtp.c
++++ b/src/transports/smtp.c
+@@ -1111,15 +1111,18 @@ if (pending_EHLO)
+ *(tls_out.active.sock < 0
+ ? &sx->ehlo_resp.cleartext_features : &sx->ehlo_resp.crypted_features) =
+ peer_offered;
+ *ap = authbits;
+ write_ehlo_cache_entry(sx);
+ }
+ else
++ {
+ invalidate_ehlo_cache_entry(sx);
++ sx->early_pipe_active = FALSE; /* cancel further early-pipe on this conn */
++ }
+
+ return OK; /* just carry on */
+ }
+ # ifdef EXPERIMENTAL_ESMTP_LIMITS
+ /* If we are handling LIMITS, compare the actual EHLO LIMITS values with the
+ cached values and invalidate cache if different. OK to carry on with
+ connect since values are advisory. */
+--
+2.40.1
+
diff -Nru exim4-4.96/debian/patches/75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch exim4-4.96/debian/patches/75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch
--- exim4-4.96/debian/patches/75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch 2023-09-03 13:16:57.000000000 +0200
@@ -0,0 +1,99 @@
+From 1209e3e19e292cee517e43a2ccfe9b44b33bb1dc Mon Sep 17 00:00:00 2001
+From: Jasen Betts <[email protected]>
+Date: Sun, 23 Jul 2023 13:43:59 +0100
+Subject: [PATCH] Expansions: disallow UTF-16 surrogates from ${utf8clean:...}.
+ Bug 2998
+
+---
+ doc/ChangeLog | 4 ++++
+ src/expand.c | 27 +++++++++++++++++----------
+ 2 files changed, 21 insertions(+), 10 deletions(-)
+
+--- a/src/expand.c
++++ b/src/expand.c
+@@ -7731,11 +7731,11 @@ NOT_ITEM: ;
+
+ case EOP_UTF8CLEAN:
+ {
+ int seq_len = 0, index = 0;
+ int bytes_left = 0;
+- long codepoint = -1;
++ ulong codepoint = (ulong)-1;
+ int complete;
+ uschar seq_buff[4]; /* accumulate utf-8 here */
+
+ /* Manually track tainting, as we deal in individual chars below */
+
+@@ -7761,40 +7761,47 @@ NOT_ITEM: ;
+ codepoint = (codepoint << 6) | (c & 0x3f);
+ seq_buff[index++] = c;
+ if (--bytes_left == 0) /* codepoint complete */
+ if(codepoint > 0x10FFFF) /* is it too large? */
+ complete = -1; /* error (RFC3629 limit) */
++ else if ( (codepoint & 0x1FF800 ) == 0xD800 ) /* surrogate */
++ /* A UTF-16 surrogate (which should be one of a pair that
++ encode a Unicode codepoint that is outside the Basic
++ Multilingual Plane). Error, not UTF8.
++ RFC2279.2 is slightly unclear on this, but
++ https://unicodebook.readthedocs.io/issues.html#strict-utf8-decoder
++ says "Surrogates characters are also invalid in UTF-8:
++ characters in U+D800—U+DFFF have to be rejected." */
++ complete = -1;
+ else
+ { /* finished; output utf-8 sequence */
+ yield = string_catn(yield, seq_buff, seq_len);
+ index = 0;
+ }
+ }
+ }
+ else /* no bytes left: new sequence */
+ {
+- if(!(c & 0x80)) /* 1-byte sequence, US-ASCII, keep it */
++ if (!(c & 0x80)) /* 1-byte sequence, US-ASCII, keep it */
+ {
+ yield = string_catn(yield, &c, 1);
+ continue;
+ }
+- if((c & 0xe0) == 0xc0) /* 2-byte sequence */
+- {
+- if(c == 0xc0 || c == 0xc1) /* 0xc0 and 0xc1 are illegal */
++ if ((c & 0xe0) == 0xc0) /* 2-byte sequence */
++ if (c == 0xc0 || c == 0xc1) /* 0xc0 and 0xc1 are illegal */
+ complete = -1;
+ else
+ {
+- bytes_left = 1;
+- codepoint = c & 0x1f;
++ bytes_left = 1;
++ codepoint = c & 0x1f;
+ }
+- }
+- else if((c & 0xf0) == 0xe0) /* 3-byte sequence */
++ else if ((c & 0xf0) == 0xe0) /* 3-byte sequence */
+ {
+ bytes_left = 2;
+ codepoint = c & 0x0f;
+ }
+- else if((c & 0xf8) == 0xf0) /* 4-byte sequence */
++ else if ((c & 0xf8) == 0xf0) /* 4-byte sequence */
+ {
+ bytes_left = 3;
+ codepoint = c & 0x07;
+ }
+ else /* invalid or too long (RFC3629 allows only 4 bytes) */
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -69,10 +69,13 @@ JH/28 Bug 2996: Fix a crash in the smtp
+ to close it tried to use an uninitialized variable. This would afftect
+ high-volume sites more, especially when running mailing-list-style loads.
+ Pollution of logs was the major effect, as the other process delivered
+ the message. Found and partly investigated by Graeme Fowler.
+
++JH/31 Bug 2998: Fix ${utf8clean:...} to disallow UTF-16 surrogate codepoints.
++ Found and fixed by Jasen Betts. No testcase for this as my usual text
++ editor insists on emitting only valid UTF-8.
+
+ Exim version 4.96
+ -----------------
+
+ JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
diff -Nru exim4-4.96/debian/patches/75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch exim4-4.96/debian/patches/75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch
--- exim4-4.96/debian/patches/75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch 2023-09-03 13:16:57.000000000 +0200
@@ -0,0 +1,92 @@
+From 8e9770348dc4173ab83657ee023c22f479ebb712 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <[email protected]>
+Date: Mon, 24 Jul 2023 13:30:40 +0100
+Subject: [PATCH] GnuTLS: fix crash with "tls_dhparam = none"
+
+---
+ doc/ChangeLog | 4 ++++
+ src/tls-gnu.c | 16 +++++++++-------
+ test/log/2049 | 7 +++++++
+ test/scripts/2000-GnuTLS/2049 | 8 ++++++++
+ 4 files changed, 28 insertions(+), 7 deletions(-)
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -73,10 +73,14 @@ JH/28 Bug 2996: Fix a crash in the smtp
+
+ JH/31 Bug 2998: Fix ${utf8clean:...} to disallow UTF-16 surrogate codepoints.
+ Found and fixed by Jasen Betts. No testcase for this as my usual text
+ editor insists on emitting only valid UTF-8.
+
++JH/32 Fix "tls_dhparam = none" under GnuTLS. At least with 3.7.9 this gave
++ a null-indireciton SIGSEGV for the receive process.
++
++
+ Exim version 4.96
+ -----------------
+
+ JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
+ after reception to before a subsequent reception. This should
+--- a/src/tls-gnu.c
++++ b/src/tls-gnu.c
+@@ -712,11 +712,11 @@ exist, we generate them. This means that
+ The new file is written as a temporary file and renamed, so that an incomplete
+ file is never present. If two processes both compute some new parameters, you
+ waste a bit of effort, but it doesn't seem worth messing around with locking to
+ prevent this.
+
+-Returns: OK/DEFER/FAIL
++Returns: OK/DEFER (expansion issue)/FAIL (requested none)
+ */
+
+ static int
+ init_server_dh(uschar ** errstr)
+ {
+@@ -750,11 +750,11 @@ if (!exp_tls_dhparam)
+ else if (Ustrcmp(exp_tls_dhparam, "historic") == 0)
+ use_file_in_spool = TRUE;
+ else if (Ustrcmp(exp_tls_dhparam, "none") == 0)
+ {
+ DEBUG(D_tls) debug_printf("Requested no DH parameters\n");
+- return OK;
++ return FAIL;
+ }
+ else if (exp_tls_dhparam[0] != '/')
+ {
+ if (!(m.data = US std_dh_prime_named(exp_tls_dhparam)))
+ return tls_error(US"No standard prime named", exp_tls_dhparam, NULL, errstr);
+@@ -1971,27 +1971,29 @@ Arguments:
+
+ Returns: OK/DEFER/FAIL
+ */
+
+ static int
+-tls_set_remaining_x509(exim_gnutls_state_st *state, uschar ** errstr)
++tls_set_remaining_x509(exim_gnutls_state_st * state, uschar ** errstr)
+ {
+-int rc;
+-const host_item *host = state->host; /* macro should be reconsidered? */
++int rc = OK;
++const host_item * host = state->host; /* macro should be reconsidered? */
+
+ /* Create D-H parameters, or read them from the cache file. This function does
+ its own SMTP error messaging. This only happens for the server, TLS D-H ignores
+ client-side params. */
+
+ if (!state->host)
+ {
+ if (!dh_server_params)
+- if ((rc = init_server_dh(errstr)) != OK) return rc;
++ if ((rc = init_server_dh(errstr)) == DEFER) return rc;
+
+ /* Unnecessary & discouraged with 3.6.0 or later, according to docs. But without it,
+ no DHE- ciphers are advertised. */
+- gnutls_certificate_set_dh_params(state->lib_state.x509_cred, dh_server_params);
++
++ if (rc == OK)
++ gnutls_certificate_set_dh_params(state->lib_state.x509_cred, dh_server_params);
+ }
+
+ /* Link the credentials to the session. */
+
+ if ((rc = gnutls_credentials_set(state->session,
diff -Nru exim4-4.96/debian/patches/75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch exim4-4.96/debian/patches/75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch
--- exim4-4.96/debian/patches/75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch 2023-09-03 13:24:54.000000000 +0200
@@ -0,0 +1,294 @@
+From 6707bfa9fb78858de938a1abca2846c820c5ded7 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <[email protected]>
+Date: Thu, 3 Aug 2023 18:40:42 +0100
+Subject: [PATCH 2/2] Fix $recipients expansion when used within ${run...}.
+ Bug 3013
+
+Broken-by: cfe6acff2ddc
+---
+ doc/ChangeLog | 3 +++
+ src/deliver.c | 2 +-
+ src/expand.c | 5 ++---
+ src/functions.h | 2 +-
+ src/macros.h | 5 +++++
+ src/routers/queryprogram.c | 3 +--
+ src/smtp_in.c | 4 ++--
+ src/transport.c | 18 +++++++++---------
+ src/transports/lmtp.c | 4 ++--
+ src/transports/pipe.c | 11 ++++++-----
+ src/transports/smtp.c | 2 +-
+ test/log/0635 | 2 +-
+ 12 files changed, 34 insertions(+), 27 deletions(-)
+
+--- a/src/deliver.c
++++ b/src/deliver.c
+@@ -2382,11 +2382,11 @@ if ((pid = exim_fork(US"delivery-local")
+
+ if (tp->filter_command)
+ {
+ ok = transport_set_up_command(&transport_filter_argv,
+ tp->filter_command,
+- TRUE, PANIC, addr, FALSE, US"transport filter", NULL);
++ TSUC_EXPAND_ARGS, PANIC, addr, US"transport filter", NULL);
+ transport_filter_timeout = tp->filter_timeout;
+ }
+ else transport_filter_argv = NULL;
+
+ if (ok)
+--- a/src/expand.c
++++ b/src/expand.c
+@@ -5527,11 +5527,11 @@ while (*s)
+
+ case EITEM_RUN:
+ {
+ FILE * f;
+ const uschar * arg, ** argv;
+- BOOL late_expand = TRUE;
++ unsigned late_expand = TSUC_EXPAND_ARGS | TSUC_ALLOW_TAINTED_ARGS | TSUC_ALLOW_RECIPIENTS;
+
+ if (expand_forbid & RDO_RUN)
+ {
+ expand_string_message = US"running a command is not permitted";
+ goto EXPAND_FAILED;
+@@ -5540,11 +5540,11 @@ while (*s)
+ /* Handle options to the "run" */
+
+ while (*s == ',')
+ {
+ if (Ustrncmp(++s, "preexpand", 9) == 0)
+- { late_expand = FALSE; s += 9; }
++ { late_expand = 0; s += 9; }
+ else
+ {
+ const uschar * t = s;
+ while (isalpha(*++t)) ;
+ expand_string_message = string_sprintf("bad option '%.*s' for run",
+@@ -5599,11 +5599,10 @@ while (*s)
+ if (!transport_set_up_command(&argv, /* anchor for arg list */
+ arg, /* raw command */
+ late_expand, /* expand args if not already done */
+ 0, /* not relevant when... */
+ NULL, /* no transporting address */
+- late_expand, /* allow tainted args, when expand-after-split */
+ US"${run} expansion", /* for error messages */
+ &expand_string_message)) /* where to put error message */
+ goto EXPAND_FAILED;
+
+ /* Create the child process, making it a group leader. */
+--- a/src/functions.h
++++ b/src/functions.h
+@@ -616,11 +616,11 @@ extern BOOL transport_pass_socket(con
+ , unsigned, unsigned, unsigned
+ #endif
+ );
+ extern uschar *transport_rcpt_address(address_item *, BOOL);
+ extern BOOL transport_set_up_command(const uschar ***, const uschar *,
+- BOOL, int, address_item *, BOOL, const uschar *, uschar **);
++ unsigned, int, address_item *, const uschar *, uschar **);
+ extern void transport_update_waiting(host_item *, uschar *);
+ extern BOOL transport_write_block(transport_ctx *, uschar *, int, BOOL);
+ extern void transport_write_reset(int);
+ extern BOOL transport_write_string(int, const char *, ...);
+ extern BOOL transport_headers_send(transport_ctx *,
+--- a/src/macros.h
++++ b/src/macros.h
+@@ -1112,6 +1112,11 @@ should not be one active. */
+
+ #define NOTIFIER_SOCKET_NAME "exim_daemon_notify"
+ #define NOTIFY_MSG_QRUN 1 /* Notify message types */
+ #define NOTIFY_QUEUE_SIZE_REQ 2
+
++/* Flags for transport_set_up_command() */
++#define TSUC_EXPAND_ARGS BIT(0)
++#define TSUC_ALLOW_TAINTED_ARGS BIT(1)
++#define TSUC_ALLOW_RECIPIENTS BIT(2)
++
+ /* End of macros.h */
+--- a/src/routers/queryprogram.c
++++ b/src/routers/queryprogram.c
+@@ -286,14 +286,13 @@ if (curr_uid != root_uid && (uid != curr
+
+ /* Set up the command to run */
+
+ if (!transport_set_up_command(&argvptr, /* anchor for arg list */
+ ob->command, /* raw command */
+- TRUE, /* expand the arguments */
++ TSUC_EXPAND_ARGS, /* arguments expanded but must not be tainted */
+ 0, /* not relevant when... */
+ NULL, /* no transporting address */
+- FALSE, /* args must be untainted */
+ US"queryprogram router", /* for error messages */
+ &addr->message)) /* where to put error message */
+ return DEFER;
+
+ /* Create the child process, making it a group leader. */
+--- a/src/smtp_in.c
++++ b/src/smtp_in.c
+@@ -5840,12 +5840,12 @@ while (done <= 0)
+ {
+ uschar *error;
+ BOOL rc;
+ etrn_command = smtp_etrn_command;
+ deliver_domain = smtp_cmd_data;
+- rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
+- FALSE, US"ETRN processing", &error);
++ rc = transport_set_up_command(&argv, smtp_etrn_command, TSUC_EXPAND_ARGS, 0, NULL,
++ US"ETRN processing", &error);
+ deliver_domain = NULL;
+ if (!rc)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "failed to set up ETRN command: %s",
+ error);
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -2082,34 +2082,34 @@ return FALSE;
+ * Set up direct (non-shell) command *
+ *************************************************/
+
+ /* This function is called when a command line is to be parsed and executed
+ directly, without the use of /bin/sh. It is called by the pipe transport,
+-the queryprogram router, and also from the main delivery code when setting up a
++the queryprogram router, for any ${run } expansion,
++and also from the main delivery code when setting up a
+ transport filter process. The code for ETRN also makes use of this; in that
+ case, no addresses are passed.
+
+ Arguments:
+ argvptr pointer to anchor for argv vector
+ cmd points to the command string (modified IN PLACE)
+- expand_arguments true if expansion is to occur
++ flags bits for expand-args, allow taint, allow $recipients
+ expand_failed error value to set if expansion fails; not relevant if
+ addr == NULL
+ addr chain of addresses, or NULL
+- allow_tainted_args as it says; used for ${run}
+ etext text for use in error messages
+ errptr where to put error message if addr is NULL;
+ otherwise it is put in the first address
+
+ Returns: TRUE if all went well; otherwise an error will be
+ set in the first address and FALSE returned
+ */
+
+ BOOL
+ transport_set_up_command(const uschar *** argvptr, const uschar * cmd,
+- BOOL expand_arguments, int expand_failed, address_item * addr,
+- BOOL allow_tainted_args, const uschar * etext, uschar ** errptr)
++ unsigned flags, int expand_failed, address_item * addr,
++ const uschar * etext, uschar ** errptr)
+ {
+ const uschar ** argv, * s;
+ int address_count = 0, argcount = 0, max_args;
+
+ /* Get store in which to build an argument list. Count the number of addresses
+@@ -2180,14 +2180,14 @@ DEBUG(D_transport)
+ debug_printf("direct command:\n");
+ for (int i = 0; argv[i]; i++)
+ debug_printf(" argv[%d] = '%s'\n", i, string_printing(argv[i]));
+ }
+
+-if (expand_arguments)
++if (flags & TSUC_EXPAND_ARGS)
+ {
+- BOOL allow_dollar_recipients = addr && addr->parent
+- && Ustrcmp(addr->parent->address, "system-filter") == 0;
++ BOOL allow_dollar_recipients = (flags & TSUC_ALLOW_RECIPIENTS)
++ || (addr && addr->parent && Ustrcmp(addr->parent->address, "system-filter") == 0); /*XXX could we check this at caller? */
+
+ for (int i = 0; argv[i]; i++)
+ {
+ DEBUG(D_expand) debug_printf_indent("arg %d\n", i);
+
+@@ -2370,11 +2370,11 @@ if (expand_arguments)
+ { /* hack, would be good to not need it */
+ DEBUG(D_transport)
+ debug_printf("SPECIFIC TESTSUITE EXEMPTION: tainted arg '%s'\n",
+ expanded_arg);
+ }
+- else if ( !allow_tainted_args
++ else if ( !(flags & TSUC_ALLOW_TAINTED_ARGS)
+ && arg_is_tainted(expanded_arg, i, addr, etext, errptr))
+ return FALSE;
+ argv[i] = expanded_arg;
+ }
+ }
+--- a/src/transports/lmtp.c
++++ b/src/transports/lmtp.c
+@@ -487,12 +487,12 @@ argument list and expanding the items. *
+
+ if (ob->cmd)
+ {
+ DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
+ sprintf(CS buffer, "%.50s transport", tblock->name);
+- if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, FALSE,
+- buffer, NULL))
++ if (!transport_set_up_command(&argv, ob->cmd, TSUC_EXPAND_ARGS, PANIC,
++ addrlist, buffer, NULL))
+ return FALSE;
+
+ /* If the -N option is set, can't do any more. Presume all has gone well. */
+ if (f.dont_deliver)
+ goto MINUS_N;
+--- a/src/transports/pipe.c
++++ b/src/transports/pipe.c
+@@ -289,24 +289,25 @@ Arguments:
+ Returns: TRUE if all went well; otherwise an error will be
+ set in the first address and FALSE returned
+ */
+
+ static BOOL
+-set_up_direct_command(const uschar ***argvptr, uschar *cmd,
+- BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname,
+- pipe_transport_options_block *ob)
++set_up_direct_command(const uschar *** argvptr, uschar * cmd,
++ BOOL expand_arguments, int expand_fail, address_item * addr, uschar * tname,
++ pipe_transport_options_block * ob)
+ {
+ BOOL permitted = FALSE;
+ const uschar **argv;
+
+ /* Set up "transport <name>" to be put in any error messages, and then
+ call the common function for creating an argument list and expanding
+ the items if necessary. If it fails, this function fails (error information
+ is in the addresses). */
+
+-if (!transport_set_up_command(argvptr, cmd, expand_arguments, expand_fail,
+- addr, FALSE, string_sprintf("%.50s transport", tname), NULL))
++if (!transport_set_up_command(argvptr, cmd,
++ expand_arguments ? TSUC_EXPAND_ARGS : 0,
++ expand_fail, addr, string_sprintf("%.50s transport", tname), NULL))
+ return FALSE;
+
+ /* Point to the set-up arguments. */
+
+ argv = *argvptr;
+--- a/src/transports/smtp.c
++++ b/src/transports/smtp.c
+@@ -3803,11 +3803,11 @@ if (tblock->filter_command)
+
+ /* On failure, copy the error to all addresses, abandon the SMTP call, and
+ yield ERROR. */
+
+ if (!transport_set_up_command(&transport_filter_argv,
+- tblock->filter_command, TRUE, DEFER, addrlist, FALSE,
++ tblock->filter_command, TSUC_EXPAND_ARGS, DEFER, addrlist,
+ string_sprintf("%.50s transport filter", tblock->name), NULL))
+ {
+ set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
+ FALSE, &sx->delivery_start);
+ yield = ERROR;
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -76,10 +76,12 @@ JH/31 Bug 2998: Fix ${utf8clean:...} to
+ editor insists on emitting only valid UTF-8.
+
+ JH/32 Fix "tls_dhparam = none" under GnuTLS. At least with 3.7.9 this gave
+ a null-indireciton SIGSEGV for the receive process.
+
++JH/34 Bug 3013: Fix use of $recipients within arguments for ${run...}.
++ In 4.96 this would expand to empty.
+
+ Exim version 4.96
+ -----------------
+
+ JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
diff -Nru exim4-4.96/debian/patches/75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch exim4-4.96/debian/patches/75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch
--- exim4-4.96/debian/patches/75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch 2023-09-03 13:24:54.000000000 +0200
@@ -0,0 +1,42 @@
+From 36bc854c86908ee921225c1d30e35c4d59eed822 Mon Sep 17 00:00:00 2001
+From: Andreas Metzler <[email protected]>
+Date: Mon, 14 Aug 2023 17:27:16 +0100
+Subject: [PATCH] GnuTLS: fix autogen cert expiry date. Bug 3014
+
+Broken-by: 48e9099006
+---
+ doc/ChangeLog | 3 +++
+ src/tls-gnu.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -79,10 +79,13 @@ JH/32 Fix "tls_dhparam = none" under Gnu
+ a null-indireciton SIGSEGV for the receive process.
+
+ JH/34 Bug 3013: Fix use of $recipients within arguments for ${run...}.
+ In 4.96 this would expand to empty.
+
++JH/35 Bug 3014: GnuTLS: fix expiry date for an auto-generated server
++ certificate. Find and fix by Andreas Metzler.
++
+ Exim version 4.96
+ -----------------
+
+ JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
+ after reception to before a subsequent reception. This should
+--- a/src/tls-gnu.c
++++ b/src/tls-gnu.c
+@@ -1001,11 +1001,11 @@ if ((rc = gnutls_x509_privkey_generate(p
+ where = US"configuring cert";
+ now = 1;
+ if ( (rc = gnutls_x509_crt_set_version(cert, 3))
+ || (rc = gnutls_x509_crt_set_serial(cert, &now, sizeof(now)))
+ || (rc = gnutls_x509_crt_set_activation_time(cert, now = time(NULL)))
+- || (rc = gnutls_x509_crt_set_expiration_time(cert, (long)2 * 60 * 60)) /* 2 hour */
++ || (rc = gnutls_x509_crt_set_expiration_time(cert, now + (long)2 * 60 * 60)) /* 2 hour */
+ || (rc = gnutls_x509_crt_set_key(cert, pkey))
+
+ || (rc = gnutls_x509_crt_set_dn_by_oid(cert,
+ GNUTLS_OID_X520_COUNTRY_NAME, 0, "UK", 2))
+ || (rc = gnutls_x509_crt_set_dn_by_oid(cert,
diff -Nru exim4-4.96/debian/patches/75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch exim4-4.96/debian/patches/75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch
--- exim4-4.96/debian/patches/75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch 1970-01-01 01:00:00.000000000 +0100
+++ exim4-4.96/debian/patches/75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch 2023-09-03 13:24:54.000000000 +0200
@@ -0,0 +1,77 @@
+From 21b172df101c2c52faf0cc56a502395451975be9 Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <[email protected]>
+Date: Thu, 24 Aug 2023 15:51:21 +0100
+Subject: [PATCH 2/2] Re-fix live variable $value free. The inital fix
+ resulted in $value from ${run...} not being available later, which is a
+ documented feature.
+
+Broken=by: cf3fecb9e873
+---
+ doc/doc-docbook/spec.xfpt | 1 +
+ doc/ChangeLog | 4 ++--
+ src/exim.c | 3 ++-
+ test/confs/0635 | 1 +
+ test/log/0635 | 1 +
+ test/mail/0635.CALLER | 13 +++++++++++++
+ 6 files changed, 20 insertions(+), 3 deletions(-)
+ create mode 100644 test/mail/0635.CALLER
+
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -76,10 +76,13 @@ JH/31 Bug 2998: Fix ${utf8clean:...} to
+ editor insists on emitting only valid UTF-8.
+
+ JH/32 Fix "tls_dhparam = none" under GnuTLS. At least with 3.7.9 this gave
+ a null-indireciton SIGSEGV for the receive process.
+
++JH/33 Fix free for live variable $value created by a ${run ...} expansion during
++ -bh use. Internal checking would spot this and take a panic.
++
+ JH/34 Bug 3013: Fix use of $recipients within arguments for ${run...}.
+ In 4.96 this would expand to empty.
+
+ JH/35 Bug 3014: GnuTLS: fix expiry date for an auto-generated server
+ certificate. Find and fix by Andreas Metzler.
+--- a/src/exim.c
++++ b/src/exim.c
+@@ -5754,11 +5754,11 @@ for (BOOL more = TRUE; more; )
+ for (int i = 0; i < count; i++)
+ {
+ int start, end, domain;
+ uschar * errmess;
+ /* There can be multiple addresses, so EXIM_DISPLAYMAIL_MAX (tuned for 1) is too short.
+- * We'll still want to cap it to something, just in case. */
++ We'll still want to cap it to something, just in case. */
+ uschar * s = string_copy_taint(
+ exim_str_fail_toolong(list[i], BIG_BUFFER_SIZE, "address argument"),
+ GET_TAINTED);
+
+ /* Loop for each comma-separated address */
+@@ -6089,10 +6089,11 @@ MORELOOP:
+ callout_address = NULL;
+ sending_ip_address = NULL;
+ deliver_localpart_data = deliver_domain_data =
+ recipient_data = sender_data = NULL;
+ acl_var_m = NULL;
++ lookup_value = NULL; /* Can be set by ACL */
+
+ store_reset(reset_point);
+ }
+
+ exim_exit(EXIT_SUCCESS); /* Never returns */
+--- a/doc/spec.txt
++++ b/doc/spec.txt
+@@ -9650,10 +9650,13 @@ ${run <options> {<command arg list>}{<st
+ If the command requires shell idioms, such as the > redirect operator, the
+ shell must be invoked directly, such as with:
+
+ ${run{/bin/bash -c "/usr/bin/id >/tmp/id"}{yes}{yes}}
+
++ Note that $value will not persist beyond the reception of a single
++ message.
++
+ The return code from the command is put in the variable $runrc, and this
+ remains set afterwards, so in a filter file you can do things like this:
+
+ if "${run{x y z}{}}$runrc" is 1 then ...
+ elif $runrc is 2 then ...
diff -Nru exim4-4.96/debian/patches/series exim4-4.96/debian/patches/series
--- exim4-4.96/debian/patches/series 2023-07-02 14:54:58.000000000 +0200
+++ exim4-4.96/debian/patches/series 2023-09-03 13:20:37.000000000 +0200
@@ -33,4 +33,10 @@
75_66-Fix-crash-in-expansions.patch
75_68-Fix-srs_encode-.-for-mod-1024-day-zero.patch
75_70-Fix-variable-initialisation-in-smtp-transport.-Bug-2.patch
+75_74-Cancel-early-pipe-on-an-observed-advertising-change.patch
+75_76-Expansions-disallow-UTF-16-surrogates-from-utf8clean.patch
+75_77-GnuTLS-fix-crash-with-tls_dhparam-none.patch
+75_79-Fix-recipients-expansion-when-used-within-run.-.-Bug.patch
+75_82-GnuTLS-fix-autogen-cert-expiry-date.-Bug-3014.patch
+75_83-Re-fix-live-variable-value-free.-The-inital-fix-resu.patch
90_localscan_dlopen.dpatch
diff -Nru exim4-4.96/debian/tests/basic exim4-4.96/debian/tests/basic
--- exim4-4.96/debian/tests/basic 2021-05-04 18:23:02.000000000 +0200
+++ exim4-4.96/debian/tests/basic 2023-09-03 13:33:51.000000000 +0200
@@ -40,6 +40,15 @@
false
fi
+runandshow $exim -be \
+ '${run{/bin/echo -n foo}{success}{error}} runrc[$runrc] value[$value]'
+rc="$($exim -be \
+ '${run{/bin/echo -n foo}{success}{error}} runrc[$runrc] value[$value]')"
+if [ "$rc" != "success runrc[0] value[foo]" ]; then
+ echo wrong expansion result $rc
+ false
+fi
+
runandshow swaks -s localhost -tlso -q ehlo
runandshow swaks -s localhost -tlso -f root@localhost -t postmaster@localhost \
-q rcpt
diff -Nru exim4-4.96/debian/tests/control exim4-4.96/debian/tests/control
--- exim4-4.96/debian/tests/control 2022-11-13 18:34:03.000000000 +0100
+++ exim4-4.96/debian/tests/control 2023-09-03 13:31:25.000000000 +0200
@@ -3,4 +3,4 @@
exim4,
libnet-ssleay-perl,
swaks,
-Restrictions: allow-stderr
+Restrictions: allow-stderr, isolation-container
signature.asc
Description: PGP signature

