Skip to content

Commit 389ea32

Browse files
committed
seccomp: add support for seccomp notify
add support for seccomp notify and add a basic support for emulating mknod and mknodat. The handler implementation is likely going to change, for now it is just a PoC to show how it would work. Requires: containers/crun#438 Requires: libseccomp-2.5 Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent 76548e1 commit 389ea32

File tree

15 files changed

+399
-13
lines changed

15 files changed

+399
-13
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ GO ?= go
66
PROJECT := github.com/containers/conmon
77
PKG_CONFIG ?= pkg-config
88
HEADERS := $(wildcard src/*.h)
9-
OBJS := src/conmon.o src/cmsg.o src/ctr_logging.o src/utils.o src/cli.o src/globals.o src/cgroup.o src/conn_sock.o src/oom.o src/ctrl.o src/ctr_stdio.o src/parent_pipe_fd.o src/ctr_exit.o src/runtime_args.o
9+
OBJS := src/conmon.o src/cmsg.o src/ctr_logging.o src/utils.o src/cli.o src/globals.o src/cgroup.o src/conn_sock.o src/oom.o src/ctrl.o src/ctr_stdio.o src/parent_pipe_fd.o src/ctr_exit.o src/runtime_args.o src/seccomp_notify.o
1010

1111

1212

@@ -26,7 +26,7 @@ else
2626
$(eval GIT_BRANCH_CLEAN := unknown)
2727
endif
2828

29-
override LIBS += $(shell $(PKG_CONFIG) --libs glib-2.0)
29+
override LIBS += $(shell $(PKG_CONFIG) --libs glib-2.0) -ldl
3030

3131
CFLAGS ?= -std=c99 -Os -Wall -Wextra -Werror
3232
override CFLAGS += $(shell $(PKG_CONFIG) --cflags glib-2.0) -DVERSION=\"$(VERSION)\" -DGIT_COMMIT=\"$(GIT_COMMIT)\"

contrib/spec/conmon.spec.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ ExclusiveArch: aarch64 %{arm} ppc64le s390x x86_64
2222
BuildRequires: gcc
2323
BuildRequires: glib2-devel
2424
BuildRequires: glibc-devel
25+
BuildRequires: libseccomp-devel
2526
BuildRequires: git
2627
BuildRequires: pkgconfig
2728

meson.build

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ add_project_arguments('-Os', '-Wall', '-Werror',
3434
language : 'c')
3535

3636
glib = dependency('glib-2.0')
37+
libdl = cc.find_library('dl')
3738

3839
executable('conmon',
3940
['src/conmon.c',
@@ -65,8 +66,10 @@ executable('conmon',
6566
'src/runtime_args.c',
6667
'src/runtime_args.h',
6768
'src/utils.c',
68-
'src/utils.h'],
69-
dependencies : [glib],
69+
'src/utils.h',
70+
'src/seccomp_notify.c',
71+
'src/seccomp_notify.h'],
72+
dependencies : [glib, libdl],
7073
install : true,
7174
install_dir : join_paths(get_option('libexecdir'), 'podman'),
7275
)

src/cli.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ char *opt_log_level = NULL;
4848
char *opt_log_tag = NULL;
4949
gboolean opt_sync = FALSE;
5050
gboolean opt_no_sync_log = FALSE;
51+
char *opt_seccomp_notify_plugins = NULL;
5152
GOptionEntry opt_entries[] = {
5253
{"terminal", 't', 0, G_OPTION_ARG_NONE, &opt_terminal, "Terminal", NULL},
5354
{"stdin", 'i', 0, G_OPTION_ARG_NONE, &opt_stdin, "Stdin", NULL},
@@ -94,6 +95,8 @@ GOptionEntry opt_entries[] = {
9495
{"no-sync-log", 0, 0, G_OPTION_ARG_NONE, &opt_no_sync_log, "Do not manually call sync on logs after container shutdown", NULL},
9596
{"sync", 0, 0, G_OPTION_ARG_NONE, &opt_sync, "Allowing caller to keep the main conmon process as its child by only forking once",
9697
NULL},
98+
{"seccomp-notify-plugins", 0, 0, G_OPTION_ARG_STRING, &opt_seccomp_notify_plugins,
99+
"Plugins to use for managing the seccomp notifications", NULL},
97100
{NULL, 0, 0, 0, NULL, NULL, NULL}};
98101

99102

@@ -140,6 +143,9 @@ void process_cli()
140143
if (opt_cuuid == NULL && (!opt_exec || opt_api_version >= 1))
141144
nexit("Container UUID not provided. Use --cuuid");
142145

146+
if (opt_seccomp_notify_plugins == NULL)
147+
opt_seccomp_notify_plugins = getenv("CONMON_SECCOMP_NOTIFY_PLUGINS");
148+
143149
if (opt_runtime_path == NULL)
144150
nexit("Runtime path not provided. Use --runtime");
145151
if (access(opt_runtime_path, X_OK) < 0)

src/cli.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ extern char *opt_log_level;
4242
extern char *opt_log_tag;
4343
extern gboolean opt_no_sync_log;
4444
extern gboolean opt_sync;
45+
extern char *opt_seccomp_notify_plugins;
4546
extern GOptionEntry opt_entries[];
4647

4748
int initialize_cli(int argc, char *argv[]);

src/conmon.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ int main(int argc, char *argv[])
124124
}
125125

126126
_cleanup_free_ char *csname = NULL;
127+
_cleanup_free_ char *seccomp_listener = NULL;
127128
int workerfd_stdin = -1;
128129
int workerfd_stdout = -1;
129130
int workerfd_stderr = -1;
@@ -165,6 +166,11 @@ int main(int argc, char *argv[])
165166
g_unix_fd_add(winsz_fd_r, G_IO_IN, ctrl_winsz_cb, NULL);
166167
}
167168

169+
if (opt_seccomp_notify_plugins != NULL) {
170+
seccomp_listener = setup_seccomp_socket();
171+
setenv("RUN_OCI_SECCOMP_RECEIVER", seccomp_listener, 1);
172+
}
173+
168174
/* We always create a stderr pipe, because that way we can capture
169175
runc stderr messages before the tty is created */
170176
if (pipe2(fds, O_CLOEXEC) < 0)
@@ -307,6 +313,9 @@ int main(int argc, char *argv[])
307313
if (workerfd_stderr > -1)
308314
close(workerfd_stderr);
309315

316+
if (seccomp_listener != NULL)
317+
g_unix_fd_add(seccomp_socket_fd, G_IO_IN, seccomp_accept_cb, csname);
318+
310319
if (csname != NULL) {
311320
g_unix_fd_add(console_socket_fd, G_IO_IN, terminal_accept_cb, csname);
312321
/* Process any SIGCHLD we may have missed before the signal handler was in place. */

src/conn_sock.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ void conn_sock_shutdown(struct conn_sock_s *sock, int how);
2121
static void sock_try_write_to_mainfd_stdin(struct conn_sock_s *sock);
2222
static gboolean mainfd_write_cb(G_GNUC_UNUSED int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
2323

24-
char *setup_console_socket(void)
24+
static char *setup_socket(int *fd)
2525
{
2626
struct sockaddr_un addr = {0};
27-
_cleanup_free_ const char *tmpdir = g_get_tmp_dir();
28-
_cleanup_free_ char *csname = g_build_filename(tmpdir, "conmon-term.XXXXXX", NULL);
27+
const char *tmpdir = NULL;
28+
_cleanup_free_ char *csname = NULL;
29+
30+
tmpdir = g_get_tmp_dir();
31+
csname = g_build_filename(tmpdir, "conmon.XXXXXX", NULL);
2932
/*
3033
* Generate a temporary name. Is this unsafe? Probably, but we can
3134
* replace it with a rename(2) setup if necessary.
@@ -42,22 +45,32 @@ char *setup_console_socket(void)
4245
ninfof("addr{sun_family=AF_UNIX, sun_path=%s}", addr.sun_path);
4346

4447
/* Bind to the console socket path. */
45-
console_socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
46-
if (console_socket_fd < 0)
47-
pexit("Failed to create console-socket");
48-
if (fchmod(console_socket_fd, 0700))
48+
*fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
49+
if (*fd < 0)
50+
pexit("Failed to create socket");
51+
if (fchmod(*fd, 0700))
4952
pexit("Failed to change console-socket permissions");
5053
/* XXX: This should be handled with a rename(2). */
5154
if (unlink(csname) < 0)
5255
pexit("Failed to unlink temporary random path");
53-
if (bind(console_socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
56+
if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
5457
pexit("Failed to bind to console-socket");
55-
if (listen(console_socket_fd, 128) < 0)
58+
if (listen(*fd, 128) < 0)
5659
pexit("Failed to listen on console-socket");
5760

5861
return g_strdup(csname);
5962
}
6063

64+
char *setup_console_socket(void)
65+
{
66+
return setup_socket(&console_socket_fd);
67+
}
68+
69+
char *setup_seccomp_socket(void)
70+
{
71+
return setup_socket(&seccomp_socket_fd);
72+
}
73+
6174
char *setup_attach_socket(void)
6275
{
6376
struct sockaddr_un attach_addr = {0};

src/conn_sock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct conn_sock_s {
1616
};
1717

1818
char *setup_console_socket(void);
19+
char *setup_seccomp_socket(void);
1920
char *setup_attach_socket(void);
2021
void conn_sock_shutdown(struct conn_sock_s *sock, int how);
2122
void schedule_main_stdin_write();

src/ctrl.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,85 @@
88
#include "conn_sock.h"
99
#include "cmsg.h"
1010
#include "cli.h" // opt_bundle_path
11+
#include "seccomp_notify.h"
1112

1213
#include <sys/ioctl.h>
1314
#include <sys/socket.h>
1415
#include <sys/stat.h>
1516
#include <termios.h>
1617

18+
#include <seccomp.h>
19+
#include <linux/seccomp.h>
20+
#include <sys/sysmacros.h>
21+
#include <sys/wait.h>
22+
#include <sys/mount.h>
23+
#include <signal.h>
24+
25+
static struct seccomp_notify_context_s *seccomp_notify_ctx;
26+
1727
static void resize_winsz(int height, int width);
1828
static gboolean read_from_ctrl_buffer(int fd, gboolean (*line_process_func)(char *));
1929
static gboolean process_terminal_ctrl_line(char *line);
2030
static gboolean process_winsz_ctrl_line(char *line);
2131
static void setup_fifo(int *fifo_r, int *fifo_w, char *filename, char *error_var_name);
2232

33+
static void cleanup_seccomp_plugins()
34+
{
35+
if (seccomp_notify_ctx) {
36+
seccomp_notify_plugins_free(seccomp_notify_ctx);
37+
seccomp_notify_ctx = NULL;
38+
}
39+
}
40+
41+
gboolean seccomp_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data)
42+
{
43+
ninfof("about to accept from seccomp_socket_fd: %d", fd);
44+
int connfd = accept4(fd, NULL, NULL, SOCK_CLOEXEC);
45+
if (connfd < 0) {
46+
nwarn("Failed to accept console-socket connection");
47+
return G_SOURCE_CONTINUE;
48+
}
49+
50+
struct file_t listener = recvfd(connfd);
51+
close(connfd);
52+
53+
_cleanup_free_ char *oci_config_path = g_strdup_printf("%s/config.json", opt_bundle_path);
54+
if (oci_config_path == NULL) {
55+
nwarn("Failed to strdup");
56+
return G_SOURCE_CONTINUE;
57+
}
58+
59+
struct seccomp_notify_conf_s conf = {
60+
.runtime_root_path = NULL,
61+
.name = opt_name,
62+
.bundle_path = opt_bundle_path,
63+
.oci_config_path = oci_config_path,
64+
};
65+
int ret = seccomp_notify_plugins_load(&seccomp_notify_ctx, opt_seccomp_notify_plugins, &conf);
66+
if (ret < 0) {
67+
nwarn("Failed to initialize seccomp notify plugins");
68+
return G_SOURCE_CONTINUE;
69+
}
70+
71+
72+
g_unix_fd_add(listener.fd, G_IO_IN | G_IO_HUP, seccomp_cb, NULL);
73+
atexit(cleanup_seccomp_plugins);
74+
75+
return G_SOURCE_CONTINUE;
76+
}
77+
78+
gboolean seccomp_cb(int fd, GIOCondition condition, G_GNUC_UNUSED gpointer user_data)
79+
{
80+
if (condition & G_IO_IN) {
81+
if (seccomp_notify_ctx == NULL)
82+
return G_SOURCE_REMOVE;
83+
84+
int ret = seccomp_notify_plugins_event(seccomp_notify_ctx, fd);
85+
return ret == 0 ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
86+
}
87+
return G_SOURCE_CONTINUE;
88+
}
89+
2390
gboolean terminal_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data)
2491
{
2592

src/ctrl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
#include <glib.h> /* gpointer */
55

6+
gboolean seccomp_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
67
gboolean terminal_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
78
gboolean ctrl_winsz_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
9+
gboolean seccomp_cb(int fd, GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
810
gboolean ctrl_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC_UNUSED gpointer user_data);
911
void setup_console_fifo();
1012
int setup_terminal_control_fifo();

src/globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ GPtrArray *conn_socks = NULL;
1111

1212
int attach_socket_fd = -1;
1313
int console_socket_fd = -1;
14+
int seccomp_socket_fd = -1;
1415
int terminal_ctrl_fd = -1;
1516
int inotify_fd = -1;
1617
int winsz_fd_w = -1;

src/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extern GPtrArray *conn_socks;
1616

1717
extern int attach_socket_fd;
1818
extern int console_socket_fd;
19+
extern int seccomp_socket_fd;
1920
extern int terminal_ctrl_fd;
2021
extern int inotify_fd;
2122
extern int winsz_fd_w;

0 commit comments

Comments
 (0)