From: "Baban" <bbnpreetsingh@gmail.com>
To: yocto-patches@lists.yoctoproject.org
Cc: Richard Purdie <richard.purdie@linuxfoundation.org>,
Mark Hatle <mark.hatle@amd.com>,
Randy MacLeod <randy.macleod@windriver.com>,
Vincent Haupert <mail@vincent-haupert.de>,
Babanpreet Singh <bbnpreetsingh@gmail.com>
Subject: [pseudo] [PATCH 0/2] close_range: implement it rather than return ENOSYS
Date: Wed, 15 Jul 2026 05:41:40 +0000 [thread overview]
Message-ID: <20260715054142.7-1-bbnpreetsingh@gmail.com> (raw)
pseudo's close_range() wrapper has returned ENOSYS unconditionally since
35433e6 ("ports/linux/guts: Add close_range wrapper for glibc 2.34"). That
was a deliberate call, and the commit message says why: "This one is
straight forward as it allows ENOSYS to be returned and the caller has to
handle it so lets do that."
It held for five years. It doesn't any more. systemd's close_all_fds() has
called close_range() since v247, but v260 raised its kernel baseline to
5.10, concluded close_range() (5.9) is always present, deleted its
/proc/self/fd fallback and started treating a failure as fatal.
safe_fork_full() then aborts the child, so under pseudo every fork+exec
dies:
Failed to close all file descriptors: Function not implemented
'(mkfs)' failed with exit status 1.
That is [YOCTO #16339], reported by Vincent Haupert against a
systemd-repart image build.
Vincent - Randy asked on the bug whether you wanted to send a patch for
this, and that question was addressed to you, not to the list. It had been
quiet for a few days and this looked worth picking up, but if you already
have it in progress please say so and ignore this series. I'm happy to
defer.
1/2 implements it. The stub was protecting something real: pseudo keeps its
own descriptors, including the socket to its server, inside the range a
caller asks to close, and the kernel does the closing, so pseudo cannot ask
it to skip one. Returning ENOSYS pushed callers onto the /proc loop, which
closes one fd at a time through close() - a path pseudo already wraps and
can defend itself inside. With the fallback gone, that no longer works.
So this follows the shape 21ff2fb ("ports/linux/guts: Add closefrom support
for glibc 2.34") already established for the same problem: a client-side op
works out the first fd above every descriptor pseudo keeps, closes the ones
below it by hand while stepping around its own, and hands that fd back so
the kernel is only turned loose on the tail that is safe. close_range() has
a top end where closefrom() does not, so both the manual loop and the path
table cleanup are bounded by maxfd.
The flags are settled before any of that. CLOSE_RANGE_UNSHARE has to take
effect first, or descriptors get closed for everyone still sharing the
table rather than just for us. CLOSE_RANGE_CLOEXEC closes nothing and
pseudo's own fds are close-on-exec already, so there is nothing to protect
and it goes straight to the kernel. An unknown flag or an inverted range is
refused up front, matching the kernel.
2/2 adds a test. It probes for kernel support with PSEUDO_DISABLED=1 first,
so that a wrapper which goes back to returning ENOSYS fails the test rather
than quietly skipping it.
Tested on x86_64 (Ubuntu 24.04, glibc 2.39). close_range() under pseudo is
identical to a run without pseudo across eight cases: single fd, bounded
range, both flags, an inverted range, an unknown flag, an already-closed
fd, and an unbounded range. pseudo also comes through close_range(3, ~0U, 0)
with its server connection intact and still tracking ownership, which is
the case that actually matters here. run_tests.sh is unchanged from master
apart from the new test passing (two pre-existing flaky parallel-* failures
show up either way).
Comparing against the real kernel is what caught the argument validation:
without it, close_range(3, 3, 0x80) returned success and closed fd 3, on a
call the kernel rejects outright.
Not tested: x86_64 only, no 32-bit/aarch64/riscv build; no end-to-end
systemd-repart reproduction, the ENOSYS-to-working transition is shown
directly instead; and CLOSE_RANGE_UNSHARE is exercised for return value and
closing behaviour but not against a real process sharing the descriptor
table, so its isolating effect rests on unshare(CLONE_FILES) semantics
rather than observation.
One question while I was in here. OP_CLOSEFROM steps around five of pseudo's
descriptors, but there are others it doesn't mention - pseudo_prefix_dir_fd,
pseudo_pwd_lck_fd, pseudo_util_evlog_fd. I kept the new op consistent with
the existing five rather than change closefrom()'s behaviour as a drive-by,
but if that list is short then it's short in both places and I'm happy to
send a follow-up.
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 | 55 +++++++++--
ports/linux/portdefs.h | 16 ++++
pseudo_client.c | 60 ++++++++++++
test/test-close-range.c | 167 +++++++++++++++++++++++++++++++++
test/test-close-range.sh | 16 ++++
6 files changed, 308 insertions(+), 7 deletions(-)
create mode 100644 test/test-close-range.c
create mode 100755 test/test-close-range.sh
--
2.43.0
next reply other threads:[~2026-07-15 9:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 5:41 Baban [this message]
2026-07-15 5:41 ` [pseudo] [PATCH 1/2] ports/linux/guts: Implement close_range() instead of returning ENOSYS Baban
2026-07-15 5:41 ` [pseudo] [PATCH 2/2] tests: Add close_range() test Baban
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260715054142.7-1-bbnpreetsingh@gmail.com \
--to=bbnpreetsingh@gmail.com \
--cc=mail@vincent-haupert.de \
--cc=mark.hatle@amd.com \
--cc=randy.macleod@windriver.com \
--cc=richard.purdie@linuxfoundation.org \
--cc=yocto-patches@lists.yoctoproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.