seccomp: send process memory fd

There's an inherent race when reading a process's memory. The easiest way is to have liblxc get an fd and check that the race was one, send it to the caller (They are free to ignore it if they don't use recvmsg()). Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 0b5afd32
......@@ -199,6 +199,12 @@ again:
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)
{
......
......@@ -35,6 +35,8 @@ extern void lxc_abstract_unix_close(int fd);
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);
......
......@@ -1335,8 +1335,10 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
{
#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;
......@@ -1355,14 +1357,33 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
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))
......@@ -1370,6 +1391,8 @@ int seccomp_notify_handler(int fd, uint32_t events, void *data,
}
} while (reconnect_count++);
close_prot_errno_disarm(fd_mem);
reconnect_count = 0;
do {
bytes = lxc_recv_nointr(listener_proxy_fd, &msg, sizeof(msg), 0);
......
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