Patch "io_uring: fix overflows checks in provide buffers" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    io_uring: fix overflows checks in provide buffers

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     io_uring-fix-overflows-checks-in-provide-buffers.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 009bd82b57fa29884b0f4621d8a5a13885eab2a5
Author: Pavel Begunkov <asml.silence@xxxxxxxxx>
Date:   Thu Apr 15 13:07:39 2021 +0100

    io_uring: fix overflows checks in provide buffers
    
    [ Upstream commit 38134ada0ceea3e848fe993263c0ff6207fd46e7 ]
    
    Colin reported before possible overflow and sign extension problems in
    io_provide_buffers_prep(). As Linus pointed out previous attempt did nothing
    useful, see d81269fecb8ce ("io_uring: fix provide_buffers sign extension").
    
    Do that with help of check_<op>_overflow helpers. And fix struct
    io_provide_buf::len type, as it doesn't make much sense to keep it
    signed.
    
    Reported-by: Colin Ian King <colin.king@xxxxxxxxxxxxx>
    Fixes: efe68c1ca8f49 ("io_uring: validate the full range of provided buffers for access")
    Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx>
    Link: https://lore.kernel.org/r/46538827e70fce5f6cdb50897cff4cacc490f380.1618488258.git.asml.silence@xxxxxxxxx
    Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 55e214defb42..369ec81033d6 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -527,7 +527,7 @@ struct io_splice {
 struct io_provide_buf {
 	struct file			*file;
 	__u64				addr;
-	__s32				len;
+	__u32				len;
 	__u32				bgid;
 	__u16				nbufs;
 	__u16				bid;
@@ -3996,7 +3996,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock,
 static int io_provide_buffers_prep(struct io_kiocb *req,
 				   const struct io_uring_sqe *sqe)
 {
-	unsigned long size;
+	unsigned long size, tmp_check;
 	struct io_provide_buf *p = &req->pbuf;
 	u64 tmp;
 
@@ -4010,6 +4010,12 @@ static int io_provide_buffers_prep(struct io_kiocb *req,
 	p->addr = READ_ONCE(sqe->addr);
 	p->len = READ_ONCE(sqe->len);
 
+	if (check_mul_overflow((unsigned long)p->len, (unsigned long)p->nbufs,
+				&size))
+		return -EOVERFLOW;
+	if (check_add_overflow((unsigned long)p->addr, size, &tmp_check))
+		return -EOVERFLOW;
+
 	size = (unsigned long)p->len * p->nbufs;
 	if (!access_ok(u64_to_user_ptr(p->addr), size))
 		return -EFAULT;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux