smbd: disconnect/destroy all connections before calling smbXsrv_session_logoff_all()
authorStefan Metzmacher <metze@samba.org>
Tue, 24 Jul 2018 15:17:29 +0000 (17:17 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 25 Jul 2018 15:49:06 +0000 (17:49 +0200)
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 <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/server_exit.c

index 652bf6a1776b752f68de39b90c73e659c7a2310c..149cd863505cff2c0f3c46767652351402a1f586 100644 (file)
@@ -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;