From eda17649f8bd3b8ce7bfc00a3c11cbcae63c845d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 4 Oct 2016 09:01:13 +0900 Subject: [PATCH] agent, dirmngr, scd: npth_init must be after fork. * agent/gpg-agent.c (thread_init_once, initialize_modules): New. (main): Make sure no daemonizing-fork call after npth_init, and no npth calls before npth_init, with care of npth calls by assuan hooks. * dirmngr/dirmngr.c (thread_init): New. (main): Make sure npth_init must not be called before daemonizing fork. * scd/scdaemon.c (main): Likewise. -- It is simply the best for nPth not to allow the daemonizing fork after npth_init, because semantics and implementations of forked child process in a threaded application is a difficult corner case. GnuPG-bug-id: 1779 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 36 ++++++++++++++++++++++++++++-------- dirmngr/dirmngr.c | 31 ++++++++++++++++++++----------- scd/scdaemon.c | 6 ++++-- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 15202accb..e65198a87 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -718,6 +718,29 @@ finalize_rereadable_options (void) } +static void +thread_init_once (void) +{ + static int npth_initialized = 0; + + if (!npth_initialized) + { + npth_initialized++; + npth_init (); + } +} + +static void +initialize_modules (void) +{ + thread_init_once (); + assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); + initialize_module_cache (); + initialize_module_call_pinentry (); + initialize_module_call_scd (); + initialize_module_trustlist (); +} + /* The main entry point. */ int @@ -765,14 +788,11 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - npth_init (); - malloc_hooks.malloc = gcry_malloc; malloc_hooks.realloc = gcry_realloc; malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug, NULL); @@ -1080,16 +1100,12 @@ main (int argc, char **argv ) exit (1); } - initialize_module_cache (); - initialize_module_call_pinentry (); - initialize_module_call_scd (); - initialize_module_trustlist (); - /* Try to create missing directories. */ create_directories (); if (debug_wait && pipe_server) { + thread_init_once (); log_debug ("waiting for debugger - my pid is %u .....\n", (unsigned int)getpid()); gnupg_sleep (debug_wait); @@ -1196,6 +1212,8 @@ main (int argc, char **argv ) /* This is the simple pipe based server */ ctrl_t ctrl; + initialize_modules (); + ctrl = xtrycalloc (1, sizeof *ctrl); if (!ctrl) { @@ -1403,6 +1421,8 @@ main (int argc, char **argv ) This is the child */ + initialize_modules (); + /* Detach from tty and put process into a new session */ if (!nodetach ) { diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 64d93b7cf..621c2bb9a 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -647,6 +647,22 @@ pid_suffix_callback (unsigned long *r_suffix) #endif /*!HAVE_W32_SYSTEM*/ +static void +thread_init (void) +{ + npth_init (); + + /* Now with NPth running we can set the logging callback. Our + windows implementation does not yet feature the NPth TLS + functions. */ +#ifndef HAVE_W32_SYSTEM + if (npth_key_create (&my_tlskey_current_fd, NULL) == 0) + if (npth_setspecific (my_tlskey_current_fd, NULL) == 0) + log_set_pid_suffix_cb (pid_suffix_callback); +#endif /*!HAVE_W32_SYSTEM*/ +} + + int main (int argc, char **argv) { @@ -680,8 +696,6 @@ main (int argc, char **argv) i18n_init (); init_common_subsystems (&argc, &argv); - npth_init (); - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* Check that the libraries are suitable. Do it here because @@ -722,15 +736,6 @@ main (int argc, char **argv) if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) csh_style = 1; - /* Now with NPth running we can set the logging callback. Our - windows implementation does not yet feature the NPth TLS - functions. */ -#ifndef HAVE_W32_SYSTEM - if (npth_key_create (&my_tlskey_current_fd, NULL) == 0) - if (npth_setspecific (my_tlskey_current_fd, NULL) == 0) - log_set_pid_suffix_cb (pid_suffix_callback); -#endif /*!HAVE_W32_SYSTEM*/ - /* Reset rereadable options to default values. */ parse_rereadable_options (NULL, 0); @@ -981,6 +986,7 @@ main (int argc, char **argv) ldap_wrapper_launch_thread (); #endif /*USE_LDAP*/ + thread_init (); cert_cache_init (); crl_cache_init (); start_command_handler (ASSUAN_INVALID_FD); @@ -1179,6 +1185,7 @@ main (int argc, char **argv) ldap_wrapper_launch_thread (); #endif /*USE_LDAP*/ + thread_init (); cert_cache_init (); crl_cache_init (); handle_connections (fd); @@ -1206,6 +1213,7 @@ main (int argc, char **argv) #if USE_LDAP ldap_wrapper_launch_thread (); #endif /*USE_LDAP*/ + thread_init (); cert_cache_init (); crl_cache_init (); if (!argc) @@ -1231,6 +1239,7 @@ main (int argc, char **argv) #if USE_LDAP ldap_wrapper_launch_thread (); #endif /*USE_LDAP*/ + thread_init (); cert_cache_init (); crl_cache_init (); rc = crl_fetch (&ctrlbuf, argv[0], &reader); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index bf54d95c0..3571e6614 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -422,8 +422,6 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - npth_init (); - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); malloc_hooks.malloc = gcry_malloc; @@ -724,6 +722,8 @@ main (int argc, char **argv ) } #endif + npth_init (); + /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually write. */ @@ -861,6 +861,8 @@ main (int argc, char **argv ) /* This is the child. */ + npth_init (); + /* Detach from tty and put process into a new session. */ if (!nodetach ) {