return ret;
}
+int lxc_unix_send_fds(int fd, int *sendfds, int num_sendfds, void *data,
+ size_t size)
+{
+ return lxc_abstract_unix_send_fds(fd, sendfds, num_sendfds, data, size);
+}
+
int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
void *data, size_t size)
{
extern int lxc_abstract_unix_connect(const char *path);
extern int lxc_abstract_unix_send_fds(int fd, int *sendfds, int num_sendfds,
void *data, size_t size);
+extern int lxc_unix_send_fds(int fd, int *sendfds, int num_sendfds, void *data,
+ size_t size);
extern int lxc_abstract_unix_recv_fds(int fd, int *recvfds, int num_recvfds,
void *data, size_t size);
extern int lxc_abstract_unix_send_credential(int fd, void *data, size_t size);
{
#if HAVE_DECL_SECCOMP_NOTIF_GET_FD
+ __do_close_prot_errno int fd_mem = -EBADF;
int reconnect_count, ret;
ssize_t bytes;
+ char mem_path[6 + 21 + 5];
struct lxc_handler *hdlr = data;
struct lxc_conf *conf = hdlr->conf;
struct seccomp_notif *req = conf->seccomp.notifier.req_buf;
goto out;
}
+ snprintf(mem_path, sizeof(mem_path), "/proc/%d/mem", req->pid);
+ fd_mem = open(mem_path, O_RDONLY | O_CLOEXEC);
+ if (fd_mem < 0) {
+ (void)seccomp_notify_default_answer(fd, req, resp, hdlr);
+ SYSERROR("Failed to open process memory for seccomp notify request");
+ goto out;
+ }
+
+ /*
+ * Make sure that the fd for /proc/<pid>/mem we just opened still
+ * refers to the correct process's memory.
+ */
+ ret = seccomp_notif_id_valid(fd, req->id);
+ if (ret < 0) {
+ (void)seccomp_notify_default_answer(fd, req, resp, hdlr);
+ SYSERROR("Invalid seccomp notify request id");
+ goto out;
+ }
+
memcpy(&msg.req, req, sizeof(msg.req));
msg.monitor_pid = hdlr->monitor_pid;
msg.init_pid = hdlr->pid;
reconnect_count = 0;
do {
- bytes = lxc_send_nointr(listener_proxy_fd, &msg, sizeof(msg),
- MSG_NOSIGNAL);
+ bytes = lxc_unix_send_fds(listener_proxy_fd, &fd_mem, 1, &msg,
+ sizeof(msg));
if (bytes != (ssize_t)sizeof(msg)) {
SYSERROR("Failed to forward message to seccomp proxy");
if (seccomp_notify_default_answer(fd, req, resp, hdlr))
}
} while (reconnect_count++);
+ close_prot_errno_disarm(fd_mem);
+
reconnect_count = 0;
do {
bytes = lxc_recv_nointr(listener_proxy_fd, &msg, sizeof(msg), 0);