Skip to content

Clone dirhandles without fchdir #23019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 28, 2025
Merged

Clone dirhandles without fchdir #23019

merged 4 commits into from
May 28, 2025

Conversation

Leont
Copy link
Contributor

@Leont Leont commented Feb 20, 2025

This is a WIP for fixing #23010 based on @ilmari's suggestion. There currently are two problems with it.

  1. It doesn't have a Configure check yet for fdopendir
  2. t/op/threads-dirh.t fails because it's assuming that the dirhandles in different threads are independent. Given that the same isn't true of filehandles, I think this is the wrong thing to aim at anyway.

@tonycoz
Copy link
Contributor

tonycoz commented Feb 24, 2025

I think it's one reasonable fix, though I think it would be an entry in incompatible changes in perldelta.

I'm not sure it's safe for multiple threads to readdir() from the same underlying fd: It's UB for both parent and child of a fork() to read from their corresponding copies of the DIR, which is the closest case I can think of to this, so I'm not sure this will be thread safe.

From my testing with simple test code, glibc gets confused about the telldir() position for the new handle.

One option might be to openat(orig_dir_fd, ".", O_DIRECTORY | ...) which, assuming no permission change on ., should give us an independent handle, which can be positioned like we do in the current code.

Of course, the simplest option is to just not pass the DIR * into the new interpreter, which resolves the original issue in #10387, but is as backward (in)compatible as this change.

@Leont
Copy link
Contributor Author

Leont commented Mar 12, 2025

I'm not sure it's safe for multiple threads to readdir() from the same underlying fd: It's UB for both parent and child of a fork() to read from their corresponding copies of the DIR, which is the closest case I can think of to this, so I'm not sure this will be thread safe.

It's not, but the same is true across forks. The same is also true across threads for filehandles, really. This all falls firmly in "doctor it hurts when I poke into my eyeballs" IMO.

@ap
Copy link
Contributor

ap commented Apr 24, 2025

Any movement here?

@Leont
Copy link
Contributor Author

Leont commented Apr 24, 2025

Any movement here?

I suspect I know how to write the missing parts in a fairly short time, but I'm not sure I'd be comfortable including it this late in the release cycle

@ap
Copy link
Contributor

ap commented May 22, 2025

Note that @vinc17fr has just posted to oss-security regarding #23010.

@Leont Leont force-pushed the leont/thread-dirhandle branch 2 times, most recently from fa1e010 to a8f1068 Compare May 23, 2025 13:48
@Leont Leont force-pushed the leont/thread-dirhandle branch from a8f1068 to e521195 Compare May 23, 2025 15:06
@Leont Leont marked this pull request as ready for review May 23, 2025 15:06
@@ -199,6 +199,7 @@ d_fd_macros='define'
d_fd_set='define'
d_fdclose='undef'
d_fdim='undef'
d_fdopendir='undef'
Copy link
Contributor

@khwilliamson khwilliamson May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should HAS_FDOPENDIR be added to metaconfig.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect not, but @Tux would know for sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell it only matters when regenerating Configure from metaconfig anyway. So I propose we leave it out for now and if it turns out to be necessary Tux can add it later when he comes back from his vacation.

@Leont Leont force-pushed the leont/thread-dirhandle branch from e521195 to 7327645 Compare May 23, 2025 20:20
@khwilliamson khwilliamson dismissed jkeenan’s stale review May 23, 2025 21:09

fixed as requested

@ap
Copy link
Contributor

ap commented May 27, 2025

Given that Windows has its own logic for dirhandle dup’ing, that fdopendir is in POSIX same as fchdir is (and apparently fdopendir is actually the older one), and that both appear to be widely supported in mainstream Unixes, it seems that deleting the fchdir implementation would not shift our platform support posture materially, if at all. Only some obscure platforms may be affected.

I’ve discussed with @book and we agreed to drop the fchdir logic. We haven’t been able to reach @haarg so maybe he’ll object, but please amend the patch accordingly so it’s ready to go if he agrees, since we’re already late on the point release. (If he objects it will be easy enough to just use the current state of the patch.)

@haarg
Copy link
Contributor

haarg commented May 27, 2025

I concur that preserving the fchdir code path seems like a bad idea.

@Leont Leont force-pushed the leont/thread-dirhandle branch from 7327645 to 9a3e1ed Compare May 27, 2025 19:43
Leont added 4 commits May 27, 2025 21:46
These tests makes assumptions that are only true for the current fchdir
based implementation of dirhandle cloning. In particular that the cloned
dirhandle is entirely separate from the original. This is not
appropriate for the upcoming fdopendir based implementation.
This uses fdopendir and dup to dirhandles. Unlike the fchdir approach
these handles share descriptor position among threads.
This is no longer needed now that the fdopendir implementation exists.
@Leont Leont force-pushed the leont/thread-dirhandle branch from 9a3e1ed to c8d71d0 Compare May 27, 2025 19:46
@ap ap merged commit 5c2e757 into blead May 28, 2025
67 checks passed
@ap ap deleted the leont/thread-dirhandle branch May 28, 2025 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants