c401cc
From e2efe667ad176ed8ffcd920edbe420d6e8f52218 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <e2efe667ad176ed8ffcd920edbe420d6e8f52218.1386932212.git.jdenemar@redhat.com>
c401cc
From: Christophe Fergeau <cfergeau@redhat.com>
c401cc
Date: Wed, 11 Dec 2013 13:39:11 +0100
c401cc
Subject: [PATCH] Tie SASL callbacks lifecycle to virNetSessionSASLContext
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1039991
c401cc
c401cc
The array of sasl_callback_t callbacks which is passed to sasl_client_new()
c401cc
must be kept alive as long as the created sasl_conn_t object is alive as
c401cc
cyrus-sasl uses this structure internally for things like logging, so
c401cc
the memory used for callbacks must only be freed after sasl_dispose() has
c401cc
been called.
c401cc
c401cc
During testing of successful SASL logins with
c401cc
virsh -c qemu+tls:///system list --all
c401cc
I've been getting invalid read reports from valgrind
c401cc
c401cc
==9237== Invalid read of size 8
c401cc
==9237==    at 0x6E93B6F: _sasl_getcallback (common.c:1745)
c401cc
==9237==    by 0x6E95430: _sasl_log (common.c:1850)
c401cc
==9237==    by 0x16593D87: digestmd5_client_mech_dispose (digestmd5.c:4580)
c401cc
==9237==    by 0x6E91653: client_dispose (client.c:332)
c401cc
==9237==    by 0x6E9476A: sasl_dispose (common.c:851)
c401cc
==9237==    by 0x4E225A1: virNetSASLSessionDispose (virnetsaslcontext.c:678)
c401cc
==9237==    by 0x4CBC551: virObjectUnref (virobject.c:262)
c401cc
==9237==    by 0x4E254D1: virNetSocketDispose (virnetsocket.c:1042)
c401cc
==9237==    by 0x4CBC551: virObjectUnref (virobject.c:262)
c401cc
==9237==    by 0x4E2701C: virNetSocketEventFree (virnetsocket.c:1794)
c401cc
==9237==    by 0x4C965D3: virEventPollCleanupHandles (vireventpoll.c:583)
c401cc
==9237==    by 0x4C96987: virEventPollRunOnce (vireventpoll.c:652)
c401cc
==9237==    by 0x4C94730: virEventRunDefaultImpl (virevent.c:274)
c401cc
==9237==    by 0x12C7BA: vshEventLoop (virsh.c:2407)
c401cc
==9237==    by 0x4CD3D04: virThreadHelper (virthreadpthread.c:161)
c401cc
==9237==    by 0x7DAEF32: start_thread (pthread_create.c:309)
c401cc
==9237==    by 0x8C86EAC: clone (clone.S:111)
c401cc
==9237==  Address 0xe2d61b0 is 0 bytes inside a block of size 168 free'd
c401cc
==9237==    at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
c401cc
==9237==    by 0x4C73827: virFree (viralloc.c:580)
c401cc
==9237==    by 0x4DE4BC7: remoteAuthSASL (remote_driver.c:4219)
c401cc
==9237==    by 0x4DE33D0: remoteAuthenticate (remote_driver.c:3639)
c401cc
==9237==    by 0x4DDBFAA: doRemoteOpen (remote_driver.c:832)
c401cc
==9237==    by 0x4DDC8DC: remoteConnectOpen (remote_driver.c:1031)
c401cc
==9237==    by 0x4D8595F: do_open (libvirt.c:1239)
c401cc
==9237==    by 0x4D863F3: virConnectOpenAuth (libvirt.c:1481)
c401cc
==9237==    by 0x12762B: vshReconnect (virsh.c:337)
c401cc
==9237==    by 0x12C9B0: vshInit (virsh.c:2470)
c401cc
==9237==    by 0x12E9A5: main (virsh.c:3338)
c401cc
c401cc
This commit changes virNetSASLSessionNewClient() to take ownership of the SASL
c401cc
callbacks. Then we can free them in virNetSASLSessionDispose() after the corresponding
c401cc
sasl_conn_t has been freed.
c401cc
c401cc
(cherry picked from commit 13fdc6d63ef64f8e231a087e1dab7d90145c3c10)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/remote/remote_driver.c  | 2 ++
c401cc
 src/rpc/virnetsaslcontext.c | 6 ++++--
