-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
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
Fix misuse of fork
in sandbox causing crashes
#18183
Conversation
2c7d7da
to
b5ca2d9
Compare
ce129ee
to
39aeb72
Compare
I think we should at least document needing to Ideally we should also find some way to enforce it (with a Rubocop maybe?), but it's not very clear to me how to do that. |
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.
Makes sense to me, thanks @Bo98! One readability comment but can self-merge before or after addressing without a re-review.
Yeah this seems very difficult to do, particularly since you'd ideally follow function calls to check it properly. A little bit of setup before |
I guess at minimum we can look at the AST to make sure |
If it doesn't get tricked by: Utils.safe_fork do
if Sandbox.available?
sandbox = Sandbox.new
sandbox.exec(*args)
else
exec(*args)
end
end then yeah it may have helped.
|
First of all: I recommend viewing the diff with "hide whitespace" enabled - the changes aren't actually that drastic.
We've recently received reports of the sandbox hard crashing Ruby in macOS 15 beta for some users. We've also seen related reports on OS X 10.11 after a recent Tempfile crypto RNG change in Ruby 3.3.
The sandbox used to be a
fork
+exec
but due to security tightening over time this has increased in complexity to the point we no longer actually have anexec
inside the top-level fork and we are now breaking the golden rule offork
on macOS, as stated byman fork
:The flow was:
Instead, let's
Util.safe_fork
insidesandbox.rb
closely around the minimum set of code required to be run in the child process before a finalexec
. This significantly reduces the surface area of external function calls we are doing in the child process pre-exec.New flow:
So only a small part is now under a
fork
.