diff options
author | Werner Koch <[email protected]> | 2016-11-11 19:35:36 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-11-11 19:36:58 +0000 |
commit | 4473db1ef24031ff4e26c9a9de95dbe898ed2b97 (patch) | |
tree | a9c219cf8b11b8f92f7a1908e74fb5da1fde9963 | |
parent | dirmngr: Prepare to trigger jobs by network activity. (diff) | |
download | gnupg-4473db1ef24031ff4e26c9a9de95dbe898ed2b97.tar.gz gnupg-4473db1ef24031ff4e26c9a9de95dbe898ed2b97.zip |
agent: Kludge to mitigate blocking calls in Libgcrypt.
* agent/gpg-agent.c (agent_libgcrypt_progress_cb): Sleep for 100ms on
"need_entropy".
--
During key generation Libgrypt will read from /dev/random which may
block. Libgcrypt is not nPth aware and thus the entire process will
block. Fortunately there is also a select with a short timeout to run
the progress callback. We detect this in gpg-agent and introduce a
short delay to give other threads (i.e. connections) an opportunity to
run.
This alone is not sufficient, an updated Libgpg-error is also required
to make the lock functions nPth aware.
Signed-off-by: Werner Koch <[email protected]>
-rw-r--r-- | agent/gpg-agent.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a3c1aa8dd..d767879ce 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -384,9 +384,9 @@ static pid_t parent_pid = (pid_t)(-1); static int active_connections; /* This object is used to dispatch progress messages from Libgcrypt to - * the right thread. Given that we won't have at max a few dozen - * connections at the same time using a linked list is the easiest way - * to handle this. */ + * the right thread. Given that we will have at max only a few dozen + * connections at a time, using a linked list is the easiest way to + * handle this. */ struct progress_dispatch_s { struct progress_dispatch_s *next; @@ -1747,6 +1747,17 @@ agent_libgcrypt_progress_cb (void *data, const char *what, int printchar, break; if (dispatch && dispatch->cb) dispatch->cb (dispatch->ctrl, what, printchar, current, total); + + /* If Libgcrypt tells us that it needs more entropy, we better take + * a nap to give other threads a chance to run. Note that Libgcrypt + * does not know about nPth and thus when it selects and reads from + * /dev/random this will block the process. Maybe we should add a + * function similar to gpgrt_set_syscall_clamp to Libgcrypt or use + * those clamps directly. For now sleeping for 100ms seems to be + * appropriate. */ + if (what && !strcmp (what, "need_entropy")) + npth_usleep (100000); + } |