[PATCH] build: Increase libassuan min version to 2.5.0

NIIBE Yutaka gniibe at fsij.org
Fri Dec 22 00:47:42 CET 2017

Werner Koch <wk at gnupg.org> writes:
> We had to use that new libassuan function to fix a hang on Windows.  I
> am not 100% sure whether Unix is also affected; @gniibe: can you enlight
> us?

The change is not needed for Unix.  Let me explain.

The problem is about the initialization of nPth (the thread library),
the use of libassuan, and UNIX domain socket emulation on Windows.

We use nPth library for cooperative threads.  When a thread of an
application calls a system call which may block, the thread should
release the "execution right" (which is only given to a single thread at
a time) and then, after the system call, it should acquire the right.
This way, an application doesn't cause any hang, and execution is done
by single thread, cooperatively.  Libassuan uses hooks for this
mechanism for its calls of usleep, read, write, recvmsg, sendmsg,
waitpid, connect, and close.

We want to defer the nPth initialization, to be done after fork(2) on
Unix, because forking a process of multiple threads may open a can of
worms (of undefined/undocumented things).  gpg-agent prepares listing
sockets, forks, and then, it comes nPth initialization.

On the other hand, before nPth initialization (forking on Unix),
gpg-agent uses libassuan to check if another gpg-agent is available or
not.  This use of libassuan is done by non-threaded mode (it blocks on

There are two access mode in use of libassuan: by assuan_sock_*
functions with standard sock_fd, and by assuan context of
type assuan_context_t CTX.

Before the fix, use of assuan_sock_* by libassuan had the setting of
non-threaded mode, because of the order of initialization (nPth
initialization is done after fork).

This worked well on Unix, because all the things done by assuan_sock_*
are things by listening socket and checking nonce before
start_command_handler.  After checking nonce (which is null on Unix), it
uses the assuan context.

Things done by listening sockets are: poll on new connection by its own
call of nPth function (npth_select), accept (by npth_accept), and create
a new thread to work with the connection.  No problem, even if
non-threaded mode of libassuan.

On Windows, UNIX domain socket emulation does checking nonce (by read
and write), and it was done in non-threaded mode of libassuan.  This
caused a race condition, where the entire gpg-agent process might hang.

The fix is that we provide an API (assuan_sock_set_system_hooks) to
initialize, for the accesses by assuan_sock_* functions (along with
assuan_set_system_hooks).  Before the fix, the accesses by assuan_sock_*
functions only inherited the setting by assuan_set_system_hooks.  Now,
it can be done independently.  Thus, on Windows, checking nonce is now
done in threaded-mode, which can avoid hang.

More information about the Gnupg-devel mailing list