From 786b8468f1ea9381357f0adcd43ca3303480e6664c810fe7846e8d9ea68c076e Mon Sep 17 00:00:00 2001 From: Peter Wullinger Date: Wed, 3 Jun 2020 05:49:45 +0000 Subject: [PATCH 1/2] Accepting request 810989 from home:pwcau:branches:server:mail - update to exim 4.94 * some transports now refuse to use tainted data in constructing their delivery location this WILL BREAK configurations which are not updated accordingly. In particular: any Transport use of $local_user which has been relying upon check_local_user far away in the Router to make it safe, should be updated to replace $local_user with $local_part_data. * Attempting to remove, in router or transport, a header name that ends with an asterisk (which is a standards-legal name) will now result in all headers named starting with the string before the asterisk being removed. OBS-URL: https://build.opensuse.org/request/show/810989 OBS-URL: https://build.opensuse.org/package/show/server:mail/exim?expand=0&rev=240 --- exim-4.93.0.4.tar.bz2 | 3 - exim-4.93.0.4.tar.bz2.asc | 11 - exim-4.94.tar.bz2 | 3 + exim-4.94.tar.bz2.asc | 11 + exim.changes | 14 + exim.spec | 7 +- ...s-ee83de04d3087efaf808d1f2235a988275c2ee94 | 1184 ----------------- 7 files changed, 30 insertions(+), 1203 deletions(-) delete mode 100644 exim-4.93.0.4.tar.bz2 delete mode 100644 exim-4.93.0.4.tar.bz2.asc create mode 100644 exim-4.94.tar.bz2 create mode 100644 exim-4.94.tar.bz2.asc delete mode 100644 patch-exim-fixes-ee83de04d3087efaf808d1f2235a988275c2ee94 diff --git a/exim-4.93.0.4.tar.bz2 b/exim-4.93.0.4.tar.bz2 deleted file mode 100644 index 8b0c07d..0000000 --- a/exim-4.93.0.4.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b67336ba06f8d8233060de073d6082d75a378faaafad660c5f124bb13d75e4d9 -size 1974190 diff --git a/exim-4.93.0.4.tar.bz2.asc b/exim-4.93.0.4.tar.bz2.asc deleted file mode 100644 index 9edb63d..0000000 --- a/exim-4.93.0.4.tar.bz2.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQEzBAABCgAdFiEE0L/WueylaUpvFJ3Or0zGdqa2wUIFAl4TxucACgkQr0zGdqa2 -wUIh/AgA0MlOgoyXxi1pOYW2TSlFd3t3sYsLjLPgwR4QT/IZ+csdj3di/SNrcruh -YnbdPSKgCpekUYiSkFjEW6rpXTgUCYg7wFLY/gwcQ8DNkCQbNppiJKPvtvCo9ZBj -RXL/jN7A7EHv+v1QWtdHcoI1pK/uB+G4V8EibslRt/lzlkFPoRBca6KqB6XgFv27 -+n6SXKQySjyQjjqNKTOVKtPiBH9+MepG0zmntvktLnGrKeMvfO8YxeFQfxn8hRai -sRUoG0+m5d5Xmyd+hvLaLKaE7zWJNMnz59rny7kHuu5flAHqS87/XPXeesC/Sneg -hQPMEge/srGzTebgstpO8bUjO4rCIg== -=IvoV ------END PGP SIGNATURE----- diff --git a/exim-4.94.tar.bz2 b/exim-4.94.tar.bz2 new file mode 100644 index 0000000..ce6bd33 --- /dev/null +++ b/exim-4.94.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73feeaa5ddb43363782db0c307b593aacb49542dd7e4b795a2880779595affe5 +size 1997217 diff --git a/exim-4.94.tar.bz2.asc b/exim-4.94.tar.bz2.asc new file mode 100644 index 0000000..853126d --- /dev/null +++ b/exim-4.94.tar.bz2.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- + +iQFEBAABCAAuFiEEqYbzpr1jd9hzCVjevOWMjOQfMt8FAl7VFJAQHGpnaEB3aXpt +YWlsLm9yZwAKCRC85YyM5B8y3y45CADBlbw+sH3fhIhhwWdremJFiED5xr/4bPjd +jnU/qOWKTg9Iv9F1gBbjpacwBZa+dc49DgeSkLWgx5z3AKke1BzFpA9/mPpVCGvZ +Q934OZ47jixuP38PSoKpEbh1peRf1o+z9tqc/SEty8q+lyH7J2IhQKx8komUI0Y7 +6we1gx1Nm7J6Z2vy0owkU6vx/iuqVE79/lV4avAIqMGBEsLfDNS+tTqe0f6lkPqM +CT+ya0/fUppQfxqSKNrVYU2reGM6H0yEtFAeD2FbFSAGUhH+MecBl/xLbRfKCoCn +WrYvgwrB8eHO3ZS9MSZJIbr9fr02xZF1k2et1oCCJ66/DZSl0BQV +=cjE1 +-----END PGP SIGNATURE----- diff --git a/exim.changes b/exim.changes index 1ccd680..7c945eb 100644 --- a/exim.changes +++ b/exim.changes @@ -1,3 +1,17 @@ +Tue Jun 2 07:12:55 CEST 2020 - wullinger@rz.uni-kiel.de + +- update to exim 4.94 + * some transports now refuse to use tainted data in constructing their delivery + location + this WILL BREAK configurations which are not updated accordingly. + In particular: any Transport use of $local_user which has been relying upon + check_local_user far away in the Router to make it safe, should be updated to + replace $local_user with $local_part_data. + * Attempting to remove, in router or transport, a header name that ends with + an asterisk (which is a standards-legal name) will now result in all headers + named starting with the string before the asterisk being removed. + +------------------------------------------------------------------- Tue May 19 13:47:05 CEST 2020 - wullinger@rz.uni-kiel.de - switch pretrans to use lua (fixes bsc#1171877) diff --git a/exim.spec b/exim.spec index 42b17c7..0aeb768 100644 --- a/exim.spec +++ b/exim.spec @@ -72,8 +72,8 @@ Requires(pre): group(mail) %endif Requires(pre): fileutils textutils %endif -Version: 4.93.0.4 -Release: 4 +Version: 4.94 +Release: 1 %if %{with_mysql} BuildRequires: mysql-devel %endif @@ -102,7 +102,6 @@ Source32: eximstats.conf-2.2 Source40: exim.service Patch0: exim-tail.patch Patch1: gnu_printf.patch -Patch2: patch-exim-fixes-ee83de04d3087efaf808d1f2235a988275c2ee94 %package -n eximon Summary: Eximon, an graphical frontend to administer Exim's mail queue @@ -146,7 +145,6 @@ once, if at all. The rest is done by logrotate / cron.) %setup -q -n exim-%{version} %patch0 %patch1 -p1 -%patch2 -p1 # build with fPIE/pie on SUSE 10.0 or newer, or on any other platform %if %{?suse_version:%suse_version}%{?!suse_version:99999} > 930 fPIE="-fPIE" @@ -227,7 +225,6 @@ cat <<-EOF > Local/Makefile AUTH_TLS=yes AUTH_LIBS=-lsasl2 USE_OPENSSL=yes - SUPPORT_TLS=yes TLS_LIBS=-lssl -lcrypto INFO_DIRECTORY=%{_infodir} LOG_FILE_PATH=/var/log/exim/%%s.log diff --git a/patch-exim-fixes-ee83de04d3087efaf808d1f2235a988275c2ee94 b/patch-exim-fixes-ee83de04d3087efaf808d1f2235a988275c2ee94 deleted file mode 100644 index efc01d9..0000000 --- a/patch-exim-fixes-ee83de04d3087efaf808d1f2235a988275c2ee94 +++ /dev/null @@ -1,1184 +0,0 @@ -Only in a: Local -diff -ru a/OS/Makefile-Base b/OS/Makefile-Base ---- a/OS/Makefile-Base 2020-01-03 13:08:52.000000000 +0100 -+++ b/OS/Makefile-Base 2020-05-12 10:13:22.020198000 +0200 -@@ -659,10 +659,13 @@ - .c.o:; @echo "$(CC) $*.c" - $(FE)$(CC) -c $(CFLAGS) -I. $(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE) $*.c - --# Update Exim's version information and build the version object. -+# Update Exim's version information and build the version object. The dependency -+# chain here avoids problems under parallel-make. - --version.h version.sh:: -+version.sh: - @../scripts/reversion -+ -+version.h: version.sh - - cnumber.h: version.h - -Only in a: doc -diff -ru a/exim_monitor/em_version.c b/exim_monitor/em_version.c ---- a/exim_monitor/em_version.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/exim_monitor/em_version.c 2020-05-12 10:13:22.022512000 +0200 -@@ -5,6 +5,8 @@ - /* Copyright (c) University of Cambridge 1995 - 2018 */ - /* See the file NOTICE for conditions of use and distribution. */ - -+#define EM_VERSION_C -+ - #include "mytypes.h" - #include "store.h" - #include "macros.h" -diff -ru a/src/acl.c b/src/acl.c ---- a/src/acl.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/acl.c 2020-05-12 10:13:22.024864000 +0200 -@@ -2259,7 +2259,7 @@ - - /* Parse the other options. */ - --while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))) -+while ((ss = string_nextinlist(&arg, &sep, NULL, 0))) - { - if (strcmpic(ss, US"leaky") == 0) leaky = TRUE; - else if (strcmpic(ss, US"strict") == 0) strict = TRUE; -diff -ru a/src/arc.c b/src/arc.c ---- a/src/arc.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/arc.c 2020-05-12 10:13:22.025287000 +0200 -@@ -735,7 +735,7 @@ - - /* Setup the interface to the signing library */ - --if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx))) -+if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx, NULL))) - { - DEBUG(D_acl) debug_printf("ARC verify init: %s\n", errstr); - as->ams_verify_done = arc_state_reason = US"internal sigverify init error"; -@@ -964,7 +964,7 @@ - /* We know the b-tag blob is of a nul-term string, so safe as a string */ - pdkim_decode_base64(hdr_as->b.data, &sighash); - --if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx))) -+if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx, NULL))) - { - DEBUG(D_acl) debug_printf("ARC verify init: %s\n", errstr); - return US"fail"; -diff -ru a/src/auths/README b/src/auths/README ---- a/src/auths/README 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/auths/README 2020-04-01 15:04:02.374233000 +0200 -@@ -34,7 +34,7 @@ - the server and/or client functions are available for this authenticator. - Typically this depends on whether server or client configuration options have - been set, but it is also possible to have an authenticator that has only one of --the server or client functions. -+the server or client functions. The function may not touch big_buffer. - - SERVER AUTHENTICATION - -diff -ru a/src/auths/call_radius.c b/src/auths/call_radius.c ---- a/src/auths/call_radius.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/auths/call_radius.c 2020-05-12 10:13:22.026117000 +0200 -@@ -2,6 +2,7 @@ - * Exim - an Internet mail transport agent * - *************************************************/ - -+/* Copyright (c) The Exim Maintainers 2020 */ - /* Copyright (c) University of Cambridge 1995 - 2016 */ - /* See the file NOTICE for conditions of use and distribution. */ - -@@ -115,34 +116,34 @@ - *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); - - else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) -- *errptr = string_sprintf("RADIUS: can't read dictionary"); -+ *errptr = US"RADIUS: can't read dictionary"; - --else if (rc_avpair_add(&send, PW_USER_NAME, user, 0) == NULL) -- *errptr = string_sprintf("RADIUS: add user name failed\n"); -+else if (!rc_avpair_add(&send, PW_USER_NAME, user, 0)) -+ *errptr = US"RADIUS: add user name failed"; - --else if (rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0) == NULL) -- *errptr = string_sprintf("RADIUS: add password failed\n"); -+else if (!rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0)) -+ *errptr = US"RADIUS: add password failed"); - --else if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0) == NULL) -- *errptr = string_sprintf("RADIUS: add service type failed\n"); -+else if (!rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0)) -+ *errptr = US"RADIUS: add service type failed"; - - #else /* RADIUS_LIB_RADIUSCLIENT unset => RADIUS_LIB_RADIUSCLIENT2 */ - --if ((h = rc_read_config(RADIUS_CONFIG_FILE)) == NULL) -+if (!(h = rc_read_config(RADIUS_CONFIG_FILE))) - *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE); - - else if (rc_read_dictionary(h, rc_conf_str(h, "dictionary")) != 0) -- *errptr = string_sprintf("RADIUS: can't read dictionary"); -+ *errptr = US"RADIUS: can't read dictionary"; - --else if (rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0) == NULL) -- *errptr = string_sprintf("RADIUS: add user name failed\n"); -+else if (!rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0)) -+ *errptr = US"RADIUS: add user name failed"; - --else if (rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args, -- Ustrlen(radius_args), 0) == NULL) -- *errptr = string_sprintf("RADIUS: add password failed\n"); -+else if (!rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args, -+ Ustrlen(radius_args), 0)) -+ *errptr = US"RADIUS: add password failed"; - --else if (rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0) == NULL) -- *errptr = string_sprintf("RADIUS: add service type failed\n"); -+else if (!rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0)) -+ *errptr = US"RADIUS: add service type failed"; - - #endif /* RADIUS_LIB_RADIUSCLIENT */ - -diff -ru a/src/auths/cyrus_sasl.c b/src/auths/cyrus_sasl.c ---- a/src/auths/cyrus_sasl.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/auths/cyrus_sasl.c 2020-05-12 10:13:22.026558000 +0200 -@@ -347,10 +347,10 @@ - } - else - { -- /* make sure that we have a null-terminated string */ -- out2 = string_copyn(output, outlen); -+ /* auth_get_data() takes a length-specfied block of binary -+ which can include zeroes; no terminating NUL is needed */ - -- if ((rc = auth_get_data(&input, out2, outlen)) != OK) -+ if ((rc = auth_get_data(&input, output, outlen)) != OK) - { - /* we couldn't get the data, so free up the library before - * returning whatever error we get */ -diff -ru a/src/auths/heimdal_gssapi.c b/src/auths/heimdal_gssapi.c ---- a/src/auths/heimdal_gssapi.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/auths/heimdal_gssapi.c 2020-05-12 10:13:22.028703000 +0200 -@@ -200,16 +200,6 @@ - - krb5_free_context(context); - --/* RFC 4121 section 5.2, SHOULD support 64K input buffers */ --if (big_buffer_size < (64 * 1024)) -- { -- uschar *newbuf; -- big_buffer_size = 64 * 1024; -- newbuf = store_malloc(big_buffer_size); -- store_free(big_buffer); -- big_buffer = newbuf; -- } -- - ablock->server = TRUE; - } - -diff -ru a/src/auths/spa.c b/src/auths/spa.c ---- a/src/auths/spa.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/auths/spa.c 2020-05-12 10:13:22.029070000 +0200 -@@ -139,7 +139,8 @@ - SPAAuthResponse response; - SPAAuthResponse *responseptr = &response; - uschar msgbuf[2048]; --uschar *clearpass; -+uschar *clearpass, *s; -+unsigned off; - - /* send a 334, MS Exchange style, and grab the client's request, - unless we already have it via an initial response. */ -@@ -194,9 +195,19 @@ - - { - int i; -- char *p = ((char*)responseptr) + IVAL(&responseptr->uUser.offset,0); -+ char * p; - int len = SVAL(&responseptr->uUser.len,0)/2; - -+ if ( (off = IVAL(&responseptr->uUser.offset,0)) >= sizeof(SPAAuthResponse) -+ || len >= sizeof(responseptr->buffer)/2 -+ || (p = (CS responseptr) + off) + len*2 >= CS (responseptr+1) -+ ) -+ { -+ DEBUG(D_auth) -+ debug_printf("auth_spa_server(): bad uUser spec in response\n"); -+ return FAIL; -+ } -+ - if (len + 1 >= sizeof(msgbuf)) return FAIL; - for (i = 0; i < len; ++i) - { -@@ -245,13 +256,17 @@ - - /* compare NT hash (LM may not be available) */ - --if (memcmp(ntRespData, -- ((unsigned char*)responseptr)+IVAL(&responseptr->ntResponse.offset,0), -- 24) == 0) -- /* success. we have a winner. */ -+off = IVAL(&responseptr->ntResponse.offset,0); -+if (off >= sizeof(SPAAuthResponse) - 24) - { -- return auth_check_serv_cond(ablock); -+ DEBUG(D_auth) -+ debug_printf("auth_spa_server(): bad ntRespData spec in response\n"); -+ return FAIL; - } -+s = (US responseptr) + off; -+ -+if (memcmp(ntRespData, s, 24) == 0) -+ return auth_check_serv_cond(ablock); /* success. we have a winner. */ - - /* Expand server_condition as an authorization check (PH) */ - -Only in a/src: cnumber.h -diff -ru a/src/dkim.c b/src/dkim.c ---- a/src/dkim.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/dkim.c 2020-05-12 10:13:22.056772000 +0200 -@@ -401,7 +401,7 @@ - dkim_cur_sig = sig; - dkim_signing_domain = US sig->domain; - dkim_signing_selector = US sig->selector; -- dkim_key_length = sig->sighash.len * 8; -+ dkim_key_length = sig->keybits; - - /* These two return static strings, so we can compare the addr - later to see if the ACL overwrote them. Check that when logging */ -diff -ru a/src/drtables.c b/src/drtables.c ---- a/src/drtables.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/drtables.c 2020-05-12 10:13:22.057565000 +0200 -@@ -740,10 +740,11 @@ - - dl = dlopen(CS big_buffer, RTLD_NOW);// TJ was LAZY - if (dl == NULL) { -- fprintf(stderr, "Error loading %s: %s\n", name, dlerror()); -- moduleerrors++; -- log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, dlerror()); -- continue; -+ errormessage = dlerror(); -+ fprintf(stderr, "Error loading %s: %s\n", name, errormessage); -+ log_write(0, LOG_MAIN|LOG_PANIC, "Error loading lookup module %s: %s\n", name, errormessage); -+ moduleerrors++; -+ continue; - } - - /* FreeBSD nsdispatch() can trigger dlerror() errors about -@@ -756,16 +757,16 @@ - info = (struct lookup_module_info*) dlsym(dl, "_lookup_module_info"); - if ((errormsg = dlerror()) != NULL) { - fprintf(stderr, "%s does not appear to be a lookup module (%s)\n", name, errormsg); -+ log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg); - dlclose(dl); - moduleerrors++; -- log_write(0, LOG_MAIN|LOG_PANIC, "%s does not appear to be a lookup module (%s)\n", name, errormsg); - continue; - } - if (info->magic != LOOKUP_MODULE_INFO_MAGIC) { - fprintf(stderr, "Lookup module %s is not compatible with this version of Exim\n", name); -+ log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name); - dlclose(dl); - moduleerrors++; -- log_write(0, LOG_MAIN|LOG_PANIC, "Lookup module %s is not compatible with this version of Exim\n", name); - continue; - } - -diff -ru a/src/exim.c b/src/exim.c ---- a/src/exim.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/exim.c 2020-05-12 10:13:22.059213000 +0200 -@@ -2554,8 +2554,10 @@ - #ifdef SUPPORT_I18N - allow_utf8_domains = TRUE; - #endif -- sender_address = parse_extract_address(argrest, &errmess, -- &dummy_start, &dummy_end, &sender_address_domain, TRUE); -+ if (!(sender_address = parse_extract_address(argrest, &errmess, -+ &dummy_start, &dummy_end, &sender_address_domain, TRUE))) -+ exim_fail("exim: bad -f address \"%s\": %s\n", argrest, errmess); -+ - sender_address = string_copy_taint(sender_address, TRUE); - #ifdef SUPPORT_I18N - message_smtputf8 = string_is_utf8(sender_address); -@@ -2563,8 +2565,6 @@ - #endif - allow_domain_literals = FALSE; - strip_trailing_dot = FALSE; -- if (!sender_address) -- exim_fail("exim: bad -f address \"%s\": %s\n", argrest, errmess); - } - f.sender_address_forced = TRUE; - } -@@ -5021,6 +5021,8 @@ - deliver_localpart_orig = NULL; - deliver_domain_orig = NULL; - callout_address = sending_ip_address = NULL; -+ deliver_localpart_data = deliver_domain_data = -+ recipient_data = sender_data = NULL; - sender_rate = sender_rate_limit = sender_rate_period = NULL; - } - smtp_log_no_mail(); -@@ -5681,6 +5683,8 @@ - #endif - callout_address = NULL; - sending_ip_address = NULL; -+ deliver_localpart_data = deliver_domain_data = -+ recipient_data = sender_data = NULL; - acl_var_m = NULL; - for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; - -diff -ru a/src/expand.c b/src/expand.c ---- a/src/expand.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/expand.c 2020-05-12 10:13:22.095677000 +0200 -@@ -5029,7 +5029,7 @@ - { - client_conn_ctx cctx; - int timeout = 5; -- int save_ptr = yield->ptr; -+ int save_ptr = yield ? yield->ptr : 0; - FILE * fp = NULL; - uschar * arg; - uschar * sub_arg[4]; -@@ -5070,8 +5070,9 @@ - uschar * item; - int sep = 0; - -- item = string_nextinlist(&list, &sep, NULL, 0); -- if ((timeout = readconf_readtime(item, 0, FALSE)) < 0) -+ if ( !(item = string_nextinlist(&list, &sep, NULL, 0)) -+ || !*item -+ || (timeout = readconf_readtime(item, 0, FALSE)) < 0) - { - expand_string_message = string_sprintf("bad time value %s", item); - goto EXPAND_FAILED; -@@ -5262,7 +5263,7 @@ - - if (sigalrm_seen) - { -- yield->ptr = save_ptr; -+ if (yield) yield->ptr = save_ptr; - expand_string_message = US "socket read timed out"; - goto SOCK_FAIL; - } -@@ -5429,7 +5430,7 @@ - - case EITEM_TR: - { -- int oldptr = yield->ptr; -+ int oldptr = yield ? yield->ptr : 0; - int o2m; - uschar *sub[3]; - -@@ -6170,7 +6171,7 @@ - case EITEM_REDUCE: - { - int sep = 0; -- int save_ptr = yield->ptr; -+ int save_ptr = yield ? yield->ptr : 0; - uschar outsep[2] = { '\0', '\0' }; - const uschar *list, *expr, *temp; - uschar *save_iterate_item = iterate_item; -@@ -6317,7 +6318,8 @@ - item of the output list, add in a space if the new item begins with the - separator character, or is an empty string. */ - -- if (yield->ptr != save_ptr && (temp[0] == *outsep || temp[0] == 0)) -+ if ( yield && yield->ptr != save_ptr -+ && (temp[0] == *outsep || temp[0] == 0)) - yield = string_catn(yield, US" ", 1); - - /* Add the string in "temp" to the output list that we are building, -@@ -6357,7 +6359,7 @@ - the redundant final separator. Even though an empty item at the end of a - list does not count, this is tidier. */ - -- else if (yield->ptr != save_ptr) yield->ptr--; -+ else if (yield && yield->ptr != save_ptr) yield->ptr--; - - /* Restore preserved $item */ - -@@ -7222,7 +7224,7 @@ - { - uschar outsep[2] = { ':', '\0' }; - uschar *address, *error; -- int save_ptr = yield->ptr; -+ int save_ptr = yield ? yield->ptr : 0; - int start, end, domain; /* Not really used */ - - while (isspace(*sub)) sub++; -@@ -7253,7 +7255,7 @@ - - if (address) - { -- if (yield->ptr != save_ptr && address[0] == *outsep) -+ if (yield && yield->ptr != save_ptr && address[0] == *outsep) - yield = string_catn(yield, US" ", 1); - - for (;;) -@@ -7282,7 +7284,7 @@ - /* If we have generated anything, remove the redundant final - separator. */ - -- if (yield->ptr != save_ptr) yield->ptr--; -+ if (yield && yield->ptr != save_ptr) yield->ptr--; - f.parse_allow_group = FALSE; - continue; - } -@@ -7421,10 +7423,10 @@ - - case EOP_FROM_UTF8: - { -- while (*sub != 0) -+ uschar * buff = store_get(4, is_tainted(sub)); -+ while (*sub) - { - int c; -- uschar buff[4]; - GETUTF8INC(c, sub); - if (c > 255) c = '_'; - buff[0] = c; -@@ -7445,7 +7447,17 @@ - int complete; - uschar seq_buff[4]; /* accumulate utf-8 here */ - -- while (*sub != 0) -+ /* Manually track tainting, as we deal in individual chars below */ -+ -+ if (is_tainted(sub)) -+ if (yield->s && yield->ptr) -+ gstring_rebuffer(yield); -+ else -+ yield->s = store_get(yield->size = Ustrlen(sub), TRUE); -+ -+ /* Check the UTF-8, byte-by-byte */ -+ -+ while (*sub) - { - complete = 0; - uschar c = *sub++; -diff -ru a/src/functions.h b/src/functions.h ---- a/src/functions.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/functions.h 2020-05-12 10:13:22.097024000 +0200 -@@ -187,6 +187,7 @@ - extern uschar *deliver_get_sender_address (uschar *id); - extern void delivery_re_exec(int); - -+extern void die_tainted(const uschar *, const uschar *, int); - extern BOOL directory_make(const uschar *, const uschar *, int, BOOL); - #ifndef DISABLE_DKIM - extern uschar *dkim_exim_query_dns_txt(const uschar *); -@@ -602,6 +603,58 @@ - extern ssize_t write_to_fd_buf(int, const uschar *, size_t); - - -+/******************************************************************************/ -+/* Predicate: if an address is in a tainted pool. -+By extension, a variable pointing to this address is tainted. -+*/ -+ -+static inline BOOL -+is_tainted(const void * p) -+{ -+#if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) || defined(EM_VERSION_C) -+return FALSE; -+ -+#else -+extern BOOL is_tainted_fn(const void *); -+return is_tainted_fn(p); -+#endif -+} -+ -+/******************************************************************************/ -+/* String functions */ -+static inline uschar * __Ustrcat(uschar * dst, const uschar * src, const char * func, int line) -+{ -+#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) -+if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcat", CUS func, line); -+#endif -+return US strcat(CS dst, CCS src); -+} -+static inline uschar * __Ustrcpy(uschar * dst, const uschar * src, const char * func, int line) -+{ -+#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) -+if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcpy", CUS func, line); -+#endif -+return US strcpy(CS dst, CCS src); -+} -+static inline uschar * __Ustrncat(uschar * dst, const uschar * src, size_t n, const char * func, int line) -+{ -+#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) -+if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncat", CUS func, line); -+#endif -+return US strncat(CS dst, CCS src, n); -+} -+static inline uschar * __Ustrncpy(uschar * dst, const uschar * src, size_t n, const char * func, int line) -+{ -+#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) -+if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncpy", CUS func, line); -+#endif -+return US strncpy(CS dst, CCS src, n); -+} -+/*XXX will likely need unchecked copy also */ -+ -+ -+/******************************************************************************/ -+ - #if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY) - /* exim_chown - in some NFSv4 setups *seemes* to be an issue with - chown(, ). -@@ -634,8 +687,8 @@ - return chown(CCS name, owner, group) - ? exim_chown_failure(-1, name, owner, group) : 0; - } -- - #endif /* !MACRO_PREDEF && !COMPILE_UTILITY */ -+ - /******************************************************************************/ - /* String functions */ - -@@ -848,6 +901,18 @@ - va_end(ap); - return g; - } -+ -+ -+/* Copy the content of a string to tainted memory */ -+ -+static inline void -+gstring_rebuffer(gstring * g) -+{ -+uschar * s = store_get(g->size, TRUE); -+memcpy(s, g->s, g->ptr); -+g->s = s; -+} -+ - - /******************************************************************************/ - -diff -ru a/src/globals.c b/src/globals.c ---- a/src/globals.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/globals.c 2020-05-12 10:13:22.097761000 +0200 -@@ -311,6 +311,7 @@ - .synchronous_delivery = FALSE, - .system_filtering = FALSE, - -+ .taint_check_slow = FALSE, - .tcp_fastopen_ok = FALSE, - .tcp_in_fastopen = FALSE, - .tcp_in_fastopen_data = FALSE, -diff -ru a/src/globals.h b/src/globals.h ---- a/src/globals.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/globals.h 2020-05-12 10:13:22.098294000 +0200 -@@ -272,6 +272,7 @@ - BOOL synchronous_delivery :1; /* TRUE if -odi is set */ - BOOL system_filtering :1; /* TRUE when running system filter */ - -+ BOOL taint_check_slow :1; /* malloc/mmap are not returning distinct ranges */ - BOOL tcp_fastopen_ok :1; /* appears to be supported by kernel */ - BOOL tcp_in_fastopen :1; /* conn usefully used fastopen */ - BOOL tcp_in_fastopen_data :1; /* fastopen carried data */ -@@ -339,7 +340,7 @@ - extern BOOL allow_domain_literals; /* As it says */ - extern BOOL allow_mx_to_ip; /* Allow MX records to -> ip address */ - #ifdef EXPERIMENTAL_ARC --struct arc_set *arc_received; /* highest ARC instance evaluation struct */ -+extern struct arc_set *arc_received; /* highest ARC instance evaluation struct */ - extern int arc_received_instance; /* highest ARC instance number in headers */ - extern int arc_oldest_pass; /* lowest passing instance number in headers */ - extern const uschar *arc_state; /* verification state */ -diff -ru a/src/ip.c b/src/ip.c ---- a/src/ip.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/ip.c 2020-05-12 10:13:22.099852000 +0200 -@@ -269,28 +269,34 @@ - /*XXX also seen on successful TFO, sigh */ - tcp_out_fastopen = fastopen_blob->len > 0 ? TFO_ATTEMPTED_DATA : TFO_ATTEMPTED_NODATA; - } -- else if (errno == EINPROGRESS) /* expected if we had no cookie for peer */ -+ else switch (errno) -+ { -+ case EINPROGRESS: /* expected if we had no cookie for peer */ - /* seen for no-data, proper TFO option, both cookie-request and with-cookie cases */ - /* apparently no visibility of the diffference at this point */ - /* seen for with-data, proper TFO opt, cookie-req */ - /* with netwk delay, post-conn tcp_info sees unacked 1 for R, 2 for C; code in smtp_out.c */ - /* ? older Experimental TFO option behaviour ? */ -- { /* queue unsent data */ -- DEBUG(D_transport|D_v) debug_printf(" TFO mode sendto, %s data: EINPROGRESS\n", -- fastopen_blob->len > 0 ? "with" : "no"); -- if (!fastopen_blob->data) -- { -- tcp_out_fastopen = TFO_ATTEMPTED_NODATA; /* we tried; unknown if useful yet */ -- rc = 0; -- } -- else -- rc = send(sock, fastopen_blob->data, fastopen_blob->len, 0); -- } -- else if(errno == EOPNOTSUPP) -- { -- DEBUG(D_transport) -- debug_printf("Tried TCP Fast Open but apparently not enabled by sysctl\n"); -- goto legacy_connect; -+ DEBUG(D_transport|D_v) debug_printf(" TFO mode sendto, %s data: EINPROGRESS\n", -+ fastopen_blob->len > 0 ? "with" : "no"); -+ if (!fastopen_blob->data) -+ { -+ tcp_out_fastopen = TFO_ATTEMPTED_NODATA; /* we tried; unknown if useful yet */ -+ rc = 0; -+ } -+ else /* queue unsent data */ -+ rc = send(sock, fastopen_blob->data, fastopen_blob->len, 0); -+ break; -+ -+ case EOPNOTSUPP: -+ DEBUG(D_transport) -+ debug_printf("Tried TCP Fast Open but apparently not enabled by sysctl\n"); -+ goto legacy_connect; -+ -+ case EPIPE: -+ DEBUG(D_transport) -+ debug_printf("Tried TCP Fast Open but kernel too old to support it\n"); -+ goto legacy_connect; - } - # endif - # ifdef EXIM_TFO_CONNECTX -diff -ru a/src/lookups/dsearch.c b/src/lookups/dsearch.c ---- a/src/lookups/dsearch.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/lookups/dsearch.c 2020-05-12 10:13:22.117328000 +0200 -@@ -28,7 +28,7 @@ - dsearch_open(uschar *dirname, uschar **errmsg) - { - DIR *dp = opendir(CS dirname); --if (dp == NULL) -+if (!dp) - { - int save_errno = errno; - *errmsg = string_open_failed(errno, "%s for directory search", dirname); -@@ -47,8 +47,8 @@ - /* The handle will always be (void *)(-1), but don't try casting it to an - integer as this gives warnings on 64-bit systems. */ - --BOOL --static dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners, -+static BOOL -+dsearch_check(void *handle, uschar *filename, int modemask, uid_t *owners, - gid_t *owngroups, uschar **errmsg) - { - handle = handle; -@@ -87,7 +87,9 @@ - filename = string_sprintf("%s/%s", dirname, keystring); - if (Ulstat(filename, &statbuf) >= 0) - { -- *result = string_copy(keystring); -+ /* Since the filename exists in the filesystem, we can return a -+ non-tainted result. */ -+ *result = string_copy_taint(keystring, FALSE); - return OK; - } - -diff -ru a/src/macros.h b/src/macros.h ---- a/src/macros.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/macros.h 2020-05-12 10:13:22.122799000 +0200 -@@ -152,12 +152,19 @@ - into big_buffer_size and in some circumstances increased. It should be at least - as long as the maximum path length. */ - --#if defined PATH_MAX && PATH_MAX > 16384 -+#ifdef AUTH_HEIMDAL_GSSAPI -+ /* RFC 4121 section 5.2, SHOULD support 64K input buffers */ -+# define __BIG_BUFFER_SIZE 65536 -+#else -+# define __BIG_BUFFER_SIZE 16384 -+#endif -+ -+#if defined PATH_MAX && PATH_MAX > __BIG_BUFFER_SIZE - # define BIG_BUFFER_SIZE PATH_MAX --#elif defined MAXPATHLEN && MAXPATHLEN > 16384 -+#elif defined MAXPATHLEN && MAXPATHLEN > __BIG_BUFFER_SIZE - # define BIG_BUFFER_SIZE MAXPATHLEN - #else --# define BIG_BUFFER_SIZE 16384 -+# define BIG_BUFFER_SIZE __BIG_BUFFER_SIZE - #endif - - /* header size of pipe content -diff -ru a/src/mytypes.h b/src/mytypes.h ---- a/src/mytypes.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/mytypes.h 2020-05-12 10:13:22.125222000 +0200 -@@ -100,19 +100,15 @@ - #define Uread(f,b,l) read(f,CS(b),l) - #define Urename(s,t) rename(CCS(s),CCS(t)) - #define Ustat(s,t) stat(CCS(s),t) --#define Ustrcat(s,t) __Ustrcat(s, CUS(t), __FUNCTION__, __LINE__) - #define Ustrchr(s,n) US strchr(CCS(s),n) - #define CUstrchr(s,n) CUS strchr(CCS(s),n) - #define CUstrerror(n) CUS strerror(n) - #define Ustrcmp(s,t) strcmp(CCS(s),CCS(t)) --#define Ustrcpy(s,t) __Ustrcpy(s, CUS(t), __FUNCTION__, __LINE__) - #define Ustrcpy_nt(s,t) strcpy(CS s, CCS t) /* no taint check */ - #define Ustrcspn(s,t) strcspn(CCS(s),CCS(t)) - #define Ustrftime(s,m,f,t) strftime(CS(s),m,f,t) - #define Ustrlen(s) (int)strlen(CCS(s)) --#define Ustrncat(s,t,n) __Ustrncat(s, CUS(t),n, __FUNCTION__, __LINE__) - #define Ustrncmp(s,t,n) strncmp(CCS(s),CCS(t),n) --#define Ustrncpy(s,t,n) __Ustrncpy(s, CUS(t),n, __FUNCTION__, __LINE__) - #define Ustrncpy_nt(s,t,n) strncpy(CS s, CCS t, n) /* no taint check */ - #define Ustrpbrk(s,t) strpbrk(CCS(s),CCS(t)) - #define Ustrrchr(s,n) US strrchr(CCS(s),n) -@@ -125,57 +121,17 @@ - #define Ustrtoul(s,t,b) strtoul(CCS(s),CSS(t),b) - #define Uunlink(s) unlink(CCS(s)) - --extern void die_tainted(const uschar *, const uschar *, int); -- --/* Predicate: if an address is in a tainted pool. --By extension, a variable pointing to this address is tainted. --*/ -- --static inline BOOL --is_tainted(const void * p) --{ --#if defined(COMPILE_UTILITY) || defined(MACRO_PREDEF) --return FALSE; -- --#elif defined(TAINT_CHECK_SLOW) --extern BOOL is_tainted_fn(const void *); --return is_tainted_fn(p); -- -+#ifdef EM_VERSION_C -+# define Ustrcat(s,t) strcat(CS(s), CCS(t)) -+# define Ustrcpy(s,t) strcpy(CS(s), CCS(t)) -+# define Ustrncat(s,t,n) strncat(CS(s), CCS(t), n) -+# define Ustrncpy(s,t,n) strncpy(CS(s), CCS(t), n) - #else --extern void * tainted_base, * tainted_top; --return p >= tainted_base && p < tainted_top; -+# define Ustrcat(s,t) __Ustrcat(s, CUS(t), __FUNCTION__, __LINE__) -+# define Ustrcpy(s,t) __Ustrcpy(s, CUS(t), __FUNCTION__, __LINE__) -+# define Ustrncat(s,t,n) __Ustrncat(s, CUS(t), n, __FUNCTION__, __LINE__) -+# define Ustrncpy(s,t,n) __Ustrncpy(s, CUS(t), n, __FUNCTION__, __LINE__) - #endif --} -- --static inline uschar * __Ustrcat(uschar * dst, const uschar * src, const char * func, int line) --{ --#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) --if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcat", CUS func, line); --#endif --return US strcat(CS dst, CCS src); --} --static inline uschar * __Ustrcpy(uschar * dst, const uschar * src, const char * func, int line) --{ --#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) --if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrcpy", CUS func, line); --#endif --return US strcpy(CS dst, CCS src); --} --static inline uschar * __Ustrncat(uschar * dst, const uschar * src, size_t n, const char * func, int line) --{ --#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) --if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncat", CUS func, line); --#endif --return US strncat(CS dst, CCS src, n); --} --static inline uschar * __Ustrncpy(uschar * dst, const uschar * src, size_t n, const char * func, int line) --{ --#if !defined(COMPILE_UTILITY) && !defined(MACRO_PREDEF) --if (!is_tainted(dst) && is_tainted(src)) die_tainted(US"Ustrncpy", CUS func, line); --#endif --return US strncpy(CS dst, CCS src, n); --} --/*XXX will likely need unchecked copy also */ - - #endif - /* End of mytypes.h */ -diff -ru a/src/pdkim/pdkim.c b/src/pdkim/pdkim.c ---- a/src/pdkim/pdkim.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/pdkim/pdkim.c 2020-05-12 10:13:22.126558000 +0200 -@@ -1430,7 +1430,7 @@ - - if ((*errstr = exim_dkim_verify_init(&p->key, - sig->keytype == KEYTYPE_ED25519 ? KEYFMT_ED25519_BARE : KEYFMT_DER, -- vctx))) -+ vctx, &sig->keybits))) - { - DEBUG(D_acl) debug_printf("verify_init: %s\n", *errstr); - sig->verify_status = PDKIM_VERIFY_INVALID; -diff -ru a/src/pdkim/pdkim.h b/src/pdkim/pdkim.h ---- a/src/pdkim/pdkim.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/pdkim/pdkim.h 2020-05-12 10:13:22.126756000 +0200 -@@ -140,8 +140,9 @@ - int version; - - /* (a=) The signature algorithm. */ -- int keytype; /* pdkim_keytypes index */ -- int hashtype; /* pdkim_hashes index */ -+ int keytype; /* pdkim_keytypes index */ -+ unsigned keybits; /* size of the key */ -+ int hashtype; /* pdkim_hashes index */ - - /* (c=x/) Header canonicalization method. Either PDKIM_CANON_SIMPLE - or PDKIM_CANON_RELAXED */ -diff -ru a/src/pdkim/signing.c b/src/pdkim/signing.c ---- a/src/pdkim/signing.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/pdkim/signing.c 2020-05-12 10:13:22.127061000 +0200 -@@ -155,7 +155,8 @@ - Return: NULL for success, or an error string */ - - const uschar * --exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx) -+exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx, -+ unsigned * bits) - { - gnutls_datum_t k; - int rc; -@@ -182,6 +183,7 @@ - ret = US"pubkey format not handled"; - break; - } -+if (!ret && bits) gnutls_pubkey_get_pk_algorithm(verify_ctx->key, bits); - return ret; - } - -@@ -552,7 +554,8 @@ - Return: NULL for success, or an error string */ - - const uschar * --exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx) -+exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx, -+ unsigned * bits) - { - /* - in code sequence per b81207d2bfa92 rsa_parse_public_key() and asn1_get_mpi() -@@ -560,6 +563,7 @@ - uschar tag_class; - int taglen; - long alen; -+unsigned nbits; - int rc; - uschar * errstr; - gcry_error_t gerr; -@@ -608,10 +612,10 @@ - - /* read two integers */ - DEBUG(D_acl) stage = US"MPI"; --if ( (errstr = as_mpi(pubkey, &verify_ctx->n)) -- || (errstr = as_mpi(pubkey, &verify_ctx->e)) -- ) -- return errstr; -+nbits = pubkey->len; -+if ((errstr = as_mpi(pubkey, &verify_ctx->n))) return errstr; -+nbits = (nbits - pubkey->len) * 8; -+if ((errstr = as_mpi(pubkey, &verify_ctx->e))) return errstr; - - #ifdef extreme_debug - DEBUG(D_acl) debug_printf_indent("rsa_verify_init:\n"); -@@ -624,6 +628,7 @@ - } - - #endif -+if (bits) *bits = nbits; - return NULL; - - asn_err: -@@ -794,7 +799,8 @@ - Return: NULL for success, or an error string */ - - const uschar * --exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx) -+exim_dkim_verify_init(blob * pubkey, keyformat fmt, ev_ctx * verify_ctx, -+ unsigned * bits) - { - const uschar * s = pubkey->data; - uschar * ret = NULL; -@@ -818,6 +824,7 @@ - break; - } - -+if (!ret && bits) *bits = EVP_PKEY_bits(verify_ctx->key); - return ret; - } - -diff -ru a/src/pdkim/signing.h b/src/pdkim/signing.h ---- a/src/pdkim/signing.h 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/pdkim/signing.h 2020-05-12 10:13:22.127197000 +0200 -@@ -90,7 +90,7 @@ - - extern const uschar * exim_dkim_signing_init(const uschar *, es_ctx *); - extern const uschar * exim_dkim_sign(es_ctx *, hashmethod, blob *, blob *); --extern const uschar * exim_dkim_verify_init(blob *, keyformat, ev_ctx *); -+extern const uschar * exim_dkim_verify_init(blob *, keyformat, ev_ctx *, unsigned *); - extern const uschar * exim_dkim_verify(ev_ctx *, hashmethod, blob *, blob *); - - #endif /*DISABLE_DKIM*/ -diff -ru a/src/readconf.c b/src/readconf.c ---- a/src/readconf.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/readconf.c 2020-05-12 10:13:22.129420000 +0200 -@@ -3788,6 +3788,7 @@ - if (!d->driver_name) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG, - "no driver defined for %s \"%s\"", class, d->name); -+ /* s is using big_buffer, so this call had better not */ - (d->info->init)(d); - d = NULL; - } -diff -ru a/src/receive.c b/src/receive.c ---- a/src/receive.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/receive.c 2020-05-12 10:13:22.130574000 +0200 -@@ -270,8 +270,8 @@ - "check_space = " PR_EXIM_ARITH "K inodes = %d msg_size = %d\n", - space, inodes, check_spool_space, check_spool_inodes, msg_size); - -- if ((space >= 0 && space < check_spool_space) || -- (inodes >= 0 && inodes < check_spool_inodes)) -+ if ( space >= 0 && space + msg_size / 1024 < check_spool_space -+ || inodes >= 0 && inodes < check_spool_inodes) - { - log_write(0, LOG_MAIN, "spool directory space check failed: space=" - PR_EXIM_ARITH " inodes=%d", space, inodes); -@@ -1755,6 +1755,13 @@ - - message_linecount = body_linecount = body_zerocount = - max_received_linelength = 0; -+ -+#ifdef WITH_CONTENT_SCAN -+/* reset non-per-part mime variables */ -+mime_is_coverletter = 0; -+mime_is_rfc822 = 0; -+mime_part_count = -1; -+#endif - - #ifndef DISABLE_DKIM - /* Call into DKIM to set up the context. In CHUNKING mode -diff -ru a/src/smtp_in.c b/src/smtp_in.c ---- a/src/smtp_in.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/smtp_in.c 2020-05-12 10:13:22.137165000 +0200 -@@ -2050,7 +2050,8 @@ - f.active_local_sender_retain = local_sender_retain; /* Can be set by ACL */ - sending_ip_address = NULL; - return_path = sender_address = NULL; --sender_data = NULL; /* Can be set by ACL */ -+deliver_localpart_data = deliver_domain_data = -+recipient_data = sender_data = NULL; /* Can be set by ACL */ - deliver_localpart_parent = deliver_localpart_orig = NULL; - deliver_domain_parent = deliver_domain_orig = NULL; - callout_address = NULL; -diff -ru a/src/spf.c b/src/spf.c ---- a/src/spf.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/spf.c 2020-05-12 10:13:22.138197000 +0200 -@@ -139,7 +139,12 @@ - srr.rr[found++] = (void *) s; - } - --srr.num_rr = found; -+/* Did we filter out all TXT RRs? Return NO_DATA instead of SUCCESS with -+empty ANSWER section. */ -+ -+if (!(srr.num_rr = found)) -+ srr.herrno = NO_DATA; -+ - /* spfrr->rr must have been malloc()d for this */ - SPF_dns_rr_dup(&spfrr, &srr); - return spfrr; -diff -ru a/src/store.c b/src/store.c ---- a/src/store.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/store.c 2020-05-12 10:13:22.139605000 +0200 -@@ -102,13 +102,6 @@ - static void *next_yield[NPOOLS]; - static int yield_length[NPOOLS] = { -1, -1, -1, -1, -1, -1 }; - --/* The limits of the tainted pools. Tracking these on new allocations enables --a fast is_tainted implementation. We assume the kernel only allocates mmaps using --one side or the other of data+heap, not both. */ -- --void * tainted_base = (void *)-1; --void * tainted_top = (void *)0; -- - /* pool_malloc holds the amount of memory used by the store pools; this goes up - and down as store is reset or released. nonpool_malloc is the total got by - malloc from other calls; this doesn't go down because it is just freed by -@@ -162,32 +155,34 @@ - - /******************************************************************************/ - --/* Slower version check, for use when platform intermixes malloc and mmap area --addresses. */ -+/* Test if a pointer refers to tainted memory. - -+Slower version check, for use when platform intermixes malloc and mmap area -+addresses. Test against the current-block of all tainted pools first, then all -+blocks of all tainted pools. -+ -+Return: TRUE iff tainted -+*/ -+ - BOOL - is_tainted_fn(const void * p) - { - storeblock * b; --int pool; - --for (pool = 0; pool < nelem(chainbase); pool++) -+for (int pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++) - if ((b = current_block[pool])) - { -- char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK; -- if (CS p >= bc && CS p <= bc + b->length) goto hit; -+ uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK; -+ if (US p >= bc && US p <= bc + b->length) return TRUE; - } - --for (pool = 0; pool < nelem(chainbase); pool++) -+for (int pool = POOL_TAINT_BASE; pool < nelem(chainbase); pool++) - for (b = chainbase[pool]; b; b = b->next) - { -- char * bc = CS b + ALIGNED_SIZEOF_STOREBLOCK; -- if (CS p >= bc && CS p <= bc + b->length) goto hit; -+ uschar * bc = US b + ALIGNED_SIZEOF_STOREBLOCK; -+ if (US p >= bc && US p <= bc + b->length) return TRUE; - } - return FALSE; -- --hit: --return pool >= POOL_TAINT_BASE; - } - - -@@ -199,6 +194,7 @@ - } - - -+ - /************************************************* - * Get a block from the current pool * - *************************************************/ -@@ -730,7 +726,7 @@ - BOOL release_ok = !tainted && store_last_get[pool] == block; - uschar * newtext; - --#ifndef MACRO_PREDEF -+#if !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY) - if (is_tainted(block) != tainted) - die_tainted(US"store_newblock", CUS func, linenumber); - #endif -@@ -786,9 +782,6 @@ - PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0))) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to mmap %d bytes of memory: " - "called from line %d of %s", size, line, func); -- --if (yield < tainted_base) tainted_base = yield; --if ((top = US yield + size) > tainted_top) tainted_top = top; - - return store_alloc_tail(yield, size, func, line, US"Mmap"); - } -diff -ru a/src/string.c b/src/string.c ---- a/src/string.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/string.c 2020-05-12 10:13:22.146645000 +0200 -@@ -12,7 +12,6 @@ - #include "exim.h" - #include - --static void gstring_rebuffer(gstring * g); - - #ifndef COMPILE_UTILITY - /************************************************* -@@ -1241,16 +1240,6 @@ - return !!gp; - } - -- -- --/* Copy the content of a string to tainted memory */ --static void --gstring_rebuffer(gstring * g) --{ --uschar * s = store_get(g->size, TRUE); --memcpy(s, g->s, g->ptr); --g->s = s; --} - - - -diff -ru a/src/tls-gnu.c b/src/tls-gnu.c ---- a/src/tls-gnu.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/tls-gnu.c 2020-05-12 10:13:22.148137000 +0200 -@@ -181,6 +181,10 @@ - BOOL peer_dane_verified; - BOOL trigger_sni_changes; - BOOL have_set_peerdn; -+#ifdef SUPPORT_CORK -+ BOOL corked:1; -+#endif -+ - const struct host_item *host; /* NULL if server */ - gnutls_x509_crt_t peercert; - uschar *peerdn; -@@ -3309,9 +3313,8 @@ - size_t left = len; - exim_gnutls_state_st * state = ct_ctx ? ct_ctx : &state_server; - #ifdef SUPPORT_CORK --static BOOL corked = FALSE; - --if (more && !corked) gnutls_record_cork(state->session); -+if (more && !state->corked) gnutls_record_cork(state->session); - #endif - - DEBUG(D_tls) debug_printf("%s(%p, " SIZE_T_FMT "%s)\n", __FUNCTION__, -@@ -3352,10 +3355,10 @@ - } - - #ifdef SUPPORT_CORK --if (more != corked) -+if (more != state->corked) - { - if (!more) (void) gnutls_record_uncork(state->session, 0); -- corked = more; -+ state->corked = more; - } - #endif - -diff -ru a/src/tls-openssl.c b/src/tls-openssl.c ---- a/src/tls-openssl.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/tls-openssl.c 2020-05-12 10:13:22.149180000 +0200 -@@ -2480,7 +2480,7 @@ - #endif - } - -- /* If a certificate file is empty, the next function fails with an -+ /* If a certificate file is empty, the load function fails with an - unhelpful error message. If we skip it, we get the correct behaviour (no - certificates are recognized, but the error message is still misleading (it - says no certificate was supplied). But this is better. */ -@@ -2489,9 +2489,9 @@ - && !SSL_CTX_load_verify_locations(sctx, CS file, CS dir)) - return tls_error(US"SSL_CTX_load_verify_locations", host, NULL, errstr); - -- /* Load the list of CAs for which we will accept certs, for sending -- to the client. This is only for the one-file tls_verify_certificates -- variant. -+ /* On the server load the list of CAs for which we will accept certs, for -+ sending to the client. This is only for the one-file -+ tls_verify_certificates variant. - If a list isn't loaded into the server, but some verify locations are set, - the server end appears to make a wildcard request for client certs. - Meanwhile, the client library as default behaviour *ignores* the list -@@ -2503,7 +2503,7 @@ - { - STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file); - -- SSL_CTX_set_client_CA_list(sctx, names); -+ if (!host) SSL_CTX_set_client_CA_list(sctx, names); - DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n", - sk_X509_NAME_num(names)); - } -diff -ru a/src/transport.c b/src/transport.c ---- a/src/transport.c 2020-01-03 13:08:52.000000000 +0100 -+++ b/src/transport.c 2020-05-12 10:13:22.150276000 +0200 -@@ -253,6 +253,7 @@ - - else - { -+ sigalrm_seen = FALSE; - ALARM(local_timeout); - - rc = -Only in a/src: version.h -Only in a/src: version.sh From 7e10bca0abd8eb884d49fcd6853424f61a55d2a6cb94b9ab565062455e2d9340 Mon Sep 17 00:00:00 2001 From: Peter Wullinger Date: Wed, 3 Jun 2020 05:53:11 +0000 Subject: [PATCH 2/2] fix download URL OBS-URL: https://build.opensuse.org/package/show/server:mail/exim?expand=0&rev=241 --- exim.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exim.spec b/exim.spec index 0aeb768..b2d903c 100644 --- a/exim.spec +++ b/exim.spec @@ -87,8 +87,8 @@ Summary: The Exim Mail Transfer Agent, a Replacement for sendmail License: GPL-2.0-or-later Group: Productivity/Networking/Email/Servers BuildRoot: %{_tmppath}/%{name}-%{version}-build -Source: http://ftp.exim.org/pub/exim/exim4/fixes/exim-%{version}.tar.bz2 -Source3: http://ftp.exim.org/pub/exim/exim4/fixes/exim-%{version}.tar.bz2.asc +Source: http://ftp.exim.org/pub/exim/exim4/exim-%{version}.tar.bz2 +Source3: http://ftp.exim.org/pub/exim/exim4/exim-%{version}.tar.bz2.asc # http://ftp.exim.org/pub/exim/Exim-Maintainers-Keyring.asc Source4: exim.keyring Source1: sysconfig.exim