Skip to content
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

Use posix_spawn instead of vfork + exec #2800

Merged
merged 3 commits into from
Mar 24, 2023
Merged

Conversation

sporksmith
Copy link
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
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
Copy link
Contributor Author

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

Copy link
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.

src/main/host/managed_thread.c Outdated Show resolved Hide resolved
src/main/host/managed_thread.c Show resolved Hide resolved
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.
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.

None yet

2 participants