smbXsrv_client: make sure that we store a valid blob
authorStefan Metzmacher <metze@samba.org>
Thu, 7 May 2020 13:49:24 +0000 (06:49 -0700)
committerGünther Deschner <gd@samba.org>
Fri, 15 May 2020 09:04:35 +0000 (09:04 +0000)
This fixes a regression introduced by
14182350f8397d27d7642dae595dc52691f0acfe
("librpc ndr: ndr_pull_advance check for unsigned overflow.")
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14236

ndr_push_smbXsrv_client_global0() is happy with
pushing NULL pointers for r->{local_address,remote_address,remote_name},
while the IDL doesn't allow it.
In turn ndr_pull_smbXsrv_client_global0() no longer ignores the error.

This means multi-channel connections were broken,
and we paniced on a NULL pointer.
It's really sad that we still don't have automated tests for it.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
source3/smbd/process.c
source3/smbd/smbXsrv_client.c

index 955f13938b48aa76f41c44fc66498ced16dd29a4..2ea721f24c0991bddea45e6de22f0d1c58fb7725 100644 (file)
@@ -4024,6 +4024,24 @@ void smbd_process(struct tevent_context *ev_ctx,
                exit_server_cleanly("tsocket_strdup() failed");
        }
 
+       client->global->local_address =
+               tsocket_address_string(sconn->local_address,
+                                      client->global);
+       if (client->global->local_address == NULL) {
+               exit_server_cleanly("tsocket_address_string() failed");
+       }
+       client->global->remote_address =
+               tsocket_address_string(sconn->remote_address,
+                                      client->global);
+       if (client->global->remote_address == NULL) {
+               exit_server_cleanly("tsocket_address_string() failed");
+       }
+       client->global->remote_name =
+               talloc_strdup(client->global, sconn->remote_hostname);
+       if (client->global->remote_name == NULL) {
+               exit_server_cleanly("tsocket_strdup() failed");
+       }
+
        if (tsocket_address_is_inet(sconn->local_address, "ip")) {
                locaddr = tsocket_address_inet_addr_string(
                                sconn->local_address,
index f81fff40bb7794c2adeffeaabce45060738fa109..ec5b5f1d04c24d60a034e868802b3f8acff488df 100644 (file)
@@ -294,6 +294,13 @@ NTSTATUS smb2srv_client_lookup_global(struct smbXsrv_client *client,
                return NT_STATUS_OBJECTID_NOT_FOUND;
        }
 
+       if (global == NULL) {
+               /*
+                * most likely ndr_pull_struct_blob() failed
+                */
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
        *_global = global;
        return NT_STATUS_OK;
 }
@@ -375,6 +382,10 @@ static NTSTATUS smbXsrv_client_global_store(struct smbXsrv_client_global0 *globa
         * store the information in the old format.
         */
 
+       SMB_ASSERT(global->local_address != NULL);
+       SMB_ASSERT(global->remote_address != NULL);
+       SMB_ASSERT(global->remote_name != NULL);
+
        if (global->db_rec == NULL) {
                return NT_STATUS_INTERNAL_ERROR;
        }