diff --git a/fuse-umount-race-fix.patch b/fuse-umount-race-fix.patch new file mode 100644 index 0000000..41f5f43 --- /dev/null +++ b/fuse-umount-race-fix.patch @@ -0,0 +1,123 @@ +--- + lib/mount_util.c | 59 ++++++++++++++++++++++++++++++++++++++++++++---------- + lib/mount_util.h | 1 + util/fusermount.c | 9 +++++++- + 3 files changed, 58 insertions(+), 11 deletions(-) + +Index: fuse-2.8.5/lib/mount_util.c +=================================================================== +--- fuse-2.8.5.orig/lib/mount_util.c 2010-09-28 10:03:09.000000000 +0200 ++++ fuse-2.8.5/lib/mount_util.c 2010-12-02 14:58:34.000000000 +0100 +@@ -140,14 +140,6 @@ static int add_mount(const char *prognam + goto out_restore; + } + if (res == 0) { +- /* +- * Hide output, because old versions don't support +- * --no-canonicalize +- */ +- int fd = open("/dev/null", O_RDONLY); +- dup2(fd, 1); +- dup2(fd, 2); +- + sigprocmask(SIG_SETMASK, &oldmask, NULL); + setuid(geteuid()); + execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", +@@ -178,8 +170,6 @@ int fuse_mnt_add_mount(const char *progn + return 0; + + res = add_mount(progname, fsname, mnt, type, opts); +- if (res == -1) +- res = add_mount_legacy(progname, fsname, mnt, type, opts); + + return res; + } +@@ -243,6 +233,55 @@ int fuse_mnt_umount(const char *progname + return exec_umount(progname, rel_mnt, lazy); + } + ++static int remove_mount(const char *progname, const char *mnt) ++{ ++ int res; ++ int status; ++ sigset_t blockmask; ++ sigset_t oldmask; ++ ++ sigemptyset(&blockmask); ++ sigaddset(&blockmask, SIGCHLD); ++ res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); ++ if (res == -1) { ++ fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); ++ return -1; ++ } ++ ++ res = fork(); ++ if (res == -1) { ++ fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); ++ goto out_restore; ++ } ++ if (res == 0) { ++ sigprocmask(SIG_SETMASK, &oldmask, NULL); ++ setuid(geteuid()); ++ execl("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", ++ "--fake", mnt, NULL); ++ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", ++ progname, strerror(errno)); ++ exit(1); ++ } ++ res = waitpid(res, &status, 0); ++ if (res == -1) ++ fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); ++ ++ if (status != 0) ++ res = -1; ++ ++ out_restore: ++ sigprocmask(SIG_SETMASK, &oldmask, NULL); ++ return res; ++} ++ ++int fuse_mnt_remove_mount(const char *progname, const char *mnt) ++{ ++ if (!mtab_needs_update(mnt)) ++ return 0; ++ ++ return remove_mount(progname, mnt); ++} ++ + char *fuse_mnt_resolve_path(const char *progname, const char *orig) + { + char buf[PATH_MAX]; +Index: fuse-2.8.5/lib/mount_util.h +=================================================================== +--- fuse-2.8.5.orig/lib/mount_util.h 2010-06-23 15:04:14.000000000 +0200 ++++ fuse-2.8.5/lib/mount_util.h 2010-12-02 14:58:34.000000000 +0100 +@@ -10,6 +10,7 @@ + + int fuse_mnt_add_mount(const char *progname, const char *fsname, + const char *mnt, const char *type, const char *opts); ++int fuse_mnt_remove_mount(const char *progname, const char *mnt); + int fuse_mnt_umount(const char *progname, const char *abs_mnt, + const char *rel_mnt, int lazy); + char *fuse_mnt_resolve_path(const char *progname, const char *orig); +Index: fuse-2.8.5/util/fusermount.c +=================================================================== +--- fuse-2.8.5.orig/util/fusermount.c 2010-09-28 10:04:13.000000000 +0200 ++++ fuse-2.8.5/util/fusermount.c 2010-12-02 14:58:34.000000000 +0100 +@@ -407,8 +407,15 @@ static int unmount_fuse_locked(const cha + if (res == -1) + goto out; + +- res = fuse_mnt_umount(progname, mnt, last, lazy); ++ res = umount2(last, lazy ? 2 : 0); ++ if (res == -1 && !quiet) { ++ fprintf(stderr, ++ "%s: failed to unmount %s: %s\n", ++ progname, mnt, strerror(errno)); ++ } + ++ if (res == 0) ++ res = fuse_mnt_remove_mount(progname, mnt); + out: + free(copy); + if (currdir_fd != -1) { diff --git a/fuse.changes b/fuse.changes index 925d148..a8abd5d 100644 --- a/fuse.changes +++ b/fuse.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Nov 16 16:16:04 CET 2010 - mszeredi@suse.cz + +- Fix symlink attack for mount and umount [bnc#651598] + ------------------------------------------------------------------- Wed Oct 27 15:34:16 CEST 2010 - mszeredi@suse.cz diff --git a/fuse.spec b/fuse.spec index f15a31d..83c56c9 100644 --- a/fuse.spec +++ b/fuse.spec @@ -21,7 +21,7 @@ Name: fuse Summary: User space File System Version: 2.8.5 -Release: 2 +Release: 3 License: GPLv2+ ; LGPLv2.1+ Group: System/Filesystems # http://sourceforge.net/projects/fuse/files/fuse-2.X/%%{version}/fuse-%%{version}.tar.gz/download @@ -30,8 +30,10 @@ Source2: fuse.rpmlintrc Source3: baselibs.conf Patch: fuse-install-fix.diff Patch2: fuse-pc-remove-libdir-from-Libs.diff +Patch3: fuse-umount-race-fix.patch Url: http://fuse.sourceforge.net BuildRoot: %{_tmppath}/%{name}-%{version}-build +Requires: util-linux >= 2.18 Requires: licenses BuildRequires: licenses pkg-config %if 0%{?suse_version} @@ -222,6 +224,7 @@ Authors: %if "%{_exec_prefix}" == "/" || "%{_exec_prefix}" == "/usr" %patch2 %endif +%patch3 -p1 %build export CFLAGS="$RPM_OPT_FLAGS -g -fno-strict-aliasing"