diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2022-01-23 21:45:16 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2022-01-25 21:05:15 +0000 |
commit | c8bd4dc8212e43b2f9af08b80df97f90cdb0df4f (patch) | |
tree | 23b7500bdfc19a2ec62157cd271d06a39da098cb /libstdc++-v3/configure | |
parent | ec543c9833c2d9283c035cd8430849eb4ec04406 (diff) | |
download | gcc-c8bd4dc8212e43b2f9af08b80df97f90cdb0df4f.tar.gz |
libstdc++: Avoid symlink race in filesystem::remove_all [PR104161]
This adds a new internal flag to the filesystem::directory_iterator
constructor that makes it fail if the path is a symlink that resolves to
a directory. This prevents filesystem::remove_all from following a
symlink to a directory, rather than deleting the symlink itself.
We can also use that new flag in recursive_directory_iterator to ensure
that we don't follow symlinks if the follow_directory_symlink option is
not set.
This also moves an error check in filesystem::remove_all after the while
loop, so that errors from the directory_iterator constructor are
reproted, instead of continuing to the filesystem::remove call below.
libstdc++-v3/ChangeLog:
PR libstdc++/104161
* acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for
fdopendir.
* config.h.in: Regenerate.
* configure: Regenerate.
* src/c++17/fs_dir.cc (_Dir): Add nofollow flag to constructor
and pass it to base class constructor.
(directory_iterator): Pass nofollow flag to _Dir constructor.
(fs::recursive_directory_iterator::increment): Likewise.
* src/c++17/fs_ops.cc (do_remove_all): Use nofollow option for
directory_iterator constructor. Move error check outside loop.
* src/filesystem/dir-common.h (_Dir_base): Add nofollow flag to
constructor and when it's set use ::open with O_NOFOLLOW and
O_DIRECTORY.
* src/filesystem/dir.cc (_Dir): Add nofollow flag to constructor
and pass it to base class constructor.
(directory_iterator): Pass nofollow flag to _Dir constructor.
(fs::recursive_directory_iterator::increment): Likewise.
* src/filesystem/ops.cc (remove_all): Use nofollow option for
directory_iterator constructor. Move error check outside loop.
Diffstat (limited to 'libstdc++-v3/configure')
-rwxr-xr-x | libstdc++-v3/configure | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 4c20c669144..5c6e51f5c11 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -77030,6 +77030,61 @@ $as_echo "$glibcxx_cv_truncate" >&6; } $as_echo "#define HAVE_TRUNCATE 1" >>confdefs.h fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fdopendir" >&5 +$as_echo_n "checking for fdopendir... " >&6; } +if ${glibcxx_cv_fdopendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test x$gcc_no_link = xyes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <dirent.h> +int +main () +{ +::fdopendir(1); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + glibcxx_cv_fdopendir=yes +else + glibcxx_cv_fdopendir=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <dirent.h> +int +main () +{ +::fdopendir(1); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + glibcxx_cv_fdopendir=yes +else + glibcxx_cv_fdopendir=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_fdopendir" >&5 +$as_echo "$glibcxx_cv_fdopendir" >&6; } + if test $glibcxx_cv_truncate = yes; then + +$as_echo "#define HAVE_FDOPENDIR 1" >>confdefs.h + + fi CXXFLAGS="$ac_save_CXXFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' |