[libvirt] [PATCH 0/1] RFC Fix problems with TLS connections & threading

Even though we are not using gcrypt directly in any libvirt code, it turns out that we are responsible for initializing its thread support, since its used by gnutls. This really sucks in terms of library API encapsulation. It is also a little annoying if libvirt is used within an app that already uses gnutls/gcrypt, because there is no checking in gcrypt to see if threading ops are already set, so our call would override any pre-existing initialization, and an apps own call would override us. The only other option I see is to punt on the whole problem and declare apps are responsible for initializing gcrypt, but then this sucks too because it means apps have to presume we're built with gnutls, and not nss - not that we support nss currently. This bug only really impacts the libvirt client if using multiple virConnectPtr objects from separate threads with a TLS based URI. The server isn't impacted because all TLS I/O is done from the single I/O thread, and not any of the RPC workers. Daniel P. Berrange (1): Initialize gcrypt threading src/remote_internal.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-)

* src/remote_internal.c: Register thread functions for gcrypt Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/remote_internal.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/src/remote_internal.c b/src/remote_internal.c index f20ed6e..65dee25 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -59,6 +59,7 @@ #include <rpc/types.h> #include <rpc/xdr.h> +#include <gcrypt.h> #include <gnutls/gnutls.h> #include <gnutls/x509.h> #include "gnutls_1_0_compat.h" @@ -1065,6 +1066,46 @@ check_cert_file (virConnectPtr conn, const char *type, const char *file) return 0; } +static int remote_mutex_init (void **priv) +{ \ + virMutexPtr lock = NULL; + + if (VIR_ALLOC(lock) < 0) + return ENOMEM; + + if (virMutexInit(lock) < 0) + return errno; + + *priv = lock; + return 0; +} + +static int remote_mutex_destroy (void **lock) +{ + virMutexDestroy(*(virMutexPtr *)lock); + return 0; +} + +static int remote_mutex_lock (void **lock) +{ + virMutexLock(*(virMutexPtr *)lock); + return 0; +} +static int remote_mutex_unlock (void **lock) +{ + virMutexUnlock(*(virMutexPtr *)lock); + return 0; +} + +static struct gcry_thread_cbs remote_thread_cbs = { + (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), + NULL, + remote_mutex_init, + remote_mutex_destroy, + remote_mutex_lock, + remote_mutex_unlock, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; static int initialise_gnutls (virConnectPtr conn) @@ -1074,6 +1115,8 @@ initialise_gnutls (virConnectPtr conn) if (initialised) return 0; + gcry_control(GCRYCTL_SET_THREAD_CBS, &remote_thread_cbs); + gcry_check_version(NULL); gnutls_global_init (); /* X509 stuff */ -- 1.6.2.5
participants (1)
-
Daniel P. Berrange