From f1f5c36581a942bcccd63ede4b023fdb1a1d3ed4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Sep 2020 13:07:20 +0200 Subject: [PATCH] smbd: make sure that xconn is alive for the lifetime of smbXsrv_connection_shutdown_send/recv BUG: https://bugzilla.samba.org/show_bug.cgi?id=14533 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- .../knownfail.d/smb2.lease.timeout-disconnect | 1 - source3/smbd/globals.h | 1 + source3/smbd/smb2_server.c | 31 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) delete mode 100644 selftest/knownfail.d/smb2.lease.timeout-disconnect diff --git a/selftest/knownfail.d/smb2.lease.timeout-disconnect b/selftest/knownfail.d/smb2.lease.timeout-disconnect deleted file mode 100644 index a277ef43fa6..00000000000 --- a/selftest/knownfail.d/smb2.lease.timeout-disconnect +++ /dev/null @@ -1 +0,0 @@ -^samba3.smb2.lease.timeout-disconnect diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 4685b6971d3..dd3d58f8509 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -367,6 +367,7 @@ struct smbXsrv_connection { struct { NTSTATUS status; + bool terminating; int sock; struct tevent_fd *fde; diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 1322cf3ba08..bd0eab00606 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1500,6 +1500,7 @@ size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client) struct smbXsrv_connection_shutdown_state { struct tevent_queue *wait_queue; + struct smbXsrv_connection *xconn; }; static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq); @@ -1520,6 +1521,7 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx, * smbXsrv_connection_disconnect_transport() before. */ SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status)); + SMB_ASSERT(xconn->transport.terminating); req = tevent_req_create(mem_ctx, &state, struct smbXsrv_connection_shutdown_state); @@ -1527,6 +1529,9 @@ static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx, return NULL; } + state->xconn = xconn; + tevent_req_defer_callback(req, ev); + status = smbXsrv_session_disconnect_xconn(xconn); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); @@ -1590,15 +1595,33 @@ static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq) struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct smbXsrv_connection_shutdown_state *state = + tevent_req_data(req, + struct smbXsrv_connection_shutdown_state); + struct smbXsrv_connection *xconn = state->xconn; tevent_queue_wait_recv(subreq); TALLOC_FREE(subreq); tevent_req_done(req); + /* + * make sure the xconn pointer is still valid, + * it should as we used tevent_req_defer_callback() + */ + SMB_ASSERT(xconn->transport.terminating); } static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req) { + struct smbXsrv_connection_shutdown_state *state = + tevent_req_data(req, + struct smbXsrv_connection_shutdown_state); + struct smbXsrv_connection *xconn = state->xconn; + /* + * make sure the xconn pointer is still valid, + * it should as we used tevent_req_defer_callback() + */ + SMB_ASSERT(xconn->transport.terminating); return tevent_req_simple_recv_ntstatus(req); } @@ -1637,6 +1660,14 @@ void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn, num_ok = smbXsrv_client_valid_connections(client); + if (xconn->transport.terminating) { + DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n", + smbXsrv_connection_dbg(xconn), num_ok, + reason, location); + return; + } + xconn->transport.terminating = true; + DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n", smbXsrv_connection_dbg(xconn), num_ok, reason, location);