#include "log.h"
#include "lxc.h"
#include "lxclock.h"
+#include "lxcseccomp.h"
#include "mainloop.h"
#include "memory_utils.h"
#include "monitor.h"
[LXC_CMD_ADD_STATE_CLIENT] = "add_state_client",
[LXC_CMD_CONSOLE_LOG] = "console_log",
[LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients",
+ [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener",
};
if (cmd >= LXC_CMD_MAX)
if (ret < 0 || (size_t)ret != sizeof(cmd->req))
return -1;
- if (cmd->req.datalen <= 0)
- return move_fd(client_fd);
+ if (cmd->req.cmd == LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER) {
+ int notify_fd = PTR_TO_INT(cmd->req.data);
+ ret = lxc_abstract_unix_send_fds(client_fd, ¬ify_fd, 1, NULL, 0);
+ if (ret <= 0)
+ return -1;
+ } else {
+ if (cmd->req.datalen <= 0)
+ return move_fd(client_fd);
- errno = EMSGSIZE;
- ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
- cmd->req.datalen, MSG_NOSIGNAL);
- if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
- return -1;
+ errno = EMSGSIZE;
+ ret = lxc_send_nointr(client_fd, (void *)cmd->req.data,
+ cmd->req.datalen, MSG_NOSIGNAL);
+ if (ret < 0 || ret != (ssize_t)cmd->req.datalen)
+ return -1;
+ }
return move_fd(client_fd);
}
}
static int lxc_cmd_get_init_pid_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
intmax_t pid = handler->pid;
}
static int lxc_cmd_get_clone_flags_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->ns_clone_flags) };
}
static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
const char *path;
struct lxc_cmd_rsp rsp;
}
static int lxc_cmd_get_config_item_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
__do_free char *cidata = NULL;
int cilen;
}
static int lxc_cmd_get_state_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp = { .data = INT_TO_PTR(handler->state) };
}
static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp;
int stopsignal = SIGKILL;
}
static int lxc_cmd_terminal_winch_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
/* should never be called */
return -1;
}
static int lxc_cmd_console_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
int masterfd, ret;
struct lxc_cmd_rsp rsp;
}
static int lxc_cmd_get_name_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp;
}
static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp;
}
static int lxc_cmd_add_state_client_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
int ret;
struct lxc_cmd_rsp rsp = {0};
}
static int lxc_cmd_console_log_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
struct lxc_cmd_rsp rsp;
uint64_t buffer_size = handler->conf->console.buffer_size;
}
static int lxc_cmd_serve_state_clients_callback(int fd, struct lxc_cmd_req *req,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
int ret;
lxc_state_t state = PTR_TO_INT(req->data);
return 1;
}
+int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
+ int fd,
+ /* unused */ unsigned int command,
+ /* unused */ unsigned int flags)
+{
+ return minus_one_set_errno(ENOSYS);
+}
+
+static int lxc_cmd_seccomp_notify_add_listener_callback(int fd,
+ struct lxc_cmd_req *req,
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
+{
+ struct lxc_cmd_rsp rsp = {
+ .ret = -ENOSYS,
+ };
+ int ret;
+
+ ret = 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,
- struct lxc_handler *handler)
+ struct lxc_handler *handler,
+ struct lxc_epoll_descr *descr)
{
- typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *);
+ typedef int (*callback)(int, struct lxc_cmd_req *, struct lxc_handler *,
+ struct lxc_epoll_descr *);
callback cb[LXC_CMD_MAX] = {
- [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
- [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
- [LXC_CMD_STOP] = lxc_cmd_stop_callback,
- [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
- [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
- [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
- [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
- [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
- [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
- [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
- [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
- [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
- [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
+ [LXC_CMD_CONSOLE] = lxc_cmd_console_callback,
+ [LXC_CMD_TERMINAL_WINCH] = lxc_cmd_terminal_winch_callback,
+ [LXC_CMD_STOP] = lxc_cmd_stop_callback,
+ [LXC_CMD_GET_STATE] = lxc_cmd_get_state_callback,
+ [LXC_CMD_GET_INIT_PID] = lxc_cmd_get_init_pid_callback,
+ [LXC_CMD_GET_CLONE_FLAGS] = lxc_cmd_get_clone_flags_callback,
+ [LXC_CMD_GET_CGROUP] = lxc_cmd_get_cgroup_callback,
+ [LXC_CMD_GET_CONFIG_ITEM] = lxc_cmd_get_config_item_callback,
+ [LXC_CMD_GET_NAME] = lxc_cmd_get_name_callback,
+ [LXC_CMD_GET_LXCPATH] = lxc_cmd_get_lxcpath_callback,
+ [LXC_CMD_ADD_STATE_CLIENT] = lxc_cmd_add_state_client_callback,
+ [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback,
+ [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback,
+ [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback,
};
if (req->cmd >= LXC_CMD_MAX) {
ERROR("Undefined command id %d", req->cmd);
return -1;
}
- return cb[req->cmd](fd, req, handler);
+ return cb[req->cmd](fd, req, handler, descr);
}
static void lxc_cmd_fd_cleanup(int fd, struct lxc_handler *handler,
- struct lxc_epoll_descr *descr,
- const lxc_cmd_t cmd)
+ struct lxc_epoll_descr *descr, const lxc_cmd_t cmd)
{
struct lxc_list *cur, *next;
lxc_terminal_free(handler->conf, fd);
lxc_mainloop_del_handler(descr, fd);
- if (cmd != LXC_CMD_ADD_STATE_CLIENT) {
- close(fd);
- return;
- }
-
- lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
- struct lxc_state_client *client = cur->elem;
- if (client->clientfd != fd)
- continue;
-
- /* kick client from list */
- lxc_list_del(cur);
- close(client->clientfd);
- free(cur->elem);
- free(cur);
- /* No need to walk the whole list. If we found the state client
- * fd there can't be a second one.
- */
+ switch (cmd) {
+ case LXC_CMD_ADD_STATE_CLIENT:
+ lxc_list_for_each_safe(cur, &handler->conf->state_clients, next) {
+ struct lxc_state_client *client = cur->elem;
+
+ if (client->clientfd != fd)
+ continue;
+
+ /* kick client from list */
+ lxc_list_del(cur);
+ close(client->clientfd);
+ free(cur->elem);
+ free(cur);
+ /* No need to walk the whole list. If we found the state
+ * client fd there can't be a second one.
+ */
+ break;
+ }
break;
+ default:
+ close(fd);
}
}
req.data = reqdata;
}
- ret = lxc_cmd_process(fd, &req, handler);
+ ret = lxc_cmd_process(fd, &req, handler, descr);
if (ret) {
/* This is not an error, but only a request to close fd. */
ret = LXC_MAINLOOP_CONTINUE;