linux-kernelforkrace-conditionglibcvfork

Why does newer glibc implement posix_spawn with vfork instead of fork?


I am tracing posix_spawn source code in glibc 2.17 and glibc 2.27.

(glibc 2.17: sysdeps/posix/spawni.c)

(glibc 2.27: sysdeps/unix/sysv/linux/spawni.c)

I found glibc 2.17 uses vfork or fork depending on flags and file actions.

I guess it is due to multithread safety or race condition.

But in glibc 2.27, it only uses vfork to create a subprocess.

Why does glibc change the implementation?

Is the newer linux kernel better to protect vfork against race conditions?


Solution

  • vfork is substantially more efficient for large processes than fork because the address space does not have to be duplicated at all. Originally, there were concerns that proper cancellation handling would require the use of fork in case of file actions present, but eventually, it was determined that the current vfork-based implementation was adequate.

    vfork is still broken in qemu-user and Microsoft's emulation, but the bugs usually are not visible when using posix_spawn because it does not actually use vfork, but a vfork-style clone system call with a separate stack, so that even if the parent process is not properly paused, the stack in the child is not clobbered.

    Some resources with background information: