s3: vfs: vfs_streams_xattr: Don't blindly re-use the base file mode bits.
authorJeremy Allison <jra@samba.org>
Wed, 11 Apr 2018 15:41:00 +0000 (08:41 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 11 Apr 2018 21:09:12 +0000 (23:09 +0200)
When returning the stat struct for an xattr stream,
we originally base the st_ex_mode field on the value
from the base file containing the xattr. If the base
file is a directory, it will have S_IFDIR set in st_ex_mode,
but streams can never be directories, they must be reported
as regular files.

The original code OR'ed in S_IFREG, but neglected to
AND out S_IFDIR.

Note this is not a complete to fix bug 13380 as
it doesn't fix the generic case with all streams
modules. See later fix and regression test.

Found in real-world use case by Andrew Walker <awalker@ixsystems.com>.

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
source3/modules/vfs_streams_xattr.c

index 580ecd0e5fff1044ec8cd0e109e7710b3b40bd58..c653656e5f833eb9cf0c293e008ca4156e1ac271 100644 (file)
@@ -277,6 +277,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
 
        sbuf->st_ex_ino = stream_inode(sbuf, io->xattr_name);
        sbuf->st_ex_mode &= ~S_IFMT;
+       sbuf->st_ex_mode &= ~S_IFDIR;
         sbuf->st_ex_mode |= S_IFREG;
         sbuf->st_ex_blocks = sbuf->st_ex_size / STAT_ST_BLOCKSIZE + 1;
 
@@ -331,6 +332,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle,
 
        smb_fname->st.st_ex_ino = stream_inode(&smb_fname->st, xattr_name);
        smb_fname->st.st_ex_mode &= ~S_IFMT;
+       smb_fname->st.st_ex_mode &= ~S_IFDIR;
         smb_fname->st.st_ex_mode |= S_IFREG;
         smb_fname->st.st_ex_blocks =
            smb_fname->st.st_ex_size / STAT_ST_BLOCKSIZE + 1;