c401cc
 src/rpc/virnetsaslcontext.h | 2 +-
c401cc
 3 files changed, 7 insertions(+), 3 deletions(-)
c401cc
c401cc
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
c401cc
index b3e86e1..557b408 100644
c401cc
--- a/src/remote/remote_driver.c
c401cc
+++ b/src/remote/remote_driver.c
c401cc
@@ -4029,6 +4029,8 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
c401cc
                                             virNetClientRemoteAddrString(priv->client),
c401cc
                                             saslcb)))
c401cc
         goto cleanup;
c401cc
+    /* saslcb is now owned by sasl */
c401cc
+    saslcb = NULL;
c401cc
 
c401cc
 # ifdef WITH_GNUTLS
c401cc
     /* Initialize some connection props we care about */
c401cc
diff --git a/src/rpc/virnetsaslcontext.c b/src/rpc/virnetsaslcontext.c
c401cc
index 35dc6cf..1baf41e 100644
c401cc
--- a/src/rpc/virnetsaslcontext.c
c401cc
+++ b/src/rpc/virnetsaslcontext.c
c401cc
@@ -44,6 +44,7 @@ struct _virNetSASLSession {
c401cc
 
c401cc
     sasl_conn_t *conn;
c401cc
     size_t maxbufsize;
c401cc
+    sasl_callback_t *callbacks;
c401cc
 };
c401cc
 
c401cc
 
c401cc
@@ -167,7 +168,7 @@ virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt ATTRIB
c401cc
                                                 const char *hostname,
c401cc
                                                 const char *localAddr,
c401cc
                                                 const char *remoteAddr,
c401cc
-                                                const sasl_callback_t *cbs)
c401cc
+                                                sasl_callback_t *cbs)
c401cc
 {
c401cc
     virNetSASLSessionPtr sasl = NULL;
c401cc
     int err;
c401cc
@@ -191,6 +192,7 @@ virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt ATTRIB
c401cc
                        err, sasl_errstring(err, NULL, NULL));
c401cc
         goto cleanup;
c401cc
     }
c401cc
+    sasl->callbacks = cbs;
c401cc
 
c401cc
     return sasl;
c401cc
 
c401cc
@@ -674,5 +676,5 @@ void virNetSASLSessionDispose(void *obj)
c401cc
 
c401cc
     if (sasl->conn)
c401cc
         sasl_dispose(&sasl->conn);
c401cc
-
c401cc
+    VIR_FREE(sasl->callbacks);
c401cc
 }
c401cc
diff --git a/src/rpc/virnetsaslcontext.h b/src/rpc/virnetsaslcontext.h
c401cc
index e726302..54634d5 100644
c401cc
--- a/src/rpc/virnetsaslcontext.h
c401cc
+++ b/src/rpc/virnetsaslcontext.h
c401cc
@@ -49,7 +49,7 @@ virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt,
c401cc
                                                 const char *hostname,
c401cc
                                                 const char *localAddr,
c401cc
                                                 const char *remoteAddr,
c401cc
-                                                const sasl_callback_t *cbs);
c401cc
+                                                sasl_callback_t *cbs);
c401cc
 virNetSASLSessionPtr virNetSASLSessionNewServer(virNetSASLContextPtr ctxt,
c401cc
                                                 const char *service,
c401cc
                                                 const char *localAddr,
c401cc
-- 
c401cc
1.8.5.1
c401cc