fuse/bugfix-invalid-free-and-core.patch
2019-09-30 10:39:10 -04:00

132 lines
3.9 KiB
Diff

From fd0cfd7fa7d37a8401c8544dfaac0172d1d35056 Mon Sep 17 00:00:00 2001
From: <mashimiao@huawei.com>
Date: Fri, 23 Nov 2018 17:14:22 +0800
Subject: [PATCH] fuse: fix invalid free and core bug
Signed-off-by: <mashimiao@huawei.com>
---
libfuse-fuse-2.9.7/lib/fuse.c | 3 ++-
libfuse-fuse-2.9.7/lib/fuse_kern_chan.c | 3 ++-
libfuse-fuse-2.9.7/lib/fuse_lowlevel.c | 26 ++++++++++++++++----------
libfuse-fuse-2.9.7/util/fusermount.c | 1 +
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/libfuse-fuse-2.9.7/lib/fuse.c b/libfuse-fuse-2.9.7/lib/fuse.c
index e7cda46..c40961d 100644
--- a/libfuse-fuse-2.9.7/lib/fuse.c
+++ b/libfuse-fuse-2.9.7/lib/fuse.c
@@ -1752,7 +1752,8 @@ static void fuse_free_buf(struct fuse_bufvec *buf)
size_t i;
for (i = 0; i < buf->count; i++)
- free(buf->buf[i].mem);
+ if (!(buf->buf[0].flags & FUSE_BUF_IS_FD))
+ free(buf->buf[i].mem);
free(buf);
}
}
diff --git a/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c b/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
index b891568..70deb6f 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
@@ -64,6 +64,7 @@ static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
int err = errno;
if (res == -1) {
+ perror("fuse: write to chan error");
struct fuse_session *se = fuse_chan_session(ch);
assert(se != NULL);
@@ -83,6 +83,7 @@
close(fd);
}
+#define KERNEL_BUF_PAGES 128
#define MIN_BUFSIZE 0x21000
struct fuse_chan *fuse_kern_chan_new(int fd)
diff --git a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
index 4dda646..0d278cf 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
@@ -2343,9 +2343,10 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
tmpbuf.buf[0].mem = mbuf;
res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
- if (res < 0)
+ if (res < 0) {
fprintf(stderr, "fuse: failed to copy from pipe\n");
goto clear_pipe;
+ }
in = mbuf;
} else {
@@ -2403,13 +2404,13 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR &&
in->opcode != FUSE_NOTIFY_REPLY) {
- fprintf(stderr, "fuse: opcode is not allowed\n");
- goto reply_err;
+ fprintf(stderr, "fuse: opcode is not allowed\n");
+ goto reply_err;
}
err = ENOSYS;
if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func) {
- fprintf(stderr, "fuse: opcode is invalid\n");
+ fprintf(stderr, "fuse: opcode is invalid %d\n", in->opcode);
goto reply_err;
}
if (in->opcode != FUSE_INTERRUPT) {
@@ -2599,12 +2600,15 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
int err;
int res;
- if (f->conn.proto_minor < 14 || !(f->conn.want & FUSE_CAP_SPLICE_READ))
+ if (f->conn.proto_minor < 14 || !(f->conn.want & FUSE_CAP_SPLICE_READ)) {
goto fallback;
+ }
llp = fuse_ll_get_pipe(f);
- if (llp == NULL)
+ if (llp == NULL) {
+ perror("fuse: failed to get pipe");
goto fallback;
+ }
if (llp->size < bufsize) {
if (llp->can_grow) {
@@ -2668,11 +2672,13 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
fuse_ll_clear_pipe(f);
return -EIO;
}
- buf->size = tmpbuf.size;
- return buf->size;
+ assert(res == tmpbuf.size);
+ } else {
+ /* Don't overwrite buf->mem, as that would cause a leak */
+ buf->fd = tmpbuf.fd;
+ buf->flags = tmpbuf.flags;
}
-
- *buf = tmpbuf;
+ buf->size = tmpbuf.size;
return res;
diff --git a/libfuse-fuse-2.9.7/util/fusermount.c b/libfuse-fuse-2.9.7/util/fusermount.c
index 265f55a..832ba2a 100644
--- a/libfuse-fuse-2.9.7/util/fusermount.c
+++ b/libfuse-fuse-2.9.7/util/fusermount.c
@@ -446,6 +446,7 @@ static int unmount_fuse_locked(const char *mnt, int quiet, int lazy)
}
out:
+ free(copy);
if (res == -1)
return -1;
--
1.8.3.1