Skip to content

Commit 722869f

Browse files
vasilisalmpanisgregkh
authored andcommitted
io_uring/nop: fix file reference leak with IOSQE_FIXED_FILE
commit 2564ca2 upstream. NOP file-acquisition support choses between a fixed (registered) file and a normal fget()'d file based on its own IORING_NOP_FIXED_FILE flag in sqe->nop_flags. However, a request's REQ_F_FIXED_FILE is set independently from the generic IOSQE_FIXED_FILE sqe flag during request init, before the issue handler runs. If a NOP is submitted with IOSQE_FIXED_FILE set (so REQ_F_FIXED_FILE is set) but without IORING_NOP_FIXED_FILE, io_nop() takes the normal path and grabs a real reference via io_file_get_normal(). On completion, io_put_file() only drops the reference when REQ_F_FIXED_FILE is clear, so the fget()'d file is never released and leaks: BUG: memory leak unreferenced object 0xffff88800f42c240 (size 176): kmem_cache_alloc_noprof+0x358/0x440 alloc_empty_file+0x57/0x180 path_openat+0x44/0x1e50 do_file_open+0x121/0x200 do_sys_openat2+0xa7/0x150 __x64_sys_openat+0x82/0xf0 Decide between fixed and normal file acquisition from REQ_F_FIXED_FILE, the same way io_assign_file() does for every other opcode, and fold IORING_NOP_FIXED_FILE into REQ_F_FIXED_FILE at prep time. Cc: stable@vger.kernel.org Fixes: a85f310 ("io_uring/nop: add support for testing registered files and buffers") Reported-by: syzbot+2cd473471e77bda12b0e@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?id=879092631b98f73a28ea405adacfa5bb34a14a25 Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com> Link: https://patch.msgid.link/20260615144619.482749-1-vasilisalmpanis@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4508366 commit 722869f

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

io_uring/nop.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ int io_nop_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
4141
nop->fd = READ_ONCE(sqe->fd);
4242
else
4343
nop->fd = -1;
44+
if (nop->flags & IORING_NOP_FIXED_FILE)
45+
req->flags |= REQ_F_FIXED_FILE;
4446
if (nop->flags & IORING_NOP_FIXED_BUFFER)
4547
req->buf_index = READ_ONCE(sqe->buf_index);
4648
if (nop->flags & IORING_NOP_CQE32) {
@@ -60,12 +62,10 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags)
6062
int ret = nop->result;
6163

6264
if (nop->flags & IORING_NOP_FILE) {
63-
if (nop->flags & IORING_NOP_FIXED_FILE) {
65+
if (req->flags & REQ_F_FIXED_FILE)
6466
req->file = io_file_get_fixed(req, nop->fd, issue_flags);
65-
req->flags |= REQ_F_FIXED_FILE;
66-
} else {
67+
else
6768
req->file = io_file_get_normal(req, nop->fd);
68-
}
6969
if (!req->file) {
7070
ret = -EBADF;
7171
goto done;

0 commit comments

Comments
 (0)