seccomp: epoll issues post addfd

From: Alok Tiagi
Date: Fri Jul 16 2021 - 02:39:57 EST


We are using seccomp to intercept syscalls like connect() and using
addfd to install new file descriptors into the client program. We are
running into an issue where any operations by epoll_ctl in the client
programs returns an ENOENT (No such file or directory) after the
syscall interception.

Example:
fd = socket(AF_INET, ...)
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event)
connect(fd, ...)

Post interception of the connect() syscall, the file descriptor
registered with epoll is no longer valid and any further epoll_ctl
operations in the client program fail. This is happening because the
original fd is closed causing it to be removed from the epoll
instance.

As a workaround, after addfd and before unblocking the client
program's syscall we traverse the client programs /proc to find all
epoll file descriptors that have the original fd as their target. We
then use pidfd_getfd() to get the client programs epoll_fd and perform
an EPOLL_CTL_ADD operation with the new fd that we installed using
addfd. Before EPOLL_CTL_ADD we ensure that the new fd's number matches
that of the original fd by calling dup2(). This helps further
epoll_ctl operations in the client program to find the fd.

It would be nice if this was handled in the kernel after addfd and I
am wondering if this is an issue which others are facing and if any
solutions have been thought of.

Thanks
Alok