Mailing List Archive

sftp rename not atomic on freebsd/aix with sticky bit enabled
Hello list,

we've recently came across an interesting problem on one of our AIX
systems which we were unable to reproduce on Linux host but we
discovered that FreeBSD (11) is showing the same behaviour.

Preparation:
- on AIX/FreeBSD system inside /tmp with the standard 1777
permissions create an empty file
touch foofile
chmod 600 foofile
chown root:system foofile

To reproduce:
- in WinSCP login as a regular (non-root) user, browse to /tmp
- navigate to /tmp/foofile, bring up a context menu (right-click),
select Rename (F2)
- receive a pop-up "Permission denied", click Abort
- refresh directory listing
- notice a new barfile (hardlink to foofile)

Expectation:
- hardlink should not be present (rename is supposed to be atomic
hence either it is processed fully or not at all).

It all comes down to a different behaviour of ln (link) on different systems:
# AIX/FreeBSD, regular user inside /tmp
ln foofile barfile # rc=0; link is created

# Linux
ln foofile barfile # rc=1 (error: Operation not permitted); link is not created

Due to the directory having sticky bit on, the operation of renaming
for AIX/FreeBSD fails in the very last stage (unlink), leaving a file
behind.

As a workaround posix-rename (which is not race-free) could be used
but there seems to be a limited support among GUI clients (for WinSCP
there is a ticket opened to add this feature:
https://winscp.net/tracker/2231).

Is there a way to address this problem in OpenSSH code-base?

Thank you,

jose
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: sftp rename not atomic on freebsd/aix with sticky bit enabled [ In reply to ]
On Fri, 1 Dec 2023, Jozef Riha wrote:

> Hello list,
>
> we've recently came across an interesting problem on one of our AIX
> systems which we were unable to reproduce on Linux host but we
> discovered that FreeBSD (11) is showing the same behaviour.
>
> Preparation:
> - on AIX/FreeBSD system inside /tmp with the standard 1777
> permissions create an empty file
> touch foofile
> chmod 600 foofile
> chown root:system foofile
>
> To reproduce:
> - in WinSCP login as a regular (non-root) user, browse to /tmp
> - navigate to /tmp/foofile, bring up a context menu (right-click),
> select Rename (F2)
> - receive a pop-up "Permission denied", click Abort
> - refresh directory listing
> - notice a new barfile (hardlink to foofile)
>
> Expectation:
> - hardlink should not be present (rename is supposed to be atomic
> hence either it is processed fully or not at all).
>
> It all comes down to a different behaviour of ln (link) on different systems:
> # AIX/FreeBSD, regular user inside /tmp
> ln foofile barfile # rc=0; link is created
>
> # Linux
> ln foofile barfile # rc=1 (error: Operation not permitted); link is not created
>
> Due to the directory having sticky bit on, the operation of renaming
> for AIX/FreeBSD fails in the very last stage (unlink), leaving a file
> behind.
>
> As a workaround posix-rename (which is not race-free) could be used
> but there seems to be a limited support among GUI clients (for WinSCP
> there is a ticket opened to add this feature:
> https://winscp.net/tracker/2231).
>
> Is there a way to address this problem in OpenSSH code-base?

I doubt it - sftp-server already tries to clean up when a legacy rename
operation fails. See the logic starting here:

https://github.com/openssh/openssh-portable/blob/V_9_5_P1/sftp-server.c#L1285

If file permissions are preventing this then there isn't anything more it
can do AFAIK. The SSH2_FXP_RENAME operation was just badly specified in
the sftp protocol, which is why we added posix-rename.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: sftp rename not atomic on freebsd/aix with sticky bit enabled [ In reply to ]
On Sat, Dec 2, 2023 at 1:40?AM Damien Miller <djm@mindrot.org> wrote:
>
> On Fri, 1 Dec 2023, Jozef Riha wrote:
>
> > Hello list,
> >
> > we've recently came across an interesting problem on one of our AIX
> > systems which we were unable to reproduce on Linux host but we
> > discovered that FreeBSD (11) is showing the same behaviour.
> >
> > Preparation:
> > - on AIX/FreeBSD system inside /tmp with the standard 1777
> > permissions create an empty file
> > touch foofile
> > chmod 600 foofile
> > chown root:system foofile
> >
> > To reproduce:
> > - in WinSCP login as a regular (non-root) user, browse to /tmp
> > - navigate to /tmp/foofile, bring up a context menu (right-click),
> > select Rename (F2)
> > - receive a pop-up "Permission denied", click Abort
> > - refresh directory listing
> > - notice a new barfile (hardlink to foofile)
> >
> > Expectation:
> > - hardlink should not be present (rename is supposed to be atomic
> > hence either it is processed fully or not at all).
> >
> > It all comes down to a different behaviour of ln (link) on different systems:
> > # AIX/FreeBSD, regular user inside /tmp
> > ln foofile barfile # rc=0; link is created
> >
> > # Linux
> > ln foofile barfile # rc=1 (error: Operation not permitted); link is not created
> >
> > Due to the directory having sticky bit on, the operation of renaming
> > for AIX/FreeBSD fails in the very last stage (unlink), leaving a file
> > behind.
> >
> > As a workaround posix-rename (which is not race-free) could be used
> > but there seems to be a limited support among GUI clients (for WinSCP
> > there is a ticket opened to add this feature:
> > https://winscp.net/tracker/2231).
> >
> > Is there a way to address this problem in OpenSSH code-base?
>
> I doubt it - sftp-server already tries to clean up when a legacy rename
> operation fails. See the logic starting here:
>
> https://github.com/openssh/openssh-portable/blob/V_9_5_P1/sftp-server.c#L1285
>
> If file permissions are preventing this then there isn't anything more it
> can do AFAIK. The SSH2_FXP_RENAME operation was just badly specified in
> the sftp protocol, which is why we added posix-rename.
>
> -d

Hello Damien and thank you for your response.

Looking at it from the user's perspective, when you request an SFTP
server (using an SFTP client) to rename a file, things might not go as
expected under certain conditions: instead of a file rename, you end
up with two files, and unfortunately, you can't get rid of either. You
might find yourself in a situation that you unintentionally caused,
but you'll be unable to rectify.

Most users aren't too concerned with the technicalities of an
operating system - they just want the task at hand to be completed.
While it's understandable that SFTP can't accurately predict the
intricacies of every OS and/or OS variant and the potential issues
with file renaming, it could offer a solution for OS administrators.
Providing a way to force POSIX rename in environments where it makes
sense would be a helpful feature.

I've experimented with "-P rename" passed to sftp-server but this is
not an actual solution as what's truly desired is a forced rename ->
posix-rename translation.

One could argue SFTP clients could be more aware of this potential
problem and take extra measures to prevent it from happening. But
wouldn't it be the best if we have an option to address on both ends -
the server and the clients?

It's worth noting that even Linux systems may face this problem if
fs.protected_hardlinks is set to 0
(https://sysctl-explorer.net/fs/protected_hardlinks/).

jose
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev