Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seccomp: support seccomp listener #438

Merged
merged 5 commits into from
Aug 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ libcrun_SOURCES = src/libcrun/utils.c \
src/libcrun/status.c \
src/libcrun/terminal.c \
src/libcrun/chroot_realpath.c \
src/libcrun/signals.c
src/libcrun/signals.c \
src/libcrun/seccomp_notify.c


libcrun_la_SOURCES = $(libcrun_SOURCES)
libcrun_la_CFLAGS = -I $(abs_top_builddir)/libocispec/src -I $(abs_top_srcdir)/libocispec/src -fvisibility=hidden
Expand Down Expand Up @@ -62,7 +64,7 @@ crun_LDFLAGS = $(CRUN_LDFLAGS)
EXTRA_DIST = COPYING COPYING.libcrun README.md NEWS SECURITY.md rpm/crun.spec.in autogen.sh \
src/crun.h src/list.h src/run.h src/delete.h src/kill.h src/pause.h src/unpause.h \
src/create.h src/start.h src/state.h src/exec.h src/spec.h src/update.h src/ps.h \
src/checkpoint.h src/restore.h \
src/checkpoint.h src/restore.h src/libcrun/seccomp_notify.h src/libcrun/seccomp_notify_plugin.h \
src/libcrun/container.h src/libcrun/seccomp.h src/libcrun/ebpf.h src/libcrun/cgroup.h \
src/libcrun/linux.h src/libcrun/utils.h src/libcrun/error.h src/libcrun/criu.h \
src/libcrun/status.h src/libcrun/terminal.h \
Expand Down
2 changes: 1 addition & 1 deletion cfg.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ local-checks-to-skip = \
show-vc-list-except:
@$(VC_LIST_EXCEPT)

VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|maint.mk|git.mk|tests.*|COPYING$$
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|maint.mk|git.mk|tests.*|COPYING|contrib/.*$$

export gl_public_submodule_commit=
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ AC_COMPILE_IFELSE(
AC_DEFINE([HAVE_FSCONFIG_CMD_CREATE], 1, [Define if FSCONFIG_CMD_CREATE is available])],
[AC_MSG_RESULT(no)])

dnl seccomp notify API
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
#include <linux/seccomp.h>
int cmd = SECCOMP_GET_NOTIF_SIZES;
]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_SECCOMP_GET_NOTIF_SIZES], 1, [Define if SECCOMP_GET_NOTIF_SIZES is available])],
[AC_MSG_RESULT(no)])

AC_DEFINE([LIBCRUN_PUBLIC], [__attribute__((visibility("default"))) extern], [LIBCRUN_PUBLIC])
AC_SUBST([FOUND_LIBS])
AC_SUBST([CRUN_LDFLAGS])
Expand All @@ -128,6 +138,7 @@ if test -z "$GPERF"; then
AC_MSG_NOTICE(gperf not found - cannot rebuild signal parser code)
fi

AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_DLOPEN], 1, [Define if DLOPEN is available])]], [])

AC_SEARCH_LIBS([argp_parse], [argp], [], [AC_MSG_ERROR([*** argp functions not found - install libargp or argp_standalone])])

Expand Down
2 changes: 2 additions & 0 deletions contrib/seccomp-notify-plugin-example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
full.so: full.c
$(CC) -fPIC -shared -o $@ $< -lpthread
113 changes: 113 additions & 0 deletions contrib/seccomp-notify-plugin-example/full.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
A simple plugin that always returns ENOSPC.
It handles the notification in an async way. Spawning a thread for each request.
*/

#include <stdlib.h>
#include <errno.h>
#include <linux/seccomp.h>
#include <stdio.h>
#include <pthread.h>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include "../../src/libcrun/seccomp_notify_plugin.h"

struct args_s
{
uint64_t id;
int seccomp_fd;
struct seccomp_notif_resp *resp;
};

static void *
start_routine (void *arg)
{
struct args_s *args = arg;
int ret;

/* Pretend we are busy. */
sleep (3);

args->resp->id = args->id;
args->resp->error = -ENOSPC;
args->resp->flags = 0;

ret = ioctl (args->seccomp_fd, SECCOMP_IOCTL_NOTIF_SEND, args->resp);
if (ret < 0)
abort ();

free (args->resp);
free (args);

return NULL;
}

static int
handle_async (struct seccomp_notif_sizes *sizes, struct seccomp_notif *sreq, int seccomp_fd)
{
/* On errors we leak memory, but anyway we return the error and the watcher is terminated immediately. */
pthread_t thread;
struct args_s *args;
pthread_attr_t attr;

args = malloc (sizeof (*args));
if (args == NULL)
return -errno;

args->resp = malloc (sizes->seccomp_notif_resp);
if (args->resp == NULL)
return -errno;

args->id = sreq->id;
args->seccomp_fd = seccomp_fd;

if (pthread_attr_init (&attr) < 0)
return -errno;

if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) < 0)
return -errno;

if (pthread_create (&thread, &attr, start_routine, args) < 0)
return -errno;

if (pthread_attr_destroy (&attr) < 0)
return -errno;

return 0;
}

int
run_oci_seccomp_notify_start (void **opaque, struct libcrun_load_seccomp_notify_conf_s *conf, size_t size_configuration)
{
if (size_configuration != sizeof (struct libcrun_load_seccomp_notify_conf_s))
return -EINVAL;

return 0;
}

int
run_oci_seccomp_notify_handle_request (void *opaque, struct seccomp_notif_sizes *sizes, struct seccomp_notif *sreq, struct seccomp_notif_resp *sresp, int seccomp_fd, int *handled)
{
int ret;

ret = handle_async (sizes, sreq, seccomp_fd);
if (ret < 0)
return ret;

*handled = RUN_OCI_SECCOMP_NOTIFY_HANDLE_DELAYED_RESPONSE;
return 0;
}

int
run_oci_seccomp_notify_stop (void *opaque)
{
return 0;
}

int
run_oci_seccomp_notify_plugin_version ()
{
return 1;
}
18 changes: 18 additions & 0 deletions contrib/seccomp-notify-plugin-rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "seccomp-watcher"
version = "0.1.0"
authors = ["Giuseppe Scrivano <[email protected]>"]
edition = "2018"

[dependencies]
libc = { version = "0.2.14", default-features = false }
nc = "0.4.7"

[lib]
name = "seccompwatcher_rs"
path = "src/seccompwatcher.rs"
crate-type = ["dylib"]

[profile.release]
panic = "abort"
lto = true
Loading