From 69622c17ae2e7b5b1ab4347b8448d88395d750ac Mon Sep 17 00:00:00 2001 From: Robert Swiecki Date: Fri, 15 May 2015 16:02:15 +0200 Subject: [PATCH] Logs from the child process (namespaced) are proxied to the parent process --- contain.c | 5 ++++- contain.h | 2 +- log.c | 13 ++++++++++++- log.h | 2 ++ subproc.c | 33 +++++++++++++++++++++++++++------ 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/contain.c b/contain.c index 7774756..a6cf60b 100644 --- a/contain.c +++ b/contain.c @@ -347,8 +347,11 @@ bool containMakeFdsCOE(void) return true; } -bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err) +bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err, int fd_log) { + /* Make sure all logs go to the parent process from now on */ + logNewLogFD(fd_log); + if (nsjconf->mode != MODE_LISTEN_TCP) { if (nsjconf->is_silent == false) { return true; diff --git a/contain.h b/contain.h index c61436d..9d97729 100644 --- a/contain.h +++ b/contain.h @@ -31,6 +31,6 @@ bool containPrepareEnv(struct nsjconf_t *nsjconf); bool containMountFS(struct nsjconf_t *nsjconf); bool containSetLimits(struct nsjconf_t *nsjconf); bool containMakeFdsCOE(void); -bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err); +bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int fd_log); #endif /* _CONTAIN_H */ diff --git a/log.c b/log.c index 8f73ef0..01f18df 100644 --- a/log.c +++ b/log.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -101,7 +102,7 @@ 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][%d] %s():%d ", timestr, logLevels[ll].descr, getpid(), fn, ln); + dprintf(log_fd, "[%s][%s][%ld] %s():%d ", timestr, logLevels[ll].descr, syscall(__NR_getpid), fn, ln); } va_list args; @@ -126,3 +127,13 @@ void logStop(int sig) { LOG_I("Server stops due to fatal signal (%d) caught. Exiting", sig); } + +void logNewLogFD(int fd) +{ + log_fd = fd; +} + +void logDirectly(const char *msg) +{ + dprintf(log_fd, "%s", msg); +} diff --git a/log.h b/log.h index 0de3c4d..e16ff51 100644 --- a/log.h +++ b/log.h @@ -55,5 +55,7 @@ bool logInitLogFile(struct nsjconf_t *nsjconf, const char *logfile, bool is_verb void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...) __attribute__ ((format(printf, 5, 6))); void logStop(int sig); +void logNewLogFD(int fd); +void logDirectly(const char *msg); #endif /* _LOG_H */ diff --git a/subproc.c b/subproc.c index 87c398e..8084732 100644 --- a/subproc.c +++ b/subproc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -44,12 +45,12 @@ #include "net.h" #include "sandbox.h" -static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err) +static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int pipefd) { if (containPrepareEnv(nsjconf) == false) { exit(1); } - if (containSetupFD(nsjconf, fd_in, fd_out, fd_err) == false) { + if (containSetupFD(nsjconf, fd_in, fd_out, fd_err, pipefd) == false) { exit(1); } if (containMountFS(nsjconf) == false) { @@ -81,8 +82,10 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int LOG_D(" Arg[%d]: '%s'", i, nsjconf->argv[i]); } execve(nsjconf->argv[0], &nsjconf->argv[0], env); - PLOG_F("execve('%s')", nsjconf->argv[0]); - exit(1); + + PLOG_E("execve('%s') failed", nsjconf->argv[0]); + + _exit(1); } static void subprocAdd(struct nsjconf_t *nsjconf, pid_t pid, int sock) @@ -135,7 +138,9 @@ void subprocDisplay(struct nsjconf_t *nsjconf) struct pids_t *p; LIST_FOREACH(p, &nsjconf->pids, pointers) { time_t diff = now - p->start; - LOG_I("PID: %d, Remote host: %s, Run time: %ld sec.", p->pid, p->remote_txt, (long)diff); + time_t left = nsjconf->tlimit ? nsjconf->tlimit - diff : 0; + LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", p->pid, p->remote_txt, + (long)diff, (long)left); } } @@ -201,9 +206,15 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er LOG_D("Creating new process with clone flags: %#x", flags); + int pipefd[2]; + if (pipe2(pipefd, O_CLOEXEC) == -1) { + PLOG_E("pipe2(pipefd, O_CLOEXEC) failed"); + return; + } + pid_t pid = syscall(__NR_clone, flags, NULL, NULL, NULL, 0); if (pid == 0) { - subprocNewProc(nsjconf, fd_in, fd_out, fd_err); + subprocNewProc(nsjconf, fd_in, fd_out, fd_err, pipefd[1]); } if (pid == -1) { PLOG_E("clone(flags=%#x) failed. You probably need root privileges if your system " @@ -212,6 +223,16 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er return; } + char log_buf[4096]; + + ssize_t sz; + while ((sz = read(pipefd[0], log_buf, sizeof(log_buf) - 1)) > 0) { + log_buf[sz] = '\0'; + logDirectly(log_buf); + } + close(pipefd[0]); + close(pipefd[1]); + subprocAdd(nsjconf, pid, fd_in); char cs_addr[64];