summaryrefslogtreecommitdiff
path: root/io_uring
diff options
context:
space:
mode:
authorDeepanshu Kartikey <kartikey406@gmail.com>2026-06-21 06:59:33 +0530
committerJens Axboe <axboe@kernel.dk>2026-06-22 15:12:54 -0600
commit3996771b8f759729cba0a28007438c085f814d61 (patch)
treecf26db7be6e9fe4f1f3c4d30c4ad9ed1262a4d13 /io_uring
parentff3ac1a0bd75400375678c0f81c2b613cbc03e14 (diff)
downloadlinux-next-3996771b8f759729cba0a28007438c085f814d61.tar.gz
linux-next-3996771b8f759729cba0a28007438c085f814d61.zip
io_uring/memmap: bound io_pin_pages() by page array byte size
io_pin_pages() checks that nr_pages does not exceed INT_MAX, then allocates a struct page * array of nr_pages entries. kvmalloc() limits allocations to INT_MAX bytes, but the check counts pages, not bytes. On 64-bit each entry is 8 bytes, so the array hits the INT_MAX byte limit at INT_MAX / sizeof(struct page *) pages, well before the page count check fires. Since commit b4e41050b212 ("io_uring/rsrc: raise registered buffer 1GB limit") raised the per-buffer cap to 1TB, a buffer near that cap maps ~2^28 pages, making the array allocation exceed INT_MAX bytes. This passes the page count check, reaches kvmalloc(), and triggers the WARN_ON_ONCE() for oversized allocations in __kvmalloc_node_noprof(). Check nr_pages against INT_MAX / sizeof(struct page *) so the buffer is rejected with -EOVERFLOW before the allocation is attempted. Reported-by: syzbot+f99b00a963915b6b52c6@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f99b00a963915b6b52c6 Fixes: b4e41050b212 ("io_uring/rsrc: raise registered buffer 1GB limit") Tested-by: syzbot+f99b00a963915b6b52c6@syzkaller.appspotmail.com Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de> Link: https://patch.msgid.link/20260621012933.50571-1-kartikey406@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring')
-rw-r--r--io_uring/memmap.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/io_uring/memmap.c b/io_uring/memmap.c
index 4f9b439319c4..da1f6c5d07f8 100644
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -53,7 +53,7 @@ struct page **io_pin_pages(unsigned long uaddr, unsigned long len, int *npages)
nr_pages = end - start;
if (WARN_ON_ONCE(!nr_pages))
return ERR_PTR(-EINVAL);
- if (WARN_ON_ONCE(nr_pages > INT_MAX))
+ if (nr_pages > INT_MAX / sizeof(struct page *))
return ERR_PTR(-EOVERFLOW);
pages = kvmalloc_objs(struct page *, nr_pages, GFP_KERNEL_ACCOUNT);