!7 update fuse2 and fuse3

Merge pull request !7 from hy/tmp
This commit is contained in:
openeuler-ci-bot 2020-01-12 16:25:38 +08:00 committed by Gitee
commit e1f3bf2e79
26 changed files with 111 additions and 1681 deletions

View File

@ -1,16 +0,0 @@
--- a/libfuse-fuse-2.9.7/lib/fuse.c 2019-04-18 22:50:35.628000000 +0800
+++ b/libfuse-fuse-2.9.7/lib/fuse_1.c 2019-04-18 22:52:07.772000000 +0800
@@ -4778,10 +4778,9 @@ out_free_name_table:
out_free_session:
fuse_session_destroy(f->se);
out_free_fs:
- /* Horrible compatibility hack to stop the destructor from being
- called on the filesystem without init being called first */
- fs->op.destroy = NULL;
- fuse_fs_destroy(f->fs);
+ if (f->fs->m)
+ fuse_put_module(f->fs->m);
+ free(f->fs);
free(f->conf.modules);
f->conf.modules = NULL;
out_free:

View File

@ -1,53 +0,0 @@
From a38722be2ba63466431616a0756981697d29fa23 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <mszeredi@suse.cz>
Date: Mon, 18 Feb 2013 16:24:11 +0100
Subject: [PATCH 032/617] fuse_opt_parse(): fix memory leak
when storing a newly allocated string for format "%s", free the previous value
stored at that location.
Reported by Marco Schuster
---
ChangeLog | 6 ++++++
include/fuse_opt.h | 5 +++--
lib/fuse_opt.c | 4 +++-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/libfuse-fuse-2.9.7/include/fuse_opt.h b/libfuse-fuse-2.9.7/include/fuse_opt.h
index add0a30..20653b1 100644
--- a/libfuse-fuse-2.9.7/include/fuse_opt.h
+++ b/libfuse-fuse-2.9.7/include/fuse_opt.h
@@ -70,8 +70,9 @@ extern "C" {
*
* 6) "-x %s", etc. Combination of 4) and 5)
*
- * If the format is "%s", memory is allocated for the string unlike
- * with scanf().
+ * If the format is "%s", memory is allocated for the string unlike with
+ * scanf(). The previous value (if non-NULL) stored at the this location is
+ * freed.
*/
struct fuse_opt {
/** Matching template and optional parameter formatting */
diff --git a/libfuse-fuse-2.9.7/lib/fuse_opt.c b/libfuse-fuse-2.9.7/lib/fuse_opt.c
index 93efd29..15f9e21 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_opt.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_opt.c
@@ -204,11 +204,13 @@ static int process_opt_param(void *var, const char *format, const char *param,
{
assert(format[0] == '%');
if (format[1] == 's') {
+ char **s = var;
char *copy = strdup(param);
if (!copy)
return alloc_failed();
- *(char **) var = copy;
+ free(*s);
+ *s = copy;
} else {
if (sscanf(param, format, var) != 1) {
fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
--
1.8.3.1

View File

@ -1,43 +0,0 @@
From 5018a0c016495155ee598b7e0167b43d5d902414 Mon Sep 17 00:00:00 2001
From: Jann Horn <jannh@google.com>
Date: Sat, 14 Jul 2018 03:47:50 -0700
Subject: [PATCH 530/617] fusermount: refuse unknown options
Blacklists are notoriously fragile; especially if the kernel wishes to add
some security-critical mount option at a later date, all existing systems
with older versions of fusermount installed will suddenly have a security
problem.
Additionally, if the kernel's option parsing became a tiny bit laxer, the
blacklist could probably be bypassed.
Whitelist known-harmless flags instead, even if it's slightly more
inconvenient.
---
util/fusermount.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/util/fusermount.c b/util/fusermount.c
index 4e0f51a..2792407 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -819,10 +819,16 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
flags |= flag;
else
flags &= ~flag;
- } else {
+ } else if (opt_eq(s, len, "default_permissions") ||
+ opt_eq(s, len, "allow_other") ||
+ begins_with(s, "max_read=") ||
+ begins_with(s, "blksize=")) {
memcpy(d, s, len);
d += len;
*d++ = ',';
+ } else {
+ fprintf(stderr, "%s: unknown option '%.*s'\n", progname, len, s);
+ exit(1);
}
}
}
--
1.8.3.1

View File

@ -1,121 +0,0 @@
From 795ad5d77434f3502e63a70c8a3fda94fa347e3d Mon Sep 17 00:00:00 2001
From: Jann Horn <jannh@google.com>
Date: Sat, 14 Jul 2018 13:37:41 +0200
Subject: [PATCH 531/617] fusermount: whitelist known-good filesystems for
mountpoints
Before:
$ _FUSE_COMMFD=1 priv_strace -s8000 -e trace=mount util/fusermount3 /proc/self/fd
mount("/dev/fuse", ".", "fuse", MS_NOSUID|MS_NODEV, "fd=3,rootmode=40000,user_id=379777,group_id=5001") = 0
sending file descriptor: Socket operation on non-socket
+++ exited with 1 +++
After:
$ _FUSE_COMMFD=1 priv_strace -s8000 -e trace=mount util/fusermount3 /proc/self/fd
util/fusermount3: mounting over filesystem type 0x009fa0 is forbidden
+++ exited with 1 +++
This patch could potentially have security
impact on some systems that are configured with allow_other;
see https://launchpad.net/bugs/1530566 for an example of how a similar
issue in the ecryptfs mount helper was exploitable. However, the FUSE
mount helper performs slightly different security checks, so that exact
attack doesn't work with fusermount; I don't know of any specific attack
you could perform using this, apart from faking the SELinux context of your
process when someone's looking at a process listing. Potential targets for
overwrite are (looking on a system with a 4.9 kernel):
writable only for the current process:
/proc/self/{fd,map_files}
(Yes, "ls -l" claims that you don't have write access, but that's not true;
"find -writable" will show you what access you really have.)
writable also for other owned processes:
/proc/$pid/{sched,autogroup,comm,mem,clear_refs,attr/*,oom_adj,
oom_score_adj,loginuid,coredump_filter,uid_map,gid_map,projid_map,
setgroups,timerslack_ns}
---
util/fusermount.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/libfuse-fuse-2.9.7/util/fusermount.c b/libfuse-fuse-2.9.7/util/fusermount.c
index 2792407..c63c50e 100644
--- a/libfuse-fuse-2.9.7/util/fusermount.c
+++ b/libfuse-fuse-2.9.7/util/fusermount.c
@@ -30,6 +30,7 @@
#include <sys/utsname.h>
#include <sched.h>
#include <stdbool.h>
+#include <sys/vfs.h>
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
@@ -915,6 +916,8 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
int res;
const char *mnt = *mntp;
const char *origmnt = mnt;
+ struct statfs fs_buf;
+ size_t i;
res = lstat(mnt, stbuf);
if (res == -1) {
@@ -987,8 +990,53 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *mountpoint_fd)
return -1;
}
+ /* Do not permit mounting over anything in procfs - it has a couple
+ * places to which we have "write access" without being supposed to be
+ * able to just put anything we want there.
+ * Luckily, without allow_other, we can't get other users to actually
+ * use any fake information we try to put there anyway.
+ * Use a whitelist to be safe. */
+ if (statfs(*mntp, &fs_buf)) {
+ fprintf(stderr, "%s: failed to access mountpoint %s: %s\n",
+ progname, mnt, strerror(errno));
+ return -1;
+ }
- return 0;
+ /* Use the same list of permitted filesystems for the mount target as
+ * the ecryptfs mount helper
+ * (https://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/view/head:/src/utils/mount.ecryptfs_private.c#L225). */
+ typeof(fs_buf.f_type) f_type_whitelist[] = {
+ 0x61756673 /* AUFS_SUPER_MAGIC */,
+ 0x9123683E /* BTRFS_SUPER_MAGIC */,
+ 0x00C36400 /* CEPH_SUPER_MAGIC */,
+ 0xFF534D42 /* CIFS_MAGIC_NUMBER */,
+ 0x0000F15F /* ECRYPTFS_SUPER_MAGIC */,
+ 0x0000EF53 /* EXT[234]_SUPER_MAGIC */,
+ 0xF2F52010 /* F2FS_SUPER_MAGIC */,
+ 0x65735546 /* FUSE_SUPER_MAGIC */,
+ 0x01161970 /* GFS2_MAGIC */,
+ 0x3153464A /* JFS_SUPER_MAGIC */,
+ 0x000072B6 /* JFFS2_SUPER_MAGIC */,
+ 0x0000564C /* NCP_SUPER_MAGIC */,
+ 0x00006969 /* NFS_SUPER_MAGIC */,
+ 0x00003434 /* NILFS_SUPER_MAGIC */,
+ 0x5346544E /* NTFS_SB_MAGIC */,
+ 0x794C7630 /* OVERLAYFS_SUPER_MAGIC */,
+ 0x52654973 /* REISERFS_SUPER_MAGIC */,
+ 0x73717368 /* SQUASHFS_MAGIC */,
+ 0x01021994 /* TMPFS_MAGIC */,
+ 0x24051905 /* UBIFS_SUPER_MAGIC */,
+ 0x58465342 /* XFS_SB_MAGIC */,
+ 0x2FC12FC1 /* ZFS_SUPER_MAGIC */,
+ };
+ for (i = 0; i < sizeof(f_type_whitelist)/sizeof(f_type_whitelist[0]); i++) {
+ if (f_type_whitelist[i] == fs_buf.f_type)
+ return 0;
+ }
+
+ fprintf(stderr, "%s: mounting over filesystem type %#010lx is forbidden\n",
+ progname, (unsigned long)fs_buf.f_type);
+ return -1;
}
static int try_open(const char *dev, char **devp, int silent)
--
1.8.3.1

View File

@ -1,32 +0,0 @@
From efa3032bc9a6d9028084a8c33c9b31946b16aea1 Mon Sep 17 00:00:00 2001
From: Rostislav Skudnov <rostislav@tuxera.com>
Date: Sat, 21 Jul 2018 21:14:06 +0000
Subject: [PATCH 533/617] fusermount: Fix memory leaks
---
util/fusermount.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/util/fusermount.c b/util/fusermount.c
index c63c50e..b8c164d 100644
--- a/util/fusermount.c
+++ b/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;
@@ -1365,6 +1366,7 @@ do_unmount:
}
if (res == -1)
goto err_out;
+ free(mnt);
return 0;
err_out:
--
1.8.3.1

View File

@ -1,27 +0,0 @@
From f814b4fa0b1a3b0d377effafe6c473745baea04b Mon Sep 17 00:00:00 2001
From: Rostislav <rostislav@users.noreply.github.com>
Date: Sat, 25 Aug 2018 18:52:53 +0000
Subject: [PATCH 545/617] Fix invalid free of memory pointer in 'struct
fuse_buf'
---
lib/fuse.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/fuse.c b/lib/fuse.c
index 2e4505b..11ffc05 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1760,7 +1760,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);
}
}
--
1.8.3.1

