8.6. Avoid Using vfork(2)

The portable way to create new processes in Unix-like systems
is to use the fork(2) call.
BSD introduced a variant called vfork(2) as an optimization technique.
In vfork(2), unlike fork(2), the child borrows the parent's memory
and thread of control until a call to execve(2V) or an exit occurs;
the parent process is suspended while the child is using its resources.
The rationale is that in old BSD systems, fork(2) would actually cause
memory to be copied while vfork(2) would not.
Linux never had this problem; because Linux used copy-on-write
semantics internally, Linux only copies pages when they changed
(actually, there are still some tables that have to be copied; in most
circumstances their overhead is not significant).
Nevertheless, since some programs depend on vfork(2),
recently Linux implemented the BSD vfork(2) semantics
(previously vfork(2) had been an alias for fork(2)).

There are a number of problems with vfork(2).
From a portability point-of-view,
the problem with vfork(2) is that it's actually fairly tricky for a
process to not interfere with its parent, especially in high-level languages.
The ``not interfering'' requirement applies to the actual machine code
generated, and many compilers generate hidden temporaries and other
code structures that cause unintended interference.
The result: programs using vfork(2) can easily fail when the code changes
or even when compiler versions change.

For secure programs it gets worse on Linux systems, because
Linux (at least 2.2 versions through 2.2.17) is vulnerable to a
race condition in vfork()'s implementation.
If a privileged process uses a vfork(2)/execve(2) pair in Linux
to execute user commands, there's a race condition
while the child process is already running as the user's
UID, but hasn`t entered execve(2) yet.
The user may be able to send signals, including SIGSTOP, to this process.
Due to the semantics of
vfork(2), the privileged parent process would then be blocked as well.
As a result, an unprivileged process could cause the privileged process
to halt, resulting in a denial-of-service of the privileged process' service.
FreeBSD and OpenBSD, at least, have code to specifically deal with this
case, so to my knowledge they are not vulnerable to this problem.
My thanks to Solar Designer, who noted and documented this
problem in Linux on the ``security-audit'' mailing list on October 7, 2000.

The bottom line with vfork(2) is simple:
don't use vfork(2) in your programs.
This shouldn't be difficult; the primary use of vfork(2) is to support old
programs that needed vfork's semantics.