Make use of subprocClone, plus remove use of syscall(__NR_getpid)
authorRobert Swiecki <robert@swiecki.net>
Sat, 15 Oct 2016 00:42:01 +0000 (02:42 +0200)
committerRobert Swiecki <robert@swiecki.net>
Sat, 15 Oct 2016 00:42:01 +0000 (02:42 +0200)
log.c
pid.c
subproc.c
subproc.h

diff --git a/log.c b/log.c
index 1117152452ad2cf331625f8b2e8c5919d66959b7..3df66ce825961579b24662414b8cdd49afe00cb2 100644 (file)
--- a/log.c
+++ b/log.c
@@ -103,8 +103,8 @@ void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt
                dprintf(log_fd, "%s", logLevels[ll].prefix);
        }
        if (logLevels[ll].print_funcline) {
-               dprintf(log_fd, "[%s][%s][%ld] %s():%d ", timestr, logLevels[ll].descr,
-                       syscall(__NR_getpid), fn, ln);
+               dprintf(log_fd, "[%s][%s][%d] %s():%d ", timestr, logLevels[ll].descr,
+                       (int)getpid(), fn, ln);
        }
 
        va_list args;
diff --git a/pid.c b/pid.c
index c53e581fab4651924bc4de26748efc3e37823f03..191c0761791bb1f58a06e818e5c5889649626fe4 100644 (file)
--- a/pid.c
+++ b/pid.c
@@ -29,6 +29,7 @@
 #include <unistd.h>
 
 #include "log.h"
+#include "subproc.h"
 
 bool pidInitNs(struct nsjconf_t *nsjconf)
 {
@@ -38,7 +39,7 @@ bool pidInitNs(struct nsjconf_t *nsjconf)
 
        LOG_D("Creating a dummy 'init' process");
 
-       pid_t pid = syscall(__NR_clone, (uintptr_t) CLONE_FS, NULL, NULL, NULL, (uintptr_t) 0);
+       pid_t pid = subprocClone(CLONE_FS);
        if (pid == -1) {
                PLOG_E("Couldn't create a dummy init process");
                return false;
index b93d9684ab925f912864b45675c151b8fa7a1baa..5f6bbce7762c2c46fc66f808412f13a73ae3df3f 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <netinet/in.h>
 #include <sched.h>
+#include <setjmp.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -58,11 +59,11 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int
        }
 
        if (pipefd == -1) {
-               if (userInitNsFromParent(nsjconf, syscall(__NR_getpid)) == false) {
+               if (userInitNsFromParent(nsjconf, getpid()) == false) {
                        LOG_E("Couldn't initialize net user namespace");
                        exit(1);
                }
-               if (cgroupInitNsFromParent(nsjconf, syscall(__NR_getpid)) == false) {
+               if (cgroupInitNsFromParent(nsjconf, getpid()) == false) {
                        LOG_E("Couldn't initialize net user namespace");
                        exit(1);
                }
@@ -289,6 +290,32 @@ static bool subprocInitParent(struct nsjconf_t *nsjconf, pid_t pid, int pipefd)
        return true;
 }
 
+static uint8_t subprocCloneStack[PTHREAD_STACK_MIN * 2];
+
+static int subproccloneFunc(void *arg)
+{
+       jmp_buf *env_ptr = (jmp_buf *) arg;
+       longjmp(*env_ptr, 1);
+}
+
+// Avoid problem with caching of PID/TID in glibc
+pid_t subprocClone(uintptr_t flags)
+{
+       if (flags & CLONE_VM) {
+               LOG_E("Cannot use clone(flags & CLONE_VM)");
+               return -1;
+       }
+
+       jmp_buf env;
+       if (setjmp(env) == 0) {
+               void *stack_mid = &subprocCloneStack[sizeof(subprocCloneStack) / 2];
+               // Parent
+               return clone(subproccloneFunc, stack_mid, flags, &env, NULL, NULL);
+       }
+       // Child
+       return 0;
+}
+
 void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err)
 {
        if (netLimitConns(nsjconf, fd_in) == false) {
@@ -326,7 +353,7 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
        int child_fd = sv[0];
        int parent_fd = sv[1];
 
-       pid_t pid = syscall(__NR_clone, (uintptr_t) flags, NULL, NULL, NULL, (uintptr_t) 0);
+       pid_t pid = subprocClone(flags);
        if (pid == 0) {
                close(parent_fd);
                subprocNewProc(nsjconf, fd_in, fd_out, fd_err, child_fd);
index fa2d61a89cef613ddf8a5df2087b1a4fce07b1a1..6607b76bd094a2fb519e842e67eda142e5372d8c 100644 (file)
--- a/subproc.h
+++ b/subproc.h
 
 #include "common.h"
 
+#include <inttypes.h>
+#include <unistd.h>
+
 void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err);
 int subprocCount(struct nsjconf_t *nsjconf);
 void subprocDisplay(struct nsjconf_t *nsjconf);
 void subprocKillAll(struct nsjconf_t *nsjconf);
 int subprocSystem(const char **argv, char **env);
+pid_t subprocClone(uintptr_t flags);
 
 /* Returns the exit code of the first failing subprocess, or 0 if none fail */
 int subprocReap(struct nsjconf_t *nsjconf);