mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-12 11:36:03 +00:00
Merge pull request #2956 from brauner/2019-04-29/seccomp_trap_cleanup
seccomp: cleanup
This commit is contained in:
commit
978dfc7ec4
@ -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,
|
|||||||
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,
|
|||||||
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
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
/* 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,
|
|||||||
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
|
#endif
|
||||||
ret = lxc_cmd_rsp_send(fd, &rsp);
|
return lxc_cmd_rsp_send(fd, &rsp);
|
||||||
if (ret < 0)
|
|
||||||
goto reap_client_fd;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
reap_client_fd:
|
|
||||||
/* Special indicator to lxc_cmd_handler() to close the fd and do
|
|
||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
#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 {
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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
|
|||||||
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,
|
|||||||
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,
|
|||||||
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:
|
|||||||
|
|
||||||
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
|
|||||||
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 @@
|
|||||||
|
|
||||||
#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 {
|
|||||||
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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
@ -32,10 +32,12 @@
|
|||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "af_unix.h"
|
#include "af_unix.h"
|
||||||
|
#include "commands.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "lxccontainer.h"
|
#include "lxccontainer.h"
|
||||||
#include "lxcseccomp.h"
|
#include "lxcseccomp.h"
|
||||||
|
#include "mainloop.h"
|
||||||
#include "memory_utils.h"
|
#include "memory_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ static int parse_config_v1(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SCMP_FILTER_CTX
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
ret = seccomp_rule_add(conf->seccomp_ctx, SCMP_ACT_ALLOW, nr, 0);
|
ret = seccomp_rule_add(conf->seccomp.seccomp_ctx, SCMP_ACT_ALLOW, nr, 0);
|
||||||
#else
|
#else
|
||||||
ret = seccomp_rule_add(SCMP_ACT_ALLOW, nr, 0);
|
ret = seccomp_rule_add(SCMP_ACT_ALLOW, nr, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -736,13 +738,13 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (default_policy_action != SCMP_ACT_KILL) {
|
if (default_policy_action != SCMP_ACT_KILL) {
|
||||||
ret = seccomp_reset(conf->seccomp_ctx, default_policy_action);
|
ret = seccomp_reset(conf->seccomp.seccomp_ctx, default_policy_action);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ERROR("Error re-initializing Seccomp");
|
ERROR("Error re-initializing Seccomp");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = seccomp_attr_set(conf->seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0);
|
ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
SYSERROR("Failed to turn off no-new-privs");
|
SYSERROR("Failed to turn off no-new-privs");
|
||||||
@ -750,7 +752,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCMP_FLTATR_ATL_TSKIP
|
#ifdef SCMP_FLTATR_ATL_TSKIP
|
||||||
ret = seccomp_attr_set(conf->seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1);
|
ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
SYSWARN("Failed to turn on seccomp nop-skip, continuing");
|
SYSWARN("Failed to turn on seccomp nop-skip, continuing");
|
||||||
@ -941,19 +943,19 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
|
|
||||||
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
if ((rule.action == SCMP_ACT_USER_NOTIF) &&
|
if ((rule.action == SCMP_ACT_USER_NOTIF) &&
|
||||||
!conf->has_seccomp_notify) {
|
!conf->seccomp.notifier.wants_supervision) {
|
||||||
ret = seccomp_attr_set(conf->seccomp_ctx,
|
ret = seccomp_attr_set(conf->seccomp.seccomp_ctx,
|
||||||
SCMP_FLTATR_NEW_LISTENER, 1);
|
SCMP_FLTATR_NEW_LISTENER, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto bad_rule;
|
goto bad_rule;
|
||||||
|
|
||||||
conf->has_seccomp_notify = true;
|
conf->seccomp.notifier.wants_supervision = true;
|
||||||
TRACE("Set SCMP_FLTATR_NEW_LISTENER attribute");
|
TRACE("Set SCMP_FLTATR_NEW_LISTENER attribute");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line,
|
if (!do_resolve_add_rule(SCMP_ARCH_NATIVE, line,
|
||||||
conf->seccomp_ctx, &rule))
|
conf->seccomp.seccomp_ctx, &rule))
|
||||||
goto bad_rule;
|
goto bad_rule;
|
||||||
|
|
||||||
INFO("Added native rule for arch %d for %s action %d(%s)",
|
INFO("Added native rule for arch %d for %s action %d(%s)",
|
||||||
@ -994,7 +996,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
INFO("Merging compat seccomp contexts into main context");
|
INFO("Merging compat seccomp contexts into main context");
|
||||||
if (ctx.contexts[0]) {
|
if (ctx.contexts[0]) {
|
||||||
if (ctx.needs_merge[0]) {
|
if (ctx.needs_merge[0]) {
|
||||||
ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[0]);
|
ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[0]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("Failed to merge first compat seccomp "
|
ERROR("Failed to merge first compat seccomp "
|
||||||
"context into main context");
|
"context into main context");
|
||||||
@ -1010,7 +1012,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
|
|
||||||
if (ctx.contexts[1]) {
|
if (ctx.contexts[1]) {
|
||||||
if (ctx.needs_merge[1]) {
|
if (ctx.needs_merge[1]) {
|
||||||
ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[1]);
|
ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[1]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("Failed to merge first compat seccomp "
|
ERROR("Failed to merge first compat seccomp "
|
||||||
"context into main context");
|
"context into main context");
|
||||||
@ -1026,7 +1028,7 @@ static int parse_config_v2(FILE *f, char *line, size_t *line_bufsz, struct lxc_c
|
|||||||
|
|
||||||
if (ctx.contexts[2]) {
|
if (ctx.contexts[2]) {
|
||||||
if (ctx.needs_merge[2]) {
|
if (ctx.needs_merge[2]) {
|
||||||
ret = seccomp_merge(conf->seccomp_ctx, ctx.contexts[2]);
|
ret = seccomp_merge(conf->seccomp.seccomp_ctx, ctx.contexts[2]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("Failed to merge third compat seccomp "
|
ERROR("Failed to merge third compat seccomp "
|
||||||
"context into main context");
|
"context into main context");
|
||||||
@ -1128,7 +1130,7 @@ static bool use_seccomp(const struct lxc_conf *conf)
|
|||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
bool already_enabled = false, found = false;
|
bool already_enabled = false, found = false;
|
||||||
|
|
||||||
if (conf->seccomp_allow_nesting > 0)
|
if (conf->seccomp.allow_nesting > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
f = fopen("/proc/self/status", "r");
|
f = fopen("/proc/self/status", "r");
|
||||||
@ -1167,7 +1169,7 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
|
|||||||
int ret;
|
int ret;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
if (!conf->seccomp)
|
if (!conf->seccomp.seccomp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!use_seccomp(conf))
|
if (!use_seccomp(conf))
|
||||||
@ -1175,8 +1177,8 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
|
|||||||
|
|
||||||
#if HAVE_SCMP_FILTER_CTX
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
/* XXX for debug, pass in SCMP_ACT_TRAP */
|
/* XXX for debug, pass in SCMP_ACT_TRAP */
|
||||||
conf->seccomp_ctx = seccomp_init(SCMP_ACT_KILL);
|
conf->seccomp.seccomp_ctx = seccomp_init(SCMP_ACT_KILL);
|
||||||
ret = !conf->seccomp_ctx;
|
ret = !conf->seccomp.seccomp_ctx;
|
||||||
#else
|
#else
|
||||||
ret = seccomp_init(SCMP_ACT_KILL) < 0;
|
ret = seccomp_init(SCMP_ACT_KILL) < 0;
|
||||||
#endif
|
#endif
|
||||||
@ -1188,7 +1190,7 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
|
|||||||
/* turn off no-new-privs. We don't want it in lxc, and it breaks
|
/* turn off no-new-privs. We don't want it in lxc, and it breaks
|
||||||
* with apparmor */
|
* with apparmor */
|
||||||
#if HAVE_SCMP_FILTER_CTX
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
ret = seccomp_attr_set(conf->seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0);
|
ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_CTL_NNP, 0);
|
||||||
#else
|
#else
|
||||||
ret = seccomp_attr_set(SCMP_FLTATR_CTL_NNP, 0);
|
ret = seccomp_attr_set(SCMP_FLTATR_CTL_NNP, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -1199,16 +1201,16 @@ int lxc_read_seccomp_config(struct lxc_conf *conf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCMP_FLTATR_ATL_TSKIP
|
#ifdef SCMP_FLTATR_ATL_TSKIP
|
||||||
ret = seccomp_attr_set(conf->seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1);
|
ret = seccomp_attr_set(conf->seccomp.seccomp_ctx, SCMP_FLTATR_ATL_TSKIP, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
SYSWARN("Failed to turn on seccomp nop-skip, continuing");
|
SYSWARN("Failed to turn on seccomp nop-skip, continuing");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
f = fopen(conf->seccomp, "r");
|
f = fopen(conf->seccomp.seccomp, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
SYSERROR("Failed to open seccomp policy file %s", conf->seccomp);
|
SYSERROR("Failed to open seccomp policy file %s", conf->seccomp.seccomp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,14 +1224,14 @@ int lxc_seccomp_load(struct lxc_conf *conf)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!conf->seccomp)
|
if (!conf->seccomp.seccomp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!use_seccomp(conf))
|
if (!use_seccomp(conf))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if HAVE_SCMP_FILTER_CTX
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
ret = seccomp_load(conf->seccomp_ctx);
|
ret = seccomp_load(conf->seccomp.seccomp_ctx);
|
||||||
#else
|
#else
|
||||||
ret = seccomp_load();
|
ret = seccomp_load();
|
||||||
#endif
|
#endif
|
||||||
@ -1245,7 +1247,7 @@ int lxc_seccomp_load(struct lxc_conf *conf)
|
|||||||
if ((lxc_log_get_level() <= LXC_LOG_LEVEL_TRACE ||
|
if ((lxc_log_get_level() <= LXC_LOG_LEVEL_TRACE ||
|
||||||
conf->loglevel <= LXC_LOG_LEVEL_TRACE) &&
|
conf->loglevel <= LXC_LOG_LEVEL_TRACE) &&
|
||||||
lxc_log_fd >= 0) {
|
lxc_log_fd >= 0) {
|
||||||
ret = seccomp_export_pfc(conf->seccomp_ctx, lxc_log_fd);
|
ret = seccomp_export_pfc(conf->seccomp.seccomp_ctx, lxc_log_fd);
|
||||||
/* Just give an warning when export error */
|
/* Just give an warning when export error */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
@ -1255,14 +1257,14 @@ int lxc_seccomp_load(struct lxc_conf *conf)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
if (conf->has_seccomp_notify) {
|
if (conf->seccomp.notifier.wants_supervision) {
|
||||||
ret = seccomp_notif_get_fd(conf->seccomp_ctx);
|
ret = seccomp_notif_get_fd(conf->seccomp.seccomp_ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf->seccomp_notify_fd = ret;
|
conf->seccomp.notifier.notify_fd = ret;
|
||||||
TRACE("Retrieved new seccomp listener fd %d", ret);
|
TRACE("Retrieved new seccomp listener fd %d", ret);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1270,24 +1272,23 @@ int lxc_seccomp_load(struct lxc_conf *conf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lxc_seccomp_free(struct lxc_conf *conf)
|
void lxc_seccomp_free(struct lxc_seccomp *seccomp)
|
||||||
{
|
{
|
||||||
free(conf->seccomp);
|
free_disarm(seccomp->seccomp);
|
||||||
conf->seccomp = NULL;
|
|
||||||
|
|
||||||
#if HAVE_SCMP_FILTER_CTX
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
if (conf->seccomp_ctx) {
|
if (seccomp->seccomp_ctx) {
|
||||||
seccomp_release(conf->seccomp_ctx);
|
seccomp_release(seccomp->seccomp_ctx);
|
||||||
conf->seccomp_ctx = NULL;
|
seccomp->seccomp_ctx = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
close_prot_errno_disarm(conf->seccomp_notify_fd);
|
close_prot_errno_disarm(seccomp->notifier.notify_fd);
|
||||||
close_prot_errno_disarm(conf->seccomp_notify_proxy_fd);
|
close_prot_errno_disarm(seccomp->notifier.proxy_fd);
|
||||||
seccomp_notif_free(conf->seccomp_notify_req, conf->seccomp_notify_resp);
|
seccomp_notif_free(seccomp->notifier.req_buf, seccomp->notifier.rsp_buf);
|
||||||
conf->seccomp_notify_req = NULL;
|
seccomp->notifier.req_buf = NULL;
|
||||||
conf->seccomp_notify_resp = NULL;
|
seccomp->notifier.rsp_buf = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,9 +1297,9 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
|
|||||||
{
|
{
|
||||||
__do_close_prot_errno int notify_fd = -EBADF;
|
__do_close_prot_errno int notify_fd = -EBADF;
|
||||||
|
|
||||||
close_prot_errno_disarm(handler->conf->seccomp_notify_proxy_fd);
|
close_prot_errno_disarm(handler->conf->seccomp.notifier.proxy_fd);
|
||||||
|
|
||||||
notify_fd = lxc_unix_connect(&handler->conf->seccomp_notify_proxy_addr);
|
notify_fd = lxc_unix_connect(&handler->conf->seccomp.notifier.proxy_addr);
|
||||||
if (notify_fd < 0) {
|
if (notify_fd < 0) {
|
||||||
SYSERROR("Failed to reconnect to seccomp proxy");
|
SYSERROR("Failed to reconnect to seccomp proxy");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1309,7 +1310,7 @@ static int seccomp_notify_reconnect(struct lxc_handler *handler)
|
|||||||
SYSERROR("Failed to set socket timeout");
|
SYSERROR("Failed to set socket timeout");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
handler->conf->seccomp_notify_proxy_fd = move_fd(notify_fd);
|
handler->conf->seccomp.notifier.proxy_fd = move_fd(notify_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1338,9 +1339,9 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
|
|||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
struct lxc_handler *hdlr = data;
|
struct lxc_handler *hdlr = data;
|
||||||
struct lxc_conf *conf = hdlr->conf;
|
struct lxc_conf *conf = hdlr->conf;
|
||||||
struct seccomp_notif *req = conf->seccomp_notify_req;
|
struct seccomp_notif *req = conf->seccomp.notifier.req_buf;
|
||||||
struct seccomp_notif_resp *resp = conf->seccomp_notify_resp;
|
struct seccomp_notif_resp *resp = conf->seccomp.notifier.rsp_buf;
|
||||||
int listener_proxy_fd = conf->seccomp_notify_proxy_fd;
|
int listener_proxy_fd = conf->seccomp.notifier.proxy_fd;
|
||||||
struct seccomp_notify_proxy_msg msg;
|
struct seccomp_notify_proxy_msg msg;
|
||||||
|
|
||||||
if (listener_proxy_fd < 0) {
|
if (listener_proxy_fd < 0) {
|
||||||
@ -1390,3 +1391,113 @@ out:
|
|||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void seccomp_conf_init(struct lxc_conf *conf)
|
||||||
|
{
|
||||||
|
conf->seccomp.seccomp = NULL;
|
||||||
|
#if HAVE_SCMP_FILTER_CTX
|
||||||
|
conf->seccomp.allow_nesting = 0;
|
||||||
|
memset(&conf->seccomp.seccomp_ctx, 0, sizeof(conf->seccomp.seccomp_ctx));
|
||||||
|
#endif /* HAVE_SCMP_FILTER_CTX */
|
||||||
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
|
conf->seccomp.notifier.wants_supervision = false;
|
||||||
|
conf->seccomp.notifier.notify_fd = -EBADF;
|
||||||
|
conf->seccomp.notifier.proxy_fd = -EBADF;
|
||||||
|
memset(&conf->seccomp.notifier.proxy_addr, 0,
|
||||||
|
sizeof(conf->seccomp.notifier.proxy_addr));
|
||||||
|
conf->seccomp.notifier.req_buf = NULL;
|
||||||
|
conf->seccomp.notifier.rsp_buf = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_seccomp_setup_notifier(struct lxc_seccomp *seccomp,
|
||||||
|
struct lxc_epoll_descr *descr,
|
||||||
|
struct lxc_handler *handler)
|
||||||
|
{
|
||||||
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
|
if (seccomp->notifier.wants_supervision &&
|
||||||
|
seccomp->notifier.proxy_addr.sun_path[1] != '\0') {
|
||||||
|
__do_close_prot_errno int notify_fd = -EBADF;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
notify_fd = lxc_unix_connect(&seccomp->notifier.proxy_addr);
|
||||||
|
if (notify_fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* 30 second timeout */
|
||||||
|
ret = lxc_socket_set_timeout(notify_fd, 30, 30);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = lxc_mainloop_add_handler(descr,
|
||||||
|
seccomp->notifier.notify_fd,
|
||||||
|
seccomp_notify_handler, handler);
|
||||||
|
if (ret < 0) {
|
||||||
|
ERROR("Failed to add seccomp notify handler for %d to mainloop",
|
||||||
|
seccomp->notifier.notify_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
seccomp->notifier.proxy_fd = move_fd(notify_fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_seccomp_send_notifier_fd(struct lxc_seccomp *seccomp, int socket_fd)
|
||||||
|
{
|
||||||
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
|
if (seccomp->notifier.wants_supervision) {
|
||||||
|
if (lxc_abstract_unix_send_fds(socket_fd,
|
||||||
|
&seccomp->notifier.notify_fd, 1,
|
||||||
|
NULL, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
close_prot_errno_disarm(seccomp->notifier.notify_fd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_seccomp_recv_notifier_fd(struct lxc_seccomp *seccomp, int socket_fd)
|
||||||
|
{
|
||||||
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
|
if (seccomp->notifier.wants_supervision) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = lxc_abstract_unix_recv_fds(socket_fd,
|
||||||
|
&seccomp->notifier.notify_fd,
|
||||||
|
1, NULL, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (seccomp->notifier.proxy_fd >= 0) {
|
||||||
|
ret = seccomp_notif_alloc(&seccomp->notifier.req_buf,
|
||||||
|
&seccomp->notifier.rsp_buf);
|
||||||
|
if (ret) {
|
||||||
|
errno = ret;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lxc_seccomp_add_notifier(const char *name, const char *lxcpath,
|
||||||
|
struct lxc_seccomp *seccomp)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
|
||||||
|
if (seccomp->notifier.proxy_fd >= 0) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = lxc_cmd_seccomp_notify_add_listener(name, lxcpath,
|
||||||
|
seccomp->notifier.notify_fd,
|
||||||
|
-1, 0);
|
||||||
|
close_prot_errno_disarm(seccomp->notifier.notify_fd);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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 @@
|
|||||||
#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"
|
||||||
|
Loading…
Reference in New Issue
Block a user