News for hackers. Stuff that matters.
Re:Fork() without exec() is dangerous in large programs (2016) by Skunkleton on Tuesday June 14, 2022 @11:38AM (#31741056)
Odd to not see any mention of vfork. vfork solves the problems with fork/exec for large programs.
Re:Fork() without exec() is dangerous in large programs (2016) by remexre on Tuesday June 14, 2022 @11:40AM (#31741095)
Isn't vfork much worse in terms of the problem the author is talking about, since the child can now acquire locks in the _parent's_ address space?
Re:Fork() without exec() is dangerous in large programs (2016) by stefan_ on Tuesday June 14, 2022 @11:54AM (#31741263)
I thought the point of vfork is that they do not share an address space. But there are other things still shared and they should really just have a CreateProcess.
Re:Fork() without exec() is dangerous in large programs (2016) by remexre on Tuesday June 14, 2022 @12:21PM (#31741672)
no, fork creates a new address space, vfork doesn't

the posix_spawn mentioned in the article is effectively the equivalent of CreateProcess

Re:Fork() without exec() is dangerous in large programs (2016) by medoc on Tuesday June 14, 2022 @01:12PM (#31742587)
Last time I looked, posix_spawn() just called fork/exec
Re:Fork() without exec() is dangerous in large programs (2016) by int_19h on Tuesday June 14, 2022 @03:55PM (#31745170)
That's an implementation detail at this point. The idea is to have a single syscall that takes all the information needed to spawn the process, and does so atomically, without the need to spread it across several calls. On Win32, that's CreateProcess(). On POSIX, the equivalent is posix_spawn().
Re:Fork() without exec() is dangerous in large programs (2016) by cryptonector on Tuesday June 14, 2022 @07:15PM (#31747179)
In glibc it uses vfork() in some cases.

In Solaris/Illumos it uses vfork() or vforkx().

In principle posix_spawn() can be a system call.

Re:Fork() without exec() is dangerous in large programs (2016) by comex on Wednesday June 15, 2022 @12:46AM (#31749213)
On macOS it is a system call.
Re:Fork() without exec() is dangerous in large programs (2016) by monocasa on Tuesday June 14, 2022 @12:23PM (#31741696)
They still share an address space until exec replaces it for one of them. Particularly awful is that they share the same mutable stack which is a pathway that only leads to the inner circle of hell.
Re:Fork() without exec() is dangerous in large programs (2016) by stefan_ on Tuesday June 14, 2022 @02:38PM (#31743926)
Assuming you call exec, of course. To not call exec after vfork is not an option; one of the many ways the fork family of functions are fundamentally broken.
Re:Fork() without exec() is dangerous in large programs (2016) by monocasa on Tuesday June 14, 2022 @03:13PM (#31744526)
Well, without undefined behavior you can also call _exit(), continue within the same function, and receive conforming signals. Unfortunately this isn't always spelled out and there's code out there that definitely does other work invoking undefined behavior.
Re:Fork() without exec() is dangerous in large programs (2016) by tsimionescu on Tuesday June 14, 2022 @01:38PM (#31743028)
vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.

vfork() solves the problem of not wasting so much time on fork() when you're just going to call exec() afterwards (fork() does A LOT of work - potentially, anyway).

Re:Fork() without exec() is dangerous in large programs (2016) by cryptonector on Tuesday June 14, 2022 @02:32PM (#31743836)
> vfork() does the opposite of solving these problems. While there are a few functions that you can call after fork(), there is absolutely no function you can call after vfork() before exec(). You can't even write most local variables.

Mostly wrong.

You can call functions on the child side of vfork(), but you don't want to exec() in them -- you want to exec() in the same function that called vfork().

And you can write to local variables, but you have to be careful about it.

There's a ton of vfork()-using code that does these things.

Now, it's true that a compiler optimizer that knows nothing about vfork() but knows about _exit()'s semantics, could delete code it thinks is unreachable. So there is some issue, but you can just disable the optimizer if you run into this.

Re:Fork() without exec() is dangerous in large programs (2016) by tsimionescu on Tuesday June 14, 2022 @02:45PM (#31744057)
That's all undefined behavior, under POSIX at least [0]:

> The vfork() function has the same effect as fork(2), except that the behavior is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit(2) or one of the exec(3) family of functions.

So sure - you can do these things, but they have very little defined semantics after vfork().

It is true that Linux describes the semantics more clearly, so perhaps on Linux it is safer to use.

[0] https://man7.org/linux/man-pages/man2/vfork.2.html

Re:Fork() without exec() is dangerous in large programs (2016) by cryptonector on Tuesday June 14, 2022 @03:22PM (#31744669)
If you can call _exit() and exec, then you can call other functions too. I do believe that the Open Group has changed the description of vfork() to discourage its use because of an old and incorrect paper from the 80s. Actual implementations of vfork() are not as dangerous as the Open Group text purports them to be.

Moreover, most posix_spawn() implementations use vfork(), and they call more functions than _exit() and exec on the child side.

Let's be reasonable about these things.

Re:Fork() without exec() is dangerous in large programs (2016) by int_19h on Tuesday June 14, 2022 @03:57PM (#31745196)
An implementation of posix_spawn() is usually owned by the same people who implemented vfork(), so they know what is and isn't safe to call in that particular implementation. But we don't, and we shouldn't assume that the implementation will not change. That's exactly why public APIs and stability guarantees exist.
Re:Fork() without exec() is dangerous in large programs (2016) by cryptonector on Tuesday June 14, 2022 @04:12PM (#31745410)
Not on Linux!
Re:Fork() without exec() is dangerous in large programs (2016) by tsimionescu on Wednesday June 15, 2022 @04:34PM (#31759106)
Even if that's true, doing so after vfork() is still much harder than after fork(), not easier.