[Devel] [PATCH RHEL8 COMMIT] fuse: fix use after free

Konstantin Khorenko khorenko at virtuozzo.com
Wed Aug 18 21:05:59 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.vz8.7.7
------>
commit 208c07541079cc707568fe470c96e7595ee788bc
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date:   Wed Aug 18 04:52:55 2021 +0800

    fuse: fix use after free
    
    Port mistake. Field io->file has gone in mainstream, but
    use of io->iocb->ki_filp is invalid, io->iocb is already freed.
    Add io->file back, but use it only in this context.
    
    It is quite possible that this particular bug will not be fixed,
    the state observed in #VSTOR-45882 is too weird and have no explanation,
    even if reused io->iocb is referenced. But yet, it is also severe bug.
    
    Affects: #VSTOR-45882
    https://pmc.acronis.com/browse/VSTOR-45882
    
    Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
    Acked-by: Andrey Zaitsev <Andrey.Zaitsev at acronis.com>
---
 fs/fuse/file.c   | 3 ++-
 fs/fuse/fuse_i.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6b273984bbb8..cda5bb82dff3 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -817,7 +817,7 @@ static void fuse_fput_routine(struct work_struct *data)
 		struct fuse_io_priv *io = list_entry(fuse_fput_head.next,
 						     struct fuse_io_priv,
 						     list);
-		struct file *file = io->iocb->ki_filp;
+		struct file *file = io->file;
 
 		list_del(&io->list);
 		spin_unlock(&fuse_fput_lock);
@@ -895,6 +895,7 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
 		io->iocb->ki_complete(io->iocb, res, 0);
 
 		if (unlikely(atomic_long_dec_and_test(&file->f_count))) {
+			io->file = file;
 			spin_lock(&fuse_fput_lock);
 			list_add(&io->list, &fuse_fput_head);
 			spin_unlock(&fuse_fput_lock);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 014c44ec9e26..eb028d0d3951 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -357,6 +357,7 @@ struct fuse_io_priv {
 	struct completion *done;
 	bool blocking;
 	struct list_head list;
+	struct file * file;
 };
 
 #define FUSE_IO_PRIV_SYNC(i) \


More information about the Devel mailing list