From patchwork Sun Jan 7 03:05:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dmitry V. Levin" X-Patchwork-Id: 25258 Received: (qmail 111357 invoked by alias); 7 Jan 2018 03:05:52 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 111331 invoked by uid 89); 7 Jan 2018 03:05:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=7816 X-HELO: vmicros1.altlinux.org Date: Sun, 7 Jan 2018 06:05:43 +0300 From: "Dmitry V. Levin" To: libc-alpha@sourceware.org Subject: [PATCH] linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679] Message-ID: <20180107030543.GA7248@altlinux.org> Mail-Followup-To: libc-alpha@sourceware.org MIME-Version: 1.0 Content-Disposition: inline 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 + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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