-
Notifications
You must be signed in to change notification settings - Fork 37.7k
util/system: Close non-std fds when execing slave processes #22417
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
Conversation
ded64d7
to
b7c45c8
Compare
Concept ACK Is it possible to easily test this functionality? I would like to give it a go. |
Should be possible with a long-running process, then looking at If you want to create a problem, write a program to write to random fd numbers (likely will corrupt things, don't try on an important node). :p |
This is a bit beyond my understanding of processes. I tested (on macOS) that 3b6153b doesn't break HWI integration, so I have no objection. |
src/util/system.h
Outdated
void on_exec_setup(Executor&exec) const | ||
{ | ||
try { | ||
for (auto it : fs::directory_iterator("/dev/fd")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL /dev/fd
is a general UNIX thing and not limited to Linux. It doesn't seem like a very nice API to iterate open file descriptors but seems portable enough.
Github-Pull: bitcoin#22417 Rebased-From: 3b6153b
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
7b0c71c
to
4c19cea
Compare
Compiling 4c19cea on macOS 12.3.1 (Boost 1.78 via Homebrew) fails with:
Compiling with depends does work. Update: compiling on master @ 4129134 also fails, so this is unrelated (and already fixed, see #22482). Maybe rebase? For some reason CI has not run yet on this PR (probably because it builds on top of commits that use a previous CI incarnation). |
Testing and CI should always be merging the PR into master. The PR itself should ideally in the case of bugfixes like this, be based on the oldest affected commit (that can still cleanly merge, in Core's case) |
4c19cea
to
2255d3b
Compare
🐙 This pull request conflicts with the target branch and needs rebase. Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft". |
Rebased and squashed |
#include <fcntl.h> | ||
#ifdef FD_CLOEXEC | ||
#include <unistd.h> | ||
#if defined(__GNUC__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In-code warning suppression has recently been removed, so you can drop all of the #if defined(__GNUC__)
blocks.
Are you still working on this? There has been no reply to a review comment for about a year: #22417 (comment) |
🐙 This pull request conflicts with the target branch and needs rebase. |
What is the status of this now that Boost Process is removed (given that this currently adds Boost Process code)? |
Closing, see above, and this is adding Boost Process code, which no-longer exists in this codebase. |
For historical reference: this patch is no longer relevant, since #28981 replaced boost-process with cpp-subprocess. @luke-jr does |
a0eed55 run_command: Enable close_fds option to avoid lingering fds (Luke Dashjr) c7c356a cpp-subprocess: Iterate through /proc/self/fd for close_fds option on Linux (Luke Dashjr) 4f5e04d Revert "remove unneeded close_fds option from cpp-subprocess" (Luke Dashjr) Pull request description: Picks up stale #30756, while addressing my fallback comment (#30756 (comment)). > Currently, RunCommandParseJSON runs its target with whatever fds happen to be open inherited on POSIX platforms. I don't think there's any practical scenario where this is a problem right now, but there's a lot of potential for weird problems (eg, if a process manages to outlive bitcoind - perhaps it's hanging - the listening port(s) won't get released and starting bitcoind again will fail). It's also a potential security issue if a child process is intended to be sandboxed at some point. Not to mention plain ugly :) > > cpp-subprocess has a feature to address this called close_fds. Not sure why it was removed in #29961 rather than fixing this during the migration, but this PR restores it, enables it for RunCommandParseJSON, and optimises it by iterating over /proc/self/fd/ like most other libraries do these days ([eg, glib]> (https://gitlab.gnome.org/GNOME/glib/blob/487b1fd20c5e494366a82ddc0fa6b53b8bd779ad/glib/gspawn.c#L1094)) since iterating all possible fd numbers [has been found to be problematic](https://bugzilla.redhat.com/show_bug.cgi?id=1537564). > > (Equivalent to #22417 was for boost::process) ACKs for top commit: achow101: ACK a0eed55 hebasto: ACK a0eed55, tested on Ubuntu 25.04: vasild: ACK a0eed55 Tree-SHA512: 7dc1cb6cc1f45ff7c4f53512e400baad1a033b4ebf14ba6f6ffa38588314932d6d01ef67b197f081e8202bb802659ac6a87998277797721d6d7b20efde8e9a6b
Currently,
RunCommandParseJSON
runs its target with whatever fds happen to be open inherited on POSIX platforms. I don't think there's any practical scenario where this is a problem right now, but there's a lot of potential for weird problems (eg, if a process manages to outlive bitcoind - perhaps it's hanging - the listening port(s) won't get released and starting bitcoind again will fail). It's also a potential security issue if a child process is intended to be sandboxed at some point. Not to mention plain ugly :)Note that boost::process has a
boost::process::limit_handles
extension for this, but it requires a newer Boost and is even in the latest version still somewhat broken on Windows (where it probably doesn't matter since handle inheritance is off by default - but will execute undefined behaviour dereferencing/writing of an end-iterator): boostorg/process#200Instead of closing directly, we have to set the
FD_CLOEXEC
flag and letexec
close them; otherwise, boost::process's internal pipe would be closed and we get the wrong exception thrown (not actually a problem outside of our tests, but might as well do this cleanly).