[Devel] [PATCH VZ9 2/2] fs/fuse: enhanced splice support, fixes

Alexey Kuznetsov kuznet at virtuozzo.com
Tue Jan 23 22:34:57 MSK 2024


Two bugs has 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

Signed-off-by: Alexey Kuznetsov <kuznet at acronis.com>
---
 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 ccc30d9..9462f8b 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -2011,11 +2011,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;
@@ -2032,7 +2033,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;
@@ -2103,6 +2105,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;
@@ -2126,6 +2129,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;
-- 
1.8.3.1



More information about the Devel mailing list