Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSHFS always follows symbolic links (even for eg. lchown) #105

Open
lapsio opened this issue Nov 1, 2017 · 8 comments
Open

SSHFS always follows symbolic links (even for eg. lchown) #105

lapsio opened this issue Nov 1, 2017 · 8 comments
Labels

Comments

@lapsio
Copy link

lapsio commented Nov 1, 2017

https://pastebin.com/fH356wkk

when symlink is copied over SSHFS it results in error "Permission denied" (if file exists on host and sshfs user doesn't have permission to it) or "No such file or directory" (if it doesn't) while performing the same operation on local filesystem results with success. It breaks scripts basing on return codes.

Simple example with /etc/shadow:

lapsio@linux-qzuq ~> ln -s /etc/shadow ./shadlink
lapsio@linux-qzuq ~> cp --preserve=all -Rnv shadlink ./shadlink2 
‘shadlink’ -> ‘./shadlink2’
lapsio@linux-qzuq ~> file shadlink2
shadlink2: symbolic link to `/etc/shadow'
lapsio@linux-qzuq ~> cp --preserve=all -Rnv shadlink ~/SSHFS/lap/home/lapsio/shadlink3 ‘shadlink’ -> ‘/home/lapsio/SSHFS/lap/home/lapsio/shadlink3’
cp: failed to preserve ownership for /home/lapsio/SSHFS/lap/home/lapsio/shadlink3: Permission denied
lapsio@linux-qzuq ~> file ~/SSHFS/lap/home/lapsio/shadlink3 
/home/lapsio/SSHFS/lap/home/lapsio/shadlink3: symbolic link to `/etc/shadow'
@g-raud
Copy link
Contributor

g-raud commented Mar 23, 2018

Most probably the SFTP server calls chown(2) to set the ownership, which attempts to set ownership of the target of the symlink (contratry to lchown(2)).

The SFTP command SETSTAT (https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6) does not provide a way to explicitely request a "lchown".

@Nikratio
Copy link
Contributor

I agree with g-raud. I'm not sure if there's a way to improve the behavior. At first I thought that maybe we should just not translate lchown to chown - but this translation actually happens in the kernel. sshfs just gets an inode, and can't tell if the original call was chown or lchown.

@Nikratio Nikratio changed the title sshfs behaves weird on symlinks lchown() syscalls become chown() SFTP commands Mar 28, 2018
@Nikratio Nikratio added the bug label Mar 28, 2018
@Nikratio Nikratio changed the title lchown() syscalls become chown() SFTP commands SSHFS always follows symbolic links (even for eg. lchown) Aug 15, 2021
@Nikratio
Copy link
Contributor

See also issue #250 for the related problem when setting other inode attributes.

@baryluk
Copy link

baryluk commented Aug 17, 2021

Copying my comment from issue #250

There is an OpenSSH extension (and almost everybody uses OpenSSH so that is enough) to support this.

[email protected]. It was added in OpenSSH 8.0, in 2019.

3.7. sftp: Extension request "[email protected]"

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		"[email protected]"
	string		path
	ATTRS		attrs

See the "setstat" command for more details.

This extension is advertised in the SSH_FXP_VERSION hello with version
"1".

@nh2
Copy link

nh2 commented Nov 8, 2023

I was just about to file a new issue titled

Security: fchownat(..., AT_SYMLINK_) follows symlink anyway

when I discovered this existing issue.

Posting what I wanted to post there here for googleability:


I found that sshfs silently ignores AT_SYMLINK_. This can be a security issue because an admin/script that uses e.g. chown -R --no-dereference to avoid following symlinks is led to believe that their invocation works, when it fact it does the opposite of wha they expect.

Repro:

# Create sshfs mount with a symlink pointing to a file
mkdir -p sshfs-dir
touch sshfs-dir/myfile
ln -s myfile sshfs-dir/link-to-myfile

mkdir -p sshfs-mount
sshfs localhost:sshfs-dir sshfs-mount

chown --no-dereference $(whoami):wheel sshfs-mount/link-to-myfile

ls -l sshfs-dir
# Now `myfile` is owned by group `wheel` -- it followed the symlink despite `--no-dereference`!

Another repro that shows that AT_SYMLINK_ is ignored even in the case that the symlink target does NOT exist:

mkdir -p sshfs-dir
mkdir -p sshfs-mount
sshfs localhost:sshfs-dir sshfs-mount
ln -s nowhere sshfs-mount/symlink-pointing-nowhere

chown --no-dereference $USER sshfs-dir/symlink-pointing-nowhere  # works as expected

chown --no-dereference $USER sshfs-mount/symlink-pointing-nowhere

# The last command fails incorrectly with:
#     chown: changing ownership of 'sshfs-mount/symlink-pointing-nowhere': No such file or directory

# `strace -fye newfstatat,fchownat` on the last command shows that it's not `chown`'s fault,
# it simply reports what the kernel and `sshfs` return:
#
#     newfstatat(AT_FDCWD</home/niklas>, "sshfs-mount/symlink-pointing-nowhere", {st_mode=S_IFLNK|0777, st_size=7, ...}, AT_SYMLINK_) = 0
#     fchownat(AT_FDCWD</home/niklas>, "sshfs-mount/symlink-pointing-nowhere", 1000, -1, AT_SYMLINK_) = -1 ENOENT (No such file or directory)
#
# The `newfstatat()` proves that the symlink exists, so returning `ENOENT` is wrong.
# That `fchownat` result should be the same as when run against `sshfs-dir`:
#
#     fchownat(AT_FDCWD</home/niklas>, "sshfs-dir/symlink-pointing-nowhere", 1000, -1, AT_SYMLINK_) = 0

@nh2
Copy link

nh2 commented Nov 8, 2023

This can be a security issue because an admin/script [..] is led to believe that their invocation works, when it fact it does the opposite

Wouldn't it be safer from a security perspective that sshfs should fail loudly when AT_SYMLINK_ is used, when sshfs cannot implement it?

@Nikratio
Copy link
Contributor

Nikratio commented Nov 9, 2023

This can be a security issue because an admin/script [..] is led to believe that their invocation works, when it fact it does the opposite

Wouldn't it be safer from a security perspective that sshfs should fail loudly when AT_SYMLINK_ is used, when sshfs cannot implement it?

Absolutely, yes.

I don't see how it could be implemented though. As far as I know, things like AT_SYMLINK_ are handled by the kernel (same as chown vs lchown etc). So SSHFS has no idea what the original request was.

@powellnorma
Copy link

As far as I know, things like AT_SYMLINK_ are handled by the kernel (same as chown vs lchown etc). So SSHFS has no idea what the original request was.

Maybe it would make sense to create an upstream kernel bug / feature request, so this can be tracked?
https://www.kernel.org/doc/html/v4.19/admin-guide/reporting-bugs.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants