forked from mirrors/kore
Merge branch 'master' of mooncake.coders.se:/home/git/kore into acme
This commit is contained in:
commit
a9864c9ff7
|
@ -448,6 +448,9 @@ struct kore_alog_header {
|
|||
struct kore_worker {
|
||||
u_int16_t id;
|
||||
u_int16_t cpu;
|
||||
#if defined(__linux__)
|
||||
int tracing;
|
||||
#endif
|
||||
pid_t pid;
|
||||
int pipe[2];
|
||||
struct connection *msg[2];
|
||||
|
|
|
@ -158,12 +158,17 @@
|
|||
KORE_FILTER_LEN(_scfilt)); \
|
||||
}
|
||||
|
||||
extern int kore_seccomp_tracing;
|
||||
|
||||
void kore_seccomp_init(void);
|
||||
void kore_seccomp_drop(void);
|
||||
void kore_seccomp_enable(void);
|
||||
void kore_seccomp_traceme(void);
|
||||
int kore_seccomp_syscall_resolve(const char *);
|
||||
int kore_seccomp_trace(struct kore_worker *, int);
|
||||
int kore_seccomp_filter(const char *, void *, size_t);
|
||||
|
||||
const char *kore_seccomp_syscall_name(long);
|
||||
struct sock_filter *kore_seccomp_syscall_filter(const char *, int);
|
||||
struct sock_filter *kore_seccomp_syscall_arg(const char *, int, int, int);
|
||||
struct sock_filter *kore_seccomp_syscall_flag(const char *, int, int, int);
|
||||
|
|
|
@ -20,6 +20,11 @@ else
|
|||
CFLAGS+=-O2
|
||||
endif
|
||||
|
||||
ifneq ("$(MINIMAL)", "")
|
||||
CFLAGS+=-DKODEV_MINIMAL
|
||||
LDFLAGS=
|
||||
endif
|
||||
|
||||
OSNAME=$(shell uname -s | sed -e 's/[-_].*//g' | tr A-Z a-z)
|
||||
ifeq ("$(OSNAME)", "darwin")
|
||||
CFLAGS+=-I/opt/local/include/ -I/usr/local/opt/openssl/include
|
||||
|
|
61
src/cli.c
61
src/cli.c
|
@ -22,9 +22,11 @@
|
|||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
@ -141,7 +143,6 @@ static void fatal(const char *, ...) __attribute__((noreturn));
|
|||
static void cli_file_close(int);
|
||||
static void cli_run_kore(void);
|
||||
static void cli_run_kore_python(void);
|
||||
static void cli_generate_certs(void);
|
||||
static void cli_compile_kore(void *);
|
||||
static void cli_link_application(void *);
|
||||
static void cli_compile_source_file(void *);
|
||||
|
@ -164,7 +165,6 @@ static void cli_write_asset(const char *, const char *,
|
|||
struct buildopt *);
|
||||
static void cli_register_kore_file(char *, struct dirent *);
|
||||
static void cli_register_source_file(char *, struct dirent *);
|
||||
static void cli_file_create(const char *, const char *, size_t);
|
||||
static int cli_file_requires_build(struct stat *, const char *);
|
||||
static void cli_find_files(const char *,
|
||||
void (*cb)(char *, struct dirent *));
|
||||
|
@ -197,10 +197,11 @@ static void cli_help(int, char **);
|
|||
static void cli_info(int, char **);
|
||||
static void cli_build(int, char **);
|
||||
static void cli_clean(int, char **);
|
||||
static void cli_create(int, char **);
|
||||
static void cli_reload(int, char **);
|
||||
static void cli_flavor(int, char **);
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static void cli_create(int, char **);
|
||||
static void cli_create_help(void);
|
||||
|
||||
static void file_create_src(void);
|
||||
|
@ -209,6 +210,10 @@ static void file_create_gitignore(void);
|
|||
static void file_create_python_src(void);
|
||||
static void file_create_python_config(void);
|
||||
|
||||
static void cli_generate_certs(void);
|
||||
static void cli_file_create(const char *, const char *, size_t);
|
||||
#endif
|
||||
|
||||
static struct cmd cmds[] = {
|
||||
{ "help", "this help text", cli_help },
|
||||
{ "run", "run an application (-fnr implied)", cli_run },
|
||||
|
@ -216,11 +221,14 @@ static struct cmd cmds[] = {
|
|||
{ "info", "show info on kore on this system", cli_info },
|
||||
{ "build", "build an application", cli_build },
|
||||
{ "clean", "cleanup the build files", cli_clean },
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
{ "create", "create a new application skeleton", cli_create },
|
||||
#endif
|
||||
{ "flavor", "switch between build flavors", cli_flavor },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static struct filegen gen_files[] = {
|
||||
{ file_create_src },
|
||||
{ file_create_config },
|
||||
|
@ -370,6 +378,8 @@ static const char *dh2048_data =
|
|||
|
||||
static const char *gitignore = "*.o\n.flavor\n.objs\n%s.so\nassets.h\ncert\n";
|
||||
|
||||
#endif /* !KODEV_MINIMAL */
|
||||
|
||||
static int s_fd = -1;
|
||||
static char *appl = NULL;
|
||||
static int run_after = 0;
|
||||
|
@ -399,6 +409,9 @@ usage(void)
|
|||
int i;
|
||||
|
||||
fprintf(stderr, "Usage: kodev [command]\n");
|
||||
#if defined(KODEV_MINIMAL)
|
||||
fprintf(stderr, "minimal (only build commands supported)\n");
|
||||
#endif
|
||||
fprintf(stderr, "\nAvailable commands:\n");
|
||||
|
||||
for (i = 0; cmds[i].name != NULL; i++)
|
||||
|
@ -457,6 +470,7 @@ cli_help(int argc, char **argv)
|
|||
usage();
|
||||
}
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static void
|
||||
cli_create_help(void)
|
||||
{
|
||||
|
@ -529,6 +543,7 @@ cli_create(int argc, char **argv)
|
|||
printf("WARNING: DO NOT USE THE GENERATED DH PARAMETERS "
|
||||
"AND CERTIFICATES IN PRODUCTION\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cli_flavor(int argc, char **argv)
|
||||
|
@ -572,13 +587,17 @@ cli_flavor(int argc, char **argv)
|
|||
static void
|
||||
cli_build(int argc, char **argv)
|
||||
{
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
int l;
|
||||
char *data;
|
||||
#endif
|
||||
struct dirent dp;
|
||||
struct cfile *cf;
|
||||
struct buildopt *bopt;
|
||||
struct timeval times[2];
|
||||
char *build_path;
|
||||
int requires_relink, l;
|
||||
char *sofile, *config, *data;
|
||||
int requires_relink;
|
||||
char *sofile, *config;
|
||||
char *assets_path, *p, *src_path;
|
||||
char pwd[PATH_MAX], *assets_header;
|
||||
|
||||
|
@ -614,11 +633,14 @@ cli_build(int argc, char **argv)
|
|||
|
||||
cli_flavor_load();
|
||||
bopt = cli_buildopt_new("_default");
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
if (!cli_file_exists(build_path)) {
|
||||
l = cli_vasprintf(&data, build_data, appl);
|
||||
cli_file_create("conf/build.conf", data, l);
|
||||
free(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
cli_find_files(src_path, cli_register_source_file);
|
||||
free(src_path);
|
||||
|
@ -695,6 +717,7 @@ cli_build(int argc, char **argv)
|
|||
|
||||
free(assets_header);
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
if (bopt->kore_flavor == NULL ||
|
||||
!strstr(bopt->kore_flavor, "NOTLS=1")) {
|
||||
if (!cli_dir_exists("cert")) {
|
||||
|
@ -702,6 +725,7 @@ cli_build(int argc, char **argv)
|
|||
cli_generate_certs();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bopt->single_binary) {
|
||||
requires_relink++;
|
||||
|
@ -817,6 +841,7 @@ cli_info(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static void
|
||||
file_create_python_src(void)
|
||||
{
|
||||
|
@ -885,6 +910,7 @@ file_create_gitignore(void)
|
|||
free(name);
|
||||
free(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cli_mkdir(const char *fpath, int mode)
|
||||
|
@ -1024,6 +1050,7 @@ cli_file_write(int fd, const void *buf, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static void
|
||||
cli_file_create(const char *name, const char *data, size_t len)
|
||||
{
|
||||
|
@ -1035,6 +1062,7 @@ cli_file_create(const char *name, const char *data, size_t len)
|
|||
|
||||
printf("created %s\n", name);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
|
||||
|
@ -1042,7 +1070,10 @@ cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
|
|||
cli_file_writef(s_fd, "extern const u_int8_t asset_%s_%s[];\n", n, e);
|
||||
cli_file_writef(s_fd, "extern const u_int32_t asset_len_%s_%s;\n", n, e);
|
||||
cli_file_writef(s_fd, "extern const time_t asset_mtime_%s_%s;\n", n, e);
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
cli_file_writef(s_fd, "extern const char *asset_sha256_%s_%s;\n", n, e);
|
||||
#endif
|
||||
|
||||
if (bopt->flavor_nohttp == 0) {
|
||||
cli_file_writef(s_fd,
|
||||
|
@ -1053,17 +1084,21 @@ cli_write_asset(const char *n, const char *e, struct buildopt *bopt)
|
|||
static void
|
||||
cli_build_asset(char *fpath, struct dirent *dp)
|
||||
{
|
||||
u_int8_t *d;
|
||||
struct stat st;
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
SHA256_CTX sctx;
|
||||
int i, len;
|
||||
struct mime_type *mime;
|
||||
const char *mime_type;
|
||||
u_int8_t digest[SHA256_DIGEST_LENGTH];
|
||||
char hash[(SHA256_DIGEST_LENGTH * 2) + 1];
|
||||
#endif
|
||||
off_t off;
|
||||
void *base;
|
||||
struct mime_type *mime;
|
||||
struct buildopt *bopt;
|
||||
const char *mime_type;
|
||||
int in, out, i, len;
|
||||
u_int8_t *d, digest[SHA256_DIGEST_LENGTH];
|
||||
int in, out;
|
||||
char *cpath, *ext, *opath, *p, *name;
|
||||
char hash[(SHA256_DIGEST_LENGTH * 2) + 1];
|
||||
|
||||
bopt = cli_buildopt_default();
|
||||
|
||||
|
@ -1145,6 +1180,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
|
|||
*/
|
||||
cli_file_writef(out, "0x00");
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
/* Calculate the SHA256 digest of the contents. */
|
||||
(void)SHA256_Init(&sctx);
|
||||
(void)SHA256_Update(&sctx, base, st.st_size);
|
||||
|
@ -1167,6 +1203,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
|
|||
mime_type = mime->type;
|
||||
else
|
||||
mime_type = "text/plain";
|
||||
#endif
|
||||
|
||||
/* Add the meta data. */
|
||||
cli_file_writef(out, "};\n\n");
|
||||
|
@ -1176,6 +1213,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
|
|||
"const time_t asset_mtime_%s_%s = %" PRI_TIME_T ";\n",
|
||||
name, ext, st.st_mtime);
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
if (bopt->flavor_nohttp == 0) {
|
||||
cli_file_writef(out,
|
||||
"const char *asset_sha256_%s_%s = \"\\\"%s\\\"\";\n",
|
||||
|
@ -1183,6 +1221,7 @@ cli_build_asset(char *fpath, struct dirent *dp)
|
|||
cli_file_writef(out, http_serveable_function,
|
||||
name, ext, name, ext, name, ext, name, ext, mime_type);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the file symbols into assets.h so they can be used. */
|
||||
cli_write_asset(name, ext, bopt);
|
||||
|
@ -1321,6 +1360,7 @@ cli_find_files(const char *path, void (*cb)(char *, struct dirent *))
|
|||
closedir(d);
|
||||
}
|
||||
|
||||
#if !defined(KODEV_MINIMAL)
|
||||
static void
|
||||
cli_generate_certs(void)
|
||||
{
|
||||
|
@ -1414,6 +1454,7 @@ cli_generate_certs(void)
|
|||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
cli_compile_source_file(void *arg)
|
||||
|
|
29
src/config.c
29
src/config.c
|
@ -49,6 +49,10 @@
|
|||
#include "acme.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "seccomp.h"
|
||||
#endif
|
||||
|
||||
/* XXX - This is becoming a clusterfuck. Fix it. */
|
||||
|
||||
static int configure_load(char *);
|
||||
|
@ -154,6 +158,10 @@ static int configure_curl_timeout(char *);
|
|||
static int configure_curl_recv_max(char *);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
static int configure_seccomp_tracing(char *);
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
int (*configure)(char *);
|
||||
|
@ -224,6 +232,9 @@ static struct {
|
|||
#if defined(KORE_USE_PLATFORM_PLEDGE)
|
||||
{ "pledge", configure_add_pledge },
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
{ "seccomp_tracing", configure_seccomp_tracing },
|
||||
#endif
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
{ "filemap_ext", configure_filemap_ext },
|
||||
{ "filemap_index", configure_filemap_index },
|
||||
|
@ -1825,3 +1836,21 @@ configure_curl_timeout(char *option)
|
|||
return (KORE_RESULT_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
static int
|
||||
configure_seccomp_tracing(char *opt)
|
||||
{
|
||||
if (!strcmp(opt, "yes")) {
|
||||
kore_seccomp_tracing = 1;
|
||||
} else if (!strcmp(opt, "no")) {
|
||||
kore_seccomp_tracing = 0;
|
||||
} else {
|
||||
printf("bad seccomp_tracing value: %s (expected yes|no)\n",
|
||||
opt);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -498,6 +498,7 @@ json_parse_object(struct kore_json *json, struct kore_json_item *object)
|
|||
|
||||
switch (ch) {
|
||||
case '}':
|
||||
json->offset++;
|
||||
ret = KORE_RESULT_OK;
|
||||
goto cleanup;
|
||||
case '"':
|
||||
|
@ -589,6 +590,7 @@ json_parse_array(struct kore_json *json, struct kore_json_item *array)
|
|||
goto cleanup;
|
||||
|
||||
if (ch == ']') {
|
||||
json->offset++;
|
||||
ret = KORE_RESULT_OK;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
117
src/seccomp.c
117
src/seccomp.c
|
@ -17,7 +17,9 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/reg.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <linux/seccomp.h>
|
||||
|
@ -36,12 +38,8 @@
|
|||
#endif
|
||||
|
||||
#if !defined(SECCOMP_KILL_POLICY)
|
||||
#if defined(KORE_DEBUG)
|
||||
#define SECCOMP_KILL_POLICY SECCOMP_RET_TRAP
|
||||
#else
|
||||
#define SECCOMP_KILL_POLICY SECCOMP_RET_KILL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The bare minimum to be able to run kore. These are added last and can
|
||||
|
@ -140,9 +138,7 @@ static struct sock_filter *seccomp_filter_update(struct sock_filter *,
|
|||
#define filter_prologue_len KORE_FILTER_LEN(filter_prologue)
|
||||
#define filter_epilogue_len KORE_FILTER_LEN(filter_epilogue)
|
||||
|
||||
#if defined(KORE_DEBUG)
|
||||
static void seccomp_trap(int sig, siginfo_t *, void *);
|
||||
#endif
|
||||
static void seccomp_register_violation(struct kore_worker *);
|
||||
|
||||
struct filter {
|
||||
char *name;
|
||||
|
@ -154,6 +150,12 @@ struct filter {
|
|||
static TAILQ_HEAD(, filter) filters;
|
||||
static struct filter *ufilter = NULL;
|
||||
|
||||
/*
|
||||
* If enabled will instruct the parent process to ptrace its children and
|
||||
* log any seccomp SECCOMP_RET_TRACE rule.
|
||||
*/
|
||||
int kore_seccomp_tracing = 0;
|
||||
|
||||
void
|
||||
kore_seccomp_init(void)
|
||||
{
|
||||
|
@ -181,26 +183,20 @@ kore_seccomp_drop(void)
|
|||
void
|
||||
kore_seccomp_enable(void)
|
||||
{
|
||||
#if defined(KORE_DEBUG)
|
||||
struct sigaction sa;
|
||||
#endif
|
||||
struct sock_filter *sf;
|
||||
struct sock_fprog prog;
|
||||
struct kore_runtime_call *rcall;
|
||||
struct filter *filter;
|
||||
size_t prog_len, off, i;
|
||||
|
||||
#if defined(KORE_DEBUG)
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = seccomp_trap;
|
||||
|
||||
if (sigfillset(&sa.sa_mask) == -1)
|
||||
fatalx("sigfillset: %s", errno_s);
|
||||
if (sigaction(SIGSYS, &sa, NULL) == -1)
|
||||
fatalx("sigaction: %s", errno_s);
|
||||
#endif
|
||||
/*
|
||||
* If kore_seccomp_tracing is turned on, set the default policy to
|
||||
* SECCOMP_RET_TRACE so we can log the system calls.
|
||||
*/
|
||||
if (kore_seccomp_tracing) {
|
||||
filter_epilogue[0].k = SECCOMP_RET_TRACE;
|
||||
kore_log(LOG_NOTICE, "seccomp tracing enabled");
|
||||
}
|
||||
|
||||
#if defined(KORE_USE_PYTHON)
|
||||
ufilter = TAILQ_FIRST(&filters);
|
||||
|
@ -243,10 +239,6 @@ kore_seccomp_enable(void)
|
|||
TAILQ_FOREACH(filter, &filters, list) {
|
||||
for (i = 0; i < filter->instructions; i++)
|
||||
sf[off++] = filter->prog[i];
|
||||
#if defined(KORE_DEBUG)
|
||||
kore_log(LOG_INFO,
|
||||
"seccomp filter '%s' added", filter->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; i < filter_epilogue_len; i++)
|
||||
|
@ -292,6 +284,55 @@ kore_seccomp_filter(const char *name, void *prog, size_t len)
|
|||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
void
|
||||
kore_seccomp_traceme(void)
|
||||
{
|
||||
if (kore_seccomp_tracing == 0)
|
||||
return;
|
||||
|
||||
if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1)
|
||||
fatalx("ptrace. %s", errno_s);
|
||||
if (kill(worker->pid, SIGSTOP) == -1)
|
||||
fatalx("kill: %s", errno_s);
|
||||
}
|
||||
|
||||
int
|
||||
kore_seccomp_trace(struct kore_worker *kw, int status)
|
||||
{
|
||||
if (kore_seccomp_tracing == 0)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP) {
|
||||
if (kw->tracing == 0) {
|
||||
kw->tracing = 1;
|
||||
if (ptrace(PTRACE_SETOPTIONS, kw->pid, NULL,
|
||||
PTRACE_O_TRACESECCOMP) == -1)
|
||||
fatal("ptrace: %s", errno_s);
|
||||
if (ptrace(PTRACE_CONT, kw->pid, NULL, NULL) == -1)
|
||||
fatal("ptrace: %s", errno_s);
|
||||
}
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
|
||||
if ((status >> 8) ==
|
||||
(SIGTRAP | (PTRACE_EVENT_SECCOMP << 8)))
|
||||
seccomp_register_violation(kw);
|
||||
if (ptrace(PTRACE_CONT, kw->pid, NULL, NULL) == -1)
|
||||
fatal("ptrace: %s", errno_s);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
if (WIFSTOPPED(status) && kw->tracing) {
|
||||
if (ptrace(PTRACE_CONT, kw->pid, NULL, WSTOPSIG(status)) == -1)
|
||||
fatal("ptrace: %s", errno_s);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
int
|
||||
kore_seccomp_syscall_resolve(const char *name)
|
||||
{
|
||||
|
@ -305,6 +346,19 @@ kore_seccomp_syscall_resolve(const char *name)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
const char *
|
||||
kore_seccomp_syscall_name(long sysnr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; kore_syscall_map[i].name != NULL; i++) {
|
||||
if (kore_syscall_map[i].nr == sysnr)
|
||||
return (kore_syscall_map[i].name);
|
||||
}
|
||||
|
||||
return ("unknown");
|
||||
}
|
||||
|
||||
struct sock_filter *
|
||||
kore_seccomp_syscall_filter(const char *name, int action)
|
||||
{
|
||||
|
@ -349,13 +403,18 @@ kore_seccomp_syscall_flag(const char *name, int action, int arg, int value)
|
|||
return (seccomp_filter_update(filter, name, KORE_FILTER_LEN(filter)));
|
||||
}
|
||||
|
||||
#if defined(KORE_DEBUG)
|
||||
static void
|
||||
seccomp_trap(int sig, siginfo_t *info, void *ucontext)
|
||||
seccomp_register_violation(struct kore_worker *kw)
|
||||
{
|
||||
kore_log(LOG_INFO, "sandbox violation - syscall=%d", info->si_syscall);
|
||||
long sysnr;
|
||||
|
||||
if ((sysnr = ptrace(PTRACE_PEEKUSER, kw->pid,
|
||||
sizeof(long) * ORIG_RAX, NULL)) == -1)
|
||||
fatal("ptrace: %s", errno_s);
|
||||
|
||||
kore_log(LOG_INFO, "seccomp violation, worker=%d, syscall=%s",
|
||||
kw->id, kore_seccomp_syscall_name(sysnr));
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct sock_filter *
|
||||
seccomp_filter_update(struct sock_filter *filter, const char *name, size_t elm)
|
||||
|
|
197
src/worker.c
197
src/worker.c
|
@ -55,6 +55,10 @@
|
|||
#include "curl.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "seccomp.h"
|
||||
#endif
|
||||
|
||||
#if !defined(WAIT_ANY)
|
||||
#define WAIT_ANY (-1)
|
||||
#endif
|
||||
|
@ -72,6 +76,7 @@ struct wlock {
|
|||
|
||||
static int worker_trylock(void);
|
||||
static void worker_unlock(void);
|
||||
static void worker_reaper(pid_t, int);
|
||||
|
||||
static inline int worker_acceptlock_obtain(void);
|
||||
static inline void worker_acceptlock_release(void);
|
||||
|
@ -220,7 +225,19 @@ kore_worker_shutdown(void)
|
|||
pid = waitpid(kw->pid, &status, 0);
|
||||
if (pid == -1)
|
||||
continue;
|
||||
kw->pid = 0;
|
||||
|
||||
#if defined(__linux__)
|
||||
kore_seccomp_trace(kw, status);
|
||||
#endif
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
kw->pid = 0;
|
||||
|
||||
if (!kore_quiet) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d exited", kw->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,6 +349,10 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
|
||||
worker = kw;
|
||||
|
||||
#if defined(__linux__)
|
||||
kore_seccomp_traceme();
|
||||
#endif
|
||||
|
||||
switch (kw->id) {
|
||||
case KORE_WORKER_KEYMGR:
|
||||
(void)snprintf(buf, sizeof(buf), "[keymgr]");
|
||||
|
@ -523,6 +544,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
kore_free(rcall);
|
||||
}
|
||||
|
||||
kore_msg_send(KORE_MSG_PARENT, KORE_MSG_SHUTDOWN, NULL, 0);
|
||||
kore_server_cleanup();
|
||||
|
||||
kore_platform_event_cleanup();
|
||||
|
@ -551,10 +573,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
void
|
||||
kore_worker_reap(void)
|
||||
{
|
||||
u_int16_t idx;
|
||||
pid_t pid;
|
||||
struct kore_worker *kw;
|
||||
const char *func;
|
||||
int status;
|
||||
|
||||
for (;;) {
|
||||
|
@ -570,83 +589,10 @@ kore_worker_reap(void)
|
|||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (pid == 0)
|
||||
return;
|
||||
|
||||
if (pid == 0)
|
||||
return;
|
||||
|
||||
for (idx = 0; idx < worker_count; idx++) {
|
||||
kw = WORKER(idx);
|
||||
if (kw->pid != pid)
|
||||
continue;
|
||||
|
||||
if (!kore_quiet) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d (%d) exited with status %d",
|
||||
kw->id, pid, status);
|
||||
}
|
||||
|
||||
func = "none";
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
if (kw->active_hdlr != NULL)
|
||||
func = kw->active_hdlr->func;
|
||||
#endif
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d (pid: %d) (hdlr: %s) gone",
|
||||
kw->id, kw->pid, func);
|
||||
|
||||
#if defined(__linux__)
|
||||
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSYS) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d died from sandbox violation", kw->id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (kw->id == KORE_WORKER_KEYMGR ||
|
||||
kw->id == KORE_WORKER_ACME) {
|
||||
kore_log(LOG_CRIT,
|
||||
"keymgr or acme process gone, stopping");
|
||||
kw->pid = 0;
|
||||
if (raise(SIGTERM) != 0) {
|
||||
kore_log(LOG_WARNING,
|
||||
"failed to raise SIGTERM signal");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (kw->pid == accept_lock->current &&
|
||||
worker_no_lock == 0)
|
||||
worker_unlock();
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
if (kw->active_hdlr != NULL) {
|
||||
kw->active_hdlr->errors++;
|
||||
kore_log(LOG_NOTICE,
|
||||
"hdlr %s has caused %d error(s)",
|
||||
kw->active_hdlr->func,
|
||||
kw->active_hdlr->errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (worker_policy == KORE_WORKER_POLICY_TERMINATE) {
|
||||
kw->pid = 0;
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker policy is 'terminate', stopping");
|
||||
if (raise(SIGTERM) != 0) {
|
||||
kore_log(LOG_WARNING,
|
||||
"failed to raise SIGTERM signal");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
|
||||
kw->restarted = 1;
|
||||
kore_msg_parent_remove(kw);
|
||||
kore_worker_spawn(idx, kw->id, kw->cpu);
|
||||
kore_msg_parent_add(kw);
|
||||
|
||||
break;
|
||||
worker_reaper(pid, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,6 +666,97 @@ kore_worker_keymgr_response_verify(struct kore_msg *msg, const void *data,
|
|||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
worker_reaper(pid_t pid, int status)
|
||||
{
|
||||
u_int16_t id;
|
||||
struct kore_worker *kw;
|
||||
const char *func;
|
||||
|
||||
for (id = 0; id < worker_count; id++) {
|
||||
kw = WORKER(id);
|
||||
if (kw->pid != pid)
|
||||
continue;
|
||||
|
||||
#if defined(__linux__)
|
||||
if (kore_seccomp_trace(kw, status))
|
||||
break;
|
||||
#endif
|
||||
|
||||
if (!kore_quiet) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d (%d) exited with status %d",
|
||||
kw->id, pid, status);
|
||||
}
|
||||
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
|
||||
kw->pid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
func = "none";
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
if (kw->active_hdlr != NULL)
|
||||
func = kw->active_hdlr->func;
|
||||
#endif
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d (pid: %d) (hdlr: %s) gone",
|
||||
kw->id, kw->pid, func);
|
||||
|
||||
#if defined(__linux__)
|
||||
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSYS) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker %d died from sandbox violation", kw->id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (kw->id == KORE_WORKER_KEYMGR ||
|
||||
kw->id == KORE_WORKER_ACME) {
|
||||
kore_log(LOG_CRIT,
|
||||
"keymgr or acme process gone, stopping");
|
||||
kw->pid = 0;
|
||||
if (raise(SIGTERM) != 0) {
|
||||
kore_log(LOG_WARNING,
|
||||
"failed to raise SIGTERM signal");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (kw->pid == accept_lock->current &&
|
||||
worker_no_lock == 0)
|
||||
worker_unlock();
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
if (kw->active_hdlr != NULL) {
|
||||
kw->active_hdlr->errors++;
|
||||
kore_log(LOG_NOTICE,
|
||||
"hdlr %s has caused %d error(s)",
|
||||
kw->active_hdlr->func,
|
||||
kw->active_hdlr->errors);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (worker_policy == KORE_WORKER_POLICY_TERMINATE) {
|
||||
kw->pid = 0;
|
||||
kore_log(LOG_NOTICE,
|
||||
"worker policy is 'terminate', stopping");
|
||||
if (raise(SIGTERM) != 0) {
|
||||
kore_log(LOG_WARNING,
|
||||
"failed to raise SIGTERM signal");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kore_log(LOG_NOTICE, "restarting worker %d", kw->id);
|
||||
kw->restarted = 1;
|
||||
kore_msg_parent_remove(kw);
|
||||
kore_worker_spawn(idx, kw->id, kw->cpu);
|
||||
kore_msg_parent_add(kw);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
worker_acceptlock_release(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue