Make use of subprocClone, plus remove use of syscall(__NR_getpid)

This commit is contained in:
Robert Swiecki 2016-10-15 02:42:01 +02:00
parent 950c91e4dd
commit 2a8faeba7a
4 changed files with 38 additions and 6 deletions

4
log.c
View File

@ -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;

3
pid.c
View File

@ -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;

View File

@ -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);

View File

@ -24,11 +24,15 @@
#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);