View File

@ -1,76 +0,0 @@
From 82ee6d6f77a2e386e42714d6ab56b39fcb00488e Mon Sep 17 00:00:00 2001
From: Rostislav <rostislav@users.noreply.github.com>
Date: Sat, 25 Aug 2018 20:50:40 +0000
Subject: [PATCH 546/617] Fix memory leak of FUSE modules
---
lib/fuse.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/lib/fuse.c b/lib/fuse.c
index 11ffc05..b88ef1a 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -234,6 +234,18 @@ static int fuse_register_module(const char *name,
return 0;
}
+static void fuse_unregister_module(struct fuse_module *m)
+{
+ struct fuse_module **mp;
+ for (mp = &fuse_modules; *mp; mp = &(*mp)->next) {
+ if (*mp == m) {
+ *mp = (*mp)->next;
+ break;
+ }
+ }
+ free(m->name);
+ free(m);
+}
static int fuse_load_so_module(const char *module)
{
@@ -313,8 +325,11 @@ static struct fuse_module *fuse_get_module(const char *module)
static void fuse_put_module(struct fuse_module *m)
{
pthread_mutex_lock(&fuse_context_lock);
- assert(m->ctr > 0);
- m->ctr--;
+ if (m->so)
+ assert(m->ctr > 0);
+ /* Builtin modules may already have m->ctr == 0 */
+ if (m->ctr > 0)
+ m->ctr--;
if (!m->ctr && m->so) {
struct fusemod_so *so = m->so;
assert(so->ctr > 0);
@@ -323,13 +338,15 @@ static void fuse_put_module(struct fuse_module *m)
struct fuse_module **mp;
for (mp = &fuse_modules; *mp;) {
if ((*mp)->so == so)
- *mp = (*mp)->next;
+ fuse_unregister_module(*mp);
else
mp = &(*mp)->next;
}
dlclose(so->handle);
free(so);
}
+ } else if (!m->ctr) {
+ fuse_unregister_module(m);
}
pthread_mutex_unlock(&fuse_context_lock);
}
@@ -4962,6 +4979,9 @@ void fuse_destroy(struct fuse *f)
assert(list_empty(&f->partial_slabs));
assert(list_empty(&f->full_slabs));
+ while (fuse_modules) {
+ fuse_put_module(fuse_modules);
+ }
free(f->id_table.array);
free(f->name_table.array);
pthread_mutex_destroy(&f->lock);
--
1.8.3.1

View File

@ -1,55 +0,0 @@
From 453a5451f20f22cb466b5be58f7d771ca5fa6d25 Mon Sep 17 00:00:00 2001
From: gulining <gulining1@huawei.com>
Date: Fri, 22 Mar 2019 02:23:47 -0400
Subject: [PATCH] backport-CVE-2018-10906.patch
Signed-off-by: gulining <gulining1@huawei.com>
---
libfuse-fuse-2.9.7/util/fusermount.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/libfuse-fuse-2.9.7/util/fusermount.c b/libfuse-fuse-2.9.7/util/fusermount.c
index d950c5c..e14e7dd 100644
--- a/libfuse-fuse-2.9.7/util/fusermount.c
+++ b/libfuse-fuse-2.9.7/util/fusermount.c
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <sys/utsname.h>
#include <sched.h>
+#include <stdbool.h>
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
@@ -740,8 +741,10 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
unsigned len;
const char *fsname_str = "fsname=";
const char *subtype_str = "subtype=";
+ bool escape_ok = begins_with(s, fsname_str) ||
+ begins_with(s, subtype_str);
for (len = 0; s[len]; len++) {
- if (s[len] == '\\' && s[len + 1])
+ if (escape_ok && s[len] == '\\' && s[len + 1])
len++;
else if (s[len] == ',')
break;
@@ -795,10 +798,16 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode,
flags |= flag;
else
flags &= ~flag;
- } else {
+ } else if (opt_eq(s, len, "default_permissions") ||
+ opt_eq(s, len, "allow_other") ||
+ begins_with(s, "max_read=") ||
+ begins_with(s, "blksize=")) {
memcpy(d, s, len);
d += len;
*d++ = ',';
+ } else {
+ fprintf(stderr, "%s: unknown option '%.*s'\n", progname, len, s);
+ exit(1);
}
}
}
--
1.8.3.1

