Subject: Re: PID namespace issue with VServer
From: Thomas Calderon <calderon.thomas@gmail.com>
Date: Mon, 8 Jun 2015 15:40:03 +0200
Mon, 8 Jun 2015 15:40:03 +0200
Hi,

This is a follow-up.

I was able to reproduce the issue on a Linux vanilla and thus exclude any
VServer specific bits.
However, this might prove useful to others facing a similar issue.

The issue has nothing to do with the Linux kernel but is related to PID
caching done by the glibc.
I was entering a new PID namespace using:

syscall(SYS_clone, CLONE_NEWPID | SIGCHLD, NULL);

Then, my forking daemon would start spawning new child.
However, when the PID space in the new namespace reached that of the
ancestor PID, an assertion checking that "pid != ppid" would fail in the
fork function.
This happens because the glibc is caching PID/PPID in an attempt to
optimize things.
I managed to clear the PID cache by forking after entering in the new
namespace (it seems it is the only way to clear the glibc cache).

Cheers,

Thomas Calderon

On Mon, Jun 1, 2015 at 4:58 PM, Thomas Calderon <calderon.thomas@gmail.com>
wrote:

> Hi,
>
> I would like to report an issue that I observed while performing stress
> tests of
> an application. This is a simple model where daemon forks child processes
> that
> handle client connections.
>
> What is observed is that the application is launched from outside the
> VServer
> context, then it jails itself using the provided API and enters a new
> namespace
> PID. Let's say the ancestor PID was 3541 prior to be jailed, in the
> context, it
> will be 1 as expected.
>
> Then we start the stress test, the forking daemon will spawn child
> processes.
> However, when one of the child reaches the PID of the ancestor (3541) in
> the
> jail, the daemon is blocked, no more connections are processed.
>
> This triggers no stack trace or warning on the system. We do not seem to
> reach
> some limits. Thus, this behavior seems wrong.
>
> I am running Linux kernel x86 version 3.2.69 with GrSecurity + VServer
> 2.3.2.17.
>
> Many thanks for any feedback on this,
>
> Thomas Calderon
>


Hi,

This is a follow-up.

I was able to reproduce the issue on a Linux vanilla and thus exclude any VServer specific bits.
However, this might prove useful to others facing a similar issue.

The issue has nothing to do with the Linux kernel but is related to PID caching done by the glibc.
I was entering a new PID namespace using:

syscall(SYS clone, CLONE NEWPID | SIGCHLD, NULL);

Then, my forking daemon would start spawning new child.
However, when the PID space in the new namespace reached that of the ancestor PID, an assertion checking that "pid != ppid" would fail in the fork function.
This happens because the glibc is caching PID/PPID in an attempt to optimize things.
I managed to clear the PID cache by forking after entering in the new namespace (it seems it is the only way to clear the glibc cache).

Cheers,

Thomas Calderon

On Mon, Jun 1, 2015 at 4:58 PM, Thomas Calderon <calderon.thomas@gmail.com> wrote:
Hi,

I would like to report an issue that I observed while performing stress tests of
an application. This is a simple model where daemon forks child processes that
handle client connections.

What is observed is that the application is launched from outside the VServer
context, then it jails itself using the provided API and enters a new namespace
PID. Let's say the ancestor PID was 3541 prior to be jailed, in the context, it
will be 1 as expected.

Then we start the stress test, the forking daemon will spawn child processes.
However, when one of the child reaches the PID of the ancestor (3541) in the
jail, the daemon is blocked, no more connections are processed.

This triggers no stack trace or warning on the system. We do not seem to reach
some limits. Thus, this behavior seems wrong.

I am running Linux kernel x86 version 3.2.69 with GrSecurity + VServer 2.3.2.17.

Many thanks for any feedback on this,

Thomas Calderon