seccomp: cleanup

Simplify and cleanup some of the seccomp code. This mainly focuses on removing the open coding of various seccomp settings all over the code place in favor of centralized helpers. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 41cd8a8d
...@@ -156,7 +156,8 @@ int lxc_abstract_unix_connect(const char *path) ...@@ -156,7 +156,8 @@ int lxc_abstract_unix_connect(const char *path)
int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
void *data, size_t size) void *data, size_t size)
{ {
__do_free char *cmsgbuf; __do_free char *cmsgbuf = NULL;
int ret;
struct msghdr msg; struct msghdr msg;
struct iovec iov; struct iovec iov;
struct cmsghdr *cmsg = NULL; struct cmsghdr *cmsg = NULL;
...@@ -189,13 +190,19 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds, ...@@ -189,13 +190,19 @@ int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
msg.msg_iov = &iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
return sendmsg(fd, &msg, MSG_NOSIGNAL); again:
ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
if (ret < 0)
if (errno == EINTR)
goto again;
return ret;
} }
int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
void *data, size_t size) void *data, size_t size)
{ {
__do_free char *cmsgbuf; __do_free char *cmsgbuf = NULL;
int ret; int ret;
struct msghdr msg; struct msghdr msg;
struct iovec iov; struct iovec iov;
...@@ -221,8 +228,15 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, ...@@ -221,8 +228,15 @@ int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
msg.msg_iov = &iov; msg.msg_iov = &iov;
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
again:
ret = recvmsg(fd, &msg, 0); ret = recvmsg(fd, &msg, 0);
if (ret <= 0) if (ret < 0) {
if (errno == EINTR)
goto again;
goto out;
}
if (ret == 0)
goto out; goto out;
/* /*
......
...@@ -608,8 +608,8 @@ static bool fetch_seccomp(struct lxc_container *c, lxc_attach_options_t *options ...@@ -608,8 +608,8 @@ static bool fetch_seccomp(struct lxc_container *c, lxc_attach_options_t *options
if (!(options->namespaces & CLONE_NEWNS) || if (!(options->namespaces & CLONE_NEWNS) ||
!(options->attach_flags & LXC_ATTACH_LSM)) { !(options->attach_flags & LXC_ATTACH_LSM)) {
free(c->lxc_conf->seccomp); free(c->lxc_conf->seccomp.seccomp);
c->lxc_conf->seccomp = NULL; c->lxc_conf->seccomp.seccomp = NULL;
return true; return true;
} }
...@@ -852,7 +852,7 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -852,7 +852,7 @@ static int attach_child_main(struct attach_clone_payload *payload)
} }
if (init_ctx->container && init_ctx->container->lxc_conf && if (init_ctx->container && init_ctx->container->lxc_conf &&
init_ctx->container->lxc_conf->seccomp) { init_ctx->container->lxc_conf->seccomp.seccomp) {
struct lxc_conf *conf = init_ctx->container->lxc_conf; struct lxc_conf *conf = init_ctx->container->lxc_conf;
ret = lxc_seccomp_load(conf); ret = lxc_seccomp_load(conf);
...@@ -861,18 +861,9 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -861,18 +861,9 @@ static int attach_child_main(struct attach_clone_payload *payload)
TRACE("Loaded seccomp profile"); TRACE("Loaded seccomp profile");
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD ret = lxc_seccomp_send_notifier_fd(&conf->seccomp, payload->ipc_socket);
if (conf->has_seccomp_notify) { if (ret < 0)
ret = lxc_abstract_unix_send_fds(payload->ipc_socket, goto on_error;
&conf->seccomp_notify_fd,
1, NULL, 0);
close_prot_errno_disarm(conf->seccomp_notify_fd);
if (ret < 0)
goto on_error;
TRACE("Sent seccomp listener fd to parent");
}
#endif
} }
close(payload->ipc_socket); close(payload->ipc_socket);
...@@ -1326,24 +1317,13 @@ int lxc_attach(const char *name, const char *lxcpath, ...@@ -1326,24 +1317,13 @@ int lxc_attach(const char *name, const char *lxcpath,
TRACE("Sent LSM label file descriptor %d to child", labelfd); TRACE("Sent LSM label file descriptor %d to child", labelfd);
} }
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD ret = lxc_seccomp_recv_notifier_fd(&conf->seccomp, ipc_sockets[0]);
if (conf->seccomp && conf->has_seccomp_notify) { if (ret < 0)
ret = lxc_abstract_unix_recv_fds(ipc_sockets[0], goto close_mainloop;
&conf->seccomp_notify_fd,
1, NULL, 0);
if (ret < 0)
goto close_mainloop;
TRACE("Retrieved seccomp listener fd %d from child", ret = lxc_seccomp_add_notifier(name, lxcpath, &conf->seccomp);
conf->seccomp_notify_fd); if (ret < 0)
ret = lxc_cmd_seccomp_notify_add_listener(name, lxcpath, goto close_mainloop;
conf->seccomp_notify_fd,
-1, 0);
close_prot_errno_disarm(conf->seccomp_notify_fd);
if (ret < 0)
goto close_mainloop;
}
#endif
/* We're done, the child process should now execute whatever it /* We're done, the child process should now execute whatever it
* is that the user requested. The parent can now track it with * is that the user requested. The parent can now track it with
......
...@@ -1053,7 +1053,7 @@ int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath, ...@@ -1053,7 +1053,7 @@ int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
/* unused */ unsigned int flags) /* unused */ unsigned int flags)
{ {
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef HAVE_SECCOMP_NOTIFY
int ret, stopped; int ret, stopped;
struct lxc_cmd_rr cmd = { struct lxc_cmd_rr cmd = {
.req = { .req = {
...@@ -1080,43 +1080,39 @@ static int lxc_cmd_seccomp_notify_add_listener_callback(int fd, ...@@ -1080,43 +1080,39 @@ static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
struct lxc_cmd_rsp rsp = {0}; struct lxc_cmd_rsp rsp = {0};
int ret;
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef HAVE_SECCOMP_NOTIFY
int ret;
__do_close_prot_errno int recv_fd = -EBADF; __do_close_prot_errno int recv_fd = -EBADF;
int notify_fd = -EBADF; int notify_fd = -EBADF;
if (!handler->conf->has_seccomp_notify || ret = lxc_abstract_unix_recv_fds(fd, &recv_fd, 1, NULL, 0);
handler->conf->seccomp_notify_proxy_fd < 0) { if (ret <= 0) {
rsp.ret = -EINVAL; rsp.ret = -errno;
goto send_error; goto out;
} }
ret = lxc_abstract_unix_recv_fds(fd, &recv_fd, 1, NULL, 0); if (!handler->conf->seccomp.notifier.wants_supervision ||
if (ret <= 0) handler->conf->seccomp.notifier.proxy_fd < 0) {
goto reap_client_fd; SYSERROR("No seccomp proxy fd specified");
rsp.ret = -EINVAL;
goto out;
}
ret = lxc_mainloop_add_handler(descr, notify_fd, seccomp_notify_handler, ret = lxc_mainloop_add_handler(descr, recv_fd, seccomp_notify_handler,
handler); handler);
if (ret < 0) {
rsp.ret = -errno;
goto out;
}
notify_fd = move_fd(recv_fd); notify_fd = move_fd(recv_fd);
if (ret < 0)
goto reap_client_fd;
send_error: out:
#else #else
rsp.ret = -ENOSYS; rsp.ret = -ENOSYS;
#endif
ret = lxc_cmd_rsp_send(fd, &rsp);
if (ret < 0)
goto reap_client_fd;
return 0;
reap_client_fd: #endif
/* Special indicator to lxc_cmd_handler() to close the fd and do return lxc_cmd_rsp_send(fd, &rsp);
* related cleanup.
*/
return 1;
} }
static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
......
...@@ -2752,14 +2752,6 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2752,14 +2752,6 @@ struct lxc_conf *lxc_conf_init(void)
new->lsm_aa_profile = NULL; new->lsm_aa_profile = NULL;
lxc_list_init(&new->lsm_aa_raw); lxc_list_init(&new->lsm_aa_raw);
new->lsm_se_context = NULL; new->lsm_se_context = NULL;
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
new->has_seccomp_notify = false;
new->seccomp_notify_fd = -EBADF;
new->seccomp_notify_proxy_fd = -EBADF;
memset(&new->seccomp_notify_proxy_addr, 0, sizeof(new->seccomp_notify_proxy_addr));
new->seccomp_notify_req = NULL;
new->seccomp_notify_resp = NULL;
#endif
new->tmp_umount_proc = false; new->tmp_umount_proc = false;
new->tmp_umount_proc = 0; new->tmp_umount_proc = 0;
new->shmount.path_host = NULL; new->shmount.path_host = NULL;
...@@ -2771,6 +2763,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2771,6 +2763,7 @@ struct lxc_conf *lxc_conf_init(void)
new->init_gid = 0; new->init_gid = 0;
memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup)); memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup));
memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX); memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX);
seccomp_conf_init(new);
return new; return new;
} }
...@@ -4074,7 +4067,7 @@ void lxc_conf_free(struct lxc_conf *conf) ...@@ -4074,7 +4067,7 @@ void lxc_conf_free(struct lxc_conf *conf)
free(conf->lsm_aa_profile); free(conf->lsm_aa_profile);
free(conf->lsm_aa_profile_computed); free(conf->lsm_aa_profile_computed);
free(conf->lsm_se_context); free(conf->lsm_se_context);
lxc_seccomp_free(conf); lxc_seccomp_free(&conf->seccomp);
lxc_clear_config_caps(conf); lxc_clear_config_caps(conf);
lxc_clear_config_keepcaps(conf); lxc_clear_config_keepcaps(conf);
lxc_clear_cgroups(conf, "lxc.cgroup", CGROUP_SUPER_MAGIC); lxc_clear_cgroups(conf, "lxc.cgroup", CGROUP_SUPER_MAGIC);
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "compiler.h" #include "compiler.h"
#include "config.h" #include "config.h"
#include "list.h" #include "list.h"
#include "lxcseccomp.h"
#include "ringbuf.h" #include "ringbuf.h"
#include "start.h" #include "start.h"
#include "terminal.h" #include "terminal.h"
...@@ -295,19 +296,7 @@ struct lxc_conf { ...@@ -295,19 +296,7 @@ struct lxc_conf {
struct lxc_list lsm_aa_raw; struct lxc_list lsm_aa_raw;
char *lsm_se_context; char *lsm_se_context;
bool tmp_umount_proc; bool tmp_umount_proc;
char *seccomp; /* filename with the seccomp rules */ struct lxc_seccomp seccomp;
unsigned int seccomp_allow_nesting;
#if HAVE_SCMP_FILTER_CTX
scmp_filter_ctx seccomp_ctx;
#endif
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
bool has_seccomp_notify;
int seccomp_notify_fd;
int seccomp_notify_proxy_fd;
struct sockaddr_un seccomp_notify_proxy_addr;
struct seccomp_notif *seccomp_notify_req;
struct seccomp_notif_resp *seccomp_notify_resp;
#endif
int maincmd_fd; int maincmd_fd;
unsigned int autodev; /* if 1, mount and fill a /dev at start */ unsigned int autodev; /* if 1, mount and fill a /dev at start */
int haltsignal; /* signal used to halt container */ int haltsignal; /* signal used to halt container */
......
...@@ -780,22 +780,27 @@ static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook) ...@@ -780,22 +780,27 @@ static int add_hook(struct lxc_conf *lxc_conf, int which, char *hook)
static int set_config_seccomp_allow_nesting(const char *key, const char *value, static int set_config_seccomp_allow_nesting(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
#ifdef HAVE_SECCOMP
if (lxc_config_value_empty(value)) if (lxc_config_value_empty(value))
return clr_config_seccomp_allow_nesting(key, lxc_conf, NULL); return clr_config_seccomp_allow_nesting(key, lxc_conf, NULL);
if (lxc_safe_uint(value, &lxc_conf->seccomp_allow_nesting) < 0) if (lxc_safe_uint(value, &lxc_conf->seccomp.allow_nesting) < 0)
return -1; return -1;
if (lxc_conf->seccomp_allow_nesting > 1) if (lxc_conf->seccomp.allow_nesting > 1)
return minus_one_set_errno(EINVAL); return minus_one_set_errno(EINVAL);
return 0; return 0;
#else
errno = ENOSYS;
return -1;
#endif
} }
static int set_config_seccomp_notify_proxy(const char *key, const char *value, static int set_config_seccomp_notify_proxy(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef HAVE_SECCOMP_NOTIFY
const char *offset; const char *offset;
if (lxc_config_value_empty(value)) if (lxc_config_value_empty(value))
...@@ -805,7 +810,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value, ...@@ -805,7 +810,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value,
return minus_one_set_errno(EINVAL); return minus_one_set_errno(EINVAL);
offset = value + 5; offset = value + 5;
if (lxc_unix_sockaddr(&lxc_conf->seccomp_notify_proxy_addr, offset) < 0) if (lxc_unix_sockaddr(&lxc_conf->seccomp.notifier.proxy_addr, offset) < 0)
return -1; return -1;
return 0; return 0;
...@@ -817,7 +822,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value, ...@@ -817,7 +822,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value,
static int set_config_seccomp_profile(const char *key, const char *value, static int set_config_seccomp_profile(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
return set_config_path_item(&lxc_conf->seccomp, value); return set_config_path_item(&lxc_conf->seccomp.seccomp, value);
} }
static int set_config_execute_cmd(const char *key, const char *value, static int set_config_execute_cmd(const char *key, const char *value,
...@@ -3726,17 +3731,22 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv, ...@@ -3726,17 +3731,22 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv,
int inlen, struct lxc_conf *c, int inlen, struct lxc_conf *c,
void *data) void *data)
{ {
return lxc_get_conf_int(c, retv, inlen, c->seccomp_allow_nesting); #ifdef HAVE_SECCOMP
return lxc_get_conf_int(c, retv, inlen, c->seccomp.allow_nesting);
#else
errno = ENOSYS;
return -1;
#endif
} }
static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inlen, static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef HAVE_SECCOMP_NOTIFY
return lxc_get_conf_str(retv, inlen, return lxc_get_conf_str(retv, inlen,
(c->seccomp_notify_proxy_addr.sun_path[0]) == '/' (c->seccomp.notifier.proxy_addr.sun_path[0]) == '/'
? &c->seccomp_notify_proxy_addr.sun_path[0] ? &c->seccomp.notifier.proxy_addr.sun_path[0]
: &c->seccomp_notify_proxy_addr.sun_path[1]); : &c->seccomp.notifier.proxy_addr.sun_path[1]);
#else #else
return minus_one_set_errno(ENOSYS); return minus_one_set_errno(ENOSYS);
#endif #endif
...@@ -3745,7 +3755,7 @@ static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inle ...@@ -3745,7 +3755,7 @@ static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inle
static int get_config_seccomp_profile(const char *key, char *retv, int inlen, static int get_config_seccomp_profile(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
return lxc_get_conf_str(retv, inlen, c->seccomp); return lxc_get_conf_str(retv, inlen, c->seccomp.seccomp);
} }
static int get_config_autodev(const char *key, char *retv, int inlen, static int get_config_autodev(const char *key, char *retv, int inlen,
...@@ -4328,16 +4338,21 @@ static inline int clr_config_console_size(const char *key, struct lxc_conf *c, ...@@ -4328,16 +4338,21 @@ static inline int clr_config_console_size(const char *key, struct lxc_conf *c,
static inline int clr_config_seccomp_allow_nesting(const char *key, static inline int clr_config_seccomp_allow_nesting(const char *key,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
c->seccomp_allow_nesting = 0; #ifdef HAVE_SECCOMP
c->seccomp.allow_nesting = 0;
return 0; return 0;
#else
errno = ENOSYS;
return -1;
#endif
} }
static inline int clr_config_seccomp_notify_proxy(const char *key, static inline int clr_config_seccomp_notify_proxy(const char *key,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef HAVE_SECCOMP_NOTIFY
memset(&c->seccomp_notify_proxy_addr, 0, memset(&c->seccomp.notifier.proxy_addr, 0,
sizeof(c->seccomp_notify_proxy_addr)); sizeof(c->seccomp.notifier.proxy_addr));
return 0; return 0;
#else #else
return minus_one_set_errno(ENOSYS); return minus_one_set_errno(ENOSYS);
...@@ -4347,8 +4362,8 @@ static inline int clr_config_seccomp_notify_proxy(const char *key, ...@@ -4347,8 +4362,8 @@ static inline int clr_config_seccomp_notify_proxy(const char *key,
static inline int clr_config_seccomp_profile(const char *key, static inline int clr_config_seccomp_profile(const char *key,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
free(c->seccomp); free(c->seccomp.seccomp);
c->seccomp = NULL; c->seccomp.seccomp = NULL;
return 0; return 0;
} }
......
...@@ -5229,7 +5229,6 @@ out: ...@@ -5229,7 +5229,6 @@ out:
static int do_lxcapi_seccomp_notify(struct lxc_container *c, unsigned int cmd, int fd) static int do_lxcapi_seccomp_notify(struct lxc_container *c, unsigned int cmd, int fd)
{ {
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
if (!c || !c->lxc_conf) if (!c || !c->lxc_conf)
return minus_one_set_errno(-EINVAL); return minus_one_set_errno(-EINVAL);
...@@ -5238,13 +5237,10 @@ static int do_lxcapi_seccomp_notify(struct lxc_container *c, unsigned int cmd, i ...@@ -5238,13 +5237,10 @@ static int do_lxcapi_seccomp_notify(struct lxc_container *c, unsigned int cmd, i
if (fd) if (fd)
return minus_one_set_errno(EINVAL); return minus_one_set_errno(EINVAL);
return c->lxc_conf->seccomp_notify_fd; return lxc_seccomp_get_notify_fd(&c->lxc_conf->seccomp);
} }
return minus_one_set_errno(EINVAL); return minus_one_set_errno(EINVAL);
#else
return minus_one_set_errno(ENOSYS);
#endif
} }
WRAP_API_2(int, lxcapi_seccomp_notify, unsigned int, int) WRAP_API_2(int, lxcapi_seccomp_notify, unsigned int, int)
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <lxc/attach_options.h> #include <lxc/attach_options.h>
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef SCMP_ACT_USER_NOTIF
#include <linux/seccomp.h>
#include <seccomp.h> #include <seccomp.h>
#endif #endif
...@@ -69,7 +70,7 @@ enum { ...@@ -69,7 +70,7 @@ enum {
LXC_SECCOMP_NOTIFY_MAX, LXC_SECCOMP_NOTIFY_MAX,
}; };
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #ifdef SCMP_ACT_USER_NOTIF
struct seccomp_notify_proxy_msg { struct seccomp_notify_proxy_msg {
uint32_t version; uint32_t version;
struct seccomp_notif req; struct seccomp_notif req;
......
...@@ -24,21 +24,86 @@ ...@@ -24,21 +24,86 @@
#ifndef __LXC_LXCSECCOMP_H #ifndef __LXC_LXCSECCOMP_H
#define __LXC_LXCSECCOMP_H #define __LXC_LXCSECCOMP_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <errno.h> #include <errno.h>
#ifdef HAVE_SECCOMP #ifdef HAVE_SECCOMP
#include <linux/seccomp.h>
#include <seccomp.h> #include <seccomp.h>
#endif #endif
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
#include <sys/socket.h>
#include <sys/un.h>
#endif
#include "conf.h" #include "conf.h"
#include "config.h"
#include "memory_utils.h"
struct lxc_conf;
struct lxc_epoll_descr;
struct lxc_handler;
#ifdef HAVE_SECCOMP #ifdef HAVE_SECCOMP
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
struct seccomp_notify {
bool wants_supervision;
int notify_fd;
int proxy_fd;
struct sockaddr_un proxy_addr;
struct seccomp_notif *req_buf;
struct seccomp_notif_resp *rsp_buf;
};
#define HAVE_SECCOMP_NOTIFY 1
#endif /* HAVE_DECL_SECCOMP_NOTIF_GET_FD */
struct lxc_seccomp {
char *seccomp;
#if HAVE_SCMP_FILTER_CTX
unsigned int allow_nesting;
scmp_filter_ctx seccomp_ctx;
#endif /* HAVE_SCMP_FILTER_CTX */
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
struct seccomp_notify notifier;
#endif /* HAVE_DECL_SECCOMP_NOTIF_GET_FD */
};
extern int lxc_seccomp_load(struct lxc_conf *conf); extern int lxc_seccomp_load(struct lxc_conf *conf);
extern int lxc_read_seccomp_config(struct lxc_conf *conf); extern int lxc_read_seccomp_config(struct lxc_conf *conf);
extern void lxc_seccomp_free(struct lxc_conf *conf); extern void lxc_seccomp_free(struct lxc_seccomp *seccomp);
extern int seccomp_notify_handler(int fd, uint32_t events, void *data, extern int seccomp_notify_handler(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr); struct lxc_epoll_descr *descr);
extern void seccomp_conf_init(struct lxc_conf *conf);
extern int lxc_seccomp_setup_notifier(struct lxc_seccomp *seccomp,
struct lxc_epoll_descr *descr,
struct lxc_handler *handler);
extern int lxc_seccomp_send_notifier_fd(struct lxc_seccomp *seccomp,
int socket_fd);
extern int lxc_seccomp_recv_notifier_fd(struct lxc_seccomp *seccomp,
int socket_fd);
extern int lxc_seccomp_add_notifier(const char *name, const char *lxcpath,
struct lxc_seccomp *seccomp);
static inline int lxc_seccomp_get_notify_fd(struct lxc_seccomp *seccomp)
{
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
return seccomp->notifier.notify_fd;
#else #else
errno = ENOSYS;
return -EBADF;
#endif
}
#else /* HAVE_SECCOMP */
struct lxc_seccomp {
char *seccomp;
};
static inline int lxc_seccomp_load(struct lxc_conf *conf) static inline int lxc_seccomp_load(struct lxc_conf *conf)
{ {
return 0; return 0;
...@@ -49,16 +114,50 @@ static inline int lxc_read_seccomp_config(struct lxc_conf *conf) ...@@ -49,16 +114,50 @@ static inline int lxc_read_seccomp_config(struct lxc_conf *conf)
return 0; return 0;
} }
static inline void lxc_seccomp_free(struct lxc_conf *conf) static inline void lxc_seccomp_free(struct lxc_seccomp *seccomp)
{ {
free(conf->seccomp); free_disarm(seccomp->seccomp);
conf->seccomp = NULL;
} }
static inline int seccomp_notify_handler(int fd, uint32_t events, void *data, static inline int seccomp_notify_handler(int fd, uint32_t events, void *data,
struct lxc_epoll_descr *descr) struct lxc_epoll_descr *descr)
{ {
return -ENOSYS; return -ENOSYS;
} }
#endif
#endif static inline void seccomp_conf_init(struct lxc_conf *conf)
{
}
static inline int lxc_seccomp_setup_notifier(struct lxc_seccomp *seccomp,
struct lxc_epoll_descr *descr,
struct lxc_handler *handler)
{
return 0;
}
static inline int lxc_seccomp_send_notifier_fd(struct lxc_seccomp *seccomp,
int socket_fd)
{
return 0;
}
static inline int lxc_seccomp_recv_notifier_fd(struct lxc_seccomp *seccomp,
int socket_fd)
{
return 0;
}
static inline int lxc_seccomp_add_notifier(const char *name, const char *lxcpath,
struct lxc_seccomp *seccomp)
{
return 0;
}
static inline int lxc_seccomp_get_notify_fd(struct lxc_seccomp *seccomp)
{
return -EBADF;
}
#endif /* HAVE_SECCOMP */
#endif /* __LXC_LXCSECCOMP_H */
...@@ -55,6 +55,12 @@ static inline void __auto_closedir__(DIR **d) ...@@ -55,6 +55,12 @@ static inline void __auto_closedir__(DIR **d)
fd = -EBADF; \ fd = -EBADF; \
} }
#define free_disarm(ptr) \
({ \
free(ptr); \
move_ptr(ptr); \
})
static inline void __auto_close__(int *fd) static inline void __auto_close__(int *fd)
{ {
close_prot_errno_disarm(*fd); close_prot_errno_disarm(*fd);
......
...@@ -591,32 +591,9 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -591,32 +591,9 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
goto out_mainloop_console; goto out_mainloop_console;
} }
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD ret = lxc_seccomp_setup_notifier(&handler->conf->seccomp, &descr, handler);
if (handler->conf->has_seccomp_notify && if (ret < 0)
handler->conf->seccomp_notify_proxy_addr.sun_path[1] != '\0') { goto out_mainloop_console;
__do_close_prot_errno int notify_fd = -EBADF;
notify_fd = lxc_unix_connect(&handler->conf->seccomp_notify_proxy_addr);
if (notify_fd < 0)
goto out_mainloop_console;
/* 30 second timeout */
ret = lxc_socket_set_timeout(notify_fd, 30, 30);
if (ret)
goto out_mainloop_console;
ret = lxc_mainloop_add_handler(&descr,
handler->conf->seccomp_notify_fd,
seccomp_notify_handler, handler);
if (ret < 0) {
ERROR("Failed to add seccomp notify handler for %d to mainloop",
handler->conf->seccomp_notify_fd);
goto out_mainloop_console;
}
handler->conf->seccomp_notify_proxy_fd = move_fd(notify_fd);
}
#endif
if (has_console) { if (has_console) {
struct lxc_terminal *console = &handler->conf->console; struct lxc_terminal *console = &handler->conf->console;
...@@ -1357,19 +1334,11 @@ static int do_start(void *data) ...@@ -1357,19 +1334,11 @@ static int do_start(void *data)
if (ret < 0) if (ret < 0)
goto out_warn_father; goto out_warn_father;
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD ret = lxc_seccomp_send_notifier_fd(&handler->conf->seccomp, data_sock0);
if (handler->conf->has_seccomp_notify) { if (ret < 0) {
ret = lxc_abstract_unix_send_fds(data_sock0, SYSERROR("Failed to send seccomp notify fd to parent");
&handler->conf->seccomp_notify_fd, goto out_warn_father;
1, NULL, 0);
if (ret < 0) {
SYSERROR("Failed to send seccomp notify fd to parent");
goto out_warn_father;
}
close(handler->conf->seccomp_notify_fd);
handler->conf->seccomp_notify_fd = -EBADF;
} }
#endif
ret = run_lxc_hooks(handler->name, "start", handler->conf, NULL); ret = run_lxc_hooks(handler->name, "start", handler->conf, NULL);
if (ret < 0) { if (ret < 0) {
...@@ -1932,25 +1901,11 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1932,25 +1901,11 @@ static int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net; goto out_delete_net;
} }
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD ret = lxc_seccomp_recv_notifier_fd(&handler->conf->seccomp, data_sock1);
if (handler->conf->has_seccomp_notify) { if (ret < 0) {
ret = lxc_abstract_unix_recv_fds(handler->data_sock[1], SYSERROR("Failed to receive seccomp notify fd from child");
&handler->conf->seccomp_notify_fd, goto out_delete_net;
1, NULL, 0);
if (ret < 0) {
SYSERROR("Failed to receive seccomp notify fd from child");
goto out_delete_net;
}
ret = seccomp_notif_alloc(&handler->conf->seccomp_notify_req,
&handler->conf->seccomp_notify_resp);
if (ret) {
errno = ret;
ret = -1;
goto out_delete_net;
}
} }
#endif
ret = handler->ops->post_start(handler, handler->data); ret = handler->ops->post_start(handler, handler->data);
if (ret < 0) if (ret < 0)
......
...@@ -25,7 +25,8 @@ lxc_test_locktests_SOURCES = locktests.c ...@@ -25,7 +25,8 @@ lxc_test_locktests_SOURCES = locktests.c
lxc_test_lxcpath_SOURCES = lxcpath.c lxc_test_lxcpath_SOURCES = lxcpath.c
lxc_test_may_control_SOURCES = may_control.c lxc_test_may_control_SOURCES = may_control.c
lxc_test_mount_injection_SOURCES = mount_injection.c lxctest.h lxc_test_mount_injection_SOURCES = mount_injection.c lxctest.h
lxc_test_parse_config_file_SOURCES = parse_config_file.c lxctest.h lxc_test_parse_config_file_SOURCES = parse_config_file.c \
lxctest.h
lxc_test_raw_clone_SOURCES = lxc_raw_clone.c \ lxc_test_raw_clone_SOURCES = lxc_raw_clone.c \
lxctest.h \ lxctest.h \
../lxc/namespace.c ../lxc/namespace.h \ ../lxc/namespace.c ../lxc/namespace.h \
...@@ -57,6 +58,11 @@ if ENABLE_APPARMOR ...@@ -57,6 +58,11 @@ if ENABLE_APPARMOR
AM_CFLAGS += -DHAVE_APPARMOR AM_CFLAGS += -DHAVE_APPARMOR
endif endif
if ENABLE_SECCOMP
AM_CFLAGS += -DHAVE_SECCOMP \
$(SECCOMP_CFLAGS)
endif
if ENABLE_SELINUX if ENABLE_SELINUX
AM_CFLAGS += -DHAVE_SELINUX AM_CFLAGS += -DHAVE_SELINUX
endif endif
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <unistd.h> #include <unistd.h>
#include <libgen.h> #include <libgen.h>
#include "conf.h"
#include "confile_utils.h" #include "confile_utils.h"
#include "lxc/state.h" #include "lxc/state.h"
#include "lxctest.h" #include "lxctest.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment