diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2017-09-15 11:31:13 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2017-09-25 18:04:16 -0700 |
commit | ccf970c7a77e86f4f5ef8ecc5e637114b1c0136a (patch) | |
tree | 93ab076d7a0c47a6f52fb79ca8b22e7579528ffa /sysdeps/unix/sysv/linux/alpha | |
parent | b4396163aa8666f970aaf43eaca25f3a92b18c1b (diff) | |
download | glibc-ccf970c7a77e86f4f5ef8ecc5e637114b1c0136a.tar.gz glibc-ccf970c7a77e86f4f5ef8ecc5e637114b1c0136a.tar.xz glibc-ccf970c7a77e86f4f5ef8ecc5e637114b1c0136a.zip |
posix: Add compat glob symbol to not follow dangling symbols
This patch follows commit 5554304f0 (posix: Allow glob to match dangling symlinks [BZ #866]) by adding a compat symbol that follow previous semantic of not following dangling symlinks and thus avoiding call gl_lstat with GLOB_ALTDIRFUNC. It avoids failure with old binaries that not set the alternate function pointer for lstat (GNUmake for instance). The following scenario, for instance, fails with current GNUmake because glibc will access unitialized memory when calling gl_lstat: $ cat src/t/t.c int main () { return 0; } $ cat Makefile SRC = $(wildcard src/*/t.c) OBJ = $(patsubst src/%.c, obj/%.o, $(SRC)) prog: $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) $(OBJ) -o prog obj/%.o: src/%.c $(CC) $(CFLAGS) -c $< -o $@ $ make This works as expected with the patch applied. Since it is for generic ABI, default compat symbols are added with override for Linux due LFS. Now we have two compat symbols for glob on Linux: 1. sysdeps/unix/sysv/linux/oldglob.c which implements glob64 with the old dirent layout. For this implementation I also set it to not follow dangling symlinks (which is the safest path). 2. sysdeps/unix/sysv/linux/glob{64}-lstat-compat.c which implements the compat symbol for dangling symlinks. As for generic glob, the implementation uses XSTAT_IS_XSTAT64 to define whether both __glob_lstat_compat and __glob64_lstat_compat should be different implementations. For archictures that define XSTAT_IS_XSTAT64, __glob_lstat_compat is aliased to __glob64_lstat_compat. 3. sysdeps/unix/sysv/linux/alpha/oldglob.c with a different glob_t layout. As for 1. this patch changes it to not follow dangling symlinks. The patch also bumps _GNU_GLOB_INTERFACE_VERSION to 2 to advertise the new semantic. On GNUmake, for instance, it will force to it use its internal glob implementation instead and avoiding triggering the same failure on builds against newer GLIBCs. Checked on x86_64-linux-gnu and i686-linux-gnu. I also checked with a build against the major ABIs required to check for the abilist. The changes should also work on gnulib (I run gnulib-tool.py check glob and it shown no regressions). [BZ #22183] * include/gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): Increase version to 2. * posix/Makefile (routines): Add glob-lstat-compat and glob64-lstat-compat. * posix/Versions (GLIBC_2.27, glob, glob64): Add symbol version. * posix/glob-lstat-compat.c: New file. * posix/glob64-lstat-compat.c: Likewise. * posix/tst-glob_lstat_compat.c: Likewise. * sysdeps/unix/sysv/linux/glob-lstat-compat.c: Likewise. * sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c: Likewise. * sysdeps/unix/sysv/linux/glob64-lstat-compat.c: Likewise. * sysdeps/unix/sysv/linux/alpha/glob.c: Remove file. * posix/glob.c (glob_lstat): New function. (glob): Rename to __glob and add versioned symbol to 2.27. (glob_in_dir): Use glob_lstat. * posix/glob64.c (glob64): Add GLOB_ATTRIBUTE. * sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/glob.c (glob): Add versioned symbol for 2.27. * sysdeps/unix/sysv/linux/glob64.c (glob64): Likewise. * sysdeps/unix/sysv/linux/oldglob.c (GLOB_NO_LSTAT): Define. * sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Do not use gl_lstat on glob call. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add GLIBC_2.27 glob and glob64 symbols. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise. * sysdeps/unix/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
Diffstat (limited to 'sysdeps/unix/sysv/linux/alpha')
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/glob.c | 47 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/libc.abilist | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/oldglob.c | 6 |
4 files changed, 9 insertions, 49 deletions
diff --git a/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c new file mode 100644 index 0000000000..a76471d4df --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c @@ -0,0 +1,2 @@ +#define GLOB_LSTAT_VERSION GLIBC_2_1 +#include <sysdeps/unix/sysv/linux/glob-lstat-compat.c> diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/alpha/glob.c deleted file mode 100644 index 1b813c1cfd..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/glob.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 1998-2017 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 - <http://www.gnu.org/licenses/>. */ - -#define glob64 __no_glob64_decl -#define globfree64 __no_globfree64_decl - -#include <sys/types.h> -#include <glob.h> -#include <shlib-compat.h> - -/* For Linux/Alpha we have to make the glob symbols versioned. */ -#define glob(pattern, flags, errfunc, pglob) \ - __new_glob (pattern, flags, errfunc, pglob) -#define globfree(pglob) \ - __new_globfree (pglob) - -/* We need prototypes for these new names. */ -extern int __new_glob (const char *__pattern, int __flags, - int (*__errfunc) (const char *, int), - glob_t *__pglob); -extern void __new_globfree (glob_t *__pglob); - -#include <posix/glob.c> - -#undef glob -#undef globfree -#undef glob64 -#undef globfree64 - -versioned_symbol (libc, __new_glob, glob, GLIBC_2_1); -libc_hidden_ver (__new_glob, glob) - -weak_alias (__new_glob, glob64) diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index fab73317ca..4836ea0374 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2014,6 +2014,9 @@ GLIBC_2.26 preadv64v2 F GLIBC_2.26 pwritev2 F GLIBC_2.26 pwritev64v2 F GLIBC_2.26 reallocarray F +GLIBC_2.27 GLIBC_2.27 A +GLIBC_2.27 glob F +GLIBC_2.27 glob64 F GLIBC_2.3 GLIBC_2.3 A GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F diff --git a/sysdeps/unix/sysv/linux/alpha/oldglob.c b/sysdeps/unix/sysv/linux/alpha/oldglob.c index 988c92ba45..b54624c611 100644 --- a/sysdeps/unix/sysv/linux/alpha/oldglob.c +++ b/sysdeps/unix/sysv/linux/alpha/oldglob.c @@ -59,7 +59,9 @@ __old_glob (const char *pattern, int flags, correct.gl_closedir = pglob->gl_closedir; correct.gl_readdir = pglob->gl_readdir; correct.gl_opendir = pglob->gl_opendir; - correct.gl_lstat = pglob->gl_lstat; + /* Set gl_lstat and gl_stat for both gl_stat for compatibility with old + implementation that did not follow dangling symlinks. */ + correct.gl_lstat = pglob->gl_stat; correct.gl_stat = pglob->gl_stat; result = glob (pattern, flags, errfunc, &correct); @@ -72,7 +74,7 @@ __old_glob (const char *pattern, int flags, pglob->gl_closedir = correct.gl_closedir; pglob->gl_readdir = correct.gl_readdir; pglob->gl_opendir = correct.gl_opendir; - pglob->gl_lstat = correct.gl_lstat; + /* Only need to restore gl_stat. */ pglob->gl_stat = correct.gl_stat; return result; |