aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-01-12 17:13:38 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-01-12 17:13:38 +0900
commit3f435efb5d6accc3fdab02e3cd061e81b1652b3a (patch)
treedf2102e2934809bb7553bf2525cac2731444efcd
parent5f78d95ac909738f6a54c8ad707ea659cf2d6ab3 (diff)
downloadpoe-3f435efb5d6accc3fdab02e3cd061e81b1652b3a.tar.gz
nonblocking pipe
-rw-r--r--sandbox/sandbox.c64
-rw-r--r--sandbox/sandbox.h1
2 files changed, 45 insertions, 20 deletions
diff --git a/sandbox/sandbox.c b/sandbox/sandbox.c
index 148d07a..cf1b584 100644
--- a/sandbox/sandbox.c
+++ b/sandbox/sandbox.c
@@ -87,11 +87,24 @@ get_arg(pid_t pid, int i)
return ptrace(PTRACE_PEEKUSER, pid, sizeof(intptr_t) * (size_t)regs[i - 1]);
}
-static enum poe_handler_result
-handle_syscall(pid_t pid, int syscalln) {
+static void
+handle_syscall(pid_t pid)
+{
+ errno = 0;
+ int syscalln = ptrace(PTRACE_PEEKUSER, pid, sizeof(long) * ORIG_RAX);
+ if (errno) ERROR("ptrace(PTRACE_PEEKUSER) failed");
+
switch (syscalln) {
+ default:
+ goto kill;
}
- return POE_PROHIBITED;
+kill:
+ kill(pid, SIGKILL);
+ char *rule = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, syscalln);
+ if (!rule) ERROR("seccomp_syscall_resolve_num_arch() failed");
+ FINISH(POE_SIGNALED, -1, "System call %s is blocked", rule);
+allowed:
+ ptrace(PTRACE_CONT, pid, 0, 0);
}
static const char *
@@ -145,21 +158,7 @@ sigchld_handler(sd_event_source *es, const struct signalfd_siginfo *si, void *vm
int e = status >> 16 & 0xff;
switch (e) {
case PTRACE_EVENT_SECCOMP:
- errno = 0;
- int syscalln = ptrace(PTRACE_PEEKUSER, spid, sizeof(long) * ORIG_RAX);
- if (errno) ERROR("ptrace(PTRACE_PEEKUSER, ) failed");
- enum poe_handler_result ret = handle_syscall(spid, syscalln);
- if (ret == POE_HANDLED) {
- // cancel syscall
- ptrace(PTRACE_POKEUSER, spid, sizeof(long) * ORIG_RAX, -1);
- } else if (ret == POE_PROHIBITED) {
- // implicitly prohibited syscall
- kill(spid, SIGKILL);
- char *rule = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, syscalln);
- if (!rule) ERROR("seccomp_syscall_resolve_num_arch() failed");
- FINISH(POE_SIGNALED, -1, "System call %s is blocked", rule);
- }
- ptrace(PTRACE_CONT, spid, 0, 0);
+ handle_syscall(spid);
break;
case PTRACE_EVENT_CLONE:
case PTRACE_EVENT_FORK:
@@ -176,9 +175,21 @@ sigchld_handler(sd_event_source *es, const struct signalfd_siginfo *si, void *vm
}
static int
+sigint_handler(sd_event_source *es, const struct signalfd_siginfo *si, void *vmpid)
+{
+ (void)es;
+ (void)si;
+ (void)vmpid;
+ FINISH(POE_TIMEDOUT, -1, "Supervisor terminated");
+ return 0;
+}
+
+static int
timer_handler(sd_event_source *es, uint64_t usec, void *vmpid)
{
- (void)es; (void)usec; (void)vmpid;
+ (void)es;
+ (void)usec;
+ (void)vmpid;
FINISH(POE_TIMEDOUT, -1, NULL);
return 0;
}
@@ -186,7 +197,8 @@ timer_handler(sd_event_source *es, uint64_t usec, void *vmpid)
static int
stdout_handler(sd_event_source *es, int fd, uint32_t revents, void *vorig_fd)
{
- (void)es; (void)revents;
+ (void)es;
+ (void)revents;
int orig_fd = *(int *)vorig_fd;
char buf[BUFSIZ];
int n;
@@ -233,6 +245,8 @@ main(int argc, char *argv[])
sigset_t mask, omask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
+ sigaddset(&mask, SIGINT); // auau
+ sigaddset(&mask, SIGTERM); // auau
sigprocmask(SIG_BLOCK, &mask, &omask);
int stdout_fd[2], stderr_fd[2];
@@ -259,8 +273,18 @@ main(int argc, char *argv[])
int stdout_fileno = STDOUT_FILENO;
int stderr_fileno = STDERR_FILENO;
+ int fflags;
+ fflags = fcntl(stdout_fd[0], F_GETFL, 0);
+ NONNEGATIVE(fflags);
+ NONNEGATIVE(fcntl(stdout_fd[0], F_SETFL, fflags | O_NONBLOCK));
+ fflags = fcntl(stderr_fd[0], F_GETFL, 0);
+ NONNEGATIVE(fflags);
+ NONNEGATIVE(fcntl(stderr_fd[0], F_SETFL, fflags | O_NONBLOCK));
+
NONNEGATIVE(sd_event_default(&event));
NONNEGATIVE(sd_event_add_signal(event, NULL, SIGCHLD, sigchld_handler, &pid));
+ NONNEGATIVE(sd_event_add_signal(event, NULL, SIGINT, sigint_handler, &pid));
+ NONNEGATIVE(sd_event_add_signal(event, NULL, SIGTERM, sigint_handler, &pid));
NONNEGATIVE(sd_event_now(event, CLOCK_MONOTONIC, &now));
NONNEGATIVE(sd_event_add_time(event, NULL, CLOCK_MONOTONIC, now + POE_TIME_LIMIT, 0, timer_handler, &pid));
NONNEGATIVE(sd_event_add_io(event, NULL, stdout_fd[0], EPOLLIN, stdout_handler, &stdout_fileno));
diff --git a/sandbox/sandbox.h b/sandbox/sandbox.h
index 25749e4..2068688 100644
--- a/sandbox/sandbox.h
+++ b/sandbox/sandbox.h
@@ -17,6 +17,7 @@
#include <signal.h>
#include <time.h>
#include <ftw.h>
+#include <fcntl.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <sys/ptrace.h>