[Devel] [PATCH RHEL9 COMMIT] fs/fuse/krpc: fix file leakage in krpc

Konstantin Khorenko khorenko at virtuozzo.com
Wed Nov 27 16:21:11 MSK 2024


The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.80.1
------>
commit a704b1b2aa611db43f74b691f5ccf4ecfc198dc9
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date:   Tue Nov 26 18:26:54 2024 +0800

    fs/fuse/krpc: fix file leakage in krpc
    
    Obvious leak, which cannot be detected unless you try to unload
    fuse module. Found accidentally searching for reasons why
    fuse_dev_find_request takes 7% of cpu in profiles.
    
    Also, make it in more optimal way, fget() is too expensive and
    well seen on profiles, there is lighter way relying on rcu protection.
    
    Signed-off-by: Alexey Kuznetsov <kuznet at virtuozzo.com>
    Acked-by: Liu Kui <kui.liu at virtuozzo.com>
    
    Feature: fuse: kRPC - single RPC for kernel and userspace
---
 fs/fuse/dev.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index f5594e49bc2f..62ecda25909e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -19,6 +19,7 @@
 #include <linux/slab.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/swap.h>
+#include <linux/fdtable.h>
 #include <linux/splice.h>
 #include <linux/sched.h>
 
@@ -2678,16 +2679,29 @@ EXPORT_SYMBOL_GPL(fuse_dev_release);
 
 struct fuse_req *fuse_dev_find_request(int fd, u64 unique)
 {
-	struct file *f = fget(fd);
-	struct fuse_dev *fud = fuse_get_dev(f);
-	struct fuse_pqueue *fpq = &fud->pq;
+	struct file *file;
+	struct fuse_dev *fud;
+	struct fuse_pqueue *fpq;
 	struct fuse_req *req = NULL;
 
+	rcu_read_lock();
+	file = files_lookup_fd_rcu(current->files, fd);
+	if (!file)
+		goto out;
+
+	if (file->f_op != &fuse_dev_operations)
+		goto out;
+
+	fud = fuse_get_dev(file);
+	fpq = &fud->pq;
+
 	spin_lock(&fpq->lock);
 	if (fpq->connected)
 		req = request_find(&fud->pq, unique);
 	spin_unlock(&fpq->lock);
 
+out:
+	rcu_read_unlock();
 	return req;
 }
 EXPORT_SYMBOL_GPL(fuse_dev_find_request);


More information about the Devel mailing list