View File

@ -1,173 +0,0 @@
From 06fc40705f23cb7e9af4df2febae8e6889b1a95d Mon Sep 17 00:00:00 2001
From: Rostislav Skudnov <rostislav@tuxera.com>
Date: Wed, 25 Jul 2018 10:36:38 +0000
Subject: [PATCH 4/7] Fix readdir() bug when a non-zero offset is specified in
filler
The bug occurs when a filesystem client reads a directory until the end,
seeks using seekdir() to some valid non-zero position and calls
readdir(). A valid 'struct dirent *' is expected, but NULL is returned
instead. Pseudocode demonstrating the bug:
DIR *dp = opendir("some_dir");
struct dirent *de = readdir(dp);
/* Get offset of the second entry */
long offset = telldir(dp);
/* Read directory until the end */
while (de)
de = readdir(de);
seekdir(dp, offset);
de = readdir(dp);
/* de must contain the second entry, but NULL is returned instead */
The reason of the bug is that when the end of directory is reached, the
kernel calls FUSE_READDIR op with an offset at the end of directory, so
the filesystem's .readdir callback never calls the filler function, and
we end up with dh->filled set to 1. After seekdir(), FUSE_READDIR is
called again with a new offset, but this time the filesystem's .readdir
callback is never called, and an empty reply is returned.
Fix by setting dh->filled to 1 only when zero offsets are given to
filler function.
This commit is backported from the following commit in 'master' branch:
commit 5f125c5e6be24c8d216a4d3c623dc73d742c8c86
Author: Rostislav <rostislav@users.noreply.github.com>
Date: Sat Jul 21 12:57:09 2018 +0300
Fix readdir() bug when a non-zero offset is specified in filler (#269)
diff -urNp a/lib/fuse.c b/lib/fuse.c
--- a/lib/fuse.c 2019-07-22 00:00:00.000000000 +0000
+++ b/lib/fuse.c 2019-07-22 00:00:00.000000000 +0000
@@ -3444,10 +3444,14 @@ static int fill_dir(void *dh_, const cha
}
if (off) {
+ if (dh->filled) {
+ dh->error = -EIO;
+ return 1;
+ }
+
if (extend_contents(dh, dh->needlen) == -1)
return 1;
- dh->filled = 0;
newlen = dh->len +
fuse_add_direntry(dh->req, dh->contents + dh->len,
dh->needlen - dh->len, name,
@@ -3455,6 +3459,8 @@ static int fill_dir(void *dh_, const cha
if (newlen > dh->needlen)
return 1;
} else {
+ dh->filled = 1;
+
newlen = dh->len +
fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
if (extend_contents(dh, newlen) == -1)
@@ -3484,7 +3490,7 @@ static int readdir_fill(struct fuse *f,
dh->len = 0;
dh->error = 0;
dh->needlen = size;
- dh->filled = 1;
+ dh->filled = 0;
dh->req = req;
fuse_prepare_interrupt(f, req, &d);
err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
diff -urNp a/test/test.c b/test/test.c
--- a/test/test.c 2019-07-22 00:00:00.000000000 +0000
+++ b/test/test.c 2019-07-22 00:00:00.000000000 +0000
@@ -21,6 +21,7 @@ static char testname[256];
static char testdata[] = "abcdefghijklmnopqrstuvwxyz";
static char testdata2[] = "1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./";
static const char *testdir_files[] = { "f1", "f2", NULL};
+static long seekdir_offsets[4];
static char zerodata[4096];
static int testdatalen = sizeof(testdata) - 1;
static int testdata2len = sizeof(testdata2) - 1;
@@ -79,6 +80,8 @@ static void __start_test(const char *fmt
#define PERROR(msg) test_perror(__FUNCTION__, msg)
#define ERROR(msg, args...) test_error(__FUNCTION__, msg, ##args)
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
static int check_size(const char *path, int len)
{
@@ -644,6 +647,63 @@ static int test_ftruncate(int len, int m
return 0;
}
+static int test_seekdir(void)
+{
+ int i;
+ int res;
+ DIR *dp;
+ struct dirent *de;
+
+ start_test("seekdir");
+ res = create_dir(testdir, testdir_files);
+ if (res == -1)
+ return res;
+
+ dp = opendir(testdir);
+ if (dp == NULL) {
+ PERROR("opendir");
+ return -1;
+ }
+
+ /* Remember dir offsets */
+ for (i = 0; i < ARRAY_SIZE(seekdir_offsets); i++) {
+ seekdir_offsets[i] = telldir(dp);
+ errno = 0;
+ de = readdir(dp);
+ if (de == NULL) {
+ if (errno) {
+ PERROR("readdir");
+ goto fail;
+ }
+ break;
+ }
+ }
+
+ /* Walk until the end of directory */
+ while (de)
+ de = readdir(dp);
+
+ /* Start from the last valid dir offset and seek backwards */
+ for (i--; i >= 0; i--) {
+ seekdir(dp, seekdir_offsets[i]);
+ de = readdir(dp);
+ if (de == NULL) {
+ ERROR("Unexpected end of directory after seekdir()");
+ goto fail;
+ }
+ }
+
+ closedir(dp);
+ res = cleanup_dir(testdir, testdir_files, 0);
+ if (!res)
+ success();
+ return res;
+fail:
+ closedir(dp);
+ cleanup_dir(testdir, testdir_files, 1);
+ return -1;
+}
+
static int test_utime(void)
{
struct utimbuf utm;
@@ -1425,6 +1485,7 @@ int main(int argc, char *argv[])
err += test_mkdir();
err += test_rename_file();
err += test_rename_dir();
+ err += test_seekdir();
err += test_utime();
err += test_truncate(0);
err += test_truncate(testdatalen / 2);

View File

@ -1,200 +0,0 @@
From 4028ca2038bab675b8464b71e038c28adfdb739f Mon Sep 17 00:00:00 2001
From: <mashimiao@huawei.com>
Date: Wed, 5 Sep 2018 21:27:38 +0800
Subject: [PATCH] increase idle thread
Signed-off-by: <mashimiao@huawei.com>
---
libfuse-fuse-2.9.7/lib/fuse.c | 8 ++++++--
libfuse-fuse-2.9.7/lib/fuse_kern_chan.c | 6 +++++-
libfuse-fuse-2.9.7/lib/fuse_loop_mt.c | 9 ++++++++-
libfuse-fuse-2.9.7/lib/fuse_lowlevel.c | 26 +++++++++++++++++++-------
4 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/libfuse-fuse-2.9.7/lib/fuse.c b/libfuse-fuse-2.9.7/lib/fuse.c
index 6a7c307..9f8c8a2 100644
--- a/libfuse-fuse-2.9.7/lib/fuse.c
+++ b/libfuse-fuse-2.9.7/lib/fuse.c
@@ -1261,6 +1261,7 @@ static void free_path_wrlock(struct fuse *f, fuse_ino_t nodeid,
wake_up_queued(f);
pthread_mutex_unlock(&f->lock);
free(path);
+ path = NULL;
}
static void free_path(struct fuse *f, fuse_ino_t nodeid, char *path)
@@ -3085,8 +3086,11 @@ static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
pthread_mutex_lock(&f->lock);
node = get_node(f, ino);
- assert(node->open_count > 0);
- --node->open_count;
+ if (node->open_count > 0) {
+ --node->open_count;
+ } else {
+ fprintf(stderr, "fuse: open_count is invalid: %d\n", node->open_count);
+ }
if (node->is_hidden && !node->open_count) {
unlink_hidden = 1;
node->is_hidden = 0;
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 4cc9b73..b891568 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
@@ -30,7 +30,9 @@ restart:
if (fuse_session_exited(se))
return 0;
+
if (res == -1) {
+ perror("fuse: read from chan error");
/* ENOENT means the operation was interrupted, it's safe
to restart */
if (err == ENOENT)
diff --git a/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c b/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
index 2f2521f..f88f339 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
@@ -121,7 +121,7 @@ static void *fuse_do_work(void *data)
pthread_mutex_lock(&mt->lock);
if (!isforget)
mt->numavail++;
- if (mt->numavail > 10) {
+ if (mt->numavail > 20) {
if (mt->exit) {
pthread_mutex_unlock(&mt->lock);
return NULL;
@@ -133,7 +133,9 @@ static void *fuse_do_work(void *data)
pthread_detach(w->thread_id);
free(w->buf);
+ w->buf = NULL;
free(w);
+ w = NULL;
return NULL;
}
pthread_mutex_unlock(&mt->lock);
@@ -229,13 +231,16 @@ static int fuse_loop_start_thread(struct fuse_mt *mt)
if (!w->buf) {
fprintf(stderr, "fuse: failed to allocate read buffer\n");
free(w);
+ w = NULL;
return -1;
}
res = fuse_start_thread(&w->thread_id, fuse_do_work, w);
if (res == -1) {
free(w->buf);
+ w->buf = NULL;
free(w);
+ w = NULL;
return -1;
}
list_add_worker(w, &mt->main);
@@ -252,7 +257,9 @@ static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w)
list_del_worker(w);
pthread_mutex_unlock(&mt->lock);
free(w->buf);
+ w->buf = NULL;
free(w);
+ w = NULL;
}
int fuse_session_loop_mt(struct fuse_session *se)
diff --git a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
index 35d0204..4dda646 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
@@ -42,8 +42,8 @@
struct fuse_pollhandle {
uint64_t kh;
- struct fuse_chan *ch;
struct fuse_ll *f;
+ struct fuse_session *se;
};
static size_t pagesize;
@@ -738,6 +738,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
return 0;
clear_pipe:
+ perror("fuse: reach clear_pipe");
fuse_ll_clear_pipe(f);
return res;
@@ -1708,8 +1709,8 @@ static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
return;
}
ph->kh = arg->kh;
- ph->ch = req->ch;
ph->f = req->f;
+ ph->se = fuse_chan_session(req->ch);
}
req->f->op.poll(req, nodeid, &fi, ph);
@@ -1972,7 +1973,8 @@ int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
iov[1].iov_base = &outarg;
iov[1].iov_len = sizeof(outarg);
- return send_notify_iov(ph->f, ph->ch, FUSE_NOTIFY_POLL, iov, 2);
+ return send_notify_iov(ph->f, ph->se->ch,
+ FUSE_NOTIFY_POLL, iov, 2);
} else {
return 0;
}
@@ -2342,6 +2344,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
res = fuse_ll_copy_from_pipe(&tmpbuf, &bufv);
if (res < 0)
+ fprintf(stderr, "fuse: failed to copy from pipe\n");
goto clear_pipe;
in = mbuf;
@@ -2359,6 +2362,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
req = fuse_ll_alloc_req(f);
if (req == NULL) {
+ fprintf(stderr, "fuse: req is NULL\n");
struct fuse_out_header out = {
.unique = in->unique,
.error = -ENOMEM,
@@ -2383,10 +2387,14 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
enum fuse_opcode expected;
expected = f->cuse_data ? CUSE_INIT : FUSE_INIT;
- if (in->opcode != expected)
+ if (in->opcode != expected) {
+ fprintf(stderr, "fuse: opcode is not as expected\n");
goto reply_err;
- } else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT)
+ }
+ } else if (in->opcode == FUSE_INIT || in->opcode == CUSE_INIT) {
+ fprintf(stderr, "fuse: opcode is *_INIT\n");
goto reply_err;
+ }
err = EACCES;
if (f->allow_root && in->uid != f->owner && in->uid != 0 &&
@@ -2394,12 +2402,16 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR &&
- in->opcode != FUSE_NOTIFY_REPLY)
+ in->opcode != FUSE_NOTIFY_REPLY) {
+ fprintf(stderr, "fuse: opcode is not allowed\n");
goto reply_err;
+ }
err = ENOSYS;
- if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
+ if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func) {
+ fprintf(stderr, "fuse: opcode is invalid\n");
goto reply_err;
+ }
if (in->opcode != FUSE_INTERRUPT) {
struct fuse_req *intr;
pthread_mutex_lock(&f->lock);
--
1.8.3.1

View File

@ -1,131 +0,0 @@
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

View File

@ -1,530 +0,0 @@
From 276380d842ea9f57f181fc8f37d268d619a753eb Mon Sep 17 00:00:00 2001
From: <mashimiao@huawei.com>
Date: Sat, 1 Dec 2018 11:35:08 +0800
Subject: [PATCH] fix memory leak and wild ptr
Signed-off-by: <mashimiao@huawei.com>
---
libfuse-fuse-2.9.7/lib/fuse.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----
libfuse-fuse-2.9.7/lib/fuse_kern_chan.c | 5 ++++-
libfuse-fuse-2.9.7/lib/fuse_loop_mt.c | 1 +
libfuse-fuse-2.9.7/lib/fuse_lowlevel.c | 28 ++++++++++++++++++++++++++-
4 files changed, 81 insertions(+), 6 deletions(-)
diff --git a/libfuse-fuse-2.9.7/lib/fuse.c b/libfuse-fuse-2.9.7/lib/fuse.c
index c40961d..05ee145 100644
--- a/libfuse-fuse-2.9.7/lib/fuse.c
+++ b/libfuse-fuse-2.9.7/lib/fuse.c
@@ -252,6 +252,7 @@ err:
if (so->handle)
dlclose(so->handle);
free(so);
+ so = NULL;
return -1;
}
@@ -266,6 +267,7 @@ static int fuse_load_so_module(const char *module)
sprintf(soname, "libfusemod_%s.so", module);
res = fuse_load_so_name(soname);
free(soname);
+ soname = NULL;
return res;
}
@@ -315,6 +317,7 @@ static void fuse_put_module(struct fuse_module *m)
}
dlclose(so->handle);
free(so);
+ so = NULL;
}
}
pthread_mutex_unlock(&fuse_context_lock);
@@ -479,6 +482,7 @@ static void free_node_mem(struct fuse *f, struct node *node)
{
(void) f;
free(node);
+ node = NULL;
}
#endif
@@ -538,8 +542,10 @@ static void set_forget_time(struct fuse *f, struct node *node)
static void free_node(struct fuse *f, struct node *node)
{
- if (node->name != node->inline_name)
+ if (node->name != node->inline_name) {
free(node->name);
+ node->name = NULL;
+ }
free_node_mem(f, node);
}
@@ -713,9 +719,10 @@ static void unhash_name(struct fuse *f, struct node *node)
*nodep = node->name_next;
node->name_next = NULL;
unref_node(f, node->parent);
- if (node->name != node->inline_name)
+ if (node->name != node->inline_name) {
free(node->name);
- node->name = NULL;
+ node->name = NULL;
+ }
node->parent = NULL;
f->name_table.use--;
@@ -1009,6 +1016,7 @@ static int try_get_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
unlock_path(f, nodeid, wnode, node);
out_free:
free(buf);
+ buf = NULL;
out_err:
return err;
@@ -1216,6 +1224,7 @@ static int try_get_path2(struct fuse *f, fuse_ino_t nodeid1, const char *name1,
unlock_path(f, nodeid1, wn1, NULL);
free(*path1);
+ *path1 = NULL;
}
}
return err;
@@ -1282,7 +1291,9 @@ static void free_path2(struct fuse *f, fuse_ino_t nodeid1, fuse_ino_t nodeid2,
wake_up_queued(f);
pthread_mutex_unlock(&f->lock);
free(path1);
+ path1 = NULL;
free(path2);
+ path2 = NULL;
}
static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
@@ -1752,9 +1763,12 @@ static void fuse_free_buf(struct fuse_bufvec *buf)
size_t i;
for (i = 0; i < buf->count; i++)
- if (!(buf->buf[0].flags & FUSE_BUF_IS_FD))
+ if (!(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
free(buf->buf[i].mem);
+ buf->buf[i].mem = NULL;
+ }
free(buf);
+ buf = NULL;
}
}
@@ -1785,6 +1799,7 @@ int fuse_fs_read_buf(struct fuse_fs *fs, const char *path,
mem = malloc(size);
if (mem == NULL) {
free(buf);
+ buf = NULL;
return -ENOMEM;
}
*buf = FUSE_BUFVEC_INIT(size);
@@ -1879,6 +1894,7 @@ int fuse_fs_write_buf(struct fuse_fs *fs, const char *path,
off, fi);
out_free:
free(mem);
+ mem = NULL;
}
out:
if (fs->debug && res >= 0)
@@ -2418,6 +2434,7 @@ static int hide_node(struct fuse *f, const char *oldpath,
if (!err)
err = rename_node(f, dir, oldname, dir, newname, 1);
free(newpath);
+ newpath = NULL;
}
return err;
}
@@ -2517,6 +2534,7 @@ static struct fuse_context_i *fuse_get_context_internal(void)
static void fuse_freecontext(void *data)
{
free(data);
+ data = NULL;
}
static int fuse_create_context_key(void)
@@ -2613,6 +2631,7 @@ void fuse_fs_destroy(struct fuse_fs *fs)
if (fs->m)
fuse_put_module(fs->m);
free(fs);
+ fs = NULL;
}
static void fuse_lib_destroy(void *data)
@@ -3360,11 +3379,13 @@ static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
fuse_fs_releasedir(f->fs, path, &fi);
pthread_mutex_destroy(&dh->lock);
free(dh);
+ dh = NULL;
}
} else {
reply_err(req, err);
pthread_mutex_destroy(&dh->lock);
free(dh);
+ dh = NULL;
}
free_path(f, ino, path);
}
@@ -3536,7 +3557,9 @@ static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
pthread_mutex_unlock(&dh->lock);
pthread_mutex_destroy(&dh->lock);
free(dh->contents);
+ dh->contents = NULL;
free(dh);
+ dh = NULL;
reply_err(req, 0);
}
@@ -3639,6 +3662,7 @@ static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
else
reply_err(req, res);
free(value);
+ value = NULL;
} else {
res = common_getxattr(f, req, ino, name, NULL, 0);
if (res >= 0)
@@ -3682,6 +3706,7 @@ static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
else
reply_err(req, res);
free(list);
+ list = NULL;
} else {
res = common_listxattr(f, req, ino, NULL, 0);
if (res >= 0)
@@ -3727,6 +3752,7 @@ static void delete_lock(struct lock **lockp)
struct lock *l = *lockp;
*lockp = l->next;
free(l);
+ l = NULL;
}
static void insert_lock(struct lock **pos, struct lock *lock)
@@ -3748,7 +3774,9 @@ static int locks_insert(struct node *node, struct lock *lock)
if (!newl1 || !newl2) {
free(newl1);
+ newl1 = NULL;
free(newl2);
+ newl2 = NULL;
return -ENOLCK;
}
}
@@ -3805,7 +3833,9 @@ static int locks_insert(struct node *node, struct lock *lock)
}
out:
free(newl1);
+ newl1 = NULL;
free(newl2);
+ newl2 = NULL;
return 0;
}
@@ -4042,6 +4072,7 @@ err:
reply_err(req, err);
out:
free(out_buf);
+ out_buf = NULL;
}
static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
@@ -4189,7 +4220,9 @@ int fuse_notify_poll(struct fuse_pollhandle *ph)
static void free_cmd(struct fuse_cmd *cmd)
{
free(cmd->buf);
+ cmd->buf = NULL;
free(cmd);
+ cmd = NULL;
}
void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
@@ -4219,6 +4252,7 @@ static struct fuse_cmd *fuse_alloc_cmd(size_t bufsize)
if (cmd->buf == NULL) {
fprintf(stderr, "fuse: failed to allocate read buffer\n");
free(cmd);
+ cmd = NULL;
return NULL;
}
return cmd;
@@ -4301,6 +4335,7 @@ static int fuse_session_loop_remember(struct fuse *f)
}
free(buf);
+ buf = NULL;
fuse_session_reset(se);
return res < 0 ? -1 : 0;
}
@@ -4719,10 +4754,13 @@ struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
out_free_root:
free(root);
+ root = NULL;
out_free_id_table:
free(f->id_table.array);
+ f->id_table.array = NULL;
out_free_name_table:
free(f->name_table.array);
+ f->name_table.array = NULL;
out_free_session:
fuse_session_destroy(f->se);
out_free_fs:
@@ -4731,8 +4769,10 @@ out_free_fs:
fs->op.destroy = NULL;
fuse_fs_destroy(f->fs);
free(f->conf.modules);
+ f->conf.modules = NULL;
out_free:
free(f);
+ f = NULL;
out_delete_context_key:
fuse_delete_context_key();
out:
@@ -4769,6 +4809,7 @@ void fuse_destroy(struct fuse *f)
if (try_get_path(f, node->nodeid, NULL, &path, NULL, false) == 0) {
fuse_fs_unlink(f->fs, path);
free(path);
+ path = NULL;
}
}
}
@@ -4788,11 +4829,15 @@ void fuse_destroy(struct fuse *f)
assert(list_empty(&f->full_slabs));
free(f->id_table.array);
+ f->id_table.array = NULL;
free(f->name_table.array);
+ f->name_table.array = NULL;
pthread_mutex_destroy(&f->lock);
fuse_session_destroy(f->se);
free(f->conf.modules);
+ f->conf.modules = NULL;
free(f);
+ f = NULL;
fuse_delete_context_key();
}
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 70deb6f..1096fa3 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
@@ -26,6 +26,9 @@ static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
restart:
res = read(fuse_chan_fd(ch), buf, size);
+ if (res >= size) {
+ fprintf(stderr, "fuse: read %d from chan, risk to leak memory\n", res);
+ }
err = errno;
if (fuse_session_exited(se))
@@ -85,7 +88,7 @@
close(fd);
}
-#define KERNEL_BUF_PAGES 128
+#define KERNEL_BUF_PAGES 32
#define MIN_BUFSIZE 0x21000
struct fuse_chan *fuse_kern_chan_new(int fd)
diff --git a/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c b/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
index ea92b62..eca39b1 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_loop_mt.c
@@ -71,6 +71,7 @@ static void *fuse_do_work(void *data)
while (!fuse_session_exited(mt->se)) {
int isforget = 0;
struct fuse_chan *ch = mt->prevch;
+ memset(w->buf, 0, w->bufsize);
struct fuse_buf fbuf = {
.mem = w->buf,
.size = w->bufsize,
diff --git a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
index 0d278cf..b4ed46d 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_lowlevel.c
@@ -121,6 +121,7 @@ static void destroy_req(fuse_req_t req)
{
pthread_mutex_destroy(&req->lock);
free(req);
+ req = NULL;
}
void fuse_free_req(fuse_req_t req)
@@ -237,6 +238,7 @@ int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
res = send_reply_iov(req, 0, padded_iov, count);
free(padded_iov);
+ padded_iov = NULL;
return res;
}
@@ -458,6 +460,7 @@ static int fuse_send_data_iov_fallback(struct fuse_ll *f, struct fuse_chan *ch,
res = fuse_buf_copy(&mem_buf, buf, 0);
if (res < 0) {
free(mbuf);
+ mbuf = NULL;
return -res;
}
len = res;
@@ -467,6 +470,7 @@ static int fuse_send_data_iov_fallback(struct fuse_ll *f, struct fuse_chan *ch,
iov_count++;
res = fuse_send_msg(f, ch, iov, iov_count);
free(mbuf);
+ mbuf = NULL;
return res;
}
@@ -482,6 +486,7 @@ static void fuse_ll_pipe_free(struct fuse_ll_pipe *llp)
close(llp->pipe[0]);
close(llp->pipe[1]);
free(llp);
+ llp = NULL;
}
#ifdef HAVE_SPLICE
@@ -498,6 +503,7 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
res = pipe(llp->pipe);
if (res == -1) {
free(llp);
+ llp = NULL;
return NULL;
}
@@ -506,6 +512,7 @@ static struct fuse_ll_pipe *fuse_ll_get_pipe(struct fuse_ll *f)
close(llp->pipe[0]);
close(llp->pipe[1]);
free(llp);
+ llp = NULL;
return NULL;
}
@@ -683,18 +690,22 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
tmpbuf = malloc(headerlen);
if (tmpbuf == NULL) {
free(mbuf);
+ mbuf = NULL;
res = ENOMEM;
goto clear_pipe;
}
res = read_back(llp->pipe[0], tmpbuf, headerlen);
free(tmpbuf);
+ tmpbuf = NULL;
if (res != 0) {
free(mbuf);
+ mbuf = NULL;
goto clear_pipe;
}
res = read_back(llp->pipe[0], mbuf, now_len);
if (res != 0) {
free(mbuf);
+ mbuf = NULL;
goto clear_pipe;
}
len = now_len + extra_len;
@@ -703,9 +714,11 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch,
iov_count++;
res = fuse_send_msg(f, ch, iov, iov_count);
free(mbuf);
+ mbuf = NULL;
return res;
}
free(mbuf);
+ mbuf = NULL;
res = now_len;
}
len = res;
@@ -907,7 +920,9 @@ int fuse_reply_ioctl_retry(fuse_req_t req,
res = send_reply_iov(req, 0, iov, count);
out:
free(in_fiov);
+ in_fiov = NULL;
free(out_fiov);
+ out_fiov = NULL;
return res;
@@ -957,6 +972,7 @@ int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
res = send_reply_iov(req, 0, padded_iov, count + 2);
free(padded_iov);
+ padded_iov = NULL;
return res;
}
@@ -1633,6 +1649,7 @@ static struct fuse_req *check_interrupt(struct fuse_ll *f, struct fuse_req *req)
req->interrupted = 1;
list_del_req(curr);
free(curr);
+ curr = NULL;
return NULL;
}
}
@@ -1688,6 +1705,7 @@ static void do_ioctl(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
{
free(ph);
+ ph = NULL;
}
static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
@@ -2141,6 +2159,7 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
}
out:
free(rreq);
+ rreq = NULL;
if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
fuse_ll_clear_pipe(f);
}
@@ -2189,6 +2208,7 @@ int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino,
list_del_nreq(&rreq->nreq);
pthread_mutex_unlock(&f->lock);
free(rreq);
+ rreq = NULL;
}
return err;
@@ -2455,6 +2475,7 @@ static void fuse_ll_process_buf(void *data, const struct fuse_buf *buf,
out_free:
free(mbuf);
+ mbuf = NULL;
return;
reply_err:
@@ -2579,7 +2600,9 @@ static void fuse_ll_destroy(void *data)
pthread_key_delete(f->pipe_key);
pthread_mutex_destroy(&f->lock);
free(f->cuse_data);
+ f->cuse_data = NULL;
free(f);
+ f = NULL;
}
static void fuse_ll_pipe_destructor(void *data)
@@ -2777,6 +2800,7 @@ out_key_destroy:
out_free:
pthread_mutex_destroy(&f->lock);
free(f);
+ f = NULL;
out:
return NULL;
}
@@ -2821,6 +2845,7 @@ retry:
if (ret == bufsize) {
free(buf);
+ buf = NULL;
bufsize *= 4;
goto retry;
}
@@ -2846,6 +2871,7 @@ retry:
out_free:
free(buf);
+ buf = NULL;
return ret;
}
#else /* linux */
--
1.8.3.1

