SSHFS always follows symlink when setting inode attributes
baryluk opened this issue · 3 comments
Using sshfs 3.7.1+repack-1 from Debian testing, amd64. Linux 5.10.28-1 (from Debian).
Standard mount settings:
baryluk@foobar:/ on /home/user/foobar type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
Somehow similar to #112 , but still is present in current version.
(on sshfs mount)
$ ln -s /bin/ls foo
$ ln -s bar b
$ touch zoo
$ ln -s zoo c
$ ls -l
total 20
drwxr-xr-x 1 user user 4096 May 7 17:35 .
drwxr-xr-x 1 user user 4096 May 7 17:28 ..
lrwxrwxrwx 1 user user 7 May 7 17:28 a -> /bin/ls
lrwxrwxrwx 1 user user 3 May 7 17:35 b -> bar
lrwxrwxrwx 1 user user 3 May 7 17:34 c -> zoo
-rw-r--r-- 1 user user 0 May 7 17:34 zoo
$
$ touch -h a
touch: setting times of 'a': Permission denied
$ touch -h b
touch: setting times of 'b': No such file or directory
$ touch -h c
$
It looks like sshfs is following symlink, even if it is requested to not do that.
This causes issues for example with dpkg-deb -x
unpacking to sshfs file system (it uses tar -x -p -f -
, that often does call utimesat on symlinks to absolute paths):
utimensat(AT_FDCWD, "./lib64/ld-linux-x86-64.so.2", [UTIME_OMIT, {tv_sec=1619902566, tv_nsec=0} /* 2021-05-01T20:56:06+0000 */], AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
Where ./usr/share/doc/libstdc++6
does in fact exist, and is a symlinking point to actually existing file:
$ stat ./lib64/ld-linux-x86-64.so.2
File: ./lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.31.so
Size: 32 Blocks: 8 IO Block: 4096 symbolic link
Device: 3dh/61d Inode: 2612 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1000/ user) Gid: ( 1000/ user)
Access: 2021-05-07 17:39:23.000000000 +0000
Modify: 2021-05-07 17:39:23.000000000 +0000
Change: 2021-05-07 17:39:23.000000000 +0000
Birth: -
$ stat /lib/x86_64-linux-gnu/ld-2.31.so
File: /lib/x86_64-linux-gnu/ld-2.31.so
Size: 177928 Blocks: 352 IO Block: 4096 regular file
Device: 1bh/27d Inode: 17868 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-05-02 08:15:26.000000000 +0000
Modify: 2021-05-01 20:56:06.000000000 +0000
Change: 2021-05-02 08:15:31.488745282 +0000
Birth: -
However, it is true that the symlink if interpreted from the mountpoint, doesn't exist:
ls: cannot access '/home/user/foobar/lib/x86_64-linux-gnu/ld-2.31.so': No such file or directory
However, it shouldn't matter, because of the AT_SYMLINK_NOFOLLOW
flag. And I don't use -o transform_symlinks
anyway.
Thanks for the report! Yes, this is a bug, but I am not sure if it can be fixed. SSHFS is using the SETSTAT
/FSETSTAT
commands of the SFTP protocol to set file attributes. As far as I can tell, there is no flag that would allow to tell the SFTP server to work on symlinks.
That said, SSHFS still uses an ancient revision of the SFTP protocol - this functionality may well be present in more recent versions. Patches are welcome :-).
It can not be done with SETSTAT
unfortunately, nor with FSETSTAT
.
It is possible to do however using OpenSSH extension: lsetstat@openssh.com
. It was added in OpenSSH 8.0, in 2019.
3.7. sftp: Extension request "lsetstat@openssh.com"
This request is like the "setstat" command, but sets file attributes on
symlinks. It is implemented as a SSH_FXP_EXTENDED request with the
following format:
uint32 id
string "lsetstat@openssh.com"
string path
ATTRS attrs
See the "setstat" command for more details.
This extension is advertised in the SSH_FXP_VERSION hello with version
"1".