]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring/openclose: fix io_pipe_fixed() slot tracking for specific slots
authorJens Axboe <axboe@kernel.dk>
Wed, 11 Feb 2026 22:12:13 +0000 (15:12 -0700)
committerSasha Levin <sashal@kernel.org>
Wed, 4 Mar 2026 12:21:28 +0000 (07:21 -0500)
[ Upstream commit f4d0668b38d8784f33a9a36c72ed5d0078247538 ]

__io_fixed_fd_install() returns 0 on success for non-alloc mode
(specific slot), not the slot index. io_pipe_fixed() used this return
value directly as the slot index in fds[], which can cause the reported
values returned via copy_to_user() to be incorrect, or the error path
operating on the incorrect direct descriptor.

Fix by computing the actual 0-based slot index (slot - 1) for specific
slot mode, while preserving the existing behavior for auto-alloc mode
where __io_fixed_fd_install() already returns the allocated index.

Cc: stable@vger.kernel.org
Fixes: 53db8a71ecb4 ("io_uring: add support for IORING_OP_PIPE")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
io_uring/openclose.c

index 15dde9bd6ff67084e3645c588bc5ecbe0cebf4a2..606ce0664e6a45f3f6b9abb8af87e37ecb144c64 100644 (file)
@@ -336,31 +336,34 @@ static int io_pipe_fixed(struct io_kiocb *req, struct file **files,
 {
        struct io_pipe *p = io_kiocb_to_cmd(req, struct io_pipe);
        struct io_ring_ctx *ctx = req->ctx;
+       bool alloc_slot;
        int ret, fds[2] = { -1, -1 };
        int slot = p->file_slot;
 
        if (p->flags & O_CLOEXEC)
                return -EINVAL;
 
+       alloc_slot = slot == IORING_FILE_INDEX_ALLOC;
+
        io_ring_submit_lock(ctx, issue_flags);
 
        ret = __io_fixed_fd_install(ctx, files[0], slot);
        if (ret < 0)
                goto err;
-       fds[0] = ret;
+       fds[0] = alloc_slot ? ret : slot - 1;
        files[0] = NULL;
 
        /*
         * If a specific slot is given, next one will be used for
         * the write side.
         */
-       if (slot != IORING_FILE_INDEX_ALLOC)
+       if (!alloc_slot)
                slot++;
 
        ret = __io_fixed_fd_install(ctx, files[1], slot);
        if (ret < 0)
                goto err;
-       fds[1] = ret;
+       fds[1] = alloc_slot ? ret : slot - 1;
        files[1] = NULL;
 
        io_ring_submit_unlock(ctx, issue_flags);