commit 00b35aee4cdc8a002b537d51585f925aba19db09 Author: Fabian Groffen Date: Tue Dec 10 17:32:12 2019 +0000 PAM: fix crash in the pam expansion condition. Bug 2489 Broken-by: f3ebb786e4 (cherry picked from commit dcbfbadac2f557dc73bbcf2b26aadf50f8414ca1) diff --git a/src/src/auths/call_pam.c b/src/src/auths/call_pam.c index 9a46b6b63..c96e146d1 100644 --- a/src/src/auths/call_pam.c +++ b/src/src/auths/call_pam.c @@ -69,9 +69,11 @@ pam_converse (int num_msg, PAM_CONVERSE_ARG2_TYPE **msg, int sep = 0; struct pam_response *reply; -if (pam_arg_ended) return PAM_CONV_ERR; +/* It seems that PAM frees reply[] */ -reply = store_get(sizeof(struct pam_response) * num_msg, FALSE); +if ( pam_arg_ended + || !(reply = malloc(sizeof(struct pam_response) * num_msg))) + return PAM_CONV_ERR; for (int i = 0; i < num_msg; i++) { @@ -80,25 +82,26 @@ for (int i = 0; i < num_msg; i++) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: - arg = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size); - if (arg == NULL) - { - arg = US""; - pam_arg_ended = TRUE; - } - reply[i].resp = CS string_copy_perm(arg, FALSE); /* PAM frees resp */ - reply[i].resp_retcode = PAM_SUCCESS; - break; + arg = string_nextinlist(&pam_args, &sep, big_buffer, big_buffer_size); + if (!arg) + { + arg = US""; + pam_arg_ended = TRUE; + } + reply[i].resp = CS string_copy_malloc(arg); /* PAM frees resp */ + reply[i].resp_retcode = PAM_SUCCESS; + break; case PAM_TEXT_INFO: /* Just acknowledge messages */ case PAM_ERROR_MSG: - reply[i].resp_retcode = PAM_SUCCESS; - reply[i].resp = NULL; - break; + reply[i].resp_retcode = PAM_SUCCESS; + reply[i].resp = NULL; + break; default: /* Must be an error of some sort... */ - pam_conv_had_error = TRUE; - return PAM_CONV_ERR; + free(reply); + pam_conv_had_error = TRUE; + return PAM_CONV_ERR; } } commit 5cb18fca8873da273fb80931b620892586cbffaf Author: Jeremy Harris Date: Fri Nov 8 22:30:04 2019 +0000 Regard command-line recipients as tainted (cherry picked from commit f0fe22cbc29ee4f887aa254f2590a9e72401e237) diff --git a/src/src/exim.c b/src/src/exim.c index 6a2e7a644..0e839c5d4 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -4822,8 +4822,9 @@ if (verify_address_mode || f.address_test_mode) { while (recipients_arg < argc) { - uschar *s = argv[recipients_arg++]; - while (*s != 0) + /* Supplied addresses are tainted since they come from a user */ + uschar * s = string_copy_taint(argv[recipients_arg++], TRUE); + while (*s) { BOOL finished = FALSE; uschar *ss = parse_find_address_end(s, FALSE); @@ -4831,16 +4832,16 @@ if (verify_address_mode || f.address_test_mode) test_address(s, flags, &exit_value); s = ss; if (!finished) - while (*(++s) != 0 && (*s == ',' || isspace(*s))); + while (*++s == ',' || isspace(*s)) ; } } } else for (;;) { - uschar *s = get_stdinput(NULL, NULL); - if (s == NULL) break; - test_address(s, flags, &exit_value); + uschar * s = get_stdinput(NULL, NULL); + if (!s) break; + test_address(string_copy_taint(s, TRUE), flags, &exit_value); } route_tidyup(); @@ -5334,13 +5335,13 @@ while (more) raw_sender = string_copy(sender_address); - /* Loop for each argument */ + /* Loop for each argument (supplied by user hence tainted) */ for (int i = 0; i < count; i++) { int start, end, domain; - uschar *errmess; - uschar *s = list[i]; + uschar * errmess; + uschar * s = string_copy_taint(list[i], TRUE); /* Loop for each comma-separated address */ commit 0582221c4a875e35b5ccefe9a17eef584819e4f0 Author: Heiko Schlittermann (HS12-RIPE) Date: Tue Dec 10 23:14:35 2019 +0100 TFO: disable for FreeBSD (cherry-picked from 52503083b9eded01c25e1c73f4510963c3cee799) diff --git a/src/src/ip.c b/src/src/ip.c index 19be51a03..70e3e2064 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -245,7 +245,7 @@ callout_address = string_sprintf("[%s]:%d", address, port); sigalrm_seen = FALSE; if (timeout > 0) ALARM(timeout); -#ifdef TCP_FASTOPEN +#if defined(TCP_FASTOPEN) && (defined(MSG_FASTOPEN) || defined(EXIM_TFO_CONNECTX)) /* TCP Fast Open, if the system has a cookie from a previous call to this peer, can send data in the SYN packet. The peer can send data before it gets our ACK of its SYN,ACK - the latter is useful for @@ -255,8 +255,8 @@ possibly use the data-on-syn, so support that too. */ if (fastopen_blob && f.tcp_fastopen_ok) { # ifdef MSG_FASTOPEN - /* This is a Linux implementation. It might be useable on FreeBSD; I have - not checked. */ + /* This is a Linux implementation. FreeBSD does not seem to have MSG_FASTOPEN so + how to get TFO is unknown. */ if ((rc = sendto(sock, fastopen_blob->data, fastopen_blob->len, MSG_FASTOPEN | MSG_DONTWAIT, s_ptr, s_len)) >= 0) commit 6397b292615a5ffb9fdb5bd305736e2ef5f00e0d Author: Samuel Thibault Date: Wed Dec 4 21:30:01 2019 +0000 Hurd: errno really uses more than a short-sized value. Bug 2476 (cherry picked from commit 377da0430697e6bcb8c48744eb5af4272a8f8075) diff --git a/src/src/structs.h b/src/src/structs.h index 3b5818df0..c05778161 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -648,11 +648,11 @@ typedef struct address_item { unsigned int domain_cache[(MAX_NAMED_LIST * 2)/32]; unsigned int localpart_cache[(MAX_NAMED_LIST * 2)/32]; int mode; /* mode for local transporting to a file */ + int basic_errno; /* status after failure */ int more_errno; /* additional error information */ /* (may need to hold a timestamp) */ unsigned int delivery_usec; /* subsecond part of delivery time */ - short int basic_errno; /* status after failure */ unsigned short child_count; /* number of child addresses */ short int return_file; /* fileno of return data file */ short int special_action; /* ( used when when deferred or failed */ commit 8ab104034bd456843cd5a4ab34af6ef339f9ac8d Author: Jeremy Harris Date: Tue Dec 10 20:04:15 2019 +0000 local_scan: align local_scan.h and docs re. store_get() (cherry picked from commit 4ec0fcb6737da9bc2603056d56fbf6e41e061967) diff --git a/src/src/local_scan.h b/src/src/local_scan.h index e0a97088f..da9a8911a 100644 --- a/src/src/local_scan.h +++ b/src/src/local_scan.h @@ -193,6 +193,14 @@ extern void smtp_vprintf(const char *, BOOL, va_list); string_sprintf_trc(fmt, US __FUNCTION__, __LINE__, __VA_ARGS__) extern uschar *string_sprintf_trc(const char *, const uschar *, unsigned, ...) ALMOST_PRINTF(1,4); +#define store_get(size, tainted) \ + store_get_3(size, tainted, __FUNCTION__, __LINE__) +extern void *store_get_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; +#define store_get_perm(size, tainted) \ + store_get_perm_3(size, tainted, __FUNCTION__, __LINE__) +extern void *store_get_perm_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; + + #if defined(LOCAL_SCAN) || defined(DLFUNC_IMPL) /* When compiling a local_scan() file we want to rename a published API, so that we can use an inlined implementation in the compiles of the main Exim files, diff --git a/src/src/store.h b/src/src/store.h index 52f211ef5..39b0f6ecf 100644 --- a/src/src/store.h +++ b/src/src/store.h @@ -34,10 +34,7 @@ tracing information for debugging. */ #define store_free(addr) \ store_free_3(addr, __FUNCTION__, __LINE__) -#define store_get(size, tainted) \ - store_get_3(size, tainted, __FUNCTION__, __LINE__) -#define store_get_perm(size, tainted) \ - store_get_perm_3(size, tainted, __FUNCTION__, __LINE__) +/* store_get & store_get_perm are in local_scan.h */ #define store_malloc(size) \ store_malloc_3(size, __FUNCTION__, __LINE__) #define store_mark(void) \ @@ -55,8 +52,7 @@ typedef void ** rmark; extern BOOL store_extend_3(void *, BOOL, int, int, const char *, int); extern void store_free_3(void *, const char *, int); -extern void *store_get_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; -extern void *store_get_perm_3(int, BOOL, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; +/* store_get_3 & store_get_perm_3 are in local_scan.h */ extern void *store_malloc_3(int, const char *, int) ALLOC ALLOC_SIZE(1) WARN_UNUSED_RESULT; extern rmark store_mark_3(const char *, int); extern void *store_newblock_3(void *, BOOL, int, int, const char *, int);