From b4f1d771777090b4e09abd34c701c0cbb47cb0c9 Mon Sep 17 00:00:00 2001
From: CoprDistGit <infra@openeuler.org>
Date: Mon, 24 Apr 2023 08:46:38 +0000
Subject: automatic import of boost

---
 ...ystem-Added-protection-for-CVE-2022-21658.patch | 330 +++++++++++++++++++++
 1 file changed, 330 insertions(+)
 create mode 100644 boost-1.78-filesystem-Added-protection-for-CVE-2022-21658.patch

(limited to 'boost-1.78-filesystem-Added-protection-for-CVE-2022-21658.patch')

diff --git a/boost-1.78-filesystem-Added-protection-for-CVE-2022-21658.patch b/boost-1.78-filesystem-Added-protection-for-CVE-2022-21658.patch
new file mode 100644
index 0000000..b306a5c
--- /dev/null
+++ b/boost-1.78-filesystem-Added-protection-for-CVE-2022-21658.patch
@@ -0,0 +1,330 @@
+From 41d076ace558cfae01e233f9746dc955dcf78dba Mon Sep 17 00:00:00 2001
+From: Andrey Semashev <andrey.semashev@gmail.com>
+Date: Sun, 30 Jan 2022 23:41:06 +0300
+Subject: [PATCH] Added protection for CVE-2022-21658 in remove_all on POSIX
+ systems.
+
+Another process could replace the directory being processed by remove_all
+with a symlink after remove_all called symlink_status but before
+it creates a directory iterator. As a result, remove_all would remove
+the linked directory contents instead of removing the symlink.
+
+On POSIX systems that support fdopendir and O_NOFOLLOW flag for open(2),
+this can be prevented by opening the directory with O_NOFOLLOW before
+iterating. This will fail if the directory was replaced with a symlink.
+
+No protection on other systems.
+
+Reported in https://github.com/boostorg/filesystem/issues/224.
+---
+ libs/filesystem/CMakeLists.txt                         |  4 ++
+ libs/filesystem/build/Jamfile.v2                       |  1 +
+ libs/filesystem/config/Jamfile.v2                      |  2 +
+ libs/filesystem/config/has_fdopendir_nofollow.cpp      | 20 ++++++
+ boost/filesystem/directory.hpp 			|  3 +-
+ libs/filesystem/src/directory.cpp                      | 53 ++++++++++++++--
+ libs/filesystem/src/operations.cpp                     | 86 ++++++++++++++++----------
+ 7 files changed, 131 insertions(+), 38 deletions(-)
+ create mode 100644 config/has_fdopendir_nofollow.cpp
+
+diff --git a/libs/filesystem/CMakeLists.txt b/libs/filesystem/CMakeLists.txt
+index 5a8678309..37ef7e161 100644
+--- a/libs/filesystem/CMakeLists.txt
++++ b/libs/filesystem/CMakeLists.txt
+@@ -59,6 +59,7 @@ if(NOT BOOST_FILESYSTEM_DISABLE_STATX)
+         check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_statx_syscall.cpp>" BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
+     endif()
+ endif()
++check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_fdopendir_nofollow.cpp>" BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
+ if(WIN32 AND NOT BOOST_FILESYSTEM_DISABLE_BCRYPT)
+     set(CMAKE_REQUIRED_LIBRARIES bcrypt)
+     check_cxx_source_compiles("#include <${CMAKE_CURRENT_SOURCE_DIR}/config/has_bcrypt.cpp>" BOOST_FILESYSTEM_HAS_BCRYPT)
+@@ -170,6 +171,9 @@ endif()
+ if(BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
+     target_compile_definitions(boost_filesystem PRIVATE BOOST_FILESYSTEM_HAS_STATX_SYSCALL)
+ endif()
++if(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++    target_compile_definitions(boost_filesystem PRIVATE BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++endif()
+ 
+ target_link_libraries(boost_filesystem
+     PUBLIC
+diff --git a/libs/filesystem/build/Jamfile.v2 b/libs/filesystem/build/Jamfile.v2
+index 6ab58ddb8..02e3b8971 100644
+--- a/libs/filesystem/build/Jamfile.v2
++++ b/libs/filesystem/build/Jamfile.v2
+@@ -112,6 +112,7 @@ project boost/filesystem
+       [ check-target-builds ../config//has_stat_st_birthtim "has stat::st_birthtim" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIM ]
+       [ check-target-builds ../config//has_stat_st_birthtimensec "has stat::st_birthtimensec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMENSEC ]
+       [ check-target-builds ../config//has_stat_st_birthtimespec "has stat::st_birthtimespec" : <define>BOOST_FILESYSTEM_HAS_STAT_ST_BIRTHTIMESPEC ]
++      [ check-target-builds ../config//has_fdopendir_nofollow "has fdopendir(O_NOFOLLOW)" : <define>BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW ]
+       <conditional>@check-statx
+       <conditional>@select-windows-crypto-api
+       <conditional>@check-cxx20-atomic-ref
+diff --git a/libs/filesystem/config/Jamfile.v2 b/libs/filesystem/config/Jamfile.v2
+index 2e9ee4bd6..5ea7dc6c7 100644
+--- a/libs/filesystem/config/Jamfile.v2
++++ b/libs/filesystem/config/Jamfile.v2
+@@ -27,6 +27,8 @@ obj has_stat_st_birthtimensec : has_stat_st_birthtimensec.cpp : <include>../src
+ explicit has_stat_st_birthtimensec ;
+ obj has_stat_st_birthtimespec : has_stat_st_birthtimespec.cpp : <include>../src ;
+ explicit has_stat_st_birthtimespec ;
++obj has_fdopendir_nofollow : has_fdopendir_nofollow.cpp : <include>../src ;
++explicit has_fdopendir_nofollow ;
+ 
+ lib bcrypt ;
+ explicit bcrypt ;
+diff --git a/libs/filesystem/config/has_fdopendir_nofollow.cpp b/libs/filesystem/config/has_fdopendir_nofollow.cpp
+new file mode 100644
+index 000000000..009a73084
+--- /dev/null
++++ b/libs/filesystem/config/has_fdopendir_nofollow.cpp
+@@ -0,0 +1,20 @@
++//  Copyright 2022 Andrey Semashev
++
++//  Distributed under the Boost Software License, Version 1.0.
++//  See http://www.boost.org/LICENSE_1_0.txt
++
++//  See library home page at http://www.boost.org/libs/filesystem
++
++#include "platform_config.hpp"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <dirent.h>
++#include <fcntl.h>
++
++int main()
++{
++    int fd = open(".", O_DIRECTORY | O_RDONLY | O_NOFOLLOW);
++    DIR* dir = fdopendir(fd);
++    return dir != 0;
++}
+diff --git a/boost/filesystem/directory.hpp b/boost/filesystem/directory.hpp
+index f487633fc..fa1e69be5 100644
+--- a/boost/filesystem/directory.hpp
++++ b/boost/filesystem/directory.hpp
+@@ -247,7 +247,8 @@ BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(directory_options, unsigned int)
+     skip_dangling_symlinks = 1u << 2,   // non-standard extension for recursive_directory_iterator: don't follow dangling directory symlinks,
+     pop_on_error = 1u << 3,             // non-standard extension for recursive_directory_iterator: instead of producing an end iterator on errors,
+                                         // repeatedly invoke pop() until it succeeds or the iterator becomes equal to end iterator
+-    _detail_no_push = 1u << 4           // internal use only
++    _detail_no_follow = 1u << 4,        // internal use only
++    _detail_no_push = 1u << 5           // internal use only
+ }
+ BOOST_SCOPED_ENUM_DECLARE_END(directory_options)
+ 
+diff --git a/libs/filesystem/src/directory.cpp b/libs/filesystem/src/directory.cpp
+index 554277580..8b41ae5e1 100644
+--- a/libs/filesystem/src/directory.cpp
++++ b/libs/filesystem/src/directory.cpp
+@@ -2,7 +2,7 @@
+ 
+ //  Copyright 2002-2009, 2014 Beman Dawes
+ //  Copyright 2001 Dietmar Kuehl
+-//  Copyright 2019 Andrey Semashev
++//  Copyright 2019, 2022 Andrey Semashev
+ 
+ //  Distributed under the Boost Software License, Version 1.0.
+ //  See http://www.boost.org/LICENSE_1_0.txt
+@@ -33,6 +33,8 @@
+ 
+ #ifdef BOOST_POSIX_API
+ 
++#include <sys/types.h>
++#include <sys/stat.h>
+ #include <dirent.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+@@ -47,6 +49,14 @@
+ #define BOOST_FILESYSTEM_USE_READDIR_R
+ #endif
+ 
++// At least Mac OS X 10.6 and older doesn't support O_CLOEXEC
++#ifndef O_CLOEXEC
++#define O_CLOEXEC 0
++#define BOOST_FILESYSTEM_NO_O_CLOEXEC
++#endif
++
++#include "posix_tools.hpp"
++
+ #else // BOOST_WINDOWS_API
+ 
+ #include <cwchar>
+@@ -206,13 +216,46 @@ inline std::size_t path_max()
+ 
+ #endif // BOOST_FILESYSTEM_USE_READDIR_R
+ 
+-error_code dir_itr_first(void*& handle, void*& buffer, const char* dir, std::string& target, fs::file_status&, fs::file_status&)
++error_code dir_itr_first(void*& handle, void*& buffer, const char* dir, std::string& target, unsigned int opts, fs::file_status&, fs::file_status&)
+ {
+-    if ((handle = ::opendir(dir)) == 0)
++#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++    int flags = O_DIRECTORY | O_RDONLY | O_NDELAY | O_CLOEXEC;
++    if ((opts & static_cast< unsigned int >(directory_options::_detail_no_follow)) != 0u)
++        flags |= O_NOFOLLOW;
++
++    int fd = ::open(dir, flags);
++    if (BOOST_UNLIKELY(fd < 0))
++    {
++        const int err = errno;
++        return error_code(err, system_category());
++    }
++
++#if defined(BOOST_FILESYSTEM_NO_O_CLOEXEC) && defined(FD_CLOEXEC)
++    int res = ::fcntl(fd, F_SETFD, FD_CLOEXEC);
++    if (BOOST_UNLIKELY(res < 0))
++    {
++        const int err = errno;
++        close_fd(fd);
++        return error_code(err, system_category());
++    }
++#endif
++
++    handle = ::fdopendir(fd);
++    if (BOOST_UNLIKELY(!handle))
+     {
+         const int err = errno;
++        close_fd(fd);
+         return error_code(err, system_category());
+     }
++#else // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++    handle = ::opendir(dir);
++    if (BOOST_UNLIKELY(!handle))
++    {
++        const int err = errno;
++        return error_code(err, system_category());
++    }
++#endif // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++
+     target.assign("."); // string was static but caused trouble
+                         // when iteration called from dtor, after
+                         // static had already been destroyed
+@@ -342,7 +385,7 @@ error_code dir_itr_increment(void*& handle, void*& buffer, std::string& target,
+ 
+ #else // BOOST_WINDOWS_API
+ 
+-error_code dir_itr_first(void*& handle, fs::path const& dir, std::wstring& target, fs::file_status& sf, fs::file_status& symlink_sf)
++error_code dir_itr_first(void*& handle, fs::path const& dir, std::wstring& target, unsigned int opts, fs::file_status& sf, fs::file_status& symlink_sf)
+ // Note: an empty root directory has no "." or ".." entries, so this
+ // causes a ERROR_FILE_NOT_FOUND error which we do not considered an
+ // error. It is treated as eof instead.
+@@ -512,7 +555,7 @@ void directory_iterator_construct(directory_iterator& it, path const& p, unsigne
+ #if defined(BOOST_POSIX_API)
+                                           imp->buffer,
+ #endif
+-                                          p.c_str(), filename, file_stat, symlink_file_stat);
++                                          p.c_str(), filename, opts, file_stat, symlink_file_stat);
+ 
+         if (result)
+         {
+diff --git a/libs/filesystem/src/operations.cpp b/libs/filesystem/src/operations.cpp
+index e14b598b7..bf42105b9 100644
+--- a/libs/filesystem/src/operations.cpp
++++ b/libs/filesystem/src/operations.cpp
+@@ -945,51 +945,73 @@ inline bool remove_impl(path const& p, error_code* ec)
+ //! remove_all() implementation
+ uintmax_t remove_all_impl(path const& p, error_code* ec)
+ {
+-    fs::file_type type;
++    for (unsigned int attempt = 0u; attempt < 5u; ++attempt)
+     {
+-        error_code local_ec;
+-        type = fs::detail::symlink_status(p, &local_ec).type();
++        fs::file_type type;
++        {
++            error_code local_ec;
++            type = fs::detail::symlink_status(p, &local_ec).type();
+ 
+-        if (type == fs::file_not_found)
+-            return 0u;
++            if (type == fs::file_not_found)
++                return 0u;
+ 
+-        if (BOOST_UNLIKELY(type == fs::status_error))
+-        {
+-            if (!ec)
+-                BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec));
++            if (BOOST_UNLIKELY(type == fs::status_error))
++            {
++                if (!ec)
++                    BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec));
+ 
+-            *ec = local_ec;
+-            return static_cast< uintmax_t >(-1);
++                *ec = local_ec;
++                return static_cast< uintmax_t >(-1);
++            }
+         }
+-    }
+ 
+-    uintmax_t count = 0u;
++        uintmax_t count = 0u;
+ 
+-    if (type == fs::directory_file) // but not a directory symlink
+-    {
+-        fs::directory_iterator itr;
+-        fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::none), ec);
+-        if (ec && *ec)
+-            return static_cast< uintmax_t >(-1);
+-
+-        const fs::directory_iterator end_dit;
+-        while (itr != end_dit)
++        if (type == fs::directory_file) // but not a directory symlink
+         {
+-            count += fs::detail::remove_all_impl(itr->path(), ec);
+-            if (ec && *ec)
+-                return static_cast< uintmax_t >(-1);
++            fs::directory_iterator itr;
++            error_code local_ec;
++            fs::detail::directory_iterator_construct(itr, p, static_cast< unsigned int >(directory_options::_detail_no_follow), &local_ec);
++            if (BOOST_UNLIKELY(!!local_ec))
++            {
++#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
++                // If open(2) with O_NOFOLLOW fails with ELOOP, this means that either the path contains a loop
++                // of symbolic links, or the last element of the path is a symbolic link. Given that lstat(2) above
++                // did not fail, most likely it is the latter case. I.e. between the lstat above and this open call
++                // the filesystem was modified so that the path no longer refers to a directory file (as opposed to a symlink).
++                if (local_ec == error_code(ELOOP, system_category()))
++                    continue;
++#endif // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW)
+ 
+-            fs::detail::directory_iterator_increment(itr, ec);
+-            if (ec && *ec)
++                if (!ec)
++                    BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec));
++
++                *ec = local_ec;
+                 return static_cast< uintmax_t >(-1);
++            }
++
++            const fs::directory_iterator end_dit;
++            while (itr != end_dit)
++            {
++                count += fs::detail::remove_all_impl(itr->path(), ec);
++                if (ec && *ec)
++                    return static_cast< uintmax_t >(-1);
++
++                fs::detail::directory_iterator_increment(itr, ec);
++                if (ec && *ec)
++                    return static_cast< uintmax_t >(-1);
++            }
+         }
+-    }
+ 
+-    count += fs::detail::remove_impl(p, type, ec);
+-    if (ec && *ec)
+-        return static_cast< uintmax_t >(-1);
++        count += fs::detail::remove_impl(p, type, ec);
++        if (ec && *ec)
++            return static_cast< uintmax_t >(-1);
+ 
+-    return count;
++        return count;
++    }
++
++    emit_error(ELOOP, p, ec, "boost::filesystem::remove_all: path cannot be opened as a directory");
++    return static_cast< uintmax_t >(-1);
+ }
+ 
+ #else // defined(BOOST_POSIX_API)
-- 
cgit v1.2.3