From: Jens Axboe <axboe@kernel.dk>
To: io-uring <io-uring@vger.kernel.org>
Cc: Pavel Begunkov <asml.silence@gmail.com>
Subject: [PATCH for-next] io_uring/query: check for loops in in_query()
Date: Wed, 10 Sep 2025 18:13:49 -0600 [thread overview]
Message-ID: <2a4811de-1e35-428d-8784-a162c0e4ea8f@kernel.dk> (raw)
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
next reply other threads:[~2025-09-11 0:13 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-11 0:13 Jens Axboe [this message]
2025-09-11 9:02 ` [PATCH for-next] io_uring/query: check for loops in in_query() 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2a4811de-1e35-428d-8784-a162c0e4ea8f@kernel.dk \
--to=axboe@kernel.dk \
--cc=asml.silence@gmail.com \
--cc=io-uring@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox