[lxc-devel] Working with glibc (PID/TID caches).

Serge Hallyn serge.hallyn at ubuntu.com
Fri Aug 1 15:32:30 UTC 2014


Hi,

so this is (iiuc) only a problem with unshare(CLONE_NEWPID).  Two
programs pasted below.  The one using unshare will show the old
pre-unshare pid.  The one using clone correctly shows pid 1.  Now
it's possible that clone() wrapper is doing something already to
clean the pid, I didn't try syscall(__NR_CLONE) with CLONE_NEWPID
today.  But I've seen quite a bit of code using clone(CLONE_NEWPID),
and noone really uses the syscall directly any more.

AFAICT most ppl use clone, not unshare.  But so, perhaps glibc sholud
have a unshare() wrapper which clears the pid cache?  Or glibc could
export a function which callers would have to explicitly call.

==============================================================
unsharepid.c:
==============================================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <linux/sched.h>

int clone_fn(void)
{
	printf("my pid is %d\n", getpid());
	exit(0);
}

int main(int argc, char **argv)
{
        if (unshare(CLONE_NEWPID) < 0) {
		perror("unshare");
		exit(1);
	}

	clone_fn();
}

==============================================================

==============================================================
clonepid.c
==============================================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <linux/sched.h>

int clone_fn(void *arg)
{
	printf("my pid is %d\n", getpid());
	exit(0);
}

int main(int argc, char **argv)
{
	int pagesize;
	void *clone_stack, *page;
	int pid, rc, status, cloneflags;

	cloneflags = CLONE_NEWPID;

        pagesize = 16*getpagesize();
        page = malloc(pagesize);
        if (!page) {
                perror("malloc");
                exit(-1);
        }
        clone_stack = page + pagesize;

        pid = clone(clone_fn, clone_stack, cloneflags | SIGCHLD, argv);

        if (pid < 0) {
                perror("clone");
                exit(-1);
        }

        pid = wait(&status);
        if (pid < 0) {
                perror("wait");
                exit(-1);
        }

        if (WIFEXITED(status)) {
                fprintf(stderr, "Child exited with status %d.\n", WEXITSTATUS(status));
                exit(WEXITSTATUS(status));
        }
	exit(0);
}

==============================================================

-serge

Quoting Carlos O'Donell (carlos at redhat.com):
> There was a complaint a while back from someone working
> on containers about glibc PID caching. I recently received
> another request to provide userspace with a way to reset
> any PID or TID caches to make clone-based sandboxing easier
> (CLONE_NEWPID).
> 
> How did lxc workaround the PID cache in glibc? What APIs
> could glibc provide to help the implementation of containers?
> 
> Cheers,
> Carlos.
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list