View File

@ -0,0 +1,32 @@
From ca0eb08b7f58a6ecffc1cb13b17a7fdc2f1cd7f2 Mon Sep 17 00:00:00 2001
From: Shijie Luo <luoshijie1@huawei.com>
Date: Sat, 11 Jan 2020 17:14:38 +0800
Subject: [PATCH] fix chown and mknod failed
remove chown and mknod when user is root.
Signed-off-by: Shijie Luo <luoshijie1@huawei.com>
---
util/install_helper.sh | 6 ------
1 file changed, 6 deletions(-)
diff --git a/util/install_helper.sh b/util/install_helper.sh
index cb649a7..a948fcc 100755
--- a/util/install_helper.sh
+++ b/util/install_helper.sh
@@ -27,13 +27,7 @@ install -D -m 644 "${MESON_SOURCE_ROOT}/util/fuse.conf" \
"${DESTDIR}${sysconfdir}/fuse.conf"
if $useroot; then
- chown root:root "${DESTDIR}${bindir}/fusermount3"
chmod u+s "${DESTDIR}${bindir}/fusermount3"
-
- if test ! -e "${DESTDIR}/dev/fuse"; then
- mkdir -p "${DESTDIR}/dev"
- mknod "${DESTDIR}/dev/fuse" -m 0666 c 10 229
- fi
fi
install -D -m 644 "${MESON_SOURCE_ROOT}/util/udev.rules" \
--
1.8.3.1

