@@ -1185,6 +1185,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
imu->ubuf = (unsigned long) iov->iov_base;
imu->ubuf_end = imu->ubuf + iov->iov_len;
imu->nr_bvecs = nr_pages;
+ imu->dir_mask = (1U << ITER_SOURCE) | (1U << ITER_DEST);
*pimu = imu;
ret = 0;
@@ -1274,6 +1275,8 @@ int io_import_fixed(int ddir, struct iov_iter *iter,
u64 buf_end;
size_t offset;
+ BUILD_BUG_ON((1U << ITER_SOURCE) & (1U << ITER_DEST));
+
if (WARN_ON_ONCE(!imu))
return -EFAULT;
if (unlikely(check_add_overflow(buf_addr, (u64)len, &buf_end)))
@@ -1281,6 +1284,8 @@ int io_import_fixed(int ddir, struct iov_iter *iter,
/* not inside the mapped region */
if (unlikely(buf_addr < imu->ubuf || buf_end > imu->ubuf_end))
return -EFAULT;
+ if (unlikely(!((1U << ddir) & imu->dir_mask)))
+ return -EFAULT;
/*
* Might not be a start of buffer, set size appropriately
@@ -57,6 +57,7 @@ struct io_mapped_ubuf {
u64 ubuf_end;
unsigned int nr_bvecs;
unsigned int max_bvecs;
+ unsigned int dir_mask;
unsigned long acct_pages;
struct bio_vec bvec[];
};
There will be buffers that only allow reading from or writing to it, so add data directions, and check it when importing a buffer. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> --- io_uring/rsrc.c | 5 +++++ io_uring/rsrc.h | 1 + 2 files changed, 6 insertions(+)