Re: [PATCH 2/2] selftests/timens: add a test for vfork+exit

From: Alexey Izbyshev
Date: Thu Oct 13 2022 - 18:15:22 EST


On 2022-10-13 20:46, Andrei Vagin wrote:
On Sun, Oct 9, 2022 at 9:10 AM Alexey Izbyshev <izbyshev@xxxxxxxxx> wrote:

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.

Hi, Andrei,

While I think you could just skip check_in_thread() in the vfork()-child instead of removing check() completely (the rest of the code in check() is unlikely to mess up the libc state), I agree that the test is still able to catch problems unconditionally affecting all CLONE_VM tasks thanks to check_in_thread() in the parent, so I don't see much point in holding it up further. Your v2 patch looks good enough to me, thanks!

Alexey