confile: add lxc.seccomp.notify.proxy

parent cdb2a47f
...@@ -316,3 +316,73 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size) ...@@ -316,3 +316,73 @@ int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size)
out: out:
return ret; return ret;
} }
int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path)
{
size_t len;
len = strlen(path);
if (len == 0)
return minus_one_set_errno(EINVAL);
if (path[0] != '/' && path[0] != '@')
return minus_one_set_errno(EINVAL);
if (path[1] == '\0')
return minus_one_set_errno(EINVAL);
if (len + 1 > sizeof(ret->sun_path))
return minus_one_set_errno(EINVAL);
*ret = (struct sockaddr_un){
.sun_family = AF_UNIX,
};
if (path[0] == '@') {
memcpy(ret->sun_path + 1, path + 1, len);
return (int)(offsetof(struct sockaddr_un, sun_path) + len);
}
memcpy(ret->sun_path, path, len + 1);
return (int)(offsetof(struct sockaddr_un, sun_path) + len + 1);
}
int lxc_unix_connect(struct sockaddr_un *addr)
{
__do_close_prot_errno int fd = -EBADF;
int ret;
ssize_t len;
fd = socket(PF_UNIX, SOCK_STREAM, SOCK_CLOEXEC);
if (fd < 0)
return -1;
if (addr->sun_path[0] == '\0')
len = strlen(&addr->sun_path[1]);
else
len = strlen(&addr->sun_path[0]);
ret = connect(fd, (struct sockaddr *)&addr,
offsetof(struct sockaddr_un, sun_path) + len + 1);
if (ret < 0)
return -1;
return move_fd(fd);
}
int lxc_socket_set_timeout(int fd, int rcv_timeout, int snd_timeout)
{
struct timeval out = {0};
int ret;
out.tv_sec = snd_timeout;
ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (const void *)&out,
sizeof(out));
if (ret < 0)
return -1;
out.tv_sec = rcv_timeout;
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const void *)&out,
sizeof(out));
if (ret < 0)
return -1;
return 0;
}
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define __LXC_AF_UNIX_H #define __LXC_AF_UNIX_H
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
/* does not enforce \0-termination */ /* does not enforce \0-termination */
extern int lxc_abstract_unix_open(const char *path, int type, int flags); extern int lxc_abstract_unix_open(const char *path, int type, int flags);
...@@ -37,5 +39,8 @@ extern int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds, ...@@ -37,5 +39,8 @@ extern int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
void *data, size_t size); void *data, size_t size);
extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size); extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size);
extern int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size); extern int lxc_abstract_unix_rcv_credential(int fd, void *data, size_t size);
extern int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path);
extern int lxc_unix_connect(struct sockaddr_un *addr);
extern int lxc_socket_set_timeout(int fd, int rcv_timeout, int snd_timeout);
#endif /* __LXC_AF_UNIX_H */ #endif /* __LXC_AF_UNIX_H */
...@@ -2756,6 +2756,7 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2756,6 +2756,7 @@ struct lxc_conf *lxc_conf_init(void)
new->has_seccomp_notify = false; new->has_seccomp_notify = false;
new->seccomp_notify_fd = -EBADF; new->seccomp_notify_fd = -EBADF;
new->seccomp_notify_proxy_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_req = NULL;
new->seccomp_notify_resp = NULL; new->seccomp_notify_resp = NULL;
#endif #endif
......
...@@ -304,6 +304,7 @@ struct lxc_conf { ...@@ -304,6 +304,7 @@ struct lxc_conf {
bool has_seccomp_notify; bool has_seccomp_notify;
int seccomp_notify_fd; int seccomp_notify_fd;
int seccomp_notify_proxy_fd; int seccomp_notify_proxy_fd;
struct sockaddr_un seccomp_notify_proxy_addr;
struct seccomp_notif *seccomp_notify_req; struct seccomp_notif *seccomp_notify_req;
struct seccomp_notif_resp *seccomp_notify_resp; struct seccomp_notif_resp *seccomp_notify_resp;
#endif #endif
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "af_unix.h"
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
#include "confile.h" #include "confile.h"
...@@ -147,6 +148,7 @@ lxc_config_define(rootfs_options); ...@@ -147,6 +148,7 @@ lxc_config_define(rootfs_options);
lxc_config_define(rootfs_path); lxc_config_define(rootfs_path);
lxc_config_define(seccomp_profile); lxc_config_define(seccomp_profile);
lxc_config_define(seccomp_allow_nesting); lxc_config_define(seccomp_allow_nesting);
lxc_config_define(seccomp_notify_proxy);
lxc_config_define(selinux_context); lxc_config_define(selinux_context);
lxc_config_define(signal_halt); lxc_config_define(signal_halt);
lxc_config_define(signal_reboot); lxc_config_define(signal_reboot);
...@@ -234,6 +236,7 @@ static struct lxc_config_t config_jump_table[] = { ...@@ -234,6 +236,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.rootfs.options", set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, }, { "lxc.rootfs.options", set_config_rootfs_options, get_config_rootfs_options, clr_config_rootfs_options, },
{ "lxc.rootfs.path", set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, }, { "lxc.rootfs.path", set_config_rootfs_path, get_config_rootfs_path, clr_config_rootfs_path, },
{ "lxc.seccomp.allow_nesting", set_config_seccomp_allow_nesting, get_config_seccomp_allow_nesting, clr_config_seccomp_allow_nesting, }, { "lxc.seccomp.allow_nesting", set_config_seccomp_allow_nesting, get_config_seccomp_allow_nesting, clr_config_seccomp_allow_nesting, },
{ "lxc.seccomp.notify.proxy", set_config_seccomp_notify_proxy, get_config_seccomp_notify_proxy, clr_config_seccomp_notify_proxy, },
{ "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, }, { "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, },
{ "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, }, { "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, },
{ "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, }, { "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, },
...@@ -784,9 +787,31 @@ static int set_config_seccomp_allow_nesting(const char *key, const char *value, ...@@ -784,9 +787,31 @@ static int set_config_seccomp_allow_nesting(const char *key, const char *value,
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 0;
}
static int set_config_seccomp_notify_proxy(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
const char *offset;
if (lxc_config_value_empty(value))
return clr_config_seccomp_notify_proxy(key, lxc_conf, NULL);
if (strncmp(value, "unix:", 5) != 0)
return minus_one_set_errno(EINVAL);
offset = value + 5;
if (lxc_unix_sockaddr(&lxc_conf->seccomp_notify_proxy_addr, offset) < 0)
return -1; return -1;
return 0; return 0;
#else
return minus_one_set_errno(ENOSYS);
#endif
} }
static int set_config_seccomp_profile(const char *key, const char *value, static int set_config_seccomp_profile(const char *key, const char *value,
...@@ -3704,6 +3729,19 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv, ...@@ -3704,6 +3729,19 @@ static int get_config_seccomp_allow_nesting(const char *key, char *retv,
return lxc_get_conf_int(c, retv, inlen, c->seccomp_allow_nesting); return lxc_get_conf_int(c, retv, inlen, c->seccomp_allow_nesting);
} }
static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
return lxc_get_conf_str(retv, inlen,
(c->seccomp_notify_proxy_addr.sun_path[0]) == '/'
? &c->seccomp_notify_proxy_addr.sun_path[0]
: &c->seccomp_notify_proxy_addr.sun_path[1]);
#else
return minus_one_set_errno(ENOSYS);
#endif
}
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)
{ {
...@@ -4294,6 +4332,18 @@ static inline int clr_config_seccomp_allow_nesting(const char *key, ...@@ -4294,6 +4332,18 @@ static inline int clr_config_seccomp_allow_nesting(const char *key,
return 0; return 0;
} }
static inline int clr_config_seccomp_notify_proxy(const char *key,
struct lxc_conf *c, void *data)
{
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
memset(&c->seccomp_notify_proxy_addr, 0,
sizeof(c->seccomp_notify_proxy_addr));
return 0;
#else
return minus_one_set_errno(ENOSYS);
#endif
}
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)
{ {
......
...@@ -593,7 +593,18 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -593,7 +593,18 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD #if HAVE_DECL_SECCOMP_NOTIF_GET_FD
if (handler->conf->has_seccomp_notify && if (handler->conf->has_seccomp_notify &&
handler->conf->seccomp_notify_proxy_fd >= 0) { handler->conf->seccomp_notify_proxy_addr.sun_path[1] != '\0') {
__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, ret = lxc_mainloop_add_handler(&descr,
handler->conf->seccomp_notify_fd, handler->conf->seccomp_notify_fd,
seccomp_notify_handler, handler); seccomp_notify_handler, handler);
...@@ -602,6 +613,8 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -602,6 +613,8 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
handler->conf->seccomp_notify_fd); handler->conf->seccomp_notify_fd);
goto out_mainloop_console; goto out_mainloop_console;
} }
handler->conf->seccomp_notify_proxy_fd = move_fd(notify_fd);
} }
#endif #endif
......
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