Messages in this thread |  | | Date | Sat, 2 Apr 2022 23:15:52 +0200 | Subject | vfork(2) fails after unshare(CLONE_NEWTIME) (was: [Bug 215769] man 2 vfork() does not document corner case when PID == 1) | From | "Alejandro Colomar (man-pages)" <> |
| |
[Added some kernel CCs that may know what's going on]
Hi,
On 3/31/22 09:53, bugzilla-daemon@kernel.org wrote: > https://bugzilla.kernel.org/show_bug.cgi?id=215769 > > --- Comment #3 from Коренберг Марк (socketpair@gmail.com) --- > Hi, > I appreciate depth of information validation. Actually, you are right. vfork() > DOES work with pid=1 processes. I figured out the cause in my case. In order to > reproduce -- add unshare(CLONE_NEWTIME) just before vfork(). Now, I don't know > if it's a bug in vfork() or in fork(). Yes, both are clone() actually. > > In any case, they should either both give EINVAL or both don't fail. But it's > definitely bug in the kernel around CLONE_NEWTIME. >
On 3/31/22 10:12, bugzilla-daemon@kernel.org wrote: > https://bugzilla.kernel.org/show_bug.cgi?id=215769 > > --- Comment #4 from Коренберг Марк (socketpair@gmail.com) --- > #define _GNU_SOURCE 1 > #include <stdio.h> > #include <sched.h> > #include <stdlib.h> > #include <unistd.h> > #include <sys/types.h> > #include <sys/wait.h> > #include <err.h> > > #ifndef CLONE_NEWTIME > #define CLONE_NEWTIME 0x00000080 > #endif > > int main (void) > { > if (unshare (CLONE_NEWTIME)) err (EXIT_FAILURE, "UNSHARE_NEWTIME"); > > pid_t pid; > switch (pid=vfork ()) > { > case 0: > _exit(0); > case -1: > err(EXIT_FAILURE, "vfork BUG"); > default: > waitpid(pid, NULL, 0); > } > return 0; > } >
I could reproduce it with the following code. I tried syscall(SYS_vfork) to make sure it's not a problem in the libc wrapper, and to make sure I do call vfork(2). If I replace vfork(2) with fork(2), I don't get the error.
$ cat vfork.c #define _GNU_SOURCE #include <err.h> #include <linux/sched.h> #include <sched.h> #include <signal.h> #include <stdlib.h> #include <sys/syscall.h> #include <unistd.h>
int main(void) { pid_t pid;
if (unshare(CLONE_NEWTIME) == -1) err(EXIT_FAILURE, "unshare(2)"); if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) err(EXIT_FAILURE, "sigaction(2)"); pid = syscall(SYS_vfork); switch (pid) { case 0: errx(EXIT_SUCCESS, "Grandchild exiting normally."); case -1: /* If we got here, the report is confirmed. */ err(EXIT_FAILURE, "vfork(2)"); default: errx(EXIT_SUCCESS, "Child exiting normally."); } }
$ cc -Wall -Wextra -Werror vfork.c $ sudo ./a.out a.out: vfork(2): Invalid argument
$ grep_syscall_def vfork kernel/fork.c:2711: SYSCALL_DEFINE0(vfork) { struct kernel_clone_args args = { .flags = CLONE_VFORK | CLONE_VM, .exit_signal = SIGCHLD, };
return kernel_clone(&args); }
Maybe someone in the kernel can send some patch for the clone(2) and/or vfork(2) manual pages that explains the reason (if it's intended).
Thanks,
Alex
-- Alejandro Colomar Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/ http://www.alejandro-colomar.es/
|  |