summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-05-01 19:35:28 +0200
committerWerner Koch <wk@gnupg.org>2018-05-01 19:45:00 +0200
commitb26a227173e8e9b91be14f06ee781c6e214e50ff (patch)
treeeb9f552c1897748f2dd370b61157ae0fd71ea215
parent7e2517a29619c35257b38aa137b6772e471d7e4e (diff)
downloadlibgpg-error-b26a227173e8e9b91be14f06ee781c6e214e50ff.tar.gz
core,w32: Avoid recursive use of npth_unprotect.
* src/w32-estream.c (reader): Use standard free. (writer): Ditto. -- There are two errors: The minor one is that we allocated with calloc but released with _gpgrt_free. The major one is the recursive use of npth_unprotect due to the syscall_clamp mechanism: 1. Around the call to _gpgrt_w32_poll 2. By gpgrt_lock_lock on behalf of a the custom allocation handler in the worker threads at their _gpgrt_free. This problem was exhibited by GnuPG's dirmngr component. GnuPG-bug-id: 3937 Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--src/init.c6
-rw-r--r--src/w32-estream.c12
2 files changed, 15 insertions, 3 deletions
diff --git a/src/init.c b/src/init.c
index 7b3eda3..81ebd0f 100644
--- a/src/init.c
+++ b/src/init.c
@@ -300,7 +300,11 @@ _gpg_err_set_errno (int err)
/* Internal tracing functions. Except for TRACE_FP we use flockfile
- * and funlockfile to protect their use. */
+ * and funlockfile to protect their use.
+ *
+ * Warning: Take care with the trace functions - they may not use any
+ * of our services, in particular not the syscall clamp mechanism for
+ * reasons explained in w32-stream.c:create_reader. */
static FILE *trace_fp;
static int trace_save_errno;
static int trace_with_errno;
diff --git a/src/w32-estream.c b/src/w32-estream.c
index c1bf212..6f916b0 100644
--- a/src/w32-estream.c
+++ b/src/w32-estream.c
@@ -239,7 +239,7 @@ reader (void *arg)
CloseHandle (ctx->have_space_ev);
CloseHandle (ctx->thread_hd);
DeleteCriticalSection (&ctx->mutex);
- _gpgrt_free (ctx);
+ free (ctx); /* Standard free! See comment in create_reader. */
return 0;
}
@@ -256,6 +256,13 @@ create_reader (estream_cookie_w32_pollable_t pcookie)
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
+ /* The CTX must be allocated in standard system memory so that we
+ * won't use any custom allocation handler which may use our lock
+ * primitives for its implementation. The problem here is that the
+ * syscall clamp mechanism (e.g. nPth) would be called recursively:
+ * 1. For example by the caller of _gpgrt_w32_poll and 2. by
+ * gpgrt_lock_lock on behalf of the the custom allocation and free
+ * functions. */
ctx = calloc (1, sizeof *ctx);
if (!ctx)
{
@@ -542,7 +549,7 @@ writer (void *arg)
CloseHandle (ctx->thread_hd);
DeleteCriticalSection (&ctx->mutex);
trace (("%p: writer is destroyed", ctx));
- _gpgrt_free (ctx);
+ free (ctx); /* Standard free! See comment in create_writer. */
return 0;
}
@@ -559,6 +566,7 @@ create_writer (estream_cookie_w32_pollable_t pcookie)
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
+ /* See comment at create_reader. */
ctx = calloc (1, sizeof *ctx);
if (!ctx)
{