On Sun, Oct 9, 2022 at 9:10 AM Alexey Izbyshev <izbyshev@xxxxxxxxx> wrote:Hi, Andrei,
On 2022-09-21 03:31, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@xxxxxxxxx>
<snip>
> + if (pid == 0) {
> + char now_str[64];
> + char *cargv[] = {"exec", now_str, NULL};
> + char *cenv[] = {NULL};
> +
> + // Check that we are still in the source timens.
> + if (check("child before exec", &now))
> + return 1;
I know this is just a test, but...
Creating threads in a vfork()-child is quite dangerous (like most other
things that touch the libc state, which is shared with the parent
process). Here it works probably only because pthread_create() followed
by pthread_join() restores everything into more-or-less the original
state before returning control to the parent, but this is something that
libcs don't guarantee and that can break at any moment.
Also, returning from a vfork()-child is explicitly forbidden by the
vfork() contract because the parent would then return to an invalid
stack frame that could be arbitrarily clobbered by code executed in the
child after main() returned. Moreover, if I'm not mistaken, on x86 with
Intel CET-enabled glibc (assuming the support for CET is ever merged
into the kernel) such return would cause the parent to always trap
because the shadow stack will become inconsistent with the normal stack.
Instead, _exit() should be used here...
Hi Alexey,
You are right, it isn't a good idea to create threads from the vfork-ed
process. Now, vfork isn't a special case in the kernel code, so I think
we can just remove the check() call from here. I have sent an updated
version of this patch, pls take a look at it.