[llvm-branch-commits] [libcxx] d61805a - [libc++] Fix double file closing in `std::filesystem::remove_all()`.

Louis Dionne via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 28 09:57:32 PST 2022


Author: Konstantin Varlamov
Date: 2022-02-28T12:57:19-05:00
New Revision: d61805a8b6863663754b1d35ad5d3b25c30365cf

URL: https://github.com/llvm/llvm-project/commit/d61805a8b6863663754b1d35ad5d3b25c30365cf
DIFF: https://github.com/llvm/llvm-project/commit/d61805a8b6863663754b1d35ad5d3b25c30365cf.diff

LOG: [libc++] Fix double file closing in `std::filesystem::remove_all()`.

According to Linux documentation (see e.g. https://linux.die.net/man/3/closedir):

> A successful call to `closedir()` also closes the underlying file
> descriptor associated with `dirp`.

Thus, calling `close()` after a successful call to `closedir()` is at
best redundant. Worse, should a different thread open a file in-between
the calls to `closedir()` and `close()` and get the same file descriptor,
the call to `close()` might actually close a different file than was
intended.

rdar://89251874

Differential Revision: https://reviews.llvm.org/D120453

(cherry picked from commit 3906ebf750b80e36c2d6c52130cf40771e1b55fb)

Added: 
    

Modified: 
    libcxx/src/filesystem/operations.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 7aeeffaae8f38..39fb5739739be 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -1414,12 +1414,14 @@ uintmax_t remove_all_impl(int parent_directory, const path& p, error_code& ec) {
   if (fd != -1) {
     // If that worked, iterate over the contents of the directory and
     // remove everything in it, recursively.
-    scope_exit close_fd([=] { ::close(fd); });
     DIR* stream = ::fdopendir(fd);
     if (stream == nullptr) {
+      ::close(fd);
       ec = detail::capture_errno();
       return 0;
     }
+    // Note: `::closedir` will also close the associated file descriptor, so
+    // there should be no call to `close(fd)`.
     scope_exit close_stream([=] { ::closedir(stream); });
 
     uintmax_t count = 0;


        


More information about the llvm-branch-commits mailing list