Commit 9e6b79a (not yet released) switched to using vfork (via CLONE_VFORK) for fork/exec on linux/amd64. However, it's not clear from the CL that the change was at all careful about the child's after-fork path corrupting the parent's stack.
I don't have a specific flaw in mind, and it's possible there isn't one right now. But, for example, if the compiler reused named stack slots (which it doesn't, but certainly could), it would be easy for the after-fork child code to corrupt the local variables later used by the parent's after-fork path.
There isn't much code in the parent's after-fork path, but there isn't none. There absolutely have to be comments saying what can and can't be done, if nothing else.
A robust solution would be for the assembly implementation of rawVforkSyscall to never return to the parent, but instead call a new function that implements the child's after-fork path. This would ensure the parent frame never gets touched by the child, but means we need to copy a bunch of arguments to forkAndExecInChild down to this new function.
I fully agree. Like it said earlier when proposing this change, I am by far not an expert on the matter. I saw the serious performance issues and found this solution by reading about the problem space. I'm all for improving this if necessary.
Question: If we would put the call to rawVforkSyscall and only the child's after-fork path in a separate Go function, would that already help?
This certainly won't get inlined right now, but in the spirit of
making this more robust, we have to disable inlining because inlining
would defeat the purpose of separating forkAndExecInChild1 into a
Run-TryBot: Austin Clements <email@example.com>
TryBot-Result: Gobot Gobot <firstname.lastname@example.org>
Reviewed-by: Brad Fitzpatrick <email@example.com>