]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring/query: cap number of queries
authorPavel Begunkov <asml.silence@gmail.com>
Fri, 19 Sep 2025 11:11:57 +0000 (12:11 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 19 Sep 2025 13:06:43 +0000 (07:06 -0600)
If a query chain forms a cycle, it'll be looping in the kernel until the
process is killed. It might be fine as any such mistake can be easily
uncovered during testing, but it's still nicer to let it break out of
the syscall if it executed too many queries.

Suggested-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/query.c

index c2183daf5a4685ba4c4129c42ab642098755bc5d..645301bd2c8293184b77aa0d357c525d65c6462f 100644 (file)
@@ -6,6 +6,7 @@
 #include "io_uring.h"
 
 #define IO_MAX_QUERY_SIZE              (sizeof(struct io_uring_query_opcode))
+#define IO_MAX_QUERY_ENTRIES           1000
 
 static ssize_t io_query_ops(void *data)
 {
@@ -74,7 +75,7 @@ int io_query(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_args)
 {
        char entry_buffer[IO_MAX_QUERY_SIZE];
        void __user *uhdr = arg;
-       int ret;
+       int ret, nr = 0;
 
        memset(entry_buffer, 0, sizeof(entry_buffer));
 
@@ -89,6 +90,9 @@ int io_query(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_args)
                        return ret;
                uhdr = u64_to_user_ptr(next_hdr);
 
+               /* Have some limit to avoid a potential cycle */
+               if (++nr >= IO_MAX_QUERY_ENTRIES)
+                       return -ERANGE;
                if (fatal_signal_pending(current))
                        return -EINTR;
                cond_resched();