From 0a22c47c9740ec891e4c04ab12e9cc10f517bc08 Mon Sep 17 00:00:00 2001 From: Xavi Hernandez Date: Thu, 28 Apr 2022 07:09:10 +0200 Subject: [PATCH] socket: fix user-after-free on name resolution error (#3471) When a connection attempt fails, a new thread is created to clean it up due to some potential deadlocks. However this new thread was executed without a reference on the rpc transport when name resolution failed, making it use stale pointer in some cases and causing a crash. The fix makes sure that the thread always has a valid reference. Fixes: #3470 Change-Id: Iebff6cd95602a6cfc3f81a0c6781f20fd1a76638 Signed-off-by: Xavi Hernandez --- rpc/rpc-transport/socket/src/socket.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 10becfe9d8d..dd9cf25e5d7 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -158,7 +158,6 @@ ssl_setup_connection_params(rpc_transport_t *this); struct socket_connect_error_state_ { xlator_t *this; rpc_transport_t *trans; - gf_boolean_t refd; }; typedef struct socket_connect_error_state_ socket_connect_error_state_t; @@ -3132,8 +3131,7 @@ socket_connect_error_cbk(void *opaque) rpc_transport_notify(arg->trans, RPC_TRANSPORT_DISCONNECT, arg->trans); - if (arg->refd) - rpc_transport_unref(arg->trans); + rpc_transport_unref(arg->trans); GF_FREE(opaque); return NULL; @@ -3458,7 +3456,11 @@ socket_connect(rpc_transport_t *this, int port) arg = GF_CALLOC(1, sizeof(*arg), gf_sock_connect_error_state_t); arg->this = THIS; arg->trans = this; - arg->refd = refd; + if (!refd) { + /* A reference is required by the thread that will handle the + * error. */ + rpc_transport_ref(this); + } th_ret = gf_thread_create_detached(&th_id, socket_connect_error_cbk, arg, "scleanup"); if (th_ret) {