aboutsummaryrefslogtreecommitdiff
path: root/src/jail.c
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-05-02 16:15:12 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-05-02 16:15:12 +0200
commite6d9e7073ea1e23a3b22440fa69ce92691ca328d (patch)
tree3fb974880b1ba48f06a5ce430ff0d5983008c180 /src/jail.c
parent3ef3c65b4d19df39e020c1d5f778dafdf493a635 (diff)
POTD skeleton #40.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src/jail.c')
-rw-r--r--src/jail.c55
1 files changed, 33 insertions, 22 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);
}