1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

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 <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Stefan Metzmacher 2018-07-24 17:17:29 +02:00
parent 984872731a
commit 8d4792e686

View 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;