After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 795805 - Copying file to Windows server (SMB2) via gvfsd-fuse and gvfsd-smb fails with EINVAL
Copying file to Windows server (SMB2) via gvfsd-fuse and gvfsd-smb fails with...
Status: RESOLVED FIXED
Product: gvfs
Classification: Core
Component: smb backend
1.36.x
Other Linux
: Normal normal
: ---
Assigned To: gvfs-maint
gvfs-maint
Depends on:
Blocks:
 
 
Reported: 2018-05-04 14:48 UTC by Ian Abbott
Modified: 2018-05-14 12:14 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GVFS_DEBUG=10 GVFS_DEBUG_FUSE=10 GVFS_SMB_DEBUG=10 /usr/lib/gvfs/gvfsd --replace -d 2>&1 (13.00 KB, text/x-log)
2018-05-04 14:48 UTC, Ian Abbott
  Details
Wireshark capture (7.11 KB, application/x-pcapng)
2018-05-04 14:51 UTC, Ian Abbott
  Details
smb: Use O_RDWR to fix fstat when writing (2.27 KB, patch)
2018-05-09 11:04 UTC, Ondrej Holy
committed Details | Review
gvfsd log after applying "smb: Use O_RDWR to fix fstat when writing" patch (3.25 KB, text/x-log)
2018-05-10 14:33 UTC, Ian Abbott
  Details

Description Ian Abbott 2018-05-04 14:48:49 UTC
Created attachment 371673 [details]
GVFS_DEBUG=10 GVFS_DEBUG_FUSE=10 GVFS_SMB_DEBUG=10 /usr/lib/gvfs/gvfsd --replace -d 2>&1

If a share on a Windows file server (not a Samba server) is mounted and uses the SMB2 protocol, any attempt to copy or create a file for writing (e.g. using the cp or cat commands from the bash shell) on the mount point via FUSE will create a zero-length file but the open will return with an EINVAL error.  Copying files via Nautilus works.

The problem seems to be due to the SMB2 GetInfo request with info level SMB2_FILE_ALL_INFO (which is issued by the vfs_getaddr handler just after a successful SMB2 Create Request for the file) being responded to with a STATUS_ACCESS_DENIED error.  This is normal for a Windows server when the file is opened write-only.  In contrast, a Samba server will process the request SMB2 GetInfo request successfully for a write-only file.  Copying a file via Nautilus works because it writes the file contents before issuing the SMB GetInfo request.


Software versions (Debian GNU/Linux):

* linux-image-4.15.0-3-amd64 4.15.17-1
* gvfs-daemons 1.36.1-1
* gvfs-fuse 1.36.1-1
* gvfs-backends 1.36.1-1
* libsmbclient 2:4.7.4+dfsg-2

Windows server version: Hyper-V Core Server 2012 R2
Comment 1 Ian Abbott 2018-05-04 14:51:47 UTC
Created attachment 371674 [details]
Wireshark capture
Comment 2 Ian Abbott 2018-05-08 10:35:45 UTC
FYI, an SMB2 GetInfo request with info level SMB2_FILE_ALL_INFO (these are as displayed by Wireshark) is officially called an SMB2 QUERY_INFO request with InfoType = SMB2_0_INFO_FILE and FileInfoClass = FileAllInformation.  The request failed because the SMB2 Create request's DesiredAccess bitmask did not have the FILE_READ_ATTRIBUTES bit set.
Comment 3 Ondrej Holy 2018-05-09 11:03:42 UTC
Thanks for your report, so O_RDWR instead O_WRONLY should fix it for Windows servers, shouldn't it? Can you please test that the following patch fixes the issue for you? I hope that O_RDWR doesn't have some limitations...
Comment 4 Ondrej Holy 2018-05-09 11:04:00 UTC
Created attachment 371836 [details] [review]
smb: Use O_RDWR to fix fstat when writing

fstat fails with EINVAL on Windows servers if O_WRONLY is used to open
(though it works properly on SAMBA servers). O_RDWR is needed to make
it work. This causes issues when copying files over gvfsd-fuse among
others.
Comment 5 Ian Abbott 2018-05-10 14:12:40 UTC
Thanks for the patch, it seems to work fine[*], although I don't know if changing O_WRONLY to O_RDWR would cause issues elsewhere.

[*] I applied the patch to the gnome-3-28 branch rather than the master branch as it was easier to sort out the dependencies on my Debian testing system that way.  I couldn't figure out how to run gvfsd-smb from the build directory manually properly, so I backed up my original /usr/lib/gvfs/gvfsd-smb and overwrote it with the test version.  (I also had to install libgvfscommon.so and libgvfsdaemon.so into /usr/local/lib and run ldconfig.)

I will attach the relevant part of the log for the part where I copied a test file to the Windows server.
Comment 6 Ian Abbott 2018-05-10 14:33:13 UTC
Created attachment 371901 [details]
gvfsd log after applying "smb: Use O_RDWR to fix fstat when writing" patch

This is the portion of the output from 	`GVFS_DEBUG=10 GVFS_DEBUG_FUSE=10 GVFS_SMB_DEBUG=10 /usr/lib/gvfs/gvfsd --replace -d 2>&1` (after patching gvfsd-smb) related to copying the file `foo.txt` to the server.

As can be seen, the two 'vfs_getattr' requests (for file 'foo.txt') before the vfs_create fail because a remote file with that name does not exist (I don't know why there is more than one 'vfs_getattr' request!). The 'vfs_create' succeeds, and the 'vfs_getattr' after the 'vfs_create' now succeeds where it was failing before the patch was applied.


Differences in file creation parameters....

Before patch:

map_open_params_to_ntcreate: fname = \foo.txt, deny_mode = 0x41, open_func = 0x10
map_open_params_to_ntcreate: file \foo.txt, access_mask = 0x120116, share_mode = 0x3, create_disposition = 0x2, create_options = 0x40 private_flags = 0x0

After patch:

map_open_params_to_ntcreate: fname = \foo.txt, deny_mode = 0x42, open_func = 0x10
map_open_params_to_ntcreate: file \foo.txt, access_mask = 0x12019f, share_mode = 0x3, create_disposition = 0x2, create_options = 0x40 private_flags = 0x0
Comment 7 Ondrej Holy 2018-05-14 12:14:09 UTC
Thanks for testing, hopefuly, it won't break anything else.

Attachment 371836 [details] pushed as 3f6f906 - smb: Use O_RDWR to fix fstat when writing

I am going to push in gnome-3-28 as well.