[Devel] [PATCH RHEL9 COMMIT] fs/fuse: enhanced splice support, fixes
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Jan 24 18:15:19 MSK 2024
The commit is pushed to "branch-rh9-5.14.0-362.8.1.vz9.35.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-362.8.1.vz9.35.8
------>
commit fbb88f3b03782706e3bc4d42425b1a795e221749
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date: Wed Jan 24 03:34:57 2024 +0800
fs/fuse: enhanced splice support, fixes
Two bugs have been noticed by Kui Liu <kui.liu at acronis.com>:
1. We used only 2 words of 8 in onstack copy of user array
2. fdput in error path was missing, we could leak open file
when daemon would supply non-pipe file descriptor
https://pmc.acronis.work/browse/VSTOR-79527
Fixes: 72dcce0c8d21 ("fs/fuse: enhanced splice support")
Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
Feature: fuse: enhanced splice support
---
fs/fuse/dev.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 060c468e80c4..e00f5b180e95 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -2013,11 +2013,12 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
int doff = ap->descs[0].offset;
int dend = doff + ap->descs[0].length;
struct page *dpage = ap->pages[0];
+ struct fd f = { .file = NULL };
nsplices = nbytes - sizeof(struct fuse_out_header);
if (nsplices & 3)
return -EINVAL;
- if (nsplices > 8) {
+ if (nsplices > sizeof(fdarr_inline)) {
fdarr = kmalloc(nsplices, GFP_KERNEL);
if (!fdarr)
return -ENOMEM;
@@ -2034,7 +2035,8 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
for (i = 0; i < nsplices; i++) {
void *src, *dst;
- struct fd f = fdget(fdarr[i]);
+
+ f = fdget(fdarr[i]);
if (f.file) {
unsigned int head, tail, mask;
@@ -2105,6 +2107,7 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
}
pipe_unlock(pipe);
fdput(f);
+ f.file = NULL;
} else {
err = -EBADF;
goto out;
@@ -2128,6 +2131,8 @@ static int copy_out_splices(struct fuse_copy_state *cs, struct fuse_args *args,
err = 0;
out:
+ if (f.file)
+ fdput(f);
if (fdarr != fdarr_inline)
kfree(fdarr);
return err;
More information about the Devel
mailing list