summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2022-05-30 10:49:54 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2022-05-30 10:49:54 +0100
commit204a7a2c2e8601558905dc34c576a627045a9f21 (patch)
tree5a6c9e698d05d47ec010d608d28a6dc94110e6bb
parentdd4daa8a2ba4986a2fc9bba17251f6955f2332b8 (diff)
downloadexim4-204a7a2c2e8601558905dc34c576a627045a9f21.tar.gz
panic_coredump option. Bug 2892
-rw-r--r--doc/doc-docbook/spec.xfpt14
-rw-r--r--doc/doc-txt/OptionLists.txt1
-rw-r--r--src/src/exim.c34
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/log.c5
-rw-r--r--src/src/readconf.c7
-rw-r--r--test/confs/00011
-rw-r--r--test/scripts/0000-Basic/05727
-rw-r--r--test/stdout/0572260
10 files changed, 323 insertions, 8 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index e2111554c..74f92f5a7 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -14726,6 +14726,7 @@ listed in more than one group.
.row &%log_timezone%& "add timezone to log lines"
.row &%message_logs%& "create per-message logs"
.row &%preserve_message_logs%& "after message completion"
+.row &%panic_coredump%& "request coredump on fatal errors"
.row &%process_log_path%& "for SIGUSR1 and &'exiwhat'&"
.row &%slow_lookup_log%& "control logging of slow DNS lookups"
.row &%syslog_duplication%& "controls duplicate log lines on syslog"
@@ -17062,6 +17063,19 @@ to be used in conjunction with &(oracle)& lookups (see section &<<SECID72>>&).
The option is available only if Exim has been built with Oracle support.
+.new
+.option panic_coredump main boolean false
+This option is rarely needed but can help for some debugging investigations.
+If set, when an internal error is detected by Exim which is sufficient
+to terminate the process
+(all such are logged in the paniclog)
+then a coredump is requested.
+
+Note that most systems require additional administrative configuration
+to permit write a core file for a setuid program, which is Exim's
+common installed configuration.
+.wen
+
.option percent_hack_domains main "domain list&!!" unset
.cindex "&""percent hack""&"
.cindex "source routing" "in email address"
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 55b0f36fc..ee62cad48 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -420,6 +420,7 @@ optional boolean false iplookup
oracle_servers string unset main 4.00
owners string list unset redirect 4.00
owngroups string list unset redirect 4.00
+panic_coredump boolean false main 4.96
pass_on_timeout boolean false routers 4.00
pass_router string unset routers 4.00
path string "/usr/bin" pipe
diff --git a/src/src/exim.c b/src/src/exim.c
index 1a4b44945..6fde16a9c 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -17,6 +17,11 @@ Also a few functions that don't naturally fit elsewhere. */
# include <gnu/libc-version.h>
#endif
+#ifndef _TIME_H
+# include <time.h>
+#endif
+#include <execinfo.h> /*XXX maybe glibc-only? */
+
#ifdef USE_GNUTLS
# include <gnutls/gnutls.h>
# if GNUTLS_VERSION_NUMBER < 0x030103 && !defined(DISABLE_OCSP)
@@ -24,10 +29,6 @@ Also a few functions that don't naturally fit elsewhere. */
# endif
#endif
-#ifndef _TIME_H
-# include <time.h>
-#endif
-
extern void init_lookup_list(void);
@@ -261,6 +262,29 @@ exit(1);
* Handler for SIGSEGV *
***********************************************/
+#define STACKDUMP_MAX 24
+void
+stackdump(ucontext_t * ucontext)
+{
+void * buf[STACKDUMP_MAX];
+char ** ss;
+int nptrs = backtrace(buf, STACKDUMP_MAX);
+
+log_write(0, LOG_MAIN|LOG_PANIC, "backtrace\n");
+log_write(0, LOG_MAIN|LOG_PANIC, "---\n");
+if ((ss = backtrace_symbols(buf, nptrs)))
+ {
+ for (int i = 0; i < nptrs; i++)
+ log_write(0, LOG_MAIN|LOG_PANIC, "\t%s\n", ss[i]);
+ free(ss);
+ }
+else
+ log_write(0, LOG_MAIN|LOG_PANIC, "backtrace_symbols: %s\n", strerror(errno));
+log_write(0, LOG_MAIN|LOG_PANIC, "---\n");
+}
+#undef STACKDUMP_MAX
+
+
static void
#ifdef SA_SIGINFO
segv_handler(int sig, siginfo_t * info, void * uctx)
@@ -281,6 +305,7 @@ else
log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)");
if (process_info_len > 0)
log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info);
+stackdump(uctx);
signal(SIGSEGV, SIG_DFL);
kill(getpid(), sig);
}
@@ -291,6 +316,7 @@ segv_handler(int sig)
log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (maybe attempt to write to immutable memory)");
if (process_info_len > 0)
log_write(0, LOG_MAIN|LOG_PANIC, "SIGSEGV (%.*s)", process_info_len, process_info);
+stackdump();
signal(SIGSEGV, SIG_DFL);
kill(getpid(), sig);
}
diff --git a/src/src/globals.c b/src/src/globals.c
index ff246feb4..70e3f568b 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1207,6 +1207,7 @@ uid_t originator_uid;
uschar *override_local_interfaces = NULL;
uschar *override_pid_file_path = NULL;
+BOOL panic_coredump = FALSE;
pcre2_general_context * pcre_gen_ctx = NULL;
pcre2_compile_context * pcre_cmp_ctx = NULL;
pcre2_match_context * pcre_mtc_ctx = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index fe099e402..ca5b0ccc9 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -792,6 +792,7 @@ extern uid_t originator_uid; /* Uid of ditto */
extern uschar *override_local_interfaces; /* Value of -oX argument */
extern uschar *override_pid_file_path; /* Value of -oP argument */
+extern BOOL panic_coredump; /* SEGV rather than exit, on LOG_PANIC_DIE */
extern pcre2_general_context * pcre_gen_ctx; /* pcre memory management */
extern pcre2_compile_context * pcre_cmp_ctx;
extern pcre2_match_context * pcre_mtc_ctx;
diff --git a/src/src/log.c b/src/src/log.c
index 8ca973f2d..a46d523db 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -1278,7 +1278,10 @@ if (flags & LOG_PANIC)
/* Give up if the DIE flag is set */
if ((flags & LOG_PANIC_DIE) != LOG_PANIC)
- die(NULL, US"Unexpected failure, please try later");
+ if (panic_coredump)
+ kill(getpid(), SIGSEGV); /* deliberate trap */
+ else
+ die(NULL, US"Unexpected failure, please try later");
}
}
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 06bc50fd8..c74b70b55 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -243,6 +243,7 @@ static optionlist optionlist_config[] = {
#ifdef LOOKUP_ORACLE
{ "oracle_servers", opt_stringptr, {&oracle_servers} },
#endif
+ { "panic_coredump", opt_bool, {&panic_coredump} },
{ "percent_hack_domains", opt_stringptr, {&percent_hack_domains} },
#ifdef EXIM_PERL
{ "perl_at_start", opt_bool, {&opt_perl_at_start} },
@@ -2667,8 +2668,8 @@ switch(ol->type & opt_mask)
break;
case opt_bit:
- printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))?
- "" : "no_", name);
+ printf("%s%s\n", (*((int *)value)) & (1 << ((ol->type >> 16) & 31))
+ ? "" : "no_", name);
break;
case opt_expand_bool:
@@ -2693,7 +2694,7 @@ switch(ol->type & opt_mask)
case opt_bool:
case opt_bool_verify:
case opt_bool_set:
- printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name);
+ printf("%s%s\n", *((BOOL *)value) ? "" : "no_", name);
break;
case opt_func:
diff --git a/test/confs/0001 b/test/confs/0001
index 4dfd09aea..09c47895b 100644
--- a/test/confs/0001
+++ b/test/confs/0001
@@ -131,6 +131,7 @@ no_message_logs
message_size_limit = 500K
mua_wrapper
never_users = root:0
+panic_coredump
percent_hack_domains =
pipelining_advertise_hosts = *.b.c
pid_file_path = /some/thing
diff --git a/test/scripts/0000-Basic/0572 b/test/scripts/0000-Basic/0572
index 2866a23f1..abab82f36 100644
--- a/test/scripts/0000-Basic/0572
+++ b/test/scripts/0000-Basic/0572
@@ -26,6 +26,13 @@ perl -e 'print "\n";'
#
exim -bP config
****
+perl -e 'print "\n";'
+****
+#
#
exim -n -bP config
****
+perl -e 'print "\n";'
+****
+#
+exim -bP
diff --git a/test/stdout/0572 b/test/stdout/0572
index 3345451c3..ea3a7d34b 100644
--- a/test/stdout/0572
+++ b/test/stdout/0572
@@ -117,6 +117,7 @@ begin transports
port = 1224
hosts_try_fastopen = :
debug_print = transport_name <$transport_name>
+
# Exim Configuration (X)
# 1 "TESTSUITE/test-config"
OPT =
@@ -156,3 +157,262 @@ interface = ip4.ip4.ip4.ip4
port = 1224
hosts_try_fastopen = :
debug_print = transport_name <$transport_name>
+
+accept_8bitmime
+acl_not_smtp =
+acl_not_smtp_mime =
+acl_not_smtp_start =
+acl_smtp_auth =
+acl_smtp_connect =
+acl_smtp_data =
+acl_smtp_data_prdr = accept
+acl_smtp_dkim =
+acl_smtp_etrn =
+acl_smtp_expn =
+acl_smtp_helo =
+acl_smtp_mail =
+acl_smtp_mailauth =
+acl_smtp_mime =
+acl_smtp_notquit =
+acl_smtp_predata =
+acl_smtp_quit =
+acl_smtp_rcpt = accept
+acl_smtp_starttls =
+acl_smtp_vrfy =
+add_environment = SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
+admin_groups =
+no_allow_domain_literals
+no_allow_mx_to_ip
+no_allow_utf8_domains
+auth_advertise_hosts = *
+auto_thaw = 0s
+av_scanner = sophie:/var/run/sophie
+bi_command =
+bounce_message_file =
+bounce_message_text =
+bounce_return_body
+bounce_return_linesize_limit = 998
+bounce_return_message
+bounce_return_size_limit = 100K
+bounce_sender_authentication =
+callout_domain_negative_expire = 3h
+callout_domain_positive_expire = 1w
+callout_negative_expire = 2h
+callout_positive_expire = 1d
+callout_random_local_part = $primary_hostname-$tod_epoch-testing
+check_log_inodes = 100
+check_log_space = 10M
+check_rfc2047_length
+check_spool_inodes = 100
+check_spool_space = 10M
+chunking_advertise_hosts =
+no_commandline_checks_require_admin
+daemon_smtp_ports = smtp
+daemon_startup_retries = 9
+daemon_startup_sleep = 30s
+no_dcc_direct_add_header
+dccifd_address = /usr/local/dcc/var/dccifd
+dccifd_options = header
+debug_store
+delay_warning = 1d
+delay_warning_condition = ${if or {{ !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }{ match{$h_precedence:}{(?i)bulk|list|junk} }{ match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }} {no}{yes}}
+no_deliver_drop_privilege
+deliver_queue_load_max =
+delivery_date_remove
+no_disable_ipv6
+dkim_verify_hashes = sha256:sha512
+dkim_verify_keytypes = ed25519:rsa
+dkim_verify_min_keysizes = rsa=1024 ed25519=250
+no_dkim_verify_minimal
+dkim_verify_signers = $dkim_signers
+dns_again_means_nonexist =
+dns_check_names_pattern = (?i)^(?>(?(1)\.|())[^\W](?>[a-z0-9/_-]*[^\W])?)+(\.?)$
+dns_cname_loops = 9
+dns_csa_search_limit = 5
+dns_csa_use_reverse
+dns_dnssec_ok = -1
+dns_ipv4_lookup =
+dns_retrans = 0s
+dns_retry = 0
+dns_trust_aa =
+dns_use_edns0 = -1
+no_drop_cr
+dsn_advertise_hosts =
+dsn_from = Mail Delivery System <Mailer-Daemon@$qualify_domain>
+envelope_to_remove
+errors_copy =
+errors_reply_to =
+event_action =
+exim_group = exim
+exim_path = TESTSUITE/eximdir/exim
+exim_user = exim
+exim_version = x.yz
+extra_local_interfaces =
+extract_addresses_remove_arguments
+finduser_retries = 0
+freeze_tell =
+gecos_name = CALLER_NAME
+gecos_pattern =
+no_gnutls_allow_auto_pkcs11
+no_gnutls_compat_mode
+header_line_maxsize = 0
+header_maxsize = 1048576
+headers_charset = ISO-8859-1
+helo_accept_junk_hosts =
+helo_allow_chars =
+helo_lookup_domains = @ : @[]
+helo_try_verify_hosts =
+helo_verify_hosts =
+hold_domains =
+host_lookup =
+host_lookup_order = bydns
+host_reject_connection =
+hosts_connection_nolog =
+hosts_proxy =
+hosts_require_alpn =
+hosts_require_helo = *
+hosts_treat_as_local =
+ignore_bounce_errors_after = 10w
+ignore_fromline_hosts =
+no_ignore_fromline_local
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+keep_malformed = 4d
+ldap_ca_cert_dir =
+ldap_ca_cert_file =
+ldap_cert_file =
+ldap_cert_key =
+ldap_cipher_suite =
+ldap_default_servers =
+ldap_require_cert =
+no_ldap_start_tls
+ldap_version = -1
+local_from_check
+local_from_prefix =
+local_from_suffix =
+local_interfaces = <; ::0 ; 0.0.0.0
+no_local_sender_retain
+localhost_number =
+log_file_path = TESTSUITE/spool/log/%slog
+log_selector = +outgoing_port
+no_log_timezone
+lookup_open_max = 25
+max_username_length = 0
+no_message_body_newlines
+message_body_visible = 500
+message_id_header_domain =
+message_id_header_text =
+message_logs
+message_size_limit = 50M
+no_move_frozen_messages
+no_mua_wrapper
+mysql_servers =
+never_users =
+notifier_socket = $spool_directory/exim_daemon_notify
+openssl_options =
+no_panic_coredump
+percent_hack_domains =
+no_perl_at_start
+perl_startup =
+no_perl_taintmode
+pgsql_servers =
+pid_file_path =
+pipelining_advertise_hosts = *
+no_prdr_enable
+no_preserve_message_logs
+primary_hostname = myhost.test.ex
+no_print_topbitchars
+process_log_path = TESTSUITE/spool/exim-process.info
+prod_requires_admin
+proxy_protocol_timeout = 3s
+qualify_domain = myhost.test.ex
+qualify_recipient = myhost.test.ex
+queue_domains =
+no_queue_fast_ramp
+queue_list_requires_admin
+no_queue_only
+queue_only_file =
+queue_only_load =
+queue_only_load_latch
+queue_only_override
+no_queue_run_in_order
+queue_run_max = 5
+queue_smtp_domains =
+receive_timeout = 0s
+received_header_text = Received: ${if def:sender_rcvhost {from $sender_rcvhost\n\t}{${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}by $primary_hostname ${if def:received_protocol {with $received_protocol }}${if def:tls_in_ver { ($tls_in_ver)}}${if def:tls_in_cipher_std { tls $tls_in_cipher_std\n\t}}(Exim $version_number)\n\t${if def:sender_address {(envelope-from <$sender_address>)\n\t}}id $message_exim_id${if def:received_for {\n\tfor $received_for}}
+received_headers_max = 30
+recipient_unqualified_hosts =
+recipients_max = 50000
+no_recipients_max_reject
+redis_servers =
+remote_max_parallel = 2
+remote_sort_domains =
+retry_data_expire = 1w
+retry_interval_max = 1d
+return_path_remove
+rfc1413_hosts = @[]
+rfc1413_query_timeout = 0s
+sender_unqualified_hosts =
+slow_lookup_log = 0
+smtp_accept_keepalive
+smtp_accept_max = 20
+smtp_accept_max_nonmail = 10
+smtp_accept_max_nonmail_hosts = *
+smtp_accept_max_per_connection = 1000
+smtp_accept_max_per_host =
+smtp_accept_queue = 0
+smtp_accept_queue_per_connection = 10
+smtp_accept_reserve = 0
+smtp_active_hostname =
+smtp_backlog_monitor = 0
+smtp_banner = $smtp_active_hostname ESMTP Exim $version_number $tod_full
+smtp_check_spool_space
+smtp_connect_backlog = 20
+smtp_enforce_sync
+smtp_etrn_command =
+smtp_etrn_serialize
+smtp_load_reserve =
+smtp_max_synprot_errors = 3
+smtp_max_unknown_commands = 3
+smtp_ratelimit_hosts =
+smtp_ratelimit_mail =
+smtp_ratelimit_rcpt =
+smtp_receive_timeout = 5m
+smtp_reserve_hosts =
+no_smtp_return_error_details
+smtputf8_advertise_hosts =
+spamd_address = 127.0.0.1 783
+spf_guess = v=spf1 a/24 mx/24 ptr ?all
+spf_smtp_comment_template = Please%_see%_http://www.open-spf.org/Why
+no_split_spool_directory
+spool_directory = TESTSUITE/spool
+no_spool_wireformat
+sqlite_dbfile =
+sqlite_lock_timeout = 5
+no_strict_acl_vars
+no_strip_excess_angle_brackets
+no_strip_trailing_dot
+syslog_duplication
+syslog_facility =
+syslog_pid
+syslog_processname = exim
+syslog_timestamp
+system_filter =
+system_filter_directory_transport =
+system_filter_file_transport =
+system_filter_group =
+system_filter_pipe_transport =
+system_filter_reply_transport =
+system_filter_user =
+tcp_nodelay
+timeout_frozen_after = 0s
+timezone =
+no_tls_remember_esmtp
+trusted_groups =
+trusted_users =
+unknown_login =
+unknown_username =
+untrusted_set_sender =
+uucp_from_pattern = ^From\s+(\S+)\s+(?:[a-zA-Z]{3},?\s+)?(?:[a-zA-Z]{3}\s+\d?\d|\d?\d\s+[a-zA-Z]{3}\s+\d\d(?:\d\d)?)\s+\d\d?:\d\d?
+uucp_from_sender = $1
+warn_message_file =
+write_rejectlog