Skip to content

Use posix_spawn instead of vfork + exec#2800

Merged
sporksmith merged 3 commits intoshadow:mainfrom
sporksmith:posix-spawn
Mar 24, 2023
Merged

Use posix_spawn instead of vfork + exec#2800
sporksmith merged 3 commits intoshadow:mainfrom
sporksmith:posix-spawn

Conversation

@sporksmith
Copy link
Copy Markdown
Contributor

@sporksmith sporksmith commented Mar 22, 2023

Bare vfork + exec are tricky to use, since it's easy to accidentally corrupt the parent process's state from the child process. It's also unsupported in Rust (rust-lang/libc#1574, rust-lang/libc#1596).

I think we could work around this in Rust by using inline assembly or a C helper function to wrap the fork and exec, but posix_spawn basically does that for us already.

@sporksmith sporksmith self-assigned this Mar 22, 2023
@github-actions github-actions bot added Component: Main Composing the core Shadow executable Component: Testing Unit and integration tests and frameworks labels Mar 22, 2023
@github-actions github-actions bot added Component: Libraries Support functions like LD_PRELOAD and logging and removed Component: Testing Unit and integration tests and frameworks labels Mar 23, 2023
@sporksmith
Copy link
Copy Markdown
Contributor Author

A tor benchmark run shows no performance difference, as expected: https://github.com/shadow/benchmark-results/tree/master/tor/2023-03-22-T22-09-20

@sporksmith sporksmith force-pushed the posix-spawn branch 2 times, most recently from 9b49f73 to ab9b126 Compare March 23, 2023 21:52
@sporksmith sporksmith requested a review from stevenengler March 23, 2023 21:53
@sporksmith
Copy link
Copy Markdown
Contributor Author

Given that this is a relatively risky change, I'll hold off on merging until after the upcoming stable release.

Copy link
Copy Markdown
Contributor

@stevenengler stevenengler left a comment

Choose a reason for hiding this comment

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

Cool! Hopefully this makes debugging easier as well.

Bare vfork + exec are tricky to use, since it's easy to accidentally
corrupt the parent process's state from the child process. It's also
unsupported in Rust (rust-lang/libc#1596).

I think we could work around this in Rust by using inline assembly or a
C helper function to wrap the fork and exec, but `posix_spawn` basically
does that for us already.
* posix_spawn_file_actions_addchdir_np isn't present on older versions
  of glibc. Work around it by instead setting the working directory in
  the shim.

* Older versions of glibc may use `fork` instead of `vfork` unless
  we explicitly request `vfork`. I'm not sure whether any of our
  supported platforms are affected by this or not, but it doesn't hurt
  to set it explicitly.

* Older versions of glibc don't have a feature/hack that lets us
  use a single call to posix_spawn_file_actions_adddup2 with equal
  descriptor numbers to clear the O_CLOEXEC attribute. Use two calls
  to posix_spawn_file_actions_adddup2 instead, with a temporary
  descriptor number.
@sporksmith sporksmith enabled auto-merge March 24, 2023 16:26
@sporksmith sporksmith merged commit ec2f888 into shadow:main Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Libraries Support functions like LD_PRELOAD and logging Component: Main Composing the core Shadow executable

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants