From patchwork Sun Jan 7 12:41:45 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: 25261 Received: (qmail 89283 invoked by alias); 7 Jan 2018 12:41:50 -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 89274 invoked by uid 89); 7 Jan 2018 12:41:49 -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= X-HELO: vmicros1.altlinux.org Date: Sun, 7 Jan 2018 15:41:45 +0300 From: "Dmitry V. Levin" To: libc-alpha@sourceware.org Subject: [PATCH v2] linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679] Message-ID: <20180107124145.GB13196@altlinux.org> Mail-Followup-To: libc-alpha@sourceware.org References: <20180107030543.GA7248@altlinux.org> <20180107113348.GA11932@altlinux.org> <87shbhvp0l.fsf@linux-m68k.org> <20180107123631.GA13196@altlinux.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20180107123631.GA13196@altlinux.org> 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 fall back to generic_getcwd if the path is not absolute. [BZ #22679] * sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to generic_getcwd 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 | 8 ++-- sysdeps/unix/sysv/linux/tst-getcwd-abspath.c | 58 ++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 5 deletions(-) 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 b1fe960..88ecb08 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -51,7 +51,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 + test-errno-linux tst-getcwd-abspath # Generate the list of SYS_* macros for the system calls (__NR_* macros). diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c index 3b556fd..f485de8 100644 --- a/sysdeps/unix/sysv/linux/getcwd.c +++ b/sysdeps/unix/sysv/linux/getcwd.c @@ -76,7 +76,7 @@ __getcwd (char *buf, size_t size) int retval; retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size); - if (retval >= 0) + if (retval > 0 && path[0] == '/') { #ifndef NO_ALLOCATION if (buf == NULL && size == 0) @@ -92,10 +92,10 @@ __getcwd (char *buf, size_t size) return buf; } - /* The system call cannot handle paths longer than a page. - Neither can the magic symlink in /proc/self. Just use the + /* The system call either cannot handle paths longer than a page + or can succeed without returning an absolute path. Just use the generic implementation right away. */ - if (errno == ENAMETOOLONG) + if (retval >= 0 || errno == ENAMETOOLONG) { #ifndef NO_ALLOCATION if (buf == NULL && size == 0) 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..69c5366 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-getcwd-abspath.c @@ -0,0 +1,58 @@ +/* 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_EXIT (cwd == NULL && errno == ENOENT); + _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