diff -urN ../exim-4.93.0.4.orig/exim_monitor/em_version.c ./exim_monitor/em_version.c --- ../exim-4.93.0.4.orig/exim_monitor/em_version.c 2020-01-03 14:08:52.000000000 +0200 +++ ./exim_monitor/em_version.c 2020-02-25 23:45:56.436844000 +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 -urN ../exim-4.93.0.4.orig/src/auths/README ./src/auths/README --- ../exim-4.93.0.4.orig/src/auths/README 2020-01-03 14:08:52.000000000 +0200 +++ ./src/auths/README 2020-02-25 23:45:56.439580000 +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 -urN ../exim-4.93.0.4.orig/src/auths/cyrus_sasl.c ./src/auths/cyrus_sasl.c --- ../exim-4.93.0.4.orig/src/auths/cyrus_sasl.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/auths/cyrus_sasl.c 2020-02-25 23:45:56.440570000 +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 -urN ../exim-4.93.0.4.orig/src/auths/heimdal_gssapi.c ./src/auths/heimdal_gssapi.c --- ../exim-4.93.0.4.orig/src/auths/heimdal_gssapi.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/auths/heimdal_gssapi.c 2020-02-25 23:45:56.441600000 +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 -urN ../exim-4.93.0.4.orig/src/cnumber.h ./src/cnumber.h --- ../exim-4.93.0.4.orig/src/cnumber.h 2020-01-07 01:46:10.000000000 +0200 +++ ./src/cnumber.h 2020-02-25 23:46:49.165634000 +0200 @@ -1 +1 @@ -1 +2 diff -urN ../exim-4.93.0.4.orig/src/drtables.c ./src/drtables.c --- ../exim-4.93.0.4.orig/src/drtables.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/drtables.c 2020-02-25 23:45:56.449549000 +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 -urN ../exim-4.93.0.4.orig/src/functions.h ./src/functions.h --- ../exim-4.93.0.4.orig/src/functions.h 2020-01-03 14:08:52.000000000 +0200 +++ ./src/functions.h 2020-02-25 23:45:56.456433000 +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 */ diff -urN ../exim-4.93.0.4.orig/src/globals.c ./src/globals.c --- ../exim-4.93.0.4.orig/src/globals.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/globals.c 2020-02-25 23:45:56.456927000 +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 -urN ../exim-4.93.0.4.orig/src/globals.h ./src/globals.h --- ../exim-4.93.0.4.orig/src/globals.h 2020-01-03 14:08:52.000000000 +0200 +++ ./src/globals.h 2020-02-25 23:45:56.457359000 +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 */ diff -urN ../exim-4.93.0.4.orig/src/ip.c ./src/ip.c --- ../exim-4.93.0.4.orig/src/ip.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/ip.c 2020-02-25 23:45:56.458718000 +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 -urN ../exim-4.93.0.4.orig/src/macros.h ./src/macros.h --- ../exim-4.93.0.4.orig/src/macros.h 2020-01-03 14:08:52.000000000 +0200 +++ ./src/macros.h 2020-02-25 23:45:56.462925000 +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 -urN ../exim-4.93.0.4.orig/src/mytypes.h ./src/mytypes.h --- ../exim-4.93.0.4.orig/src/mytypes.h 2020-01-03 14:08:52.000000000 +0200 +++ ./src/mytypes.h 2020-02-25 23:45:56.464386000 +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 -urN ../exim-4.93.0.4.orig/src/readconf.c ./src/readconf.c --- ../exim-4.93.0.4.orig/src/readconf.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/readconf.c 2020-02-25 23:45:56.468096000 +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 -urN ../exim-4.93.0.4.orig/src/spf.c ./src/spf.c --- ../exim-4.93.0.4.orig/src/spf.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/spf.c 2020-02-25 23:45:56.476171000 +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 -urN ../exim-4.93.0.4.orig/src/store.c ./src/store.c --- ../exim-4.93.0.4.orig/src/store.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/store.c 2020-02-25 23:45:56.477340000 +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 -urN ../exim-4.93.0.4.orig/src/tls-gnu.c ./src/tls-gnu.c --- ../exim-4.93.0.4.orig/src/tls-gnu.c 2020-01-03 14:08:52.000000000 +0200 +++ ./src/tls-gnu.c 2020-02-25 23:45:56.478990000 +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 -urN ../exim-4.93.0.4.orig/src/version.h ./src/version.h --- ../exim-4.93.0.4.orig/src/version.h 2020-01-07 01:46:10.000000000 +0200 +++ ./src/version.h 2020-02-25 23:45:58.364333000 +0200 @@ -1,5 +1,5 @@ /* automatically generated file - see ../scripts/reversion */ -#define EXIM_RELEASE_VERSION "4.93.0.4" +#define EXIM_RELEASE_VERSION "4.93.0.4-9-26b045604" #ifdef EXIM_VARIANT_VERSION #define EXIM_VERSION_STR EXIM_RELEASE_VERSION "-" EXIM_VARIANT_VERSION #else diff -urN ../exim-4.93.0.4.orig/src/version.sh ./src/version.sh --- ../exim-4.93.0.4.orig/src/version.sh 2020-01-07 01:46:10.000000000 +0200 +++ ./src/version.sh 2020-02-25 23:46:49.165767000 +0200 @@ -1,3 +1,3 @@ # automatically generated file - see ../scripts/reversion -EXIM_RELEASE_VERSION="4.93.0.4" -EXIM_COMPILE_NUMBER="1" +EXIM_RELEASE_VERSION="4.93.0.4-9-26b045604" +EXIM_COMPILE_NUMBER="2"