This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679]


As the underlying getcwd syscall, starting with linux commit
v2.6.36-rc1~96^2~2, may succeed without returning an absolute path,
check for the path returned by syscall and fail with EACCES if the path
is not absolute.

[BZ #22679]
* sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Set errno to EACCES and
return NULL if the path returned by getcwd syscall is not absolute.
* sysdeps/unix/sysv/linux/tst-getcwd-abspath.c: New test.
* sysdeps/unix/sysv/linux/Makefile (tests): Add tst-getcwd-abspath.
---
 ChangeLog                                    |  8 ++++
 sysdeps/unix/sysv/linux/Makefile             |  2 +-
 sysdeps/unix/sysv/linux/getcwd.c             | 10 +++++
 sysdeps/unix/sysv/linux/tst-getcwd-abspath.c | 59 ++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-getcwd-abspath.c

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 8f19e0e..34c5c39 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -45,7 +45,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
-	 tst-rlimit-infinity
+	 tst-rlimit-infinity tst-getcwd-abspath
 
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c
index f545106..2a4320d 100644
--- a/sysdeps/unix/sysv/linux/getcwd.c
+++ b/sysdeps/unix/sysv/linux/getcwd.c
@@ -78,6 +78,16 @@ __getcwd (char *buf, size_t size)
   retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size);
   if (retval >= 0)
     {
+      if (retval == 0 || path[0] != '/')
+	{
+#ifndef NO_ALLOCATION
+	  if (buf == NULL && size == 0)
+	    free (path);
+#endif
+	  __set_errno (EACCES);
+	  return NULL;
+	}
+
 #ifndef NO_ALLOCATION
       if (buf == NULL && size == 0)
 	/* Ensure that the buffer is only as large as necessary.  */
diff --git a/sysdeps/unix/sysv/linux/tst-getcwd-abspath.c b/sysdeps/unix/sysv/linux/tst-getcwd-abspath.c
new file mode 100644
index 0000000..2a81bbd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-getcwd-abspath.c
@@ -0,0 +1,59 @@
+/* BZ #22679 getcwd(3) does not succeed without returning an absolute path.
+
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+static char *chroot_dir;
+
+/* The actual test.  Run it in a subprocess, so that the test harness
+   can remove the temporary directory in --direct mode.  */
+static void
+getcwd_callback (void *closure)
+{
+  xchroot (chroot_dir);
+  errno = 0;
+  char *cwd = getcwd (NULL, 0);
+  TEST_VERIFY (cwd == NULL);
+  TEST_VERIFY (errno == EACCES);
+  _exit (0);
+}
+
+static int
+do_test (void)
+{
+  support_become_root ();
+  if (!support_can_chroot ())
+    return EXIT_UNSUPPORTED;
+
+  chroot_dir = support_create_temp_directory ("tst-getcwd-abspath-");
+  support_isolate_in_subprocess (getcwd_callback, NULL);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
ldv


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]