| Message ID | 20260716055633.7-1-bbnpreetsingh@gmail.com |
|---|---|
| Headers | show |
| Series | close_range: implement it rather than return ENOSYS | expand |
On Thu, 2026-07-16 at 05:56 +0000, Babanpreet Singh wrote: > pseudo's close_range() wrapper has returned ENOSYS unconditionally since > 35433e6 ("ports/linux/guts: Add close_range wrapper for glibc 2.34"). > systemd v260 deleted its /proc/self/fd fallback and treats a failure as > fatal, so under pseudo every fork+exec dies. That is [YOCTO #16339]. Full > story in v1: > > https://lore.kernel.org/yocto-patches/20260715054142.7-1-bbnpreetsingh@gmail.com/ I had a quick look through this and it looks ok to me, thanks! > The v1 question about OP_CLOSEFROM stepping around five of pseudo's > descriptors while others exist (pseudo_prefix_dir_fd, pseudo_pwd_lck_fd, > pseudo_util_evlog_fd) still stands; happy to send a follow-up if that list > is short in both places. I had a quick look and yes, we should really be protecting these too. That said, I couldn't see what pseudo_prefix_dir_fd actually helps with and I couldn't see why we need that... Cheers, Richard
pseudo's close_range() wrapper has returned ENOSYS unconditionally since 35433e6 ("ports/linux/guts: Add close_range wrapper for glibc 2.34"). systemd v260 deleted its /proc/self/fd fallback and treats a failure as fatal, so under pseudo every fork+exec dies. That is [YOCTO #16339]. Full story in v1: https://lore.kernel.org/yocto-patches/20260715054142.7-1-bbnpreetsingh@gmail.com/ Paul, thanks for the review. Changes in v2, both from it: 1/2: no code change apart from one comment. The commit message is rewritten in plainer language throughout; the "takes descriptors with it on the way out" sentence and the comment that repeated it now simply say that invalid arguments are rejected with EINVAL before anything is closed. 2/2: two real gaps closed. - CLOSE_RANGE_CLOEXEC needs a 5.11 kernel while the syscall itself needs 5.9, so probing only for the syscall made the test fail on 5.9/5.10. The shell wrapper now probes for the flag separately, the same PSEUDO_DISABLED=1 way, and on such a kernel only the CLOEXEC part of the test is left out. - CLOSE_RANGE_UNSHARE is now tested against a real sharer, not argued from unshare() semantics: a child cloned with CLONE_FILES closes a shared descriptor with the flag set, and the parent must still hold it afterwards. A second child closes the same descriptor without the flag and the parent must see it gone, so a clone that quietly stopped sharing the table cannot make the first check pass vacuously. The new test was checked for sensitivity by deliberately removing the unshare() call from the wrapper: it fails with "child's CLOSE_RANGE_UNSHARE closed the parent's fd 3", and passes with the real implementation. The 5.9/5.10 probe path cannot be exercised end to end on this host (6.17 kernel); the --no-cloexec branch it selects was run directly under pseudo and passes. Full run_tests.sh is unchanged from master apart from the new test passing (the two pre-existing flaky parallel-* failures show up either way). The v1 question about OP_CLOSEFROM stepping around five of pseudo's descriptors while others exist (pseudo_prefix_dir_fd, pseudo_pwd_lck_fd, pseudo_util_evlog_fd) still stands; happy to send a follow-up if that list is short in both places. Babanpreet Singh (2): ports/linux/guts: Implement close_range() instead of returning ENOSYS tests: Add close_range() test enums/op.in | 1 + ports/linux/guts/close_range.c | 54 ++++++- ports/linux/portdefs.h | 16 ++ pseudo_client.c | 60 +++++++ test/test-close-range.c | 283 +++++++++++++++++++++++++++++++++ test/test-close-range.sh | 24 +++ 6 files changed, 431 insertions(+), 7 deletions(-) create mode 100644 test/test-close-range.c create mode 100755 test/test-close-range.sh