From 8d4792e68604c2ea96bb179774e4745d49d8bade Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Jul 2018 17:17:29 +0200 Subject: [PATCH] smbd: disconnect/destroy all connections before calling smbXsrv_session_logoff_all() This means the pending requests are destroyed before tevent_context impersonation wrapper are destroyed. Otherwise, with a pending struct tevent_req that is a child of client->xconn like this in exit_server_common(): conn[ipv4:127.0.0.11:40745] reason[NT_STATUS_CONNECTION_RESET] at ../source3/smbd/smb2_server.c:4015 full talloc report on 'struct smbXsrv_connection' (total 6085 bytes in 43 blocks) struct smbd_smb2_request contains 648 bytes in 1 blocks (ref 0) 0x55ed41634740 struct smbd_smb2_request contains 3438 bytes in 32 blocks (ref 0) 0x55ed416331e0 struct tevent_req contains 1824 bytes in 20 blocks (ref 0) 0x55ed41635860 struct smb_filename contains 206 bytes in 2 blocks (ref 0) 0x55ed41635560 lease_v2_complex2.dat contains 22 bytes in 1 blocks (ref 0) 0x55ed4161b950 struct smbd_smb2_create_state contains 1386 bytes in 16 blocks (ref 0) 0x55ed41635a10 struct deferred_open_record contains 804 bytes in 12 blocks (ref 0) 0x55ed41633090 struct defer_open_state contains 764 bytes in 11 blocks (ref 0) 0x55ed41634f10 struct tevent_req contains 748 bytes in 10 blocks (ref 0) 0x55ed41636390 struct tevent_timer contains 96 bytes in 1 blocks (ref 0) 0x55ed41636ad0 struct dbwrap_watched_watch_state contains 420 bytes in 7 blocks (ref 0) 0x55ed41636540 struct tevent_req contains 296 bytes in 5 blocks (ref 0) 0x55ed41636700 struct messaging_filtered_read_state contains 64 bytes in 3 blocks (ref 0) 0x55ed416368b0 struct messaging_dgm_fde contains 8 bytes in 2 blocks (ref 0) 0x55ed41636950 reference to: struct messaging_dgm_fde_ev we crash when freeing the xconn as the the tevent_req child has a cleanup function that tries to access a (wrapped) tevent context that was already destroyed via smb1srv_tcon_disconnect_all() for SMB1 or smbXsrv_session_logoff_all() for SMB2 a few lines above. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- source3/smbd/server_exit.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c index 652bf6a1776..149cd863505 100644 --- a/source3/smbd/server_exit.c +++ b/source3/smbd/server_exit.c @@ -90,15 +90,12 @@ static void exit_server_common(enum server_exit_reason how, { struct smbXsrv_client *client = global_smbXsrv_client; struct smbXsrv_connection *xconn = NULL; + struct smbXsrv_connection *xconn_next = NULL; struct smbd_server_connection *sconn = NULL; struct messaging_context *msg_ctx = server_messaging_context(); if (client != NULL) { sconn = client->sconn; - /* - * Here we typically have just one connection - */ - xconn = client->connections; } if (!exit_firsttime) @@ -107,7 +104,14 @@ static void exit_server_common(enum server_exit_reason how, change_to_root_user(); - if (xconn != NULL) { + + /* + * Here we typically have just one connection + */ + for (xconn = client->connections; xconn != NULL; xconn = xconn_next) { + xconn_next = xconn->next; + DLIST_REMOVE(client->connections, xconn); + /* * This is typically the disconnect for the only * (or with multi-channel last) connection of the client @@ -123,7 +127,8 @@ static void exit_server_common(enum server_exit_reason how, } } - TALLOC_FREE(xconn->smb1.negprot.auth_context); + TALLOC_FREE(xconn); + DO_PROFILE_INC(disconnect); } change_to_root_user(); @@ -203,14 +208,6 @@ static void exit_server_common(enum server_exit_reason how, * because smbd_msg_ctx is not a talloc child of smbd_server_conn. */ if (client != NULL) { - struct smbXsrv_connection *next; - - for (; xconn != NULL; xconn = next) { - next = xconn->next; - DLIST_REMOVE(client->connections, xconn); - talloc_free(xconn); - DO_PROFILE_INC(disconnect); - } TALLOC_FREE(client->sconn); } sconn = NULL; -- 2.47.3