Unverified Commit 978dfc7e by Stéphane Graber Committed by GitHub

Merge pull request #2956 from brauner/2019-04-29/seccomp_trap_cleanup

seccomp: cleanup
parents 27b73709 c3e3c21a
...@@ -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