panic_coredump option. Bug 2892
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 30 May 2022 09:49:54 +0000 (10:49 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 30 May 2022 09:49:54 +0000 (10:49 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/OptionLists.txt
src/src/exim.c
src/src/globals.c
src/src/globals.h
src/src/log.c
src/src/readconf.c
test/confs/0001
test/scripts/0000-Basic/0572
test/stdout/0572

index e2111554c12f78f77f42c0801f1103d5a93c9782..74f92f5a78891614c23cd3ce847bf95284cc0276 100644 (file)
@@ -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"
index 55b0f36fc5c6ff93c14cd8e6c3e612158c0926f1..ee62cad4835e588098f123483dd5e951b8850b88 100644 (file)
@@ -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
index 1a4b4494507d37b201a957c28246d1d9d0f54784..6fde16a9cf2f4213a9b01ca029265a7b1782cae6 100644 (file)
@@ -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);
 }
index ff246feb4801f0c9e73a0ae97d6e0c7794ca7978..70e3f568bbe6e554f2900880b3b8f49068c3b678 100644 (file)
@@ -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;
index fe099e4020eddb771b1f827ec136e2383c5805bf..ca5b0ccc9c2595275cfb6735b291798826432fab 100644 (file)
@@ -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;
index 8ca973f2def7a8b7b8a32796d4e9edb43a04aaea..a46d523db1fe9bdadf89ee3a0243ea94cedc172e 100644 (file)
@@ -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");
   }
 }
 
index 06bc50fd88a5e8e946c5b1a10cc87bf3f9c25d6f..c74b70b555e87d21090e5e67f0519af32ba07463 100644 (file)
@@ -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:
index 4dfd09aeacbca3eaf4008856538cffdfa47211fc..09c47895b618c1e9904cc9686b0803e0e12f5ef7 100644 (file)
@@ -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
index 2866a23f16464e69d158395e65db2bc7ebfbdd67..abab82f363096629f7be296c289f487804440e1a 100644 (file)
@@ -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
index 3345451c33343d290691ebbb2dd274ba3b1ae0e2..ea3a7d34b10aebd14ead48335a2ef043b7ec8b13 100644 (file)
@@ -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