smbd: fix close order of base_fsp and stream_fsp in smb_fname_fsp_destructor()
authorRalph Boehme <slow@samba.org>
Thu, 16 Nov 2023 09:50:32 +0000 (10:50 +0100)
committerJule Anger <janger@samba.org>
Tue, 21 Nov 2023 10:24:37 +0000 (10:24 +0000)
VFS modules like streams_xattr use the function fsp_is_alternate_stream() on the
fsp to determine in an fsp is a stream, eg in streams_xattr_close(). If
fspo->base_fsp is arlready set to NULL, this won't work anymore.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15521

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Nov 16 18:31:17 UTC 2023 on atb-devel-224

(cherry picked from commit 4481a67c1b20549a71d6c5132b637798a09f966d)

Autobuild-User(v4-18-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-18-test): Tue Nov 21 10:24:37 UTC 2023 on atb-devel-224

source3/smbd/files.c

index 792e9424bdce592fb2b59287b4850a1a635ac4a2..d3f6b629264a6fa063bfd8e5db1d0af40335f16e 100644 (file)
@@ -406,6 +406,7 @@ static void destroy_fsp_smb_fname_link(struct fsp_smb_fname_link **_link)
 static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
 {
        struct files_struct *fsp = smb_fname->fsp;
+       struct files_struct *base_fsp = NULL;
        NTSTATUS status;
        int saved_errno = errno;
 
@@ -417,17 +418,7 @@ static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
        }
 
        if (fsp_is_alternate_stream(fsp)) {
-               struct files_struct *tmp_base_fsp = fsp->base_fsp;
-
-               fsp_set_base_fsp(fsp, NULL);
-
-               status = fd_close(tmp_base_fsp);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DBG_ERR("Closing fd for fsp [%s] failed: %s. "
-                               "Please check your filesystem!!!\n",
-                               fsp_str_dbg(fsp), nt_errstr(status));
-               }
-               file_free(NULL, tmp_base_fsp);
+               base_fsp = fsp->base_fsp;
        }
 
        status = fd_close(fsp);
@@ -439,6 +430,17 @@ static int smb_fname_fsp_destructor(struct smb_filename *smb_fname)
        file_free(NULL, fsp);
        smb_fname->fsp = NULL;
 
+       if (base_fsp != NULL) {
+               base_fsp->stream_fsp = NULL;
+               status = fd_close(base_fsp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Closing fd for base_fsp [%s] failed: %s. "
+                               "Please check your filesystem!!!\n",
+                               fsp_str_dbg(base_fsp), nt_errstr(status));
+               }
+               file_free(NULL, base_fsp);
+       }
+
        errno = saved_errno;
        return 0;
 }