Skip to content

Conversation

@luke-jr
Copy link
Member

@luke-jr luke-jr commented Aug 29, 2024

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) since iterating all possible fd numbers has been found to be problematic.

(Equivalent to #22417 was for boost::process)

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 29, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/30756.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK laanwj

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

No conflicts as of last run.

@luke-jr
Copy link
Member Author

luke-jr commented Aug 30, 2024

(Tangent: CI passed with 1e6b0f3ec3a878efb96019f40185809ed2b0699e, but it appears there's a CI bug making it fail with the equivalent 28f6d4fa7eb1b0da16ee940922c5c466da2ec0ec)

@laanwj
Copy link
Member

laanwj commented Oct 24, 2024

Concept ACK. Closing unnecessary fds before starting external commands is good practice.

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

Pretty sure i brought up this exact concern prior to the cpp-subprocess cleanup, but was assured it wasn't removed. Apparently it was, one PR later.

optimises it by iterating over /proc/self/fd/

i don't think this necessarily ports over to to non-Linux BSDs and such, but not sure, it's definitely a better way if it is available.

@laanwj laanwj self-requested a review October 24, 2024 13:05
@luke-jr luke-jr mentioned this pull request Dec 5, 2024
18 tasks
@luke-jr
Copy link
Member Author

luke-jr commented Jan 8, 2025

Refactored to build a std::vector<int> just in case fs::directory_iterator uses a fd itself during iteration.

@maflcko
Copy link
Member

maflcko commented Apr 4, 2025

(Tangent: CI passed with 1e6b0f3, but it appears there's a CI bug making it fail with the equivalent 28f6d4f)

fixed by #32218

@maflcko maflcko closed this Apr 4, 2025
@maflcko maflcko reopened this Apr 4, 2025
@maflcko maflcko closed this Apr 7, 2025
@maflcko maflcko reopened this Apr 7, 2025
if (parent_->close_fds_) {
try {
std::vector<int> fds_to_close;
for (const auto& it : fs::directory_iterator("/proc/self/fd")) {
Copy link
Member

@laanwj laanwj Apr 7, 2025

Choose a reason for hiding this comment

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

This optimization is good to have, but imo we need the brute-force fallback in case this directory is not available. This can happen in the case of a chroot, filesystem namespacing, or on operating systems that don't have /proc/self.

This can be taken as-is from: https://github.com/arun11299/cpp-subprocess/blob/master/subprocess.hpp#L1768

This comment was marked as off-topic.

@laanwj
Copy link
Member

laanwj commented Apr 24, 2025

Continued in #32343.

@laanwj laanwj closed this Apr 24, 2025
achow101 added a commit that referenced this pull request May 14, 2025
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
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.

5 participants