public inbox for io-uring@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-next] io_uring/query: check for loops in in_query()
@ 2025-09-11  0:13 Jens Axboe
  2025-09-11  9:02 ` Pavel Begunkov
  0 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2025-09-11  0:13 UTC (permalink / raw)
  To: io-uring; +Cc: Pavel Begunkov

io_query() loops over query items that the application or liburing
passes in. But it has no checking for a max number of items, or if a
loop could be present. If someone were to do:

        struct io_uring_query_hdr hdr1, hdr2, hdr3;

        hdr3.next_entry = &hdr1;
        hdr2.next_entry = &hdr3;
        hdr1.next_entry = &hdr2;

        io_uring_register(fd, IORING_REGISTER_QUERY, &hdr1, 0);

then it'll happily loop forever and process hdr1 -> hdr2 -> hdr3 and
then loop back to hdr1.

Add a max cap for these kinds of cases, which is arbitrarily set to
1024 as well. Since there's now a cap, it seems that it would be saner
to have this interface return the number of items processed. Eg 0..N
for success, and < 0 for an error. Then if someone does need to query
more than the supported number of items, they can do so iteratively.

Fixes: c265ae75f900 ("io_uring: introduce io_uring querying")
Signed-off-by: Jens Axboe <axboe@kernel.dk>

---

This would obviously need liburing changes too, but not a big deal
since a) the changes aren't in liburing yet, and b) this is still
unreleased code.

diff --git a/io_uring/query.c b/io_uring/query.c
index 9eed0f371956..99402e8e0a4a 100644
--- a/io_uring/query.c
+++ b/io_uring/query.c
@@ -70,11 +70,14 @@ static int io_handle_query_entry(struct io_ring_ctx *ctx,
 	return 0;
 }
 
+/*
+ * Returns number of items processed, or < 0 in case of error.
+ */
 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));
 
@@ -86,8 +89,11 @@ int io_query(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_args)
 
 		ret = io_handle_query_entry(ctx, entry_buffer, uhdr, &next_hdr);
 		if (ret)
-			return ret;
+			break;
 		uhdr = u64_to_user_ptr(next_hdr);
+		/* Have some limit to avoid a potential loop */
+		if (++nr >= 1024)
+			break;
 	}
-	return 0;
+	return nr ?: ret;
 }

-- 
Jens Axboe


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-09-18 10:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-11  0:13 [PATCH for-next] io_uring/query: check for loops in in_query() Jens Axboe
2025-09-11  9:02 ` Pavel Begunkov
2025-09-11 11:40   ` Pavel Begunkov
2025-09-15 18:41     ` Jens Axboe
2025-09-16 15:05       ` Pavel Begunkov
2025-09-16 18:33         ` Jens Axboe
2025-09-16 18:35           ` Jens Axboe
2025-09-18  9:50             ` Pavel Begunkov
2025-09-18 10:27           ` Pavel Begunkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox