Bug 2428 - realpath command doesn't work
Summary: realpath command doesn't work
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: Build system (show other bugs)
Version: 6.9p1
Hardware: amd64 Linux
: P5 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_7_0
  Show dependency treegraph
 
Reported: 2015-07-15 00:25 AEST by David Kahles
Modified: 2015-08-11 23:05 AEST (History)
2 users (show)

See Also:


Attachments
The configure command after running 'autoreconf -fi' (27.08 KB, text/x-log)
2015-07-15 00:25 AEST, David Kahles
no flags Details
The ouput of 'make' (173.51 KB, text/plain)
2015-07-15 00:27 AEST, David Kahles
no flags Details
The logged output of the sftp-server when the problem occurs (4.44 KB, text/x-log)
2015-07-15 00:28 AEST, David Kahles
no flags Details
My sshd_config file (3.84 KB, application/octet-stream)
2015-07-15 00:29 AEST, David Kahles
no flags Details
Check if realpath works with non-existent files. (1.22 KB, patch)
2015-07-15 11:50 AEST, Darren Tucker
no flags Details | Diff
Makefile after patch applied (23.86 KB, text/plain)
2015-07-16 07:04 AEST, David Kahles
no flags Details
Use compat realpath if native one does not work with non-existent files. (1.86 KB, patch)
2015-07-16 08:45 AEST, Darren Tucker
djm: ok+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Kahles 2015-07-15 00:25:45 AEST
Created attachment 2665 [details]
The configure command after running 'autoreconf -fi'

I use libssh to access a server via sftp, but the issue is not related to libssh according to the logs.

How to reproduce:
"/home/david/test" exists, but "/home/david/test/test" doesn't exist. When I canonicalize "/home/david/test/test" using the SSH_FXP_REALPATH command it doesn't work and reports "no such file".
I did also compile OpenSSH from git, see the attached files.

Expected result:
Canonicalizing "/home/david/test/test" works, according to [1]

Notes:
Further investigation showed that the libc realpath function is linked, and not the included OpenBSD one. The included realpath function works fine, but the libc one doesn't. As far as I understand the build system, the OpenBSD realpath function should not be used on linux, but the libc realpath function seems not to work.
Or is the realpath function not supposed to work if the file doesn't exist?

System: Up-to-date Archlinux
GCC 5.1.0
make 4.1
glibc 2.21

[1]: http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt, page 17: "...canonicalize any given path name..."
Comment 1 David Kahles 2015-07-15 00:27:01 AEST
Created attachment 2666 [details]
The ouput of 'make'
Comment 2 David Kahles 2015-07-15 00:28:37 AEST
Created attachment 2667 [details]
The logged output of the sftp-server when the problem occurs
Comment 3 David Kahles 2015-07-15 00:29:05 AEST
Created attachment 2668 [details]
My sshd_config file
Comment 4 Darren Tucker 2015-07-15 09:58:23 AEST
The only platform that sets BROKEN_REALPATH is AIX, not Linux, and I can't remember what the reason for that one was offhand.

The OpenBSD man page says ("All but the last component of pathname must exist when realpath() is called."

The POSIX spec (http://pubs.opengroup.org/onlinepubs/009695399/functions/realpath.html) says that it can return ENOENT if "a component of file_name does not name an existing file".

but it also says:

"IEEE Std 1003.1-2001/Cor 2-2004, item XSH/TC2/D6/110 is applied, updating the ERRORS section to refer to the file_name argument, rather than a nonexistent path argument."

so it looks like earlier versions of the spec allowed (or in fact specified, depending on how you read it) the OpenBSD behaviour.

The filexfer (v3) spec is silent on the question of what to do in the case of a non-existent file.  Later versions[1] punt on this by adding an optional flag to select either behaviour, but the default is to not check  for the existence of the file, so you could argue that this is the behaviour openssh should have.

[1] https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13
Comment 5 Darren Tucker 2015-07-15 11:50:47 AEST
Created attachment 2669 [details]
Check if realpath works with non-existent files.

Here's a patch to check for this behaviour at build time.   If you try it you'll need to run "autoreconf" to rebuild configure before running it.
Comment 6 David Kahles 2015-07-16 07:03:23 AEST
Thank you for the patch, it changes config.h to contain
#define BROKEN_REALPATH 1
but unfortunately it still doesn't work. There seems to be a linker problem. The openbsd realpath function gets build (I checked it with a #pragma message), but it seems as the libc version gets linked. I copied the openbsd function, renamed it and executed it when the libc function failed, and the result was as expected: the openbsd function didn't fail.
But I wonder why the libc version gets linked, as the openbsd one should overwrite it? I attach the Makefile, but it seems to be right.
I tried it also with gcc 4.9.2 - no difference.
Do you have a clue what's going wrong?

PS: of course I reconfigured and rebuild the whole project after applying the patch.
Comment 7 David Kahles 2015-07-16 07:04:47 AEST
Created attachment 2671 [details]
Makefile after patch applied
Comment 8 Darren Tucker 2015-07-16 08:26:56 AEST
Comment on attachment 2671 [details]
Makefile after patch applied

That's weird, we do that kind of thing all the time.  I'll see if I can figure out what's going on.
Comment 9 Darren Tucker 2015-07-16 08:34:57 AEST
Ah, I see what happened:

$ nm sftp-server | grep realpath
00003060 t process_realpath
         U __realpath_chk@@GLIBC_2.4

That symbol is the checked version of realpath enabled by -DFORTIFY_SOURCE=2.  If I remove that from the Makefile:

$ nm sftp-server | grep realpath00003030 t process_realpath
0000e280 T realpath
Comment 10 Darren Tucker 2015-07-16 08:45:55 AEST
Created attachment 2672 [details]
Use compat realpath if native one does not work with non-existent files.

This seems to behave as expected:

$ nm sftp-server | grep realpath
00003090 t process_realpath
0000e610 T _ssh_compat_realpath
Comment 11 David Kahles 2015-07-16 17:37:16 AEST
Thank you, this works well :-)
Will it be included in the next OpenSSH release?
Comment 12 Darren Tucker 2015-07-16 19:02:50 AEST
Comment on attachment 2672 [details]
Use compat realpath if native one does not work with non-existent files.

Probably.  Damien, what do you think?
Comment 13 Darren Tucker 2015-07-17 13:01:01 AEST
Patch applied, it will be in the 7.0p1 release.  Thanks.
Comment 14 David Kahles 2015-07-17 17:11:46 AEST
Thank you too.
Comment 15 Damien Miller 2015-08-11 23:05:23 AEST
Set all RESOLVED bugs to CLOSED with release of OpenSSH 7.1