This is an archive of the discontinued LLVM Phabricator instance.

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

Authored by var-const on Feb 23 2022, 9:13 PM.

Details

Summary

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:

// Thread 1.
int fd = ::openat(AT_FDCWD, "foo", O_DIRECTORY);

DIR* stream = ::fdopendir(fd);
int result = ::closedir(stream);
assert(result == 0); // `fd` is now closed.

{
  // Thread 2.
  int fd2 = ::openat(AT_FDCWD, "BAR", O_DIRECTORY);
  assert(fd2 == fd); // Quite possible.
}

// Thread 1.
result = ::close(fd);
assert(result == 0);
// The call to `close` succeeds but closes a different file ("BAR",
// which was never opened by this function).

rdar://89251874

Diff Detail

Event Timeline

var-const created this revision.Feb 23 2022, 9:13 PM
var-const requested review of this revision.Feb 23 2022, 9:13 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 23 2022, 9:13 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript

According to Linux documentation [...]

I couldn't see the same note in BSD documentation but it works the same in practice.

I'm not sure if it's possible to test this -- please let me know if I'm missing something.

var-const edited the summary of this revision. (Show Details)Feb 24 2022, 1:54 AM
var-const edited the summary of this revision. (Show Details)
ldionne accepted this revision.Feb 28 2022, 9:55 AM

LGTM, thanks for fixing this. I'll land this on main and cherry-pick to release/14.x because I think it's important to fix this bug.

This revision is now accepted and ready to land.Feb 28 2022, 9:55 AM
This revision was landed with ongoing or failed builds.Feb 28 2022, 9:57 AM
This revision was automatically updated to reflect the committed changes.