s3: smbd: Ignore fstat() error on deleted stream in fd_close().
authorRalph Boehme <slow@samba.org>
Wed, 20 Sep 2023 21:21:44 +0000 (14:21 -0700)
committerJule Anger <janger@samba.org>
Mon, 13 Nov 2023 12:16:15 +0000 (12:16 +0000)
In the fd_close() fsp->fsp_flags.fstat_before_close code path.

If this is a stream and delete-on-close was set, the
backing object (an xattr from streams_xattr) might
already be deleted so fstat() fails with
NT_STATUS_NOT_FOUND. So if fsp refers to a stream we
ignore the error and only bail for normal files where
an fstat() should still work. NB. We cannot use
fsp_is_alternate_stream(fsp) for this as the base_fsp
has already been closed at this point and so the value
fsp_is_alternate_stream() checks for is already NULL.

Remove knownfail.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=15487

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Tue Oct 10 09:39:27 UTC 2023 on atb-devel-224

(cherry picked from commit 633a3ee6894cc1d05b44dbe47a278202803d9b21)

Autobuild-User(v4-18-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-18-test): Mon Nov 13 12:16:15 UTC 2023 on atb-devel-224

source3/smbd/open.c

index 0c9ddfe7c948123318b136dbe34d60b0f49963ac..c848243c9b584e33ccf642785fb221e9ab970b74 100644 (file)
@@ -997,7 +997,20 @@ NTSTATUS fd_close(files_struct *fsp)
        if (fsp->fsp_flags.fstat_before_close) {
                status = vfs_stat_fsp(fsp);
                if (!NT_STATUS_IS_OK(status)) {
-                       return status;
+                       /*
+                        * If this is a stream and delete-on-close was set, the
+                        * backing object (an xattr from streams_xattr) might
+                        * already be deleted so fstat() fails with
+                        * NT_STATUS_NOT_FOUND. So if fsp refers to a stream we
+                        * ignore the error and only bail for normal files where
+                        * an fstat() should still work. NB. We cannot use
+                        * fsp_is_alternate_stream(fsp) for this as the base_fsp
+                        * has already been closed at this point and so the value
+                        * fsp_is_alternate_stream() checks for is already NULL.
+                        */
+                       if (fsp->fsp_name->stream_name == NULL) {
+                               return status;
+                       }
                }
        }