I verified using an expirement (see below) that the modern glibc wrapper
getcwd() actually never returns "(unreachable)". I have also read the
modern glibc sources for all three functions documented here. None of
them return "(unreachable)".
Now let me describe my expirement:
d-user@comp:/tmp$ cat getcwd.c
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int
main(void)
{
char buf[1000];
if (syscall(SYS_getcwd, buf, sizeof(buf)) == -1)
perror("SYS_getcwd");
else
printf("SYS_getcwd: %s\n", buf);
if (getcwd(buf, sizeof(buf)) == NULL)
perror("getcwd");
else
printf("getcwd: %s\n", buf);
return 0;
}
d-user@comp:/tmp$ gcc -Wall -Wextra -o getcwd getcwd.c
d-user@comp:/tmp$ sudo unshare --mount bash
d-root@comp:/tmp# mkdir /tmp/dir
d-root@comp:/tmp# mount -t tmpfs tmpfs /tmp/dir
d-root@comp:/tmp# cd /tmp/dir
d-root@comp:/tmp/dir# umount -l .
d-root@comp:/tmp/dir# /tmp/getcwd
SYS_getcwd: (unreachable)/
getcwd: No such file or directory
d-root@comp:/tmp/dir# exit
exit
Link: <https://sourceware.org/bugzilla/show_bug.cgi?id=18203>
Link: <https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=
52a713fdd0a30e1bd79818e2e3c4ab44ddca1a94>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Signed-off-by: Askar Safin <safinaskar@zohomail.com>
Message-ID: <
20250220091926.
3985504-2-safinaskar@zohomail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Such behavior can also be caused by an unprivileged user by changing
the current directory into another mount namespace.
When dealing with pathname from untrusted sources, callers of the
-functions described in this page
+functions described in this page (before glibc 2.27)
+or the raw
+.BR getcwd ()
+system call
should consider checking whether the returned pathname starts
with '/' or '(' to avoid misinterpreting an unreachable path
as a relative pathname.