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;
#include <unistd.h>
#include "log.h"
+#include "subproc.h"
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;
#include <linux/sched.h>
#include <netinet/in.h>
#include <sched.h>
+#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdint.h>
}
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);
}
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) {
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);
#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);