From eda17649f8bd3b8ce7bfc00a3c11cbcae63c845d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 4 Oct 2016 09:01:13 +0900 Subject: 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 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'agent') 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 ) { -- cgit v1.2.3