aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jail.c55
-rw-r--r--src/log_colored.c65
-rw-r--r--src/main.c21
-rw-r--r--src/utils.c8
4 files changed, 92 insertions, 57 deletions
diff --git a/src/jail.c b/src/jail.c
index 8e05352..1b5cb5b 100644
--- a/src/jail.c
+++ b/src/jail.c
@@ -16,16 +16,17 @@
#include "log.h"
typedef struct jail_prisoner_process {
- pid_t prisoner_pid;
psocket client_psock;
char host_buf[NI_MAXHOST], service_buf[NI_MAXSERV];
char *newroot;
} jail_prisoner_process;
-static int jail_mainloop_epoll(int epoll_fd, jail_ctx *ctx[], size_t siz);
+static int jail_mainloop_epoll(int epoll_fd, jail_ctx *ctx[], size_t siz)
+ __attribute__((noreturn));
static int jail_accept_client(jail_ctx *ctx[],
size_t siz, struct epoll_event *event);
-static int jail_childfn(void *arg);
+static int jail_childfn(void *arg)
+ __attribute__((noreturn));
void jail_init_ctx(jail_ctx **ctx, size_t stacksize)
@@ -144,12 +145,15 @@ pid_t jail_daemonize(int epoll_fd, jail_ctx *ctx[], size_t siz)
W_STRERR("%s", "Jail daemonize");
return -1;
case 0:
- N("%s", "Jail daemon mainloop");
+ N("Jail daemon mainloop on Epoll fd %d", epoll_fd);
jail_mainloop_epoll(epoll_fd, ctx, siz);
- break;
}
D2("Jail daemon pid: %d", p);
+ close(epoll_fd);
+ for (i = 0; i < siz; ++i)
+ socket_close(&ctx[i]->sock);
+
return p;
}
@@ -169,7 +173,6 @@ static int jail_mainloop_epoll(int epoll_fd, jail_ctx *ctx[], size_t siz)
assert( set_child_sighandler() == 0 );
sigemptyset(&eset);
- D2("Epoll fd: %d", epoll_fd);
while (1) {
int n, i;
@@ -205,10 +208,9 @@ error:
static int jail_accept_client(jail_ctx *ctx[],
size_t siz, struct epoll_event *event)
{
- int clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|
- CLONE_NEWNS|CLONE_NEWNET;
size_t i, rc = 0;
int s;
+ pid_t prisoner_pid;
jail_prisoner_process *args;
for (i = 0; i < siz; ++i) {
@@ -234,8 +236,15 @@ static int jail_accept_client(jail_ctx *ctx[],
ctx[i]->host_buf, ctx[i]->service_buf,
args->client_psock.fd);
- args->prisoner_pid = clone(jail_childfn, ctx[i]->stack_beg,
- SIGCHLD|clone_flags, args);
+ prisoner_pid = fork();
+ switch (prisoner_pid) {
+ case -1:
+ W_STRERR("%s", "Jail client fork");
+ goto error;
+ case 0:
+ jail_childfn(args);
+ }
+ N2("Jail prisoner pid %d", prisoner_pid);
rc = 1;
error:
@@ -256,21 +265,26 @@ static int jail_childfn(void *arg)
int s, term_fd;
struct termios *term = NULL;
struct winsize *win = NULL;
- pid_t child_pid;
+ int unshare_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|
+ CLONE_NEWNS|CLONE_NEWNET;
+ pid_t self_pid, child_pid;
assert(arg);
args = (jail_prisoner_process *) arg;
+ self_pid = getpid();
if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0)
- FATAL("Jail child prctl for pid %d", args->prisoner_pid);
+ FATAL("Jail child prctl for pid %d", self_pid);
if (!args->newroot)
- FATAL("New root set for pid %d", args->prisoner_pid);
+ FATAL("New root set for pid %d", self_pid);
+
+ D2("Unshare prisoner %d", self_pid);
+ if (unshare(unshare_flags))
+ FATAL("Unshare prisoner %d", self_pid);
D2("Safe change root to: '%s'", args->newroot);
- if (safe_chroot(args->newroot)) {
- E2("Safe jail chroot to '%s' failed", args->newroot);
- exit(EXIT_FAILURE);
- }
+ if (safe_chroot(args->newroot))
+ FATAL("Safe jail chroot to '%s' failed", args->newroot);
D2("Mounting rootfs to '%s'", args->newroot);
mount_root();
@@ -305,19 +319,16 @@ static int jail_childfn(void *arg)
switch (child_pid) {
case -1:
FATAL("Forking a new pseudo terminal for pid %d",
- args->prisoner_pid);
+ self_pid);
break;
case 0:
D2("Executing '%s'", "/bin/bash");
if (execl("/bin(bash", "/bin/bash", (char *) NULL))
- FATAL("Execute a shell for pid %d", args->prisoner_pid);
+ FATAL("Execute a shell for pid %d", self_pid);
break;
default:
waitpid(child_pid, &s, 0);
}
-printf("_%d,%d_\n", child_pid, getuid());
-sleep(10);
-
exit(EXIT_FAILURE);
}
diff --git a/src/log_colored.c b/src/log_colored.c
index 9aaa23f..5434562 100644
--- a/src/log_colored.c
+++ b/src/log_colored.c
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <assert.h>
#include "log_colored.h"
@@ -29,6 +31,7 @@ void log_close_colored(void)
void log_fmt_colored(log_priority prio, const char *fmt, ...)
{
+ pid_t my_pid;
char out[LOGMSG_MAXLEN+1] = {0};
va_list arglist;
@@ -37,18 +40,19 @@ void log_fmt_colored(log_priority prio, const char *fmt, ...)
assert( vsnprintf(&out[0], LOGMSG_MAXLEN, fmt, arglist) >= 0 );
va_end(arglist);
+ my_pid = getpid();
switch (prio) {
case DEBUG:
- printf("[DEBUG] %s\n", out);
+ printf("[DEBUG] [%d] %s\n", my_pid, out);
break;
case NOTICE:
- printf("[" GRN "NOTICE" RESET "] %s\n", out);
+ printf("[" GRN "NOTICE" RESET "] [%d] %s\n", my_pid, out);
break;
case WARNING:
- printf("[" YEL "WARNING" RESET "] %s\n", out);
+ printf("[" YEL "WARNING" RESET "][%d] %s\n", my_pid, out);
break;
case ERROR:
- printf("[" RED "ERROR" RESET "] %s\n", out);
+ printf("[" RED "ERROR" RESET "] [%d] %s\n", my_pid, out);
break;
}
}
@@ -56,6 +60,7 @@ void log_fmt_colored(log_priority prio, const char *fmt, ...)
void log_fmtex_colored(log_priority prio, const char *srcfile,
size_t line, const char *fmt, ...)
{
+ pid_t my_pid;
char out[LOGMSG_MAXLEN+1] = {0};
va_list arglist;
@@ -64,18 +69,22 @@ void log_fmtex_colored(log_priority prio, const char *srcfile,
assert( vsnprintf(&out[0], LOGMSG_MAXLEN, fmt, arglist) >= 0 );
va_end(arglist);
+ my_pid = getpid();
switch (prio) {
case DEBUG:
- printf("[DEBUG] %s.%lu: %s\n", srcfile, line, out);
+ printf("[DEBUG] [%d] %s.%lu: %s\n", my_pid, srcfile, line, out);
break;
case NOTICE:
- printf("[" GRN "NOTICE" RESET "] %s.%lu: %s\n", srcfile, line, out);
+ printf("[" GRN "NOTICE" RESET "] [%d] %s.%lu: %s\n",
+ my_pid, srcfile, line, out);
break;
case WARNING:
- printf("[" YEL "WARNING" RESET "] %s.%lu: %s\n", srcfile, line, out);
+ printf("[" YEL "WARNING" RESET "][%d] %s.%lu: %s\n",
+ my_pid, srcfile, line, out);
break;
case ERROR:
- printf("[" RED "ERROR" RESET "] %s.%lu: %s\n", srcfile, line, out);
+ printf("[" RED "ERROR" RESET "] [%d] %s.%lu: %s\n",
+ my_pid, srcfile, line, out);
break;
}
}
@@ -83,6 +92,7 @@ void log_fmtex_colored(log_priority prio, const char *srcfile,
void log_fmtexerr_colored(log_priority prio, const char *srcfile,
size_t line, const char *fmt, ...)
{
+ pid_t my_pid;
int saved_errno = errno;
char out[LOGMSG_MAXLEN+1] = {0};
va_list arglist;
@@ -92,37 +102,46 @@ void log_fmtexerr_colored(log_priority prio, const char *srcfile,
assert( vsnprintf(&out[0], LOGMSG_MAXLEN, fmt, arglist) >= 0 );
va_end(arglist);
+ my_pid = getpid();
switch (prio) {
case DEBUG:
if (saved_errno)
- printf("[DEBUG] %s.%lu: %s failed: %s\n", srcfile, line, out,
- strerror(saved_errno));
+ printf("[DEBUG] [%d] %s.%lu: %s failed: %s\n",
+ my_pid, srcfile, line, out,
+ strerror(saved_errno));
else
- printf("[DEBUG] %s.%lu: %s failed\n", srcfile, line, out);
+ printf("[DEBUG] [%d] %s.%lu: %s failed\n",
+ my_pid, srcfile, line, out);
break;
case NOTICE:
if (saved_errno)
- printf("[" GRN "NOTICE" RESET "] %s.%lu: %s failed: %s\n", srcfile,
- line, out, strerror(saved_errno));
+ printf("[" GRN "NOTICE" RESET "] [%d] %s.%lu: %s failed: %s\n",
+ my_pid, srcfile,
+ line, out, strerror(saved_errno));
else
- printf("[" GRN "NOTICE" RESET "] %s.%lu: %s failed\n", srcfile,
- line, out);
+ printf("[" GRN "NOTICE" RESET "] [%d] %s.%lu: %s failed\n",
+ my_pid, srcfile,
+ line, out);
break;
case WARNING:
if (saved_errno)
- printf("[" YEL "WARNING" RESET "] %s.%lu: %s failed: %s\n", srcfile,
- line, out, strerror(saved_errno));
+ printf("[" YEL "WARNING" RESET "][%d] %s.%lu: %s failed: %s\n",
+ my_pid, srcfile,
+ line, out, strerror(saved_errno));
else
- printf("[" YEL "WARNING" RESET "] %s.%lu: %s failed\n", srcfile,
- line, out);
+ printf("[" YEL "WARNING" RESET "][%d] %s.%lu: %s failed\n",
+ my_pid, srcfile,
+ line, out);
break;
case ERROR:
if (saved_errno)
- printf("[" RED "ERROR" RESET "] %s.%lu: %s failed: %s\n", srcfile,
- line, out, strerror(saved_errno));
+ printf("[" RED "ERROR" RESET "] [%d] %s.%lu: %s failed: %s\n",
+ my_pid, srcfile,
+ line, out, strerror(saved_errno));
else
- printf("[" RED "ERROR" RESET "] %s.%lu: %s failed\n", srcfile,
- line, out);
+ printf("[" RED "ERROR" RESET "] [%d] %s.%lu: %s failed\n",
+ my_pid, srcfile,
+ line, out);
break;
}
}
diff --git a/src/main.c b/src/main.c
index a3b9941..73fb5b2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -23,7 +23,7 @@ int main(int argc, char *argv[])
server_ctx *srv[srv_siz];
jail_ctx *jail[jail_siz];
forward_ctx *ssh_fwd = NULL;
- int epoll_fd, proc_status;
+ int jail_epoll_fd, srv_epoll_fd, proc_status;
pid_t daemon_pid, srv_pid, jail_pid, wpid;
(void) argc;
@@ -48,6 +48,8 @@ int main(int argc, char *argv[])
jail_ports[1] = "33334";
for (size_t i = 0; i < jail_siz; ++i) {
+ D("Initialising jail service on port %s", jail_ports[i]);
+
jail_init_ctx(&jail[i], MAX_STACKSIZE);
jail[i]->newroot = strdup("/home/lns/git/busybox/sysroot");
ABORT_ON_FATAL( jail_setup(jail[i], "127.0.0.1", jail_ports[i]),
@@ -56,11 +58,10 @@ int main(int argc, char *argv[])
"Jail validation" );
}
- D2("%s", "Jail daemon epoll setup");
- epoll_fd = jail_setup_epoll( jail, jail_siz );
- D2("Jail epoll fd: %d", epoll_fd);
- ABORT_ON_FATAL( epoll_fd < 0, "Jail daemon epoll setup" );
- jail_pid = jail_daemonize(epoll_fd, jail, jail_siz);
+ jail_epoll_fd = jail_setup_epoll( jail, jail_siz );
+ D2("Jail epoll fd: %d", jail_epoll_fd);
+ ABORT_ON_FATAL( jail_epoll_fd < 0, "Jail daemon epoll setup" );
+ jail_pid = jail_daemonize(jail_epoll_fd, jail, jail_siz);
ABORT_ON_FATAL( jail_pid < 1, "Jail daemon startup" );
{
@@ -88,16 +89,16 @@ int main(int argc, char *argv[])
}
D2("%s", "Server epoll setup");
- epoll_fd = server_setup_epoll( srv, srv_siz );
- D2("Server epoll fd: %d", epoll_fd);
- ABORT_ON_FATAL( epoll_fd < 0, "Server epoll setup" );
+ srv_epoll_fd = server_setup_epoll( srv, srv_siz );
+ D2("Server epoll fd: %d", srv_epoll_fd);
+ ABORT_ON_FATAL( srv_epoll_fd < 0, "Server epoll setup" );
D2("Server dropping privileges to %s:%s", "nobody", "NULL");
ABORT_ON_FATAL( change_user_group("nobody", NULL),
"Server dropping privileges" );
N("%s", "Server epoll mainloop");
- srv_pid = server_daemonize( epoll_fd, srv, srv_siz );
+ srv_pid = server_daemonize( srv_epoll_fd, srv, srv_siz );
ABORT_ON_FATAL( srv_pid < 1, "Server epoll mainloop" );
while (1) {
diff --git a/src/utils.c b/src/utils.c
index 41fc7d4..0959cee 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -125,10 +125,12 @@ int close_fds_except(int fds, ...)
max_fd = sysconf(_SC_OPEN_MAX) - 1;
if (max_fd <= 0)
return 1;
+ if (fds < 0)
+ return 1;
va_start(ap, fds);
{
- int *all_fds = malloc(max_fd * sizeof(*all_fds));
+ int *all_fds = (int *) malloc((max_fd+1) * sizeof(*all_fds));
assert(all_fds);
memset(all_fds, -1, max_fd * sizeof(*all_fds));
@@ -136,6 +138,7 @@ int close_fds_except(int fds, ...)
while ( (fd = va_arg(ap, int)) >= 0 ) {
all_fds[except_count++] = fd;
}
+ all_fds[except_count++] = fds;
for (fd = max_fd; fd >= 0; --fd) {
found = 0;
@@ -164,7 +167,8 @@ int redirect_devnull_to(int fds, ...)
null_fd = open("/dev/null", O_RDWR);
if (null_fd < 0)
return -1;
- assert(null_fd >= 0);
+ if (fds < -1)
+ return -1;
va_start(ap, fds);
{