View File

@ -0,0 +1,37 @@
From 7757c9011776c5a37bee3fa0c1ca4fab7e4567b2 Mon Sep 17 00:00:00 2001
From: Shijie Luo <luoshijie1@huawei.com>
Date: Fri, 10 Jan 2020 00:55:50 +0000
Subject: [PATCH] fix compile error because of ns colliding
fix compile error because of ns colliding.
Signed-off-by: Shijie Luo <luoshijie1@huawei.com>
---
include/fuse_kernel.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index c632b58..9e02fe3 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -88,12 +88,16 @@
#ifndef _LINUX_FUSE_H
#define _LINUX_FUSE_H
-#include <sys/types.h>
+#ifdef __linux__
+#include <linux/types.h>
+#else
+#include <stdint.h>
#define __u64 uint64_t
#define __s64 int64_t
#define __u32 uint32_t
#define __s32 int32_t
#define __u16 uint16_t
+#endif
/*
* Version negotiation:
--
1.8.3.1

View File

@ -1,34 +0,0 @@
From a17e9cd2c332084092888b3ee67a891ebcba2ac6 Mon Sep 17 00:00:00 2001
From: Shijie Luo <luoshijie1@huawei.com>
Date: Tue, 23 Jul 2019 19:12:56 +0000
Subject: [PATCH] fix fuse crash problem when rm node
When using fuse to mount a filesystem, there is a problem that
when running command "rm" to delete a file, fuse will crash.
This patch fixes the problem.
Signed-off-by: Shijie Luo <luoshijie1@huawei.com>
---
libfuse-fuse-2.9.7/lib/fuse.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/libfuse-fuse-2.9.7/lib/fuse.c b/libfuse-fuse-2.9.7/lib/fuse.c
index 0913388..f9b6b07 100644
--- a/libfuse-fuse-2.9.7/lib/fuse.c
+++ b/libfuse-fuse-2.9.7/lib/fuse.c
@@ -720,10 +720,9 @@ static void unhash_name(struct fuse *f, struct node *node)
*nodep = node->name_next;
node->name_next = NULL;
unref_node(f, node->parent);
- if (node->name != node->inline_name) {
+ if (node->name != node->inline_name)
free(node->name);
- node->name = NULL;
- }
+ node->name = NULL;
node->parent = NULL;
f->name_table.use--;
--
1.8.3.1

View File

@ -1,52 +0,0 @@
From 22ba14e45e84e0bd12a9ab1c9d0460b9ae27c10c Mon Sep 17 00:00:00 2001
From: Peter Lemenkov <lemenkov@gmail.com>
Date: Mon, 9 Aug 2010 12:10:40 +0400
Subject: [PATCH 1/1] More parentheses
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
---
lib/fuse.c | 8 +++-----
lib/fuse_lowlevel.c | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/lib/fuse.c b/lib/fuse.c
index d511964..328ebba 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -991,17 +991,15 @@ static int fuse_compat_open(struct fuse_fs *fs, const char *path,
{
int err;
if (!fs->compat || fs->compat >= 25)
- err = fs->op.open(path, fi);
+ err = (fs->op.open)(path, fi);
else if (fs->compat == 22) {
struct fuse_file_info_compat tmp;
memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)->open(path,
- &tmp);
+ err = (((struct fuse_operations_compat22 *) &fs->op)->open)(path, &tmp);
memcpy(fi, &tmp, sizeof(tmp));
fi->fh = tmp.fh;
} else
- err = ((struct fuse_operations_compat2 *) &fs->op)
- ->open(path, fi->flags);
+ err = (((struct fuse_operations_compat2 *) &fs->op)->open)(path, fi->flags);
return err;
}
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index c86a910..4f19d61 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -716,7 +716,7 @@ static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
fi.flags = arg->flags;
if (req->f->op.open)
- req->f->op.open(req, nodeid, &fi);
+ (req->f->op.open)(req, nodeid, &fi);
else
fuse_reply_open(req, &fi);
}
--
1.7.9.3

View File

@ -1,21 +0,0 @@
diff -up fuse-2.9.2/include/fuse_kernel.h.conflictfix fuse-2.9.2/include/fuse_kernel.h
--- fuse-2.9.2/include/fuse_kernel.h.conflictfix 2013-06-26 09:31:57.862198038 -0400
+++ fuse-2.9.2/include/fuse_kernel.h 2013-06-26 09:32:19.679198365 -0400
@@ -88,12 +88,16 @@
#ifndef _LINUX_FUSE_H
#define _LINUX_FUSE_H
-#include <sys/types.h>
+#ifdef __linux__
+#include <linux/types.h>
+#else
+#include <stdint.h>
#define __u64 uint64_t
#define __s64 int64_t
#define __u32 uint32_t
#define __s32 int32_t
#define __u16 uint16_t
+#endif
/*
* Version negotiation:

Binary file not shown.

BIN
fuse-2.9.9.tar.gz Normal file

Binary file not shown.

View File

@ -1,13 +0,0 @@
diff -up libfuse-fuse-3.0.0/lib/fuse.c.parens libfuse-fuse-3.0.0/lib/fuse.c
--- libfuse-fuse-3.0.0/lib/fuse.c.parens 2017-03-21 09:31:31.979537796 -0400
+++ libfuse-fuse-3.0.0/lib/fuse.c 2017-03-21 09:31:42.676250718 -0400
@@ -1653,7 +1653,7 @@ int fuse_fs_open(struct fuse_fs *fs, con
fprintf(stderr, "open flags: 0x%x %s\n", fi->flags,
path);
- err = fs->op.open(path, fi);
+ err = (fs->op.open)(path, fi);
if (fs->debug && !err)
fprintf(stderr, " open[%llu] flags: 0x%x %s\n",
diff -up libfuse-fuse-3.0.0/lib/fuse_lowlevel.c.parens libfuse-fuse-3.0.0/lib/fuse_lowlevel.c

View File

@ -1,19 +0,0 @@
diff -up libfuse-fuse-3.2.1/util/install_helper.sh.nodev libfuse-fuse-3.2.1/util/install_helper.sh
--- libfuse-fuse-3.2.1/util/install_helper.sh.nodev 2017-11-14 15:48:15.000000000 -0500
+++ libfuse-fuse-3.2.1/util/install_helper.sh 2017-11-16 15:23:20.552413938 -0500
@@ -11,14 +11,9 @@ bindir="$2"
udevrulesdir="$3"
prefix="${MESON_INSTALL_DESTDIR_PREFIX}"
-chown root:root "${prefix}/${bindir}/fusermount3"
+# chown root:root "${prefix}/${bindir}/fusermount3"
chmod u+s "${prefix}/${bindir}/fusermount3"
-if test ! -e "${DESTDIR}/dev/fuse"; then
- mkdir -p "${DESTDIR}/dev"
- mknod "${DESTDIR}/dev/fuse" -m 0666 c 10 229
-fi
-
install -D -m 644 "${MESON_SOURCE_ROOT}/util/udev.rules" \
"${DESTDIR}/${udevrulesdir}/99-fuse3.rules"

Binary file not shown.

BIN
fuse-3.9.0.tar.xz Normal file

Binary file not shown.

View File

@ -1,29 +0,0 @@
From 0aa4f47172f5f9a5001be8cda988b89d4d54874c Mon Sep 17 00:00:00 2001
From: <mashimiao@huawei.com>
Date: Tue, 4 Dec 2018 14:11:31 +0800
Subject: [PATCH] fuse: exit when got EINVAL error
Signed-off-by: <mashimiao@huawei.com>
---
lib/fuse_kern_chan.c | 5 +++++
1 file changed, 5 insertions(+)
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 1096fa3..dc964e1 100644
--- a/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
+++ b/libfuse-fuse-2.9.7/lib/fuse_kern_chan.c
@@ -72,6 +72,11 @@ static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
assert(se != NULL);
+ /* EINVAL means can not reply the request any more */
+ if (err == EINVAL) {
+ fuse_session_exit(se);
+ return 0;
+ }
/* ENOENT means the operation was interrupted */
if (!fuse_session_exited(se) && err != ENOENT)
perror("fuse: writing device");
--
1.8.3.1

