Skip to content

Instantly share code, notes, and snippets.

@k-popov
Created March 25, 2015 09:43
Show Gist options
  • Select an option

  • Save k-popov/ef87076785d8264ac66f to your computer and use it in GitHub Desktop.

Select an option

Save k-popov/ef87076785d8264ac66f to your computer and use it in GitHub Desktop.

Revisions

  1. k-popov created this gist Mar 25, 2015.
    69 changes: 69 additions & 0 deletions escape_pid_ns.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    #define _GNU_SOURCE
    #include <sys/wait.h>
    #include <sys/utsname.h>
    #include <sched.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>

    #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
    } while (0)


    static int /* Start function for cloned child */
    childFunc()
    {
    printf("PID from child point of view just after clone() is %ld\n", (long) getpid());

    int pid_one_pid_ns;
    pid_one_pid_ns = open("/proc/1/ns/pid", O_RDONLY);
    if (pid_one_pid_ns == -1)
    errExit("open failed");
    /*
    CLONE_NEWPID behaves somewhat differently from the other nstype
    values: reassociating the calling thread with a PID namespace changes
    only the PID namespace that child processes of the caller will be
    created in; it does not change the PID namespace of the caller
    itself. Reassociating with a PID namespace is allowed only if the
    PID namespace specified by fd is a descendant (child, grandchild,
    etc.) of the PID namespace of the caller. For further details on
    PID namespaces, see pid_namespaces(7).
    */

    if (setns(pid_one_pid_ns, CLONE_NEWPID) == -1)
    errExit("setns failed");

    printf("PID from child point of view just after ns switch is %ld\n", (long) getpid());
    close(pid_one_pid_ns);

    sleep(100);

    return 0; /* Terminates child */
    }



    #define STACK_SIZE (1024 * 1024) /* Stack size for cloned child */

    static char child_stack[STACK_SIZE];

    int
    main(int argc, char *argv[])
    {
    pid_t child_pid;

    child_pid = clone(childFunc,
    child_stack + STACK_SIZE, /* Points to start of
    downwardly growing stack */
    CLONE_NEWPID | SIGCHLD, NULL);
    printf("PID of child created by clone() is %ld\n", (long) child_pid);

    if (waitpid(child_pid, NULL, 0) == -1) /* Wait for child */
    errExit("child wait failed");

    exit(EXIT_SUCCESS);
    }