[forkserver] Refactor sandbox process launch and clean up forkserver integration
Categories
(Core :: IPC, task)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox122 | --- | fixed |
People
(Reporter: jld, Assigned: jld)
References
Details
Attachments
(2 external files)
Back when I added Linux sandboxing features that needed to integrate with process launch by effectively replacing the fork() call, I thought it made sense to make that fully abstract, via a ForkDelegate object rather than by having IPC make a direct call into sandboxing.
Unfortunately, the fork server basically needs to serialize that abstract object and send it to another process. The current approach is kind of hacky — the information is smuggled across in launch parameters that aren't actually used by the launched process, the lifecycle(s) of the SandboxFork object become(s) confusing, and there are ifdef'ed hooks that aren't really necessary.
Also, this blocks bug 1858272 because the sandbox flags are hidden in one of the environment strings.
I have proof-of-concept patches for a fix:
- Replace
LaunchOptions::fork_delegatewith plain-old-data fields that have the sandboxing info. (Not the best encapsulation but in my opinion better than the alternative. Contrast Chromium, wherefork_flagsbecomes a first-class feature ofLaunchOptionsand the other parts are handled by an abstractPreExecDelegate; however, Chromium uses a different interface for zygote commands vs. lauching directly.) - Separate the current
SandboxLaunchPrepareintoConfigure(deciding what sandboxing features are to be used and setting thoseLaunchOptionsfields) andPrepare(actions to be done in the process that will do theclone, before it bakes theFileDescriptorShuffle). - Adjust the current users of
SandboxLaunch/ForkDelegateaccordingly.
Currently this seems to work for both the classic and forkserver cases, but it needs more testing and documentation.
As a convenient side-effect, the failing socketpair calls seen in bug 1685642 can now return an error instead of crashing.
(Also, in the forkserver case, that socketpair call moves into the forkserver process (which shouldn't be anywhere near fd exhaustion) rather than the parent; however, bug 1858272 / bug 1752638 will add another parent-process socketpair.)
| Assignee | ||
Comment 1•2 years ago
|
||
The next patch will need the Linux version of LaunchApp to side-effect
the LaunchOptions in some cases; given that none of the callers ever
try to reuse a LaunchOptions, we might as well change it from a const
reference to an rvalue reference. The Mac version is also changed,
because it uses the same declaration / function type.
Also, the overload of LaunchApp that takes a CommandLine has been
removed, because it was unused.
However, the Windows version is not changed; there's no need for it,
and it accepts different types of arguments anyway so it's not necessary
to match the Unix one. Also, the CommandLine overload of the Windows
LaunchApp is used and continues to exist.
| Assignee | ||
Comment 2•2 years ago
|
||
Currently, process launch interfaces with Linux sandboxing via the
ForkDelegate abstraction, basically replacing fork with an opaque
stateful callback, configured using various info from the parent process
(prefs, gfxInfo, etc.). Unfortunately, the fork server effectively
needs to move that object into another process, and this is accomplished
in a way that's complicated and difficult to deal with and causes some
problems.
Instead, this patch makes the sandboxing state transparent: fields
are added to LaunchOptions which are serialized/deserialized, and the
sandbox launcher object is now exposed in a header and used directly by
LaunchApp (and its fork server equivalent).
There are a few other changes that follow from this. In particular,
the pipe for the chroot server is now created later, during LaunchApp
but before FileDescriptorShuffle::Init, so LaunchApp will side-effect
LaunchOptions::fds_to_remap. (But this also means we're no longer
using a fake mapping of fd 10 which isn't actually used, and we're no
longer creating a socketpair in one process and sending both ends to
another process that could have just created it itself.)
For more details, see the comments in SandboxLaunch.h for the member
functions Configure, Prepare, and Fork.
As a convenient side effect of this change, Prepare is now fallible,
so we can handle certain error cases (like failing to create a socket
pair) more gracefully.
Comment 4•2 years ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/b63072009211
https://hg.mozilla.org/mozilla-central/rev/bf4c1083cec1
Description
•