View File

@ -1,2 +1,17 @@
# mount_max = 1000
# user_allow_other
# The file /etc/fuse.conf allows for the following parameters:
#
# user_allow_other - Using the allow_other mount option works fine as root, in
# order to have it work as user you need user_allow_other in /etc/fuse.conf as
# well. (This option allows users to use the allow_other option.) You need
# allow_other if you want users other than the owner to access a mounted fuse.
# This option must appear on a line by itself. There is no value, just the
# presence of the option.
#user_allow_other
# mount_max = n - this option sets the maximum number of mounts.
# Currently (2014) it must be typed exactly as shown
# (with a single space before and after the equals sign).
#mount_max = 1000

View File

@ -1,38 +1,20 @@
%global fuse2ver 2.9.7
%global fuse3ver 3.2.3
%global fuse2ver 2.9.9
%global fuse3ver 3.9.0
Name: fuse
Version: %{fuse2ver}
Release: 23
Release: 0
Summary: User space File System of fuse2
License: GPL+ and LGPLv2+
URL: http://fuse.sf.net
#fuse2 sources
Source0: https://github.com/libfuse/libfuse/archive/%{name}-%{fuse2ver}.tar.gz
#fuse3 sources
Source1: https://github.com/libfuse/libfuse/archive/%{name}-%{fuse3ver}.tar.gz
Source1: https://github.com/libfuse/libfuse/archive/%{name}-%{fuse3ver}.tar.xz
Source2: %{name}.conf
Patch1: fuse-3.0.0-More-parentheses.patch
Patch2: fuse-0001-More-parentheses.patch
Patch3: fuse-2.9.2-namespace-conflict-fix.patch
Patch4: fuse-3.2.1-no-dev.patch
Patch6000: CVE-2018-10906.patch
Patch6001: 0015-libfuse-fix-fs-cleanup.patch
Patch6002: 0032-fuse_opt_parse-fix-memory-leak.patch
Patch6003: 0530-fusermount-refuse-unknown-options.patch
Patch6004: 0531-fusermount-whitelist-known-good-filesystems-for-moun.patch
Patch6005: 0533-fusermount-Fix-memory-leaks.patch
Patch6006: 0545-Fix-invalid-free-of-memory-pointer-in-struct-fuse_bu.patch
Patch6007: 0546-Fix-memory-leak-of-FUSE-modules.patch
Patch6008: Fix-readdir-bug-when-a-non-zero-offset-is-specified-.patch
Patch9000: bugfix-increase-idle-thread.patch
Patch9001: bugfix-invalid-free-and-core.patch
Patch9002: bugfix-memory-leak-and-wild-ptr.patch
Patch9003: fuse-exit-when-got-EINVAL-error.patch
Patch9004: fix-fuse-crash-problem-when-rm-node.patch
Patch1: fix-compile-error-because-of-ns-colliding.patch
Patch2: fix-chown-and-mknod-failed.patch
BuildRequires: libselinux-devel, pkgconfig, systemd-udev, meson, fdupes
BuildRequires: autoconf, automake, libtool, gettext-devel, ninja-build
@ -99,36 +81,18 @@ This contains man files for the using of fuse
%setup -q -T -c -n fuse2and3 -a0 -a1
# fuse 2
pushd lib%{name}-%{name}-%{fuse2ver}
./makeconf.sh
%patch2 -p1
%patch3 -p1
%patch6008 -p1
pushd %{name}-%{fuse2ver}
%patch1 -p1
popd
# fuse 3
pushd lib%{name}-%{name}-%{fuse3ver}
%patch1 -p1
%patch4 -p1
%patch6003 -p1
%patch6005 -p1
%patch6006 -p1
%patch6007 -p1
pushd %{name}-%{fuse3ver}
%patch2 -p1
popd
%patch9000 -p1
%patch9001 -p1
%patch9002 -p1
%patch9003 -p1
%patch6000 -p1
%patch9004 -p1
%patch6001 -p1
%patch6002 -p1
%patch6004 -p1
%build
# fuse 2
pushd lib%{name}-%{name}-%{fuse2ver}
pushd %{name}-%{fuse2ver}
export MOUNT_FUSE_PATH="%{_sbindir}"
export CFLAGS="%{optflags} -D_GNU_SOURCE"
%configure --enable-lib
@ -136,19 +100,19 @@ export CFLAGS="%{optflags} -D_GNU_SOURCE"
popd
# fuse 3
pushd lib%{name}-%{name}-%{fuse3ver}
pushd %{name}-%{fuse3ver}
%meson
%meson_build
popd
%install
# fuse 2
pushd lib%{name}-%{name}-%{fuse2ver}
pushd %{name}-%{fuse2ver}
%make_install
popd
# fuse 3
pushd lib%{name}-%{name}-%{fuse3ver}
pushd %{name}-%{fuse3ver}
export MESON_INSTALL_DESTDIR_PREFIX=%{buildroot}/usr
%meson_install
popd
@ -172,8 +136,8 @@ install -p -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}
%postun -n fuse3 -p /sbin/ldconfig
%files
%doc libfuse-fuse-%{fuse2ver}/{AUTHORS,ChangeLog,NEWS,README*}
%license libfuse-fuse-%{fuse2ver}/COPYING
%doc fuse-%{fuse2ver}/{AUTHORS,ChangeLog,NEWS,README*}
%license fuse-%{fuse2ver}/COPYING
%{_sbindir}/mount.fuse
%attr(4755,root,root) %{_bindir}/fusermount
%{_bindir}/ulockmgr_server
@ -182,8 +146,8 @@ install -p -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}
%config(noreplace) %{_sysconfdir}/%{name}.conf
%files -n fuse3
%doc libfuse-fuse-%{fuse3ver}/{AUTHORS,ChangeLog*,README*}
%license libfuse-fuse-%{fuse3ver}/COPYING
%doc fuse-%{fuse3ver}/{AUTHORS,ChangeLog*,README*}
%license fuse-%{fuse3ver}/LICENSE fuse-%{fuse3ver}/*GPL2.txt
%{_sbindir}/mount.fuse3
%attr(4755,root,root) %{_bindir}/fusermount3
%{_libdir}/libfuse3.so.*
@ -208,6 +172,13 @@ install -p -m 0644 %{SOURCE2} %{buildroot}%{_sysconfdir}
%changelog
* Sat Jan 11 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.9.9-0
- Type:enhancement
- ID:NA
- SUG:NA
- DESC:update fuse2 from 2.9.7 to 2.9.9,
update fuse3 from 3.2.3 to 3.9.0
* Sat Dec 28 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.7-23
- Type:bugfix
- ID:NA