[committed] libstdc++: Avoid symlink race in filesystem::remove_all [PR104161]
Jonathan Wakely
jwakely@redhat.com
Wed Jan 26 22:11:17 GMT 2022
On Wed, 26 Jan 2022 at 22:08, Dimitar Dimitrov <dimitar@dinux.eu> wrote:
>
> On Tue, Jan 25, 2022 at 09:09:51PM +0000, Jonathan Wakely via Gcc-patches wrote:
> > Tested x86_64-linux, pushed to trunk. Backports to follow.
> >
> >
> > 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.
> > ---
> > libstdc++-v3/acinclude.m4 | 12 ++++++
> > libstdc++-v3/config.h.in | 3 ++
> > libstdc++-v3/configure | 55 ++++++++++++++++++++++++
> > libstdc++-v3/src/c++17/fs_dir.cc | 13 ++++--
> > libstdc++-v3/src/c++17/fs_ops.cc | 12 +++---
> > libstdc++-v3/src/filesystem/dir-common.h | 48 ++++++++++++++++-----
> > libstdc++-v3/src/filesystem/dir.cc | 13 ++++--
> > libstdc++-v3/src/filesystem/ops.cc | 6 +--
> > 8 files changed, 134 insertions(+), 28 deletions(-)
> >
> > diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
> > index d996477254c..7b6b807114a 100644
> > --- a/libstdc++-v3/acinclude.m4
> > +++ b/libstdc++-v3/acinclude.m4
> > @@ -4735,6 +4735,18 @@ dnl
> > if test $glibcxx_cv_truncate = yes; then
> > AC_DEFINE(HAVE_TRUNCATE, 1, [Define if truncate is available in <unistd.h>.])
> > fi
> > +dnl
> > + AC_CACHE_CHECK([for fdopendir],
> > + glibcxx_cv_fdopendir, [dnl
> > + GCC_TRY_COMPILE_OR_LINK(
> > + [#include <dirent.h>],
> > + [::fdopendir(1);],
> > + [glibcxx_cv_fdopendir=yes],
> > + [glibcxx_cv_fdopendir=no])
> > + ])
> > + if test $glibcxx_cv_truncate = yes; then
>
> This is a typo. Should check glibcxx_cv_fdopendir.
Oops, thanks! Copy&pasto.
More information about the Libstdc++
mailing list