On Thu, 2026-05-14 at 08:07 -0600, Jens Axboe wrote:
> One of the nastier things about epoll is how it allows adding epoll
> files to epoll contexts. This leads to all sorts of loop detection
> code, and has been a source of issues in the past.
>
> Arguably adding IORING_EPOLL_CTL is a historical mistake on the
> io_uring side, but we're kind of stuck with it now as it does seem
> to be in use according to code searches. But we can at least minimize
> the damage a bit and just disallow this part of epoll, where nesting
> issues can arise.
libuv uses this ... thing and there's even a test case against
exercising the code path adding an epoll file:
-
https://github.com/libuv/libuv/commit/3b6a1a14caee
-
https://github.com/libuv/libuv/blob/09591002d38e/test/test-poll.c#L690
And the test triggers an abort on the EINVAL at
https://github.com/libuv/libuv/blob/09591002d38e/src/unix/linux.c#L1360
I'm unsure what to do here.
> Suggested-by: Linus Torvalds <
torv...@linux-foundation.org>
> Signed-off-by: Jens Axboe <
ax...@kernel.dk>
> ---
> io_uring/epoll.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/io_uring/epoll.c b/io_uring/epoll.c
> index b9db8bde27ec..eecd748cad01 100644
> --- a/io_uring/epoll.c
> +++ b/io_uring/epoll.c
> @@ -62,6 +62,9 @@ int io_epoll_ctl(struct io_kiocb *req, unsigned int
> issue_flags)
> CLASS(fd, tf)(ie->fd);
> if (fd_empty(tf))
> return -EBADF;
> + /* disallow adding an epoll context to another epoll context
> */
> + if (ie->op == EPOLL_CTL_ADD && is_file_epoll(fd_file(tf)))
> + return -EINVAL;
>
> key.file = fd_file(tf);
> key.fd = ie->fd;
--
Xi Ruoyao <xry...@xry111.site>