summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Begunkov <asml.silence@gmail.com>2023-03-06 13:21:40 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-10 09:40:04 +0100
commitdde0d0dfbde23974d7449c04ef2fb8814d09deef (patch)
treeab13f01005c6dacdcd5743e4d0b9b9231c6894b9
parentabd54d87dabae7e50492f6ce1199a7ddadbbcaf8 (diff)
downloadlinux-rt-dde0d0dfbde23974d7449c04ef2fb8814d09deef.tar.gz
io_uring/rsrc: disallow multi-source reg buffers
commit edd478269640b360c6f301f2baa04abdda563ef3 upstream. If two or more mappings go back to back to each other they can be passed into io_uring to be registered as a single registered buffer. That would even work if mappings came from different sources, e.g. it's possible to mix in this way anon pages and pages from shmem or hugetlb. That is not a problem but it'd rather be less prone if we forbid such mixing. Cc: <stable@vger.kernel.org> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--io_uring/io_uring.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 503a216b321b..acf4d49c7339 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -9228,14 +9228,17 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
pret = pin_user_pages(ubuf, nr_pages, FOLL_WRITE | FOLL_LONGTERM,
pages, vmas);
if (pret == nr_pages) {
+ struct file *file = vmas[0]->vm_file;
+
/* don't support file backed memory */
for (i = 0; i < nr_pages; i++) {
- struct vm_area_struct *vma = vmas[i];
-
- if (vma_is_shmem(vma))
+ if (vmas[i]->vm_file != file) {
+ ret = -EINVAL;
+ break;
+ }
+ if (!file)
continue;
- if (vma->vm_file &&
- !is_file_hugepages(vma->vm_file)) {
+ if (!vma_is_shmem(vmas[i]) && !is_file_hugepages(file)) {
ret = -EOPNOTSUPP